ipprobe-mt_mngr.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ipprobe-mt_mngr.c 347265 2009-11-19 13:55:39Z kdickman $
00003  *
00004  * This code is provided as is by Juniper Networks SDK Developer Support.
00005  * It is provided with no warranties or guarantees, and Juniper Networks
00006  * will not provide support or maintenance of this code in any fashion.
00007  * The code is provided only to help a developer better understand how
00008  * the SDK can be used.
00009  * 
00010  * Copyright (c) 2009, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00023 #include <string.h>
00024 #include <errno.h>
00025 #include <pthread.h>
00026 #include <sys/types.h>
00027 #include <sys/queue.h>
00028 #include <isc/eventlib.h>
00029 #include <netinet/in.h>
00030 #include <netinet/in_systm.h>
00031 #include <netinet/ip.h>
00032 #include <netinet/udp.h>
00033 #include <netinet/ip_icmp.h>
00034 #include <jnx/aux_types.h>
00035 #include <jnx/bits.h>
00036 #include <jnx/patricia.h>
00037 #include <jnx/pconn.h>
00038 #include <jnx/junos_trace.h>
00039 #include "ipprobe-mt.h"
00040 #include IPPROBE_MT_OUT_H
00041 
00042 probe_mngr_t probe_mngr;
00043 
00044 static LIST_HEAD(, probe_s)  probe_list;
00045 
00055 static probe_t *
00056 probe_get_by_ssn (pconn_session_t *ssn)
00057 {
00058     probe_t *probe;
00059 
00060     LIST_FOREACH(probe, &probe_list, entry) {
00061         if (probe->ssn == ssn) {
00062             return probe;
00063         }
00064     }
00065     return NULL;
00066 }
00067 
00077 static probe_t *
00078 probe_get_by_name (char *name)
00079 {
00080     probe_t *probe;
00081 
00082     LIST_FOREACH(probe, &probe_list, entry) {
00083         if (strncmp(name, probe->params.name, sizeof(probe->params.name))
00084                 == 0) {
00085             return probe;
00086         }
00087     }
00088     return NULL;
00089 }
00090 
00095 static status_t
00096 probe_mngr_msg_hdlr (pconn_session_t *ssn, ipc_msg_t *msg, void *cookie UNUSED)
00097 {
00098     probe_t *probe;
00099 
00100     if (msg->subtype == PROBE_MGMT_MSG_REG) {
00101         PROBE_TRACE(PROBE_TF_NORMAL, "%s: Received probe register message.",
00102             __func__);
00103         probe = probe_get_by_name((char *)msg->data);
00104         if (probe) {
00105             probe->ssn = ssn;
00106 
00107             /* Pass the first destination to the thread. */
00108             pconn_server_send(ssn, PROBE_MGMT_MSG_ADD_DST, &probe->dst_first,
00109                     sizeof(probe->dst_first));
00110         } else {
00111             PROBE_TRACE(PROBE_TF_MNGR, "%s: Probe thrd %s does not exist.",
00112                 __func__);
00113         }
00114     }
00115     return 0;
00116 }
00117 
00122 static void
00123 probe_mngr_event_hdlr (pconn_session_t *ssn, pconn_event_t event,
00124         void *cookie UNUSED)
00125 {
00126     probe_t *probe;
00127 
00128     switch (event) {
00129     case PCONN_EVENT_ESTABLISHED:
00130         /* A client is connected. */
00131         PROBE_TRACE(PROBE_TF_NORMAL, "%s: Client 0x%x is connected.",
00132                 __func__, ssn);
00133         break;
00134     case PCONN_EVENT_SHUTDOWN:
00135         /* A client is dwon. */
00136         PROBE_TRACE(PROBE_TF_NORMAL, "%s: Client 0x%x is gone.",
00137                 __func__, ssn);
00138         probe = probe_get_by_ssn(ssn);
00139         if (probe) {
00140             probe->ssn = NULL;
00141         }
00142         break;
00143     default:
00144         PROBE_LOG(LOG_ERR, "%s: Invalid event %d!", __func__, event);
00145     }
00146 }
00147 
00152 static void
00153 probe_mngr_probe_close_all (void)
00154 {
00155     probe_t *probe;
00156 
00157     /* Close all running probe threads. */
00158     LIST_FOREACH(probe, &probe_list, entry) {
00159         if (probe->tid) {
00160             if (pthread_cancel(probe->tid) < 0) {
00161                 PROBE_LOG(LOG_ERR, "%s: Close thread 0x%x ERROR(%d)!",
00162                         __func__, probe->tid, errno);
00163             } else {
00164                 PROBE_TRACE(PROBE_TF_MNGR, "%s: Thread 0x%08x is canceled.",
00165                         __func__, probe->tid);
00166             }
00167         }
00168     }
00169 
00170     /* Wait till all running probe threads are closed. */
00171     LIST_FOREACH(probe, &probe_list, entry) {
00172         if (probe->tid) {
00173             if (pthread_join(probe->tid, NULL) < 0) {
00174                 PROBE_LOG(LOG_ERR, "%s: Wait thread 0x%x close ERROR(%d)!",
00175                         __func__, probe->tid, errno);
00176             } else {
00177                 PROBE_TRACE(PROBE_TF_MNGR, "%s: Thread 0x%08x is closed.",
00178                         __func__, probe->tid);
00179             }
00180             probe->tid = 0;
00181         }
00182     }
00183 }
00184 
00196 int
00197 probe_mngr_probe_start (char *name, in_addr_t dst_addr)
00198 {
00199     probe_t *probe;
00200     probe_params_t *params;
00201 
00202     params = probe_params_get(name);
00203     if (!params) {
00204         PROBE_TRACE(PROBE_TF_MNGR, "%s: Probe %s is not configured.",
00205                 __func__, name);
00206         return -1;
00207     }
00208     probe = probe_get_by_name(name);
00209     if (probe) {
00210         if (probe->tid) {
00211             PROBE_TRACE(PROBE_TF_MNGR, "%s: Probe thread %s is running, "
00212                     "add dst address 0x%08x.", __func__, name, dst_addr);
00213             pconn_server_send(probe->ssn, PROBE_MGMT_MSG_ADD_DST, &dst_addr,
00214                     sizeof(dst_addr));
00215         } else {
00216             PROBE_TRACE(PROBE_TF_MNGR, "%s: Probe thread %s is closed, "
00217                     "reopen it.", __func__, name);
00218             probe->dst_first = dst_addr;
00219             pthread_create(&probe->tid, NULL, (void *)probe_thrd_entry, probe);
00220         }
00221     } else {
00222         probe = calloc(1, sizeof(*probe));
00223         INSIST_ERR(probe);
00224         bcopy(params, &probe->params, sizeof(probe->params));
00225         probe->dst_first = dst_addr;
00226         LIST_INSERT_HEAD(&probe_list, probe, entry);
00227         PROBE_TRACE(PROBE_TF_MNGR, "%s: Probe thread %s does not exist, "
00228                     "create it.", __func__, name);
00229         PROBE_TRACE(PROBE_TF_MNGR, "%s: protocol %d, port %d, size %d, "
00230                 "count %d, interval %d.", __func__,
00231                 params->proto, params->dst_port, params->pkt_size,
00232                 params->pkt_count, params->pkt_interval);
00233         pthread_create(&probe->tid, NULL, (void *)probe_thrd_entry, probe);
00234     }
00235     return 0;
00236 }
00237 
00247 patroot *
00248 probe_mngr_probe_result_get (char *name)
00249 {
00250     probe_t *probe;
00251 
00252     probe = probe_get_by_name(name);
00253     if (!probe) {
00254         PROBE_LOG(LOG_ERR, "%s: Did not find the probe %s.", __func__, name);
00255         return NULL;
00256     }
00257     return &probe->dst_pat;
00258 }
00259 
00269 int
00270 probe_mngr_probe_stop (char *name)
00271 {
00272     probe_t *probe;
00273 
00274     probe = probe_get_by_name(name);
00275     if (!probe) {
00276         PROBE_LOG(LOG_ERR, "%s: Did not find the probe %s.", __func__, name);
00277         goto ret_err;
00278     }
00279     if (probe->tid) {
00280         if (pthread_cancel(probe->tid) < 0) {
00281             PROBE_LOG(LOG_ERR, "%s: Close thread 0x%x ERROR(%d)!",
00282                     __func__, probe->tid, errno);
00283             goto ret_err;
00284         } else {
00285             PROBE_TRACE(PROBE_TF_MNGR, "%s: Thread 0x%08x is canceled.",
00286                     __func__, probe->tid);
00287         }
00288         if (pthread_join(probe->tid, NULL) < 0) {
00289             PROBE_LOG(LOG_ERR, "%s: Wait thread 0x%x close ERROR(%d)!",
00290                     __func__, probe->tid, errno);
00291             goto ret_err;
00292         } else {
00293             PROBE_TRACE(PROBE_TF_MNGR, "%s: Thread 0x%08x is closed.",
00294                     __func__, probe->tid);
00295         }
00296         probe->tid = 0;
00297     }
00298     return 0;
00299 
00300 ret_err:
00301     return -1;
00302 }
00303 
00313 int
00314 probe_mngr_probe_clear (char *name)
00315 {
00316     probe_t *probe;
00317     probe_dst_t *dst;
00318 
00319     probe = probe_get_by_name(name);
00320     if (!probe) {
00321         PROBE_LOG(LOG_ERR, "%s: Did not find the probe %s.", __func__, name);
00322         return -1;
00323     }
00324     if (probe->tid) {
00325         PROBE_LOG(LOG_ERR, "%s: Probe %s is running.", __func__, name);
00326         return -1;
00327     }
00328     while ((dst = (probe_dst_t *)patricia_find_next(&probe->dst_pat, NULL))) {
00329         patricia_delete(&probe->dst_pat, (patnode *)dst);
00330         free(dst);
00331     }
00332     LIST_REMOVE(probe, entry);
00333     free(probe);
00334     return 0;
00335 }
00336 
00341 void
00342 probe_mngr_close (void)
00343 {
00344     probe_t *probe;
00345 
00346     /* Close all running probe threads. */
00347     probe_mngr_probe_close_all();
00348 
00349     /* Close the server and all sessions. */
00350     pconn_server_shutdown(probe_mngr.hdl);
00351     probe_mngr.hdl = NULL;
00352 
00353     /* Clear the session in local probe thread list. */
00354     LIST_FOREACH(probe, &probe_list, entry) {
00355         probe->ssn = NULL;
00356     }
00357 }
00358 
00368 int
00369 probe_mngr_open (uint16_t port)
00370 {
00371     pconn_server_params_t params;
00372 
00373     if (probe_mngr.hdl) {
00374         if (probe_mngr.port == port) {
00375             return 0;
00376         } else {
00377             probe_mngr_close();
00378         }
00379     }
00380     probe_mngr.port = port;
00381 
00382     LIST_INIT(&probe_list);
00383 
00384     bzero(&params, sizeof(params));
00385     params.pconn_port = probe_mngr.port;
00386     params.pconn_event_handler = probe_mngr_event_hdlr;
00387 
00388     probe_mngr.hdl = pconn_server_create(&params, probe_mngr.ev_ctx,
00389             probe_mngr_msg_hdlr, NULL);
00390     if (!probe_mngr.hdl) {
00391         PROBE_LOG(LOG_ERR, "%s: Open probe manager ERROR!", __func__);
00392         return -1;
00393     }
00394     PROBE_TRACE(PROBE_TF_NORMAL, "%s: The probe manager is open on port %d.",
00395             __func__, probe_mngr.port);
00396     return 0;
00397 }
00398 
00408 int
00409 probe_mngr_init (evContext lev_ctx)
00410 {
00411     bzero(&probe_mngr, sizeof(probe_mngr));
00412     probe_mngr.port = PROBE_MNGR_PORT_DEFAULT;
00413     probe_mngr.ev_ctx = lev_ctx;
00414 
00415     return 0;
00416 }
00417 

2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:27:00 2010 for SDK Your Net Corporation IP Probe MT: ipprobe-mt 1.0 by Doxygen 1.5.1