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