snmp_transport.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:11k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #include <stdio.h>
  3. #if HAVE_STRING_H
  4. #include <string.h>
  5. #else
  6. #include <strings.h>
  7. #endif
  8. #include <sys/types.h>
  9. #if HAVE_STDLIB_H
  10. #include <stdlib.h>
  11. #endif
  12. #if HAVE_DMALLOC_H
  13. #include <dmalloc.h>
  14. #endif
  15. #include <net-snmp/output_api.h>
  16. #include <net-snmp/utilities.h>
  17. #include <net-snmp/library/snmp_transport.h>
  18. #include <net-snmp/library/snmpUDPDomain.h>
  19. #ifdef SNMP_TRANSPORT_TCP_DOMAIN
  20. #include <net-snmp/library/snmpTCPDomain.h>
  21. #endif
  22. #ifdef SNMP_TRANSPORT_IPX_DOMAIN
  23. #include <net-snmp/library/snmpIPXDomain.h>
  24. #endif
  25. #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
  26. #include <net-snmp/library/snmpUnixDomain.h>
  27. #endif
  28. #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
  29. #include <net-snmp/library/snmpAAL5PVCDomain.h>
  30. #endif
  31. #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
  32. #include <net-snmp/library/snmpUDPIPv6Domain.h>
  33. #endif
  34. #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
  35. #include <net-snmp/library/snmpTCPIPv6Domain.h>
  36. #endif
  37. #include <net-snmp/library/snmp_api.h>
  38. /*
  39.  * Our list of supported transport domains.  
  40.  */
  41. static netsnmp_tdomain *domain_list = NULL;
  42. /*
  43.  * The standard SNMP domains.  
  44.  */
  45. oid             netsnmpUDPDomain[] = { 1, 3, 6, 1, 6, 1, 1 };
  46. size_t          netsnmpUDPDomain_len = OID_LENGTH(netsnmpUDPDomain);
  47. oid             netsnmpCLNSDomain[] = { 1, 3, 6, 1, 6, 1, 2 };
  48. size_t          netsnmpCLNSDomain_len = OID_LENGTH(netsnmpCLNSDomain);
  49. oid             netsnmpCONSDomain[] = { 1, 3, 6, 1, 6, 1, 3 };
  50. size_t          netsnmpCONSDomain_len = OID_LENGTH(netsnmpCONSDomain);
  51. oid             netsnmpDDPDomain[] = { 1, 3, 6, 1, 6, 1, 4 };
  52. size_t          netsnmpDDPDomain_len = OID_LENGTH(netsnmpDDPDomain);
  53. oid             netsnmpIPXDomain[] = { 1, 3, 6, 1, 6, 1, 5 };
  54. size_t          netsnmpIPXDomain_len = OID_LENGTH(netsnmpIPXDomain);
  55. static void     netsnmp_tdomain_dump(void);
  56. /*
  57.  * Make a deep copy of an netsnmp_transport.  
  58.  */
  59. netsnmp_transport *
  60. netsnmp_transport_copy(netsnmp_transport *t)
  61. {
  62.     netsnmp_transport *n = NULL;
  63.     n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
  64.     if (n == NULL) {
  65.         return NULL;
  66.     }
  67.     memset(n, 0, sizeof(netsnmp_transport));
  68.     if (t->domain != NULL) {
  69.         n->domain = t->domain;
  70.         n->domain_length = t->domain_length;
  71.     } else {
  72.         n->domain = NULL;
  73.         n->domain_length = 0;
  74.     }
  75.     if (t->local != NULL) {
  76.         n->local = (u_char *) malloc(t->local_length);
  77.         if (n->local == NULL) {
  78.             netsnmp_transport_free(n);
  79.             return NULL;
  80.         }
  81.         n->local_length = t->local_length;
  82.         memcpy(n->local, t->local, t->local_length);
  83.     } else {
  84.         n->local = NULL;
  85.         n->local_length = 0;
  86.     }
  87.     if (t->remote != NULL) {
  88.         n->remote = (u_char *) malloc(t->remote_length);
  89.         if (n->remote == NULL) {
  90.             netsnmp_transport_free(n);
  91.             return NULL;
  92.         }
  93.         n->remote_length = t->remote_length;
  94.         memcpy(n->remote, t->remote, t->remote_length);
  95.     } else {
  96.         n->remote = NULL;
  97.         n->remote_length = 0;
  98.     }
  99.     if (t->data != NULL && t->data_length > 0) {
  100.         n->data = malloc(t->data_length);
  101.         if (n->data == NULL) {
  102.             netsnmp_transport_free(n);
  103.             return NULL;
  104.         }
  105.         n->data_length = t->data_length;
  106.         memcpy(n->data, t->data, t->data_length);
  107.     } else {
  108.         n->data = NULL;
  109.         n->data_length = 0;
  110.     }
  111.     n->msgMaxSize = t->msgMaxSize;
  112.     n->f_accept = t->f_accept;
  113.     n->f_recv = t->f_recv;
  114.     n->f_send = t->f_send;
  115.     n->f_close = t->f_close;
  116.     n->f_fmtaddr = t->f_fmtaddr;
  117.     n->sock = t->sock;
  118.     n->flags = t->flags;
  119.     return n;
  120. }
  121. void
  122. netsnmp_transport_free(netsnmp_transport *t)
  123. {
  124.     if (NULL == t)
  125.         return;
  126.     if (t->local != NULL) {
  127.         SNMP_FREE(t->local);
  128.     }
  129.     if (t->remote != NULL) {
  130.         SNMP_FREE(t->remote);
  131.     }
  132.     if (t->data != NULL) {
  133.         SNMP_FREE(t->data);
  134.     }
  135.     SNMP_FREE(t);
  136. }
  137. int
  138. netsnmp_tdomain_support(const oid * in_oid,
  139.                         size_t in_len,
  140.                         const oid ** out_oid, size_t * out_len)
  141. {
  142.     netsnmp_tdomain *d = NULL;
  143.     for (d = domain_list; d != NULL; d = d->next) {
  144.         if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) {
  145.             if (out_oid != NULL && out_len != NULL) {
  146.                 *out_oid = d->name;
  147.                 *out_len = d->name_length;
  148.             }
  149.             return 1;
  150.         }
  151.     }
  152.     return 0;
  153. }
  154. void
  155. netsnmp_tdomain_init(void)
  156. {
  157.     DEBUGMSGTL(("tdomain", "netsnmp_tdomain_init() calledn"));
  158.     netsnmp_udp_ctor();
  159. #ifdef SNMP_TRANSPORT_TCP_DOMAIN
  160.     netsnmp_tcp_ctor();
  161. #endif
  162. #ifdef SNMP_TRANSPORT_IPX_DOMAIN
  163.     netsnmp_ipx_ctor();
  164. #endif
  165. #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
  166.     netsnmp_unix_ctor();
  167. #endif
  168. #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
  169.     netsnmp_aal5pvc_ctor();
  170. #endif
  171. #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
  172.     netsnmp_udp6_ctor();
  173. #endif
  174. #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
  175.     netsnmp_tcp6_ctor();
  176. #endif
  177.     netsnmp_tdomain_dump();
  178. }
  179. void
  180. netsnmp_clear_tdomain_list(void)
  181. {
  182.     netsnmp_tdomain *list = domain_list, *next = NULL;
  183.     DEBUGMSGTL(("tdomain", "clear_tdomain_list() calledn"));
  184.     while (list != NULL) {
  185. next = list->next;
  186. SNMP_FREE(list->prefix);
  187.         /* attention!! list itself is not in the heap, so we must not free it! */
  188. list = next;
  189.     }
  190.     domain_list = NULL;
  191. }
  192. static void
  193. netsnmp_tdomain_dump(void)
  194. {
  195.     netsnmp_tdomain *d;
  196.     int i = 0;
  197.     DEBUGMSGTL(("tdomain", "domain_list -> "));
  198.     for (d = domain_list; d != NULL; d = d->next) {
  199.         DEBUGMSG(("tdomain", "{ "));
  200.         DEBUGMSGOID(("tdomain", d->name, d->name_length));
  201.         DEBUGMSG(("tdomain", ", ""));
  202.         for (i = 0; d->prefix[i] != NULL; i++) {
  203.             DEBUGMSG(("tdomain", "%s%s", d->prefix[i],
  204.       (d->prefix[i + 1]) ? "/" : ""));
  205.         }
  206.         DEBUGMSG(("tdomain", "" } -> "));
  207.     }
  208.     DEBUGMSG(("tdomain", "[NIL]n"));
  209. }
  210. int
  211. netsnmp_tdomain_register(netsnmp_tdomain *n)
  212. {
  213.     netsnmp_tdomain **prevNext = &domain_list, *d;
  214.     if (n != NULL) {
  215.         for (d = domain_list; d != NULL; d = d->next) {
  216.             if (netsnmp_oid_equals(n->name, n->name_length,
  217.                                 d->name, d->name_length) == 0) {
  218.                 /*
  219.                  * Already registered.  
  220.                  */
  221.                 return 0;
  222.             }
  223.             prevNext = &(d->next);
  224.         }
  225.         n->next = NULL;
  226.         *prevNext = n;
  227.         return 1;
  228.     } else {
  229.         return 0;
  230.     }
  231. }
  232. int
  233. netsnmp_tdomain_unregister(netsnmp_tdomain *n)
  234. {
  235.     netsnmp_tdomain **prevNext = &domain_list, *d;
  236.     if (n != NULL) {
  237.         for (d = domain_list; d != NULL; d = d->next) {
  238.             if (netsnmp_oid_equals(n->name, n->name_length,
  239.                                 d->name, d->name_length) == 0) {
  240.                 *prevNext = n->next;
  241. SNMP_FREE(n->prefix);
  242.                 return 1;
  243.             }
  244.             prevNext = &(d->next);
  245.         }
  246.         return 0;
  247.     } else {
  248.         return 0;
  249.     }
  250. }
  251. netsnmp_transport *
  252. netsnmp_tdomain_transport(const char *str, int local,
  253.                           const char *default_domain)
  254. {
  255.     netsnmp_tdomain *d;
  256.     netsnmp_transport *t = NULL;
  257.     const char     *spec, *addr;
  258.     char           *cp, *mystring;
  259.     int             i;
  260.     if (str == NULL) {
  261.         return NULL;
  262.     }
  263.     if ((mystring = strdup(str)) == NULL) {
  264.         DEBUGMSGTL(("tdomain", "can't strdup("%s")n", str));
  265.         return NULL;
  266.     }
  267.     if ((cp = strchr(mystring, ':')) == NULL) {
  268.         /*
  269.          * There doesn't appear to be a transport specifier.  
  270.          */
  271.         DEBUGMSGTL(("tdomain", "no specifier in "%s"n", mystring));
  272.         if (*mystring == '/') {
  273.             spec = "unix";
  274.             addr = mystring;
  275.         } else {
  276.             if (default_domain) {
  277.                 spec = default_domain;
  278.             } else {
  279.                 spec = "udp";
  280.             }
  281.             addr = mystring;
  282.         }
  283.     } else {
  284.         *cp = '';
  285.         spec = mystring;
  286.         addr = cp + 1;
  287.     }
  288.     DEBUGMSGTL(("tdomain", "specifier "%s" address "%s"n", spec,
  289.                 addr));
  290.     for (d = domain_list; d != NULL; d = d->next) {
  291.         for (i = 0; d->prefix[i] != NULL; i++) {
  292.             if (strcasecmp(d->prefix[i], spec) == 0) {
  293.                 DEBUGMSGTL(("tdomain", "specifier "%s" matchedn",
  294.                             spec));
  295.                 t = d->f_create_from_tstring(addr, local);
  296.                 SNMP_FREE(mystring);
  297.                 return t;
  298.             }
  299.         }
  300.     }
  301.     /*
  302.      * Okay no match so far.  Consider the possibility that we have something
  303.      * like hostname.domain.com:port which will have confused the parser above.
  304.      * Try and match again with the appropriate default domain.  
  305.      */
  306.     if (default_domain) {
  307.         spec = default_domain;
  308.     } else {
  309.         spec = "udp";
  310.     }
  311.     if (cp) {
  312.         *cp = ':';
  313.     }
  314.     addr = mystring;
  315.     DEBUGMSGTL(("tdomain",
  316.                 "try again with specifier "%s" address "%s"n", spec,
  317.                 addr));
  318.     for (d = domain_list; d != NULL; d = d->next) {
  319.         for (i = 0; d->prefix[i] != NULL; i++) {
  320.             if (strcmp(d->prefix[i], spec) == 0) {
  321.                 DEBUGMSGTL(("tdomain", "specifier "%s" matchedn",
  322.                             spec));
  323.                 t = d->f_create_from_tstring(addr, local);
  324.                 SNMP_FREE(mystring);
  325.                 return t;
  326.             }
  327.         }
  328.     }
  329.     snmp_log(LOG_ERR, "No support for requested transport domain "%s"n",
  330.              spec);
  331.     SNMP_FREE(mystring);
  332.     return NULL;
  333. }
  334. netsnmp_transport *
  335. netsnmp_tdomain_transport_oid(const oid * dom,
  336.                               size_t dom_len,
  337.                               const u_char * o, size_t o_len, int local)
  338. {
  339.     netsnmp_tdomain *d;
  340.     int             i;
  341.     DEBUGMSGTL(("tdomain", "domain ""));
  342.     DEBUGMSGOID(("tdomain", dom, dom_len));
  343.     DEBUGMSG(("tdomain", ""n"));
  344.     for (d = domain_list; d != NULL; d = d->next) {
  345.         for (i = 0; d->prefix[i] != NULL; i++) {
  346.             if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
  347.                 0) {
  348.                 return d->f_create_from_ostring(o, o_len, local);
  349.             }
  350.         }
  351.     }
  352.     snmp_log(LOG_ERR, "No support for requested transport domainn");
  353.     return NULL;
  354. }
  355. /** adds a transport to a linked list of transports.
  356.     Returns 1 on failure, 0 on success */
  357. int
  358. netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list,
  359.                               netsnmp_transport *transport)
  360. {
  361.     netsnmp_transport_list *newptr =
  362.         SNMP_MALLOC_TYPEDEF(netsnmp_transport_list);
  363.     if (!newptr)
  364.         return 1;
  365.     newptr->next = *transport_list;
  366.     newptr->transport = transport;
  367.     *transport_list = newptr;
  368.     return 0;
  369. }
  370. /**  removes a transport from a linked list of transports.
  371.      Returns 1 on failure, 0 on success */
  372. int
  373. netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list,
  374.                                    netsnmp_transport *transport)
  375. {
  376.     netsnmp_transport_list *ptr = *transport_list, *lastptr = NULL;
  377.     while (ptr && ptr->transport != transport) {
  378.         lastptr = ptr;
  379.         ptr = ptr->next;
  380.     }
  381.     if (!ptr)
  382.         return 1;
  383.     if (lastptr)
  384.         lastptr->next = ptr->next;
  385.     else
  386.         *transport_list = ptr->next;
  387.     SNMP_FREE(ptr);
  388.     return 0;
  389. }