snmp_transport.c

00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #include <stdio.h>
00004 #if HAVE_STRING_H
00005 #include <string.h>
00006 #else
00007 #include <strings.h>
00008 #endif
00009 #include <sys/types.h>
00010 
00011 #if HAVE_STDLIB_H
00012 #include <stdlib.h>
00013 #endif
00014 
00015 #if HAVE_DMALLOC_H
00016 #include <dmalloc.h>
00017 #endif
00018 
00019 #include <net-snmp/output_api.h>
00020 #include <net-snmp/utilities.h>
00021 
00022 #include <net-snmp/library/snmp_transport.h>
00023 #include <net-snmp/library/snmpUDPDomain.h>
00024 #ifdef SNMP_TRANSPORT_TLS_DOMAIN
00025 #include <net-snmp/library/snmpTLSDomain.h>
00026 #endif
00027 #ifdef SNMP_TRANSPORT_TCP_DOMAIN
00028 #include <net-snmp/library/snmpTCPDomain.h>
00029 #endif
00030 #ifdef SNMP_TRANSPORT_IPX_DOMAIN
00031 #include <net-snmp/library/snmpIPXDomain.h>
00032 #endif
00033 #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
00034 #include <net-snmp/library/snmpUnixDomain.h>
00035 #endif
00036 #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
00037 #include <net-snmp/library/snmpAAL5PVCDomain.h>
00038 #endif
00039 #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
00040 #include <net-snmp/library/snmpUDPIPv6Domain.h>
00041 #endif
00042 #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
00043 #include <net-snmp/library/snmpTCPIPv6Domain.h>
00044 #endif
00045 #include <net-snmp/library/snmp_api.h>
00046 
00047 
00048 /*
00049  * Our list of supported transport domains.  
00050  */
00051 
00052 static netsnmp_tdomain *domain_list = NULL;
00053 
00054 
00055 
00056 /*
00057  * The standard SNMP domains.  
00058  */
00059 
00060 oid             netsnmpUDPDomain[] = { 1, 3, 6, 1, 6, 1, 1 };
00061 size_t          netsnmpUDPDomain_len = OID_LENGTH(netsnmpUDPDomain);
00062 oid             netsnmpCLNSDomain[] = { 1, 3, 6, 1, 6, 1, 2 };
00063 size_t          netsnmpCLNSDomain_len = OID_LENGTH(netsnmpCLNSDomain);
00064 oid             netsnmpCONSDomain[] = { 1, 3, 6, 1, 6, 1, 3 };
00065 size_t          netsnmpCONSDomain_len = OID_LENGTH(netsnmpCONSDomain);
00066 oid             netsnmpDDPDomain[] = { 1, 3, 6, 1, 6, 1, 4 };
00067 size_t          netsnmpDDPDomain_len = OID_LENGTH(netsnmpDDPDomain);
00068 oid             netsnmpIPXDomain[] = { 1, 3, 6, 1, 6, 1, 5 };
00069 size_t          netsnmpIPXDomain_len = OID_LENGTH(netsnmpIPXDomain);
00070 
00071 
00072 
00073 static void     netsnmp_tdomain_dump(void);
00074 
00075 
00076 /*
00077  * Make a deep copy of an netsnmp_transport.  
00078  */
00079 
00080 netsnmp_transport *
00081 netsnmp_transport_copy(netsnmp_transport *t)
00082 {
00083     netsnmp_transport *n = NULL;
00084 
00085     n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
00086     if (n == NULL) {
00087         return NULL;
00088     }
00089     memset(n, 0, sizeof(netsnmp_transport));
00090 
00091     if (t->domain != NULL) {
00092         n->domain = t->domain;
00093         n->domain_length = t->domain_length;
00094     } else {
00095         n->domain = NULL;
00096         n->domain_length = 0;
00097     }
00098 
00099     if (t->local != NULL) {
00100         n->local = (u_char *) malloc(t->local_length);
00101         if (n->local == NULL) {
00102             netsnmp_transport_free(n);
00103             return NULL;
00104         }
00105         n->local_length = t->local_length;
00106         memcpy(n->local, t->local, t->local_length);
00107     } else {
00108         n->local = NULL;
00109         n->local_length = 0;
00110     }
00111 
00112     if (t->remote != NULL) {
00113         n->remote = (u_char *) malloc(t->remote_length);
00114         if (n->remote == NULL) {
00115             netsnmp_transport_free(n);
00116             return NULL;
00117         }
00118         n->remote_length = t->remote_length;
00119         memcpy(n->remote, t->remote, t->remote_length);
00120     } else {
00121         n->remote = NULL;
00122         n->remote_length = 0;
00123     }
00124 
00125     if (t->data != NULL && t->data_length > 0) {
00126         n->data = malloc(t->data_length);
00127         if (n->data == NULL) {
00128             netsnmp_transport_free(n);
00129             return NULL;
00130         }
00131         n->data_length = t->data_length;
00132         memcpy(n->data, t->data, t->data_length);
00133     } else {
00134         n->data = NULL;
00135         n->data_length = 0;
00136     }
00137 
00138     n->msgMaxSize = t->msgMaxSize;
00139     n->f_accept = t->f_accept;
00140     n->f_recv = t->f_recv;
00141     n->f_send = t->f_send;
00142     n->f_close = t->f_close;
00143     n->f_fmtaddr = t->f_fmtaddr;
00144     n->sock = t->sock;
00145     n->flags = t->flags;
00146 
00147     return n;
00148 }
00149 
00150 
00151 
00152 void
00153 netsnmp_transport_free(netsnmp_transport *t)
00154 {
00155     if (NULL == t)
00156         return;
00157 
00158     if (t->local != NULL) {
00159         SNMP_FREE(t->local);
00160     }
00161     if (t->remote != NULL) {
00162         SNMP_FREE(t->remote);
00163     }
00164     if (t->data != NULL) {
00165         SNMP_FREE(t->data);
00166     }
00167     SNMP_FREE(t);
00168 }
00169 
00170 
00171 
00172 int
00173 netsnmp_tdomain_support(const oid * in_oid,
00174                         size_t in_len,
00175                         const oid ** out_oid, size_t * out_len)
00176 {
00177     netsnmp_tdomain *d = NULL;
00178 
00179     for (d = domain_list; d != NULL; d = d->next) {
00180         if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) {
00181             if (out_oid != NULL && out_len != NULL) {
00182                 *out_oid = d->name;
00183                 *out_len = d->name_length;
00184             }
00185             return 1;
00186         }
00187     }
00188     return 0;
00189 }
00190 
00191 
00192 
00193 void
00194 netsnmp_tdomain_init(void)
00195 {
00196     DEBUGMSGTL(("tdomain", "netsnmp_tdomain_init() called\n"));
00197     netsnmp_udp_ctor();
00198 #ifdef SNMP_TRANSPORT_STD_DOMAIN
00199     netsnmp_std_ctor();
00200 #endif
00201 #ifdef SNMP_TRANSPORT_TCP_DOMAIN
00202     netsnmp_tcp_ctor();
00203 #endif
00204 #ifdef SNMP_TRANSPORT_IPX_DOMAIN
00205     netsnmp_ipx_ctor();
00206 #endif
00207 #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
00208     netsnmp_unix_ctor();
00209 #endif
00210 #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
00211     netsnmp_aal5pvc_ctor();
00212 #endif
00213 #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
00214     netsnmp_udp6_ctor();
00215 #endif
00216 #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
00217     netsnmp_tcp6_ctor();
00218 #endif
00219     netsnmp_tdomain_dump();
00220 }
00221 
00222 void
00223 netsnmp_clear_tdomain_list(void)
00224 {
00225     netsnmp_tdomain *list = domain_list, *next = NULL;
00226     DEBUGMSGTL(("tdomain", "clear_tdomain_list() called\n"));
00227 
00228     while (list != NULL) {
00229         next = list->next;
00230         SNMP_FREE(list->prefix);
00231         /* attention!! list itself is not in the heap, so we must not free it! */
00232         list = next;
00233     }
00234     domain_list = NULL;
00235 }
00236 
00237 
00238 static void
00239 netsnmp_tdomain_dump(void)
00240 {
00241     netsnmp_tdomain *d;
00242     int i = 0;
00243 
00244     DEBUGMSGTL(("tdomain", "domain_list -> "));
00245     for (d = domain_list; d != NULL; d = d->next) {
00246         DEBUGMSG(("tdomain", "{ "));
00247         DEBUGMSGOID(("tdomain", d->name, d->name_length));
00248         DEBUGMSG(("tdomain", ", \""));
00249         for (i = 0; d->prefix[i] != NULL; i++) {
00250             DEBUGMSG(("tdomain", "%s%s", d->prefix[i],
00251                       (d->prefix[i + 1]) ? "/" : ""));
00252         }
00253         DEBUGMSG(("tdomain", "\" } -> "));
00254     }
00255     DEBUGMSG(("tdomain", "[NIL]\n"));
00256 }
00257 
00258 
00259 
00260 int
00261 netsnmp_tdomain_register(netsnmp_tdomain *n)
00262 {
00263     netsnmp_tdomain **prevNext = &domain_list, *d;
00264 
00265     if (n != NULL) {
00266         for (d = domain_list; d != NULL; d = d->next) {
00267             if (netsnmp_oid_equals(n->name, n->name_length,
00268                                 d->name, d->name_length) == 0) {
00269                 /*
00270                  * Already registered.  
00271                  */
00272                 return 0;
00273             }
00274             prevNext = &(d->next);
00275         }
00276         n->next = NULL;
00277         *prevNext = n;
00278         return 1;
00279     } else {
00280         return 0;
00281     }
00282 }
00283 
00284 
00285 
00286 int
00287 netsnmp_tdomain_unregister(netsnmp_tdomain *n)
00288 {
00289     netsnmp_tdomain **prevNext = &domain_list, *d;
00290 
00291     if (n != NULL) {
00292         for (d = domain_list; d != NULL; d = d->next) {
00293             if (netsnmp_oid_equals(n->name, n->name_length,
00294                                 d->name, d->name_length) == 0) {
00295                 *prevNext = n->next;
00296                 SNMP_FREE(n->prefix);
00297                 return 1;
00298             }
00299             prevNext = &(d->next);
00300         }
00301         return 0;
00302     } else {
00303         return 0;
00304     }
00305 }
00306 
00307 
00308 
00309 netsnmp_transport *
00310 netsnmp_tdomain_transport(const char *str, int local,
00311                           const char *default_domain)
00312 {
00313     netsnmp_tdomain *d;
00314     netsnmp_transport *t = NULL;
00315     const char     *spec, *addr;
00316     char           *cp, *mystring;
00317     int             i;
00318 
00319     if (str == NULL) {
00320         return NULL;
00321     }
00322 
00323     if ((mystring = strdup(str)) == NULL) {
00324         DEBUGMSGTL(("tdomain", "can't strdup(\"%s\")\n", str));
00325         return NULL;
00326     }
00327 
00328     if ((cp = strchr(mystring, ':')) == NULL) {
00329         /*
00330          * There doesn't appear to be a transport specifier.  
00331          */
00332         DEBUGMSGTL(("tdomain", "no specifier in \"%s\"\n", mystring));
00333         if (*mystring == '/') {
00334             spec = "unix";
00335             addr = mystring;
00336         } else {
00337             if (default_domain) {
00338                 spec = default_domain;
00339             } else {
00340                 spec = "udp";
00341             }
00342             addr = mystring;
00343         }
00344     } else {
00345         *cp = '\0';
00346         spec = mystring;
00347         addr = cp + 1;
00348     }
00349     DEBUGMSGTL(("tdomain", "specifier \"%s\" address \"%s\"\n", spec,
00350                 addr));
00351 
00352     for (d = domain_list; d != NULL; d = d->next) {
00353         for (i = 0; d->prefix[i] != NULL; i++) {
00354             if (strcasecmp(d->prefix[i], spec) == 0) {
00355                 DEBUGMSGTL(("tdomain", "specifier \"%s\" matched\n",
00356                             spec));
00357                 t = d->f_create_from_tstring(addr, local);
00358                 SNMP_FREE(mystring);
00359                 return t;
00360             }
00361         }
00362     }
00363 
00364     /*
00365      * Okay no match so far.  Consider the possibility that we have something
00366      * like hostname.domain.com:port which will have confused the parser above.
00367      * Try and match again with the appropriate default domain.  
00368      */
00369 
00370     if (default_domain) {
00371         spec = default_domain;
00372     } else {
00373         spec = "udp";
00374     }
00375     if (cp) {
00376         *cp = ':';
00377     }
00378 
00379     addr = mystring;
00380     DEBUGMSGTL(("tdomain",
00381                 "try again with specifier \"%s\" address \"%s\"\n", spec,
00382                 addr));
00383 
00384     for (d = domain_list; d != NULL; d = d->next) {
00385         for (i = 0; d->prefix[i] != NULL; i++) {
00386             if (strcmp(d->prefix[i], spec) == 0) {
00387                 DEBUGMSGTL(("tdomain", "specifier \"%s\" matched\n",
00388                             spec));
00389                 t = d->f_create_from_tstring(addr, local);
00390                 SNMP_FREE(mystring);
00391                 return t;
00392             }
00393         }
00394     }
00395 
00396     snmp_log(LOG_ERR, "No support for requested transport domain \"%s\"\n",
00397              spec);
00398     SNMP_FREE(mystring);
00399     return NULL;
00400 }
00401 
00402 
00403 netsnmp_transport *
00404 netsnmp_tdomain_transport_oid(const oid * dom,
00405                               size_t dom_len,
00406                               const u_char * o, size_t o_len, int local)
00407 {
00408     netsnmp_tdomain *d;
00409     int             i;
00410 
00411     DEBUGMSGTL(("tdomain", "domain \""));
00412     DEBUGMSGOID(("tdomain", dom, dom_len));
00413     DEBUGMSG(("tdomain", "\"\n"));
00414 
00415     for (d = domain_list; d != NULL; d = d->next) {
00416         for (i = 0; d->prefix[i] != NULL; i++) {
00417             if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
00418                 0) {
00419                 return d->f_create_from_ostring(o, o_len, local);
00420             }
00421         }
00422     }
00423 
00424     snmp_log(LOG_ERR, "No support for requested transport domain\n");
00425     return NULL;
00426 }
00427 
00428 
00431 int
00432 netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list,
00433                               netsnmp_transport *transport)
00434 {
00435     netsnmp_transport_list *newptr =
00436         SNMP_MALLOC_TYPEDEF(netsnmp_transport_list);
00437 
00438     if (!newptr)
00439         return 1;
00440 
00441     newptr->next = *transport_list;
00442     newptr->transport = transport;
00443 
00444     *transport_list = newptr;
00445 
00446     return 0;
00447 }
00448 
00449 
00452 int
00453 netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list,
00454                                    netsnmp_transport *transport)
00455 {
00456     netsnmp_transport_list *ptr = *transport_list, *lastptr = NULL;
00457 
00458     while (ptr && ptr->transport != transport) {
00459         lastptr = ptr;
00460         ptr = ptr->next;
00461     }
00462 
00463     if (!ptr)
00464         return 1;
00465 
00466     if (lastptr)
00467         lastptr->next = ptr->next;
00468     else
00469         *transport_list = ptr->next;
00470 
00471     SNMP_FREE(ptr);
00472 
00473     return 0;
00474 }

net-snmpに対してSat Sep 5 13:14:25 2009に生成されました。  doxygen 1.4.7