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
00054
00055
00056 static netsnmp_tdomain *domain_list = NULL;
00057
00058
00059
00060
00061
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
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
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
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
00314
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
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
00363
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
00408
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 }