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