net-snmp
5.4.1
|
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 NETSNMP_TRANSPORT_TLS_DOMAIN 00025 #include <net-snmp/library/snmpTLSDomain.h> 00026 #endif 00027 #ifdef NETSNMP_TRANSPORT_STD_DOMAIN 00028 #include <net-snmp/library/snmpSTDDomain.h> 00029 #endif 00030 #ifdef NETSNMP_TRANSPORT_TCP_DOMAIN 00031 #include <net-snmp/library/snmpTCPDomain.h> 00032 #endif 00033 #ifdef NETSNMP_TRANSPORT_IPX_DOMAIN 00034 #include <net-snmp/library/snmpIPXDomain.h> 00035 #endif 00036 #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN 00037 #include <net-snmp/library/snmpUnixDomain.h> 00038 #endif 00039 #ifdef NETSNMP_TRANSPORT_AAL5PVC_DOMAIN 00040 #include <net-snmp/library/snmpAAL5PVCDomain.h> 00041 #endif 00042 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN 00043 #include <net-snmp/library/snmpUDPIPv6Domain.h> 00044 #endif 00045 #ifdef NETSNMP_TRANSPORT_TCPIPV6_DOMAIN 00046 #include <net-snmp/library/snmpTCPIPv6Domain.h> 00047 #endif 00048 #include <net-snmp/library/snmp_api.h> 00049 #include <net-snmp/library/snmp_service.h> 00050 00051 00052 /* 00053 * Our list of supported transport domains. 00054 */ 00055 00056 static netsnmp_tdomain *domain_list = NULL; 00057 00058 00059 00060 /* 00061 * The standard SNMP domains. 00062 */ 00063 00064 oid netsnmpUDPDomain[] = { 1, 3, 6, 1, 6, 1, 1 }; 00065 size_t netsnmpUDPDomain_len = OID_LENGTH(netsnmpUDPDomain); 00066 oid netsnmpCLNSDomain[] = { 1, 3, 6, 1, 6, 1, 2 }; 00067 size_t netsnmpCLNSDomain_len = OID_LENGTH(netsnmpCLNSDomain); 00068 oid netsnmpCONSDomain[] = { 1, 3, 6, 1, 6, 1, 3 }; 00069 size_t netsnmpCONSDomain_len = OID_LENGTH(netsnmpCONSDomain); 00070 oid netsnmpDDPDomain[] = { 1, 3, 6, 1, 6, 1, 4 }; 00071 size_t netsnmpDDPDomain_len = OID_LENGTH(netsnmpDDPDomain); 00072 oid netsnmpIPXDomain[] = { 1, 3, 6, 1, 6, 1, 5 }; 00073 size_t netsnmpIPXDomain_len = OID_LENGTH(netsnmpIPXDomain); 00074 00075 00076 00077 static void netsnmp_tdomain_dump(void); 00078 00079 00080 /* 00081 * Make a deep copy of an netsnmp_transport. 00082 */ 00083 00084 netsnmp_transport * 00085 netsnmp_transport_copy(netsnmp_transport *t) 00086 { 00087 netsnmp_transport *n = NULL; 00088 00089 n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport)); 00090 if (n == NULL) { 00091 return NULL; 00092 } 00093 memset(n, 0, sizeof(netsnmp_transport)); 00094 00095 if (t->domain != NULL) { 00096 n->domain = t->domain; 00097 n->domain_length = t->domain_length; 00098 } else { 00099 n->domain = NULL; 00100 n->domain_length = 0; 00101 } 00102 00103 if (t->local != NULL) { 00104 n->local = (u_char *) malloc(t->local_length); 00105 if (n->local == NULL) { 00106 netsnmp_transport_free(n); 00107 return NULL; 00108 } 00109 n->local_length = t->local_length; 00110 memcpy(n->local, t->local, t->local_length); 00111 } else { 00112 n->local = NULL; 00113 n->local_length = 0; 00114 } 00115 00116 if (t->remote != NULL) { 00117 n->remote = (u_char *) malloc(t->remote_length); 00118 if (n->remote == NULL) { 00119 netsnmp_transport_free(n); 00120 return NULL; 00121 } 00122 n->remote_length = t->remote_length; 00123 memcpy(n->remote, t->remote, t->remote_length); 00124 } else { 00125 n->remote = NULL; 00126 n->remote_length = 0; 00127 } 00128 00129 if (t->data != NULL && t->data_length > 0) { 00130 n->data = malloc(t->data_length); 00131 if (n->data == NULL) { 00132 netsnmp_transport_free(n); 00133 return NULL; 00134 } 00135 n->data_length = t->data_length; 00136 memcpy(n->data, t->data, t->data_length); 00137 } else { 00138 n->data = NULL; 00139 n->data_length = 0; 00140 } 00141 00142 n->msgMaxSize = t->msgMaxSize; 00143 n->f_accept = t->f_accept; 00144 n->f_recv = t->f_recv; 00145 n->f_send = t->f_send; 00146 n->f_close = t->f_close; 00147 n->f_fmtaddr = t->f_fmtaddr; 00148 n->sock = t->sock; 00149 n->flags = t->flags; 00150 00151 return n; 00152 } 00153 00154 00155 00156 void 00157 netsnmp_transport_free(netsnmp_transport *t) 00158 { 00159 if (NULL == t) 00160 return; 00161 00162 if (t->local != NULL) { 00163 SNMP_FREE(t->local); 00164 } 00165 if (t->remote != NULL) { 00166 SNMP_FREE(t->remote); 00167 } 00168 if (t->data != NULL) { 00169 SNMP_FREE(t->data); 00170 } 00171 SNMP_FREE(t); 00172 } 00173 00174 00175 00176 int 00177 netsnmp_tdomain_support(const oid * in_oid, 00178 size_t in_len, 00179 const oid ** out_oid, size_t * out_len) 00180 { 00181 netsnmp_tdomain *d = NULL; 00182 00183 for (d = domain_list; d != NULL; d = d->next) { 00184 if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) { 00185 if (out_oid != NULL && out_len != NULL) { 00186 *out_oid = d->name; 00187 *out_len = d->name_length; 00188 } 00189 return 1; 00190 } 00191 } 00192 return 0; 00193 } 00194 00195 00196 00197 void 00198 netsnmp_tdomain_init(void) 00199 { 00200 DEBUGMSGTL(("tdomain", "netsnmp_tdomain_init() called\n")); 00201 netsnmp_udp_ctor(); 00202 #ifdef NETSNMP_TRANSPORT_STD_DOMAIN 00203 netsnmp_std_ctor(); 00204 #endif 00205 #ifdef NETSNMP_TRANSPORT_TCP_DOMAIN 00206 netsnmp_tcp_ctor(); 00207 #endif 00208 #ifdef NETSNMP_TRANSPORT_IPX_DOMAIN 00209 netsnmp_ipx_ctor(); 00210 #endif 00211 #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN 00212 netsnmp_unix_ctor(); 00213 #endif 00214 #ifdef NETSNMP_TRANSPORT_AAL5PVC_DOMAIN 00215 netsnmp_aal5pvc_ctor(); 00216 #endif 00217 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN 00218 netsnmp_udp6_ctor(); 00219 #endif 00220 #ifdef NETSNMP_TRANSPORT_TCPIPV6_DOMAIN 00221 netsnmp_tcp6_ctor(); 00222 #endif 00223 netsnmp_tdomain_dump(); 00224 } 00225 00226 void 00227 netsnmp_clear_tdomain_list(void) 00228 { 00229 netsnmp_tdomain *list = domain_list, *next = NULL; 00230 DEBUGMSGTL(("tdomain", "clear_tdomain_list() called\n")); 00231 00232 while (list != NULL) { 00233 next = list->next; 00234 SNMP_FREE(list->prefix); 00235 /* attention!! list itself is not in the heap, so we must not free it! */ 00236 list = next; 00237 } 00238 domain_list = NULL; 00239 } 00240 00241 00242 static void 00243 netsnmp_tdomain_dump(void) 00244 { 00245 netsnmp_tdomain *d; 00246 int i = 0; 00247 00248 DEBUGMSGTL(("tdomain", "domain_list -> ")); 00249 for (d = domain_list; d != NULL; d = d->next) { 00250 DEBUGMSG(("tdomain", "{ ")); 00251 DEBUGMSGOID(("tdomain", d->name, d->name_length)); 00252 DEBUGMSG(("tdomain", ", \"")); 00253 for (i = 0; d->prefix[i] != NULL; i++) { 00254 DEBUGMSG(("tdomain", "%s%s", d->prefix[i], 00255 (d->prefix[i + 1]) ? "/" : "")); 00256 } 00257 DEBUGMSG(("tdomain", "\" } -> ")); 00258 } 00259 DEBUGMSG(("tdomain", "[NIL]\n")); 00260 } 00261 00262 00263 00264 int 00265 netsnmp_tdomain_register(netsnmp_tdomain *n) 00266 { 00267 netsnmp_tdomain **prevNext = &domain_list, *d; 00268 00269 if (n != NULL) { 00270 for (d = domain_list; d != NULL; d = d->next) { 00271 if (netsnmp_oid_equals(n->name, n->name_length, 00272 d->name, d->name_length) == 0) { 00273 /* 00274 * Already registered. 00275 */ 00276 return 0; 00277 } 00278 prevNext = &(d->next); 00279 } 00280 n->next = NULL; 00281 *prevNext = n; 00282 return 1; 00283 } else { 00284 return 0; 00285 } 00286 } 00287 00288 00289 00290 int 00291 netsnmp_tdomain_unregister(netsnmp_tdomain *n) 00292 { 00293 netsnmp_tdomain **prevNext = &domain_list, *d; 00294 00295 if (n != NULL) { 00296 for (d = domain_list; d != NULL; d = d->next) { 00297 if (netsnmp_oid_equals(n->name, n->name_length, 00298 d->name, d->name_length) == 0) { 00299 *prevNext = n->next; 00300 SNMP_FREE(n->prefix); 00301 return 1; 00302 } 00303 prevNext = &(d->next); 00304 } 00305 return 0; 00306 } else { 00307 return 0; 00308 } 00309 } 00310 00311 00312 /* 00313 * Locate the appropriate transport domain and call the create function for 00314 * it. 00315 */ 00316 netsnmp_transport * 00317 netsnmp_tdomain_transport_full(const char *application, 00318 const char *str, int local, 00319 const char *default_domain, 00320 const char *default_target) 00321 { 00322 netsnmp_tdomain *d, *match = NULL; 00323 netsnmp_transport *t = NULL; 00324 const char *spec, *addr = NULL, *addr2; 00325 char *cp, *mystring = NULL; 00326 int i; 00327 00328 DEBUGMSGTL(("tdomain", 00329 "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n", 00330 application, str ? str : "[NIL]", local, 00331 default_domain ? default_domain : "[NIL]", 00332 default_target ? default_target : "[NIL]")); 00333 00334 /* First try - assume that there is a domain in str (domain:target) */ 00335 00336 if (str != NULL) { 00337 if ((mystring = strdup(str)) == NULL) { 00338 DEBUGMSGTL(("tdomain", "can't strdup(\"%s\")\n", str)); 00339 return NULL; 00340 } 00341 00342 if ((cp = strchr(mystring, ':')) != NULL) { 00343 *cp = '\0'; 00344 spec = mystring; 00345 addr = cp + 1; 00346 00347 for (d = domain_list; d != NULL && match == NULL; d = d->next) 00348 for (i = 0; d->prefix[i] != NULL && match == NULL; i++) 00349 if (strcasecmp(d->prefix[i], spec) == 0) 00350 match = d; 00351 if (match != NULL) 00352 DEBUGMSGTL(("tdomain", 00353 "Found domain \"%s\" from specifier \"%s\"\n", 00354 match->prefix[0], spec)); 00355 else 00356 DEBUGMSGTL(("tdomain", 00357 "Found no domain from specifier \"%s\"\n", spec)); 00358 } 00359 } 00360 00361 /* 00362 * Second try, if there is no domain in str (target), then try the 00363 * default domain 00364 */ 00365 00366 if (match == NULL) { 00367 addr = str; 00368 if (addr && *addr == '/') { 00369 spec = "unix"; 00370 DEBUGMSGTL(("tdomain", 00371 "Address starts with '/', so assume \"unix\" " 00372 "domain\n")); 00373 } else if (default_domain) { 00374 spec = default_domain; 00375 DEBUGMSGTL(("tdomain", 00376 "Use user specified default domain \"%s\"\n", spec)); 00377 } else { 00378 spec = netsnmp_lookup_default_domain(application); 00379 if (spec == NULL) { 00380 spec = "udp"; 00381 DEBUGMSGTL(("tdomain", 00382 "No default domain found, assume \"udp\"\n")); 00383 } else { 00384 DEBUGMSGTL(("tdomain", 00385 "Use application default domain \"%s\"\n", spec)); 00386 } 00387 } 00388 for (d = domain_list; d != NULL && match == NULL; d = d->next) 00389 for (i = 0; d->prefix[i] != NULL && match == NULL; i++) 00390 if (strcasecmp(d->prefix[i], spec) == 0) 00391 match = d; 00392 if (match != NULL) 00393 DEBUGMSGTL(("tdomain", 00394 "Found domain \"%s\" from specifier \"%s\"\n", 00395 match->prefix[0], spec)); 00396 else { 00397 DEBUGMSGTL(("tdomain", 00398 "Found no domain from specifier \"%s\"\n", spec)); 00399 SNMP_FREE(mystring); 00400 snmp_log(LOG_ERR, 00401 "No support for any checked transport domain\n"); 00402 return NULL; 00403 } 00404 } 00405 00406 /* 00407 * Ok, we know what domain to use, lets see what default data that should 00408 * be used 00409 */ 00410 00411 if (default_target != NULL) 00412 addr2 = default_target; 00413 else 00414 addr2 = netsnmp_lookup_default_target(application, match->prefix[0]); 00415 00416 DEBUGMSGTL(("tdomain", 00417 "domain \"%s\" address \"%s\" default address \"%s\"\n", 00418 match->prefix[0], addr ? addr : "[NIL]", 00419 addr2 ? addr2 : "[NIL]")); 00420 00421 if (match->f_create_from_tstring) 00422 t = match->f_create_from_tstring(addr, local); 00423 else 00424 t = match->f_create_from_tstring_new(addr, local, addr2); 00425 SNMP_FREE(mystring); 00426 return t; 00427 } 00428 00429 00430 netsnmp_transport * 00431 netsnmp_tdomain_transport(const char *str, int local, 00432 const char *default_domain) 00433 { 00434 return netsnmp_tdomain_transport_full("snmp", str, local, default_domain, 00435 NULL); 00436 } 00437 00438 00439 netsnmp_transport * 00440 netsnmp_tdomain_transport_oid(const oid * dom, 00441 size_t dom_len, 00442 const u_char * o, size_t o_len, int local) 00443 { 00444 netsnmp_tdomain *d; 00445 int i; 00446 00447 DEBUGMSGTL(("tdomain", "domain \"")); 00448 DEBUGMSGOID(("tdomain", dom, dom_len)); 00449 DEBUGMSG(("tdomain", "\"\n")); 00450 00451 for (d = domain_list; d != NULL; d = d->next) { 00452 for (i = 0; d->prefix[i] != NULL; i++) { 00453 if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) == 00454 0) { 00455 return d->f_create_from_ostring(o, o_len, local); 00456 } 00457 } 00458 } 00459 00460 snmp_log(LOG_ERR, "No support for requested transport domain\n"); 00461 return NULL; 00462 } 00463 00464 netsnmp_transport* 00465 netsnmp_transport_open(const char* application, const char* str, int local) 00466 { 00467 return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL); 00468 } 00469 00470 netsnmp_transport* 00471 netsnmp_transport_open_server(const char* application, const char* str) 00472 { 00473 return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL); 00474 } 00475 00476 netsnmp_transport* 00477 netsnmp_transport_open_client(const char* application, const char* str) 00478 { 00479 return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL); 00480 } 00481 00484 int 00485 netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list, 00486 netsnmp_transport *transport) 00487 { 00488 netsnmp_transport_list *newptr = 00489 SNMP_MALLOC_TYPEDEF(netsnmp_transport_list); 00490 00491 if (!newptr) 00492 return 1; 00493 00494 newptr->next = *transport_list; 00495 newptr->transport = transport; 00496 00497 *transport_list = newptr; 00498 00499 return 0; 00500 } 00501 00502 00505 int 00506 netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list, 00507 netsnmp_transport *transport) 00508 { 00509 netsnmp_transport_list *ptr = *transport_list, *lastptr = NULL; 00510 00511 while (ptr && ptr->transport != transport) { 00512 lastptr = ptr; 00513 ptr = ptr->next; 00514 } 00515 00516 if (!ptr) 00517 return 1; 00518 00519 if (lastptr) 00520 lastptr->next = ptr->next; 00521 else 00522 *transport_list = ptr->next; 00523 00524 SNMP_FREE(ptr); 00525 00526 return 0; 00527 }