net-snmp 5.7
|
00001 #include <net-snmp/net-snmp-config.h> 00002 #include <net-snmp/net-snmp-features.h> 00003 00004 #include <net-snmp/types.h> 00005 #include <net-snmp/library/snmp_transport.h> 00006 00007 #include <stdio.h> 00008 #if HAVE_STRING_H 00009 #include <string.h> 00010 #else 00011 #include <strings.h> 00012 #endif 00013 #include <sys/types.h> 00014 00015 #if HAVE_STDLIB_H 00016 #include <stdlib.h> 00017 #endif 00018 00019 #include <ctype.h> 00020 00021 #if HAVE_UNISTD_H 00022 #include <unistd.h> 00023 #endif 00024 #if HAVE_DMALLOC_H 00025 #include <dmalloc.h> 00026 #endif 00027 00028 #include <net-snmp/output_api.h> 00029 #include <net-snmp/utilities.h> 00030 00031 #include <net-snmp/library/default_store.h> 00032 00033 #include <net-snmp/library/snmpUDPDomain.h> 00034 #ifdef NETSNMP_TRANSPORT_TLSBASE_DOMAIN 00035 #include <net-snmp/library/snmpTLSBaseDomain.h> 00036 #endif 00037 #ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN 00038 #include <net-snmp/library/snmpTLSTCPDomain.h> 00039 #endif 00040 #ifdef NETSNMP_TRANSPORT_STD_DOMAIN 00041 #include <net-snmp/library/snmpSTDDomain.h> 00042 #endif 00043 #ifdef NETSNMP_TRANSPORT_TCP_DOMAIN 00044 #include <net-snmp/library/snmpTCPDomain.h> 00045 #endif 00046 #ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN 00047 #include <net-snmp/library/snmpDTLSUDPDomain.h> 00048 #endif 00049 #ifdef NETSNMP_TRANSPORT_SSH_DOMAIN 00050 #include <net-snmp/library/snmpSSHDomain.h> 00051 #endif 00052 #ifdef NETSNMP_TRANSPORT_ALIAS_DOMAIN 00053 #include <net-snmp/library/snmpAliasDomain.h> 00054 #endif 00055 #ifdef NETSNMP_TRANSPORT_IPX_DOMAIN 00056 #include <net-snmp/library/snmpIPXDomain.h> 00057 #endif 00058 #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN 00059 #include <net-snmp/library/snmpUnixDomain.h> 00060 #endif 00061 #ifdef NETSNMP_TRANSPORT_AAL5PVC_DOMAIN 00062 #include <net-snmp/library/snmpAAL5PVCDomain.h> 00063 #endif 00064 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN 00065 #include <net-snmp/library/snmpUDPIPv6Domain.h> 00066 #endif 00067 #ifdef NETSNMP_TRANSPORT_TCPIPV6_DOMAIN 00068 #include <net-snmp/library/snmpTCPIPv6Domain.h> 00069 #endif 00070 #include <net-snmp/library/snmp_api.h> 00071 #include <net-snmp/library/snmp_service.h> 00072 #include <net-snmp/library/read_config.h> 00073 00074 netsnmp_feature_child_of(transport_all, libnetsnmp) 00075 00076 netsnmp_feature_child_of(tdomain_support, transport_all) 00077 netsnmp_feature_child_of(tdomain_transport_oid, transport_all) 00078 netsnmp_feature_child_of(sockaddr_size, transport_all) 00079 00080 /* 00081 * Our list of supported transport domains. 00082 */ 00083 00084 static netsnmp_tdomain *domain_list = NULL; 00085 00086 00087 00088 /* 00089 * The standard SNMP domains. 00090 */ 00091 00092 oid netsnmpUDPDomain[] = { 1, 3, 6, 1, 6, 1, 1 }; 00093 size_t netsnmpUDPDomain_len = OID_LENGTH(netsnmpUDPDomain); 00094 oid netsnmpCLNSDomain[] = { 1, 3, 6, 1, 6, 1, 2 }; 00095 size_t netsnmpCLNSDomain_len = OID_LENGTH(netsnmpCLNSDomain); 00096 oid netsnmpCONSDomain[] = { 1, 3, 6, 1, 6, 1, 3 }; 00097 size_t netsnmpCONSDomain_len = OID_LENGTH(netsnmpCONSDomain); 00098 oid netsnmpDDPDomain[] = { 1, 3, 6, 1, 6, 1, 4 }; 00099 size_t netsnmpDDPDomain_len = OID_LENGTH(netsnmpDDPDomain); 00100 oid netsnmpIPXDomain[] = { 1, 3, 6, 1, 6, 1, 5 }; 00101 size_t netsnmpIPXDomain_len = OID_LENGTH(netsnmpIPXDomain); 00102 00103 00104 00105 static void netsnmp_tdomain_dump(void); 00106 00107 00108 00109 void 00110 init_snmp_transport(void) 00111 { 00112 netsnmp_ds_register_config(ASN_BOOLEAN, 00113 "snmp", "dontLoadHostConfig", 00114 NETSNMP_DS_LIBRARY_ID, 00115 NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES); 00116 } 00117 00118 /* 00119 * Make a deep copy of an netsnmp_transport. 00120 */ 00121 netsnmp_transport * 00122 netsnmp_transport_copy(netsnmp_transport *t) 00123 { 00124 netsnmp_transport *n = NULL; 00125 00126 if (t == NULL) { 00127 return NULL; 00128 } 00129 00130 n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport)); 00131 if (n == NULL) { 00132 return NULL; 00133 } 00134 memset(n, 0, sizeof(netsnmp_transport)); 00135 00136 if (t->domain != NULL) { 00137 n->domain = t->domain; 00138 n->domain_length = t->domain_length; 00139 } else { 00140 n->domain = NULL; 00141 n->domain_length = 0; 00142 } 00143 00144 if (t->local != NULL) { 00145 n->local = (u_char *) malloc(t->local_length); 00146 if (n->local == NULL) { 00147 netsnmp_transport_free(n); 00148 return NULL; 00149 } 00150 n->local_length = t->local_length; 00151 memcpy(n->local, t->local, t->local_length); 00152 } else { 00153 n->local = NULL; 00154 n->local_length = 0; 00155 } 00156 00157 if (t->remote != NULL) { 00158 n->remote = (u_char *) malloc(t->remote_length); 00159 if (n->remote == NULL) { 00160 netsnmp_transport_free(n); 00161 return NULL; 00162 } 00163 n->remote_length = t->remote_length; 00164 memcpy(n->remote, t->remote, t->remote_length); 00165 } else { 00166 n->remote = NULL; 00167 n->remote_length = 0; 00168 } 00169 00170 if (t->data != NULL && t->data_length > 0) { 00171 n->data = malloc(t->data_length); 00172 if (n->data == NULL) { 00173 netsnmp_transport_free(n); 00174 return NULL; 00175 } 00176 n->data_length = t->data_length; 00177 memcpy(n->data, t->data, t->data_length); 00178 } else { 00179 n->data = NULL; 00180 n->data_length = 0; 00181 } 00182 00183 n->msgMaxSize = t->msgMaxSize; 00184 n->f_accept = t->f_accept; 00185 n->f_recv = t->f_recv; 00186 n->f_send = t->f_send; 00187 n->f_close = t->f_close; 00188 n->f_copy = t->f_copy; 00189 n->f_config = t->f_config; 00190 n->f_fmtaddr = t->f_fmtaddr; 00191 n->sock = t->sock; 00192 n->flags = t->flags; 00193 n->base_transport = netsnmp_transport_copy(t->base_transport); 00194 00195 /* give the transport a chance to do "special things" */ 00196 if (t->f_copy) 00197 t->f_copy(t, n); 00198 00199 return n; 00200 } 00201 00202 00203 00204 void 00205 netsnmp_transport_free(netsnmp_transport *t) 00206 { 00207 if (NULL == t) 00208 return; 00209 00210 SNMP_FREE(t->local); 00211 SNMP_FREE(t->remote); 00212 SNMP_FREE(t->data); 00213 netsnmp_transport_free(t->base_transport); 00214 00215 SNMP_FREE(t); 00216 } 00217 00218 /* 00219 * netsnmp_transport_peer_string 00220 * 00221 * returns string representation of peer address. 00222 * 00223 * caller is responsible for freeing the allocated string. 00224 */ 00225 char * 00226 netsnmp_transport_peer_string(netsnmp_transport *t, void *data, int len) 00227 { 00228 char *str; 00229 00230 if (NULL == t) 00231 return NULL; 00232 00233 if (t->f_fmtaddr != NULL) 00234 str = t->f_fmtaddr(t, data, len); 00235 else 00236 str = strdup("<UNKNOWN>"); 00237 00238 return str; 00239 } 00240 00241 #ifndef NETSNMP_FEATURE_REMOVE_SOCKADDR_SIZE 00242 int 00243 netsnmp_sockaddr_size(struct sockaddr *sa) 00244 { 00245 if (NULL == sa) 00246 return 0; 00247 00248 switch (sa->sa_family) { 00249 case AF_INET: 00250 return sizeof(struct sockaddr_in); 00251 break; 00252 #ifdef NETSNMP_ENABLE_IPV6 00253 case AF_INET6: 00254 return sizeof(struct sockaddr_in6); 00255 break; 00256 #endif 00257 } 00258 00259 return 0; 00260 } 00261 #endif /* NETSNMP_FEATURE_REMOVE_SOCKADDR_SIZE */ 00262 00263 int 00264 netsnmp_transport_send(netsnmp_transport *t, void *packet, int length, 00265 void **opaque, int *olength) 00266 { 00267 int dumpPacket, debugLength; 00268 00269 if ((NULL == t) || (NULL == t->f_send)) { 00270 DEBUGMSGTL(("transport:pkt:send", "NULL transport or send function\n")); 00271 return SNMPERR_GENERR; 00272 } 00273 00274 dumpPacket = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 00275 NETSNMP_DS_LIB_DUMP_PACKET); 00276 debugLength = (SNMPERR_SUCCESS == 00277 debug_is_token_registered("transport:send")); 00278 00279 if (dumpPacket | debugLength) { 00280 char *str = netsnmp_transport_peer_string(t, 00281 opaque ? *opaque : NULL, 00282 olength ? *olength : 0); 00283 if (debugLength) 00284 DEBUGMSGT_NC(("transport:send","%lu bytes to %s\n", 00285 (unsigned long)length, str)); 00286 if (dumpPacket) 00287 snmp_log(LOG_DEBUG, "\nSending %lu bytes to %s\n", 00288 (unsigned long)length, str); 00289 SNMP_FREE(str); 00290 } 00291 if (dumpPacket) 00292 xdump(packet, length, ""); 00293 00294 return t->f_send(t, packet, length, opaque, olength); 00295 } 00296 00297 int 00298 netsnmp_transport_recv(netsnmp_transport *t, void *packet, int length, 00299 void **opaque, int *olength) 00300 { 00301 int debugLength; 00302 00303 if ((NULL == t) || (NULL == t->f_recv)) { 00304 DEBUGMSGTL(("transport:recv", "NULL transport or recv function\n")); 00305 return SNMPERR_GENERR; 00306 } 00307 00308 length = t->f_recv(t, packet, length, opaque, olength); 00309 00310 if (length <=0) 00311 return length; /* don't log timeouts/socket closed */ 00312 00313 debugLength = (SNMPERR_SUCCESS == 00314 debug_is_token_registered("transport:recv")); 00315 00316 if (debugLength) { 00317 char *str = netsnmp_transport_peer_string(t, 00318 opaque ? *opaque : NULL, 00319 olength ? *olength : 0); 00320 if (debugLength) 00321 DEBUGMSGT_NC(("transport:recv","%d bytes from %s\n", 00322 length, str)); 00323 SNMP_FREE(str); 00324 } 00325 00326 return length; 00327 } 00328 00329 00330 00331 #ifndef NETSNMP_FEATURE_REMOVE_TDOMAIN_SUPPORT 00332 int 00333 netsnmp_tdomain_support(const oid * in_oid, 00334 size_t in_len, 00335 const oid ** out_oid, size_t * out_len) 00336 { 00337 netsnmp_tdomain *d = NULL; 00338 00339 for (d = domain_list; d != NULL; d = d->next) { 00340 if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) { 00341 if (out_oid != NULL && out_len != NULL) { 00342 *out_oid = d->name; 00343 *out_len = d->name_length; 00344 } 00345 return 1; 00346 } 00347 } 00348 return 0; 00349 } 00350 #endif /* NETSNMP_FEATURE_REMOVE_TDOMAIN_SUPPORT */ 00351 00352 00353 void 00354 netsnmp_tdomain_init(void) 00355 { 00356 DEBUGMSGTL(("tdomain", "netsnmp_tdomain_init() called\n")); 00357 00358 /* include the configure generated list of constructor calls */ 00359 #include "transports/snmp_transport_inits.h" 00360 00361 netsnmp_tdomain_dump(); 00362 } 00363 00364 void 00365 netsnmp_clear_tdomain_list(void) 00366 { 00367 netsnmp_tdomain *list = domain_list, *next = NULL; 00368 DEBUGMSGTL(("tdomain", "clear_tdomain_list() called\n")); 00369 00370 while (list != NULL) { 00371 next = list->next; 00372 SNMP_FREE(list->prefix); 00373 /* attention!! list itself is not in the heap, so we must not free it! */ 00374 list = next; 00375 } 00376 domain_list = NULL; 00377 } 00378 00379 00380 static void 00381 netsnmp_tdomain_dump(void) 00382 { 00383 netsnmp_tdomain *d; 00384 int i = 0; 00385 00386 DEBUGMSGTL(("tdomain", "domain_list -> ")); 00387 for (d = domain_list; d != NULL; d = d->next) { 00388 DEBUGMSG(("tdomain", "{ ")); 00389 DEBUGMSGOID(("tdomain", d->name, d->name_length)); 00390 DEBUGMSG(("tdomain", ", \"")); 00391 for (i = 0; d->prefix[i] != NULL; i++) { 00392 DEBUGMSG(("tdomain", "%s%s", d->prefix[i], 00393 (d->prefix[i + 1]) ? "/" : "")); 00394 } 00395 DEBUGMSG(("tdomain", "\" } -> ")); 00396 } 00397 DEBUGMSG(("tdomain", "[NIL]\n")); 00398 } 00399 00400 00401 00402 int 00403 netsnmp_tdomain_register(netsnmp_tdomain *n) 00404 { 00405 netsnmp_tdomain **prevNext = &domain_list, *d; 00406 00407 if (n != NULL) { 00408 for (d = domain_list; d != NULL; d = d->next) { 00409 if (netsnmp_oid_equals(n->name, n->name_length, 00410 d->name, d->name_length) == 0) { 00411 /* 00412 * Already registered. 00413 */ 00414 return 0; 00415 } 00416 prevNext = &(d->next); 00417 } 00418 n->next = NULL; 00419 *prevNext = n; 00420 return 1; 00421 } else { 00422 return 0; 00423 } 00424 } 00425 00426 00427 00428 netsnmp_feature_child_of(tdomain_unregister, netsnmp_unused) 00429 #ifndef NETSNMP_FEATURE_REMOVE_TDOMAIN_UNREGISTER 00430 int 00431 netsnmp_tdomain_unregister(netsnmp_tdomain *n) 00432 { 00433 netsnmp_tdomain **prevNext = &domain_list, *d; 00434 00435 if (n != NULL) { 00436 for (d = domain_list; d != NULL; d = d->next) { 00437 if (netsnmp_oid_equals(n->name, n->name_length, 00438 d->name, d->name_length) == 0) { 00439 *prevNext = n->next; 00440 SNMP_FREE(n->prefix); 00441 return 1; 00442 } 00443 prevNext = &(d->next); 00444 } 00445 return 0; 00446 } else { 00447 return 0; 00448 } 00449 } 00450 #endif /* NETSNMP_FEATURE_REMOVE_TDOMAIN_UNREGISTER */ 00451 00452 00453 static netsnmp_tdomain * 00454 find_tdomain(const char* spec) 00455 { 00456 netsnmp_tdomain *d; 00457 for (d = domain_list; d != NULL; d = d->next) { 00458 int i; 00459 for (i = 0; d->prefix[i] != NULL; i++) 00460 if (strcasecmp(d->prefix[i], spec) == 0) { 00461 DEBUGMSGTL(("tdomain", 00462 "Found domain \"%s\" from specifier \"%s\"\n", 00463 d->prefix[0], spec)); 00464 return d; 00465 } 00466 } 00467 DEBUGMSGTL(("tdomain", "Found no domain from specifier \"%s\"\n", spec)); 00468 return NULL; 00469 } 00470 00471 static int 00472 netsnmp_is_fqdn(const char *thename) 00473 { 00474 if (!thename) 00475 return 0; 00476 while(*thename) { 00477 if (*thename != '.' && !isupper((unsigned char)*thename) && 00478 !islower((unsigned char)*thename) && 00479 !isdigit((unsigned char)*thename) && *thename != '-') { 00480 return 0; 00481 } 00482 thename++; 00483 } 00484 return 1; 00485 } 00486 00487 /* 00488 * Locate the appropriate transport domain and call the create function for 00489 * it. 00490 */ 00491 netsnmp_transport * 00492 netsnmp_tdomain_transport_full(const char *application, 00493 const char *str, int local, 00494 const char *default_domain, 00495 const char *default_target) 00496 { 00497 netsnmp_tdomain *match = NULL; 00498 const char *addr = NULL; 00499 const char * const *spec = NULL; 00500 int any_found = 0; 00501 char buf[SNMP_MAXPATH]; 00502 extern const char *curfilename; /* from read_config.c */ 00503 const char *prev_curfilename; 00504 00505 prev_curfilename = curfilename; 00506 00507 DEBUGMSGTL(("tdomain", 00508 "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n", 00509 application, str ? str : "[NIL]", local, 00510 default_domain ? default_domain : "[NIL]", 00511 default_target ? default_target : "[NIL]")); 00512 00513 /* see if we can load a host-name specific set of conf files */ 00514 if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 00515 NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES) && 00516 netsnmp_is_fqdn(str)) { 00517 static int have_added_handler = 0; 00518 char *newhost; 00519 struct config_line *config_handlers; 00520 struct config_files file_names; 00521 char *prev_hostname; 00522 00523 /* register a "transport" specifier */ 00524 if (!have_added_handler) { 00525 have_added_handler = 1; 00526 netsnmp_ds_register_config(ASN_OCTET_STR, 00527 "snmp", "transport", 00528 NETSNMP_DS_LIBRARY_ID, 00529 NETSNMP_DS_LIB_HOSTNAME); 00530 } 00531 00532 /* we save on specific setting that we don't allow to change 00533 from one transport creation to the next; ie, we don't want 00534 the "transport" specifier to be a default. It should be a 00535 single invocation use only */ 00536 prev_hostname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 00537 NETSNMP_DS_LIB_HOSTNAME); 00538 if (prev_hostname) 00539 prev_hostname = strdup(prev_hostname); 00540 00541 /* read in the hosts/STRING.conf files */ 00542 config_handlers = read_config_get_handlers("snmp"); 00543 snprintf(buf, sizeof(buf)-1, "hosts/%s", str); 00544 file_names.fileHeader = buf; 00545 file_names.start = config_handlers; 00546 file_names.next = NULL; 00547 DEBUGMSGTL(("tdomain", "checking for host specific config %s\n", 00548 buf)); 00549 read_config_files_of_type(EITHER_CONFIG, &file_names); 00550 00551 if (NULL != 00552 (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 00553 NETSNMP_DS_LIB_HOSTNAME))) { 00554 strncpy(buf, newhost, sizeof(buf)-1); 00555 str = buf; 00556 } 00557 00558 netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, 00559 NETSNMP_DS_LIB_HOSTNAME, 00560 prev_hostname); 00561 SNMP_FREE(prev_hostname); 00562 } 00563 00564 /* First try - assume that there is a domain in str (domain:target) */ 00565 00566 if (str != NULL) { 00567 const char *cp; 00568 if ((cp = strchr(str, ':')) != NULL) { 00569 char* mystring = (char*)malloc(cp + 1 - str); 00570 memcpy(mystring, str, cp - str); 00571 mystring[cp - str] = '\0'; 00572 addr = cp + 1; 00573 00574 match = find_tdomain(mystring); 00575 free(mystring); 00576 } 00577 } 00578 00579 /* 00580 * Second try, if there is no domain in str (target), then try the 00581 * default domain 00582 */ 00583 00584 if (match == NULL) { 00585 addr = str; 00586 if (addr && *addr == '/') { 00587 DEBUGMSGTL(("tdomain", 00588 "Address starts with '/', so assume \"unix\" " 00589 "domain\n")); 00590 match = find_tdomain("unix"); 00591 } else if (default_domain) { 00592 DEBUGMSGTL(("tdomain", 00593 "Use user specified default domain \"%s\"\n", 00594 default_domain)); 00595 match = find_tdomain(default_domain); 00596 } else { 00597 spec = netsnmp_lookup_default_domains(application); 00598 if (spec == NULL) { 00599 DEBUGMSGTL(("tdomain", 00600 "No default domain found, assume \"udp\"\n")); 00601 match = find_tdomain("udp"); 00602 } else { 00603 const char * const * r = spec; 00604 DEBUGMSGTL(("tdomain", 00605 "Use application default domains")); 00606 while(*r) { 00607 DEBUGMSG(("tdomain", " \"%s\"", *r)); 00608 ++r; 00609 } 00610 DEBUGMSG(("tdomain", "\n")); 00611 } 00612 } 00613 } 00614 00615 for(;;) { 00616 if (match) { 00617 netsnmp_transport *t = NULL; 00618 const char* addr2; 00619 00620 any_found = 1; 00621 /* 00622 * Ok, we know what domain to try, lets see what default data 00623 * should be used with it 00624 */ 00625 if (default_target != NULL) 00626 addr2 = default_target; 00627 else 00628 addr2 = netsnmp_lookup_default_target(application, 00629 match->prefix[0]); 00630 DEBUGMSGTL(("tdomain", 00631 "trying domain \"%s\" address \"%s\" " 00632 "default address \"%s\"\n", 00633 match->prefix[0], addr ? addr : "[NIL]", 00634 addr2 ? addr2 : "[NIL]")); 00635 if (match->f_create_from_tstring) { 00636 NETSNMP_LOGONCE((LOG_WARNING, 00637 "transport domain %s uses deprecated f_create_from_tstring\n", 00638 match->prefix[0])); 00639 t = match->f_create_from_tstring(addr, local); 00640 } 00641 else 00642 t = match->f_create_from_tstring_new(addr, local, addr2); 00643 if (t) { 00644 curfilename = prev_curfilename; 00645 return t; 00646 } 00647 } 00648 addr = str; 00649 if (spec && *spec) 00650 match = find_tdomain(*spec++); 00651 else 00652 break; 00653 } 00654 if (!any_found) 00655 snmp_log(LOG_ERR, "No support for any checked transport domain\n"); 00656 curfilename = prev_curfilename; 00657 return NULL; 00658 } 00659 00660 00661 netsnmp_transport * 00662 netsnmp_tdomain_transport(const char *str, int local, 00663 const char *default_domain) 00664 { 00665 return netsnmp_tdomain_transport_full("snmp", str, local, default_domain, 00666 NULL); 00667 } 00668 00669 00670 #ifndef NETSNMP_FEATURE_REMOVE_TDOMAIN_TRANSPORT_OID 00671 netsnmp_transport * 00672 netsnmp_tdomain_transport_oid(const oid * dom, 00673 size_t dom_len, 00674 const u_char * o, size_t o_len, int local) 00675 { 00676 netsnmp_tdomain *d; 00677 int i; 00678 00679 DEBUGMSGTL(("tdomain", "domain \"")); 00680 DEBUGMSGOID(("tdomain", dom, dom_len)); 00681 DEBUGMSG(("tdomain", "\"\n")); 00682 00683 for (d = domain_list; d != NULL; d = d->next) { 00684 for (i = 0; d->prefix[i] != NULL; i++) { 00685 if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) == 00686 0) { 00687 return d->f_create_from_ostring(o, o_len, local); 00688 } 00689 } 00690 } 00691 00692 snmp_log(LOG_ERR, "No support for requested transport domain\n"); 00693 return NULL; 00694 } 00695 #endif /* NETSNMP_FEATURE_REMOVE_TDOMAIN_TRANSPORT_OID */ 00696 00697 netsnmp_transport* 00698 netsnmp_transport_open(const char* application, const char* str, int local) 00699 { 00700 return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL); 00701 } 00702 00703 netsnmp_transport* 00704 netsnmp_transport_open_server(const char* application, const char* str) 00705 { 00706 return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL); 00707 } 00708 00709 netsnmp_transport* 00710 netsnmp_transport_open_client(const char* application, const char* str) 00711 { 00712 return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL); 00713 } 00714 00717 int 00718 netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list, 00719 netsnmp_transport *transport) 00720 { 00721 netsnmp_transport_list *newptr = 00722 SNMP_MALLOC_TYPEDEF(netsnmp_transport_list); 00723 00724 if (!newptr) 00725 return 1; 00726 00727 newptr->next = *transport_list; 00728 newptr->transport = transport; 00729 00730 *transport_list = newptr; 00731 00732 return 0; 00733 } 00734 00735 00738 int 00739 netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list, 00740 netsnmp_transport *transport) 00741 { 00742 netsnmp_transport_list *ptr = *transport_list, *lastptr = NULL; 00743 00744 while (ptr && ptr->transport != transport) { 00745 lastptr = ptr; 00746 ptr = ptr->next; 00747 } 00748 00749 if (!ptr) 00750 return 1; 00751 00752 if (lastptr) 00753 lastptr->next = ptr->next; 00754 else 00755 *transport_list = ptr->next; 00756 00757 SNMP_FREE(ptr); 00758 00759 return 0; 00760 } 00761 00762 int 00763 netsnmp_transport_config_compare(netsnmp_transport_config *left, 00764 netsnmp_transport_config *right) { 00765 return strcmp(left->key, right->key); 00766 } 00767 00768 netsnmp_transport_config * 00769 netsnmp_transport_create_config(char *key, char *value) { 00770 netsnmp_transport_config *entry = 00771 SNMP_MALLOC_TYPEDEF(netsnmp_transport_config); 00772 entry->key = strdup(key); 00773 entry->value = strdup(value); 00774 return entry; 00775 }