Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / net-snmp / snmplib / snmp_transport.c
1 #include <net-snmp/net-snmp-config.h>
2
3 #include <stdio.h>
4 #if HAVE_STRING_H
5 #include <string.h>
6 #else
7 #include <strings.h>
8 #endif
9 #include <sys/types.h>
10
11 #if HAVE_STDLIB_H
12 #include <stdlib.h>
13 #endif
14
15 #if HAVE_DMALLOC_H
16 #include <dmalloc.h>
17 #endif
18
19 #include <net-snmp/output_api.h>
20 #include <net-snmp/utilities.h>
21
22 #include <net-snmp/library/snmp_transport.h>
23 #include <net-snmp/library/snmpUDPDomain.h>
24 #ifdef SNMP_TRANSPORT_TCP_DOMAIN
25 #include <net-snmp/library/snmpTCPDomain.h>
26 #endif
27 #ifdef SNMP_TRANSPORT_IPX_DOMAIN
28 #include <net-snmp/library/snmpIPXDomain.h>
29 #endif
30 #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
31 #include <net-snmp/library/snmpUnixDomain.h>
32 #endif
33 #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
34 #include <net-snmp/library/snmpAAL5PVCDomain.h>
35 #endif
36 #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
37 #include <net-snmp/library/snmpUDPIPv6Domain.h>
38 #endif
39 #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
40 #include <net-snmp/library/snmpTCPIPv6Domain.h>
41 #endif
42 #include <net-snmp/library/snmp_api.h>
43
44
45 /*
46  * Our list of supported transport domains.  
47  */
48
49 static netsnmp_tdomain *domain_list = NULL;
50
51
52
53 /*
54  * The standard SNMP domains.  
55  */
56
57 oid             netsnmpUDPDomain[] = { 1, 3, 6, 1, 6, 1, 1 };
58 size_t          netsnmpUDPDomain_len = OID_LENGTH(netsnmpUDPDomain);
59 oid             netsnmpCLNSDomain[] = { 1, 3, 6, 1, 6, 1, 2 };
60 size_t          netsnmpCLNSDomain_len = OID_LENGTH(netsnmpCLNSDomain);
61 oid             netsnmpCONSDomain[] = { 1, 3, 6, 1, 6, 1, 3 };
62 size_t          netsnmpCONSDomain_len = OID_LENGTH(netsnmpCONSDomain);
63 oid             netsnmpDDPDomain[] = { 1, 3, 6, 1, 6, 1, 4 };
64 size_t          netsnmpDDPDomain_len = OID_LENGTH(netsnmpDDPDomain);
65 oid             netsnmpIPXDomain[] = { 1, 3, 6, 1, 6, 1, 5 };
66 size_t          netsnmpIPXDomain_len = OID_LENGTH(netsnmpIPXDomain);
67
68 static void     netsnmp_tdomain_dump(void);
69
70 /*
71  * Make a deep copy of an netsnmp_transport.  
72  */
73
74 netsnmp_transport *
75 netsnmp_transport_copy(netsnmp_transport *t)
76 {
77     netsnmp_transport *n = NULL;
78
79     n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
80     if (n == NULL) {
81         return NULL;
82     }
83     memset(n, 0, sizeof(netsnmp_transport));
84
85     if (t->domain != NULL) {
86         n->domain = t->domain;
87         n->domain_length = t->domain_length;
88     } else {
89         n->domain = NULL;
90         n->domain_length = 0;
91     }
92
93     if (t->local != NULL) {
94         n->local = (u_char *) malloc(t->local_length);
95         if (n->local == NULL) {
96             netsnmp_transport_free(n);
97             return NULL;
98         }
99         n->local_length = t->local_length;
100         memcpy(n->local, t->local, t->local_length);
101     } else {
102         n->local = NULL;
103         n->local_length = 0;
104     }
105
106     if (t->remote != NULL) {
107         n->remote = (u_char *) malloc(t->remote_length);
108         if (n->remote == NULL) {
109             netsnmp_transport_free(n);
110             return NULL;
111         }
112         n->remote_length = t->remote_length;
113         memcpy(n->remote, t->remote, t->remote_length);
114     } else {
115         n->remote = NULL;
116         n->remote_length = 0;
117     }
118
119     if (t->data != NULL && t->data_length > 0) {
120         n->data = malloc(t->data_length);
121         if (n->data == NULL) {
122             netsnmp_transport_free(n);
123             return NULL;
124         }
125         n->data_length = t->data_length;
126         memcpy(n->data, t->data, t->data_length);
127     } else {
128         n->data = NULL;
129         n->data_length = 0;
130     }
131
132     n->msgMaxSize = t->msgMaxSize;
133     n->f_accept = t->f_accept;
134     n->f_recv = t->f_recv;
135     n->f_send = t->f_send;
136     n->f_close = t->f_close;
137     n->f_fmtaddr = t->f_fmtaddr;
138     n->sock = t->sock;
139     n->flags = t->flags;
140
141     return n;
142 }
143
144
145
146 void
147 netsnmp_transport_free(netsnmp_transport *t)
148 {
149     if (t->local != NULL) {
150         free(t->local);
151     }
152     if (t->remote != NULL) {
153         free(t->remote);
154     }
155     if (t->data != NULL) {
156         free(t->data);
157     }
158     free(t);
159 }
160
161
162 #if BRCM_SNMP_SUPPORT
163 int
164 netsnmp_tdomain_support(const oid * in_oid,
165                         size_t in_len,
166                         const oid ** out_oid, size_t * out_len)
167 {
168     netsnmp_tdomain *d = NULL;
169
170     for (d = domain_list; d != NULL; d = d->next) {
171         if (netsnmp_oid_equals(in_oid, in_len, d->name, d->name_length) == 0) {
172             if (out_oid != NULL && out_len != NULL) {
173                 *out_oid = d->name;
174                 *out_len = d->name_length;
175             }
176             return 1;
177         }
178     }
179     return 0;
180 }
181 #endif /* BRCM_SNMP_SUPPORT */
182
183
184 void
185 netsnmp_tdomain_init(void)
186 {
187     DEBUGMSGTL(("tdomain", "netsnmp_tdomain_init() called\n"));
188     netsnmp_udp_ctor();
189 #ifdef SNMP_TRANSPORT_TCP_DOMAIN
190     netsnmp_tcp_ctor();
191 #endif
192 #ifdef SNMP_TRANSPORT_IPX_DOMAIN
193     netsnmp_ipx_ctor();
194 #endif
195 #ifdef SNMP_TRANSPORT_UNIX_DOMAIN
196     netsnmp_unix_ctor();
197 #endif
198 #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN
199     netsnmp_aal5pvc_ctor();
200 #endif
201 #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN
202     netsnmp_udp6_ctor();
203 #endif
204 #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN
205     netsnmp_tcp6_ctor();
206 #endif
207 #if BRCM_SNMP_SUPPORT
208     netsnmp_tdomain_dump();
209 #endif
210 }
211
212 #if BRCM_SNMP_SUPPORT
213 static void
214 netsnmp_tdomain_dump(void)
215 {
216     netsnmp_tdomain *d;
217     int i = 0;
218
219     DEBUGMSGTL(("tdomain", "domain_list -> "));
220     for (d = domain_list; d != NULL; d = d->next) {
221         DEBUGMSG(("tdomain", "{ "));
222         DEBUGMSGOID(("tdomain", d->name, d->name_length));
223         DEBUGMSG(("tdomain", ", \""));
224         for (i = 0; d->prefix[i] != NULL; i++) {
225             DEBUGMSG(("tdomain", "%s%s", d->prefix[i],
226                       (d->prefix[i + 1]) ? "/" : ""));
227         }
228         DEBUGMSG(("tdomain", "\" } -> "));
229     }
230     DEBUGMSG(("tdomain", "[NIL]\n"));
231 }
232 #endif /* #if BRCM_SNMP_SUPPORT */
233
234
235 int
236 netsnmp_tdomain_register(netsnmp_tdomain *n)
237 {
238     netsnmp_tdomain **prevNext = &domain_list, *d;
239
240     if (n != NULL) {
241         for (d = domain_list; d != NULL; d = d->next) {
242             if (netsnmp_oid_equals(n->name, n->name_length,
243                                 d->name, d->name_length) == 0) {
244                 /*
245                  * Already registered.  
246                  */
247                 return 0;
248             }
249             prevNext = &(d->next);
250         }
251         n->next = NULL;
252         *prevNext = n;
253         return 1;
254     } else {
255         return 0;
256     }
257 }
258
259
260
261 int
262 netsnmp_tdomain_unregister(netsnmp_tdomain *n)
263 {
264     netsnmp_tdomain **prevNext = &domain_list, *d;
265
266     if (n != NULL) {
267         for (d = domain_list; d != NULL; d = d->next) {
268             if (netsnmp_oid_equals(n->name, n->name_length,
269                                 d->name, d->name_length) == 0) {
270                 *prevNext = n->next;
271                 return 1;
272             }
273             prevNext = &(d->next);
274         }
275         return 0;
276     } else {
277         return 0;
278     }
279 }
280
281
282
283 netsnmp_transport *
284 netsnmp_tdomain_transport(const char *string, int local,
285                           const char *default_domain)
286 {
287     netsnmp_tdomain *d;
288     netsnmp_transport *t = NULL;
289     const char     *spec, *addr;
290     char           *cp, *mystring;
291     int             i;
292
293     if (string == NULL) {
294         return NULL;
295     }
296
297     if ((mystring = strdup(string)) == NULL) {
298         DEBUGMSGTL(("tdomain", "can't strdup(\"%s\")\n", string));
299         return NULL;
300     }
301
302     if ((cp = strchr(mystring, ':')) == NULL) {
303         /*
304          * There doesn't appear to be a transport specifier.  
305          */
306         DEBUGMSGTL(("tdomain", "no specifier in \"%s\"\n", mystring));
307         if (*mystring == '/') {
308             spec = "unix";
309             addr = mystring;
310         } else {
311             if (default_domain) {
312                 spec = default_domain;
313             } else {
314                 spec = "udp";
315             }
316             addr = mystring;
317         }
318     } else {
319         *cp = '\0';
320         spec = mystring;
321         addr = cp + 1;
322     }
323     DEBUGMSGTL(("tdomain", "specifier \"%s\" address \"%s\"\n", spec,
324                 addr));
325
326     for (d = domain_list; d != NULL; d = d->next) {
327         for (i = 0; d->prefix[i] != NULL; i++) {
328             if (strcasecmp(d->prefix[i], spec) == 0) {
329                 DEBUGMSGTL(("tdomain", "specifier \"%s\" matched\n",
330                             spec));
331                 t = d->f_create_from_tstring(addr, local);
332                 free(mystring);
333                 return t;
334             }
335         }
336     }
337
338     /*
339      * Okay no match so far.  Consider the possibility that we have something
340      * like hostname.domain.com:port which will have confused the parser above.
341      * Try and match again with the appropriate default domain.  
342      */
343
344     if (default_domain) {
345         spec = default_domain;
346     } else {
347         spec = "udp";
348     }
349     if (cp) {
350         *cp = ':';
351     }
352
353     addr = mystring;
354     DEBUGMSGTL(("tdomain",
355                 "try again with specifier \"%s\" address \"%s\"\n", spec,
356                 addr));
357
358     for (d = domain_list; d != NULL; d = d->next) {
359         for (i = 0; d->prefix[i] != NULL; i++) {
360             if (strcmp(d->prefix[i], spec) == 0) {
361                 DEBUGMSGTL(("tdomain", "specifier \"%s\" matched\n",
362                             spec));
363                 t = d->f_create_from_tstring(addr, local);
364                 free(mystring);
365                 return t;
366             }
367         }
368     }
369
370     snmp_log(LOG_ERR, "No support for requested transport domain \"%s\"\n",
371              spec);
372     free(mystring);
373     return NULL;
374 }
375
376
377 netsnmp_transport *
378 netsnmp_tdomain_transport_oid(const oid * dom,
379                               size_t dom_len,
380                               const u_char * o, size_t o_len, int local)
381 {
382     netsnmp_tdomain *d;
383     int             i;
384
385     DEBUGMSGTL(("tdomain", "domain \""));
386     DEBUGMSGOID(("tdomain", dom, dom_len));
387     DEBUGMSG(("tdomain", "\"\n"));
388
389     for (d = domain_list; d != NULL; d = d->next) {
390         for (i = 0; d->prefix[i] != NULL; i++) {
391             if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
392                 0) {
393                 return d->f_create_from_ostring(o, o_len, local);
394             }
395         }
396     }
397
398     snmp_log(LOG_ERR, "No support for requested transport domain\n");
399     return NULL;
400 }
401
402
403 /** adds a transport to a linked list of transports.
404     Returns 1 on failure, 0 on success */
405 int
406 netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list,
407                               netsnmp_transport *transport)
408 {
409     netsnmp_transport_list *newptr =
410         SNMP_MALLOC_TYPEDEF(netsnmp_transport_list);
411
412     if (!newptr)
413         return 1;
414
415     newptr->next = *transport_list;
416     newptr->transport = transport;
417
418     *transport_list = newptr;
419
420     return 0;
421 }
422
423
424 /**  removes a transport from a linked list of transports.
425      Returns 1 on failure, 0 on success */
426 int
427 netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list,
428                                    netsnmp_transport *transport)
429 {
430     netsnmp_transport_list *ptr = *transport_list, *lastptr = NULL;
431
432     while (ptr && ptr->transport != transport) {
433         lastptr = ptr;
434         ptr = ptr->next;
435     }
436
437     if (!ptr)
438         return 1;
439
440     if (lastptr)
441         lastptr->next = ptr->next;
442     else
443         *transport_list = ptr->next;
444
445     free(ptr);
446
447     return 0;
448 }
449