# BRCM_VERSION=3
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / mibII / udpTable.c
1 #ifdef BUILD_SNMP_UDP_MIB
2 /*
3  *  UDP MIB group Table implementation - udpTable.c
4  *
5  */
6
7 #include <net-snmp/net-snmp-config.h>
8
9 #if HAVE_STRING_H
10 #include <string.h>
11 #else
12 #include <strings.h>
13 #endif
14 #include <sys/types.h>
15 #if HAVE_WINSOCK_H
16 #include <winsock.h>
17 #endif
18
19 #if HAVE_SYS_PARAM_H
20 #include <sys/param.h>
21 #endif
22
23 #if HAVE_NETINET_IN_H
24 #include <netinet/in.h>
25 #endif
26 #if HAVE_SYS_SYSMP_H
27 #include <sys/sysmp.h>
28 #endif
29 #if HAVE_SYS_TCPIPSTATS_H
30 #include <sys/tcpipstats.h>
31 #endif
32 #if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL)
33 #define _KERNEL 1
34 #define _I_DEFINED_KERNEL
35 #endif
36 #if HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
38 #endif
39 #if HAVE_NET_IF_H
40 #include <net/if.h>
41 #endif
42 #if HAVE_NET_IF_VAR_H
43 #include <net/if_var.h>
44 #endif
45 #ifdef _I_DEFINED_KERNEL
46 #undef _KERNEL
47 #endif
48
49 #if HAVE_SYS_STREAM_H
50 #include <sys/stream.h>
51 #endif
52 #if HAVE_NET_ROUTE_H
53 #include <net/route.h>
54 #endif
55 #if HAVE_NETINET_IN_SYSTM_H
56 #include <netinet/in_systm.h>
57 #endif
58 #if HAVE_NETINET_IP_H
59 #include <netinet/ip.h>
60 #endif
61 #if HAVE_SYS_QUEUE_H
62 #include <sys/queue.h>
63 #endif
64 #if HAVE_SYS_SOCKETVAR_H
65 #include <sys/socketvar.h>
66 #endif
67 #if HAVE_NETINET_IP_VAR_H
68 #include <netinet/ip_var.h>
69 #endif
70 #ifdef INET6
71 #if HAVE_NETINET6_IP6_VAR_H
72 #include <netinet6/ip6_var.h>
73 #endif
74 #endif
75 #if HAVE_NETINET_IN_PCB_H
76 #include <netinet/in_pcb.h>
77 #endif
78 #if HAVE_NETINET_UDP_H
79 #include <netinet/udp.h>
80 #endif
81 #if HAVE_NETINET_UDP_VAR_H
82 #include <netinet/udp_var.h>
83 #endif
84 #if HAVE_INET_MIB2_H
85 #include <inet/mib2.h>
86 #endif
87
88 #ifdef solaris2
89 #include "kernel_sunos5.h"
90 #else
91 #include "kernel.h"
92 #endif
93
94 #ifdef cygwin
95 #define WIN32
96 #include <windows.h>
97 #endif
98
99 #include <net-snmp/net-snmp-includes.h>
100 #include <net-snmp/agent/net-snmp-agent-includes.h>
101 #include <net-snmp/agent/auto_nlist.h>
102
103 #ifdef hpux
104 #include <sys/mib.h>
105 #include <netinet/mib_kern.h>
106 #endif                          /* hpux */
107
108 #ifdef linux
109 #include "tcpTable.h"
110 #endif
111 #include "udp.h"
112 #include "udpTable.h"
113 #include "sysORTable.h"
114
115 #ifdef CAN_USE_SYSCTL
116 #include <sys/sysctl.h>
117 #endif
118
119 #if HAVE_DMALLOC_H
120 #include <dmalloc.h>
121 #endif
122
123         /*********************
124          *
125          *  Kernel & interface information,
126          *   and internal forward declarations
127          *
128          *********************/
129
130 #ifndef solaris2
131 static void     UDP_Scan_Init(void);
132 #ifdef hpux11
133 static int      UDP_Scan_Next(mib_udpLsnEnt *);
134 #else
135 static int      UDP_Scan_Next(struct inpcb *);
136 #endif
137 #endif
138
139         /*********************
140          *
141          *  Initialisation & common implementation functions
142          *
143          *********************/
144
145
146         /*********************
147          *
148          *  System specific implementation functions
149          *
150          *********************/
151
152 #ifndef WIN32
153 #ifndef solaris2
154
155 u_char         *
156 var_udpEntry(struct variable *vp,
157              oid * name,
158              size_t * length,
159              int exact, size_t * var_len, WriteMethod ** write_method)
160 {
161     int             i;
162     oid             newname[MAX_OID_LEN], lowest[MAX_OID_LEN], *op;
163     u_char         *cp;
164     int             LowState;
165 #ifdef hpux11
166     static mib_udpLsnEnt udp, Lowudp;
167 #else
168     static struct inpcb inpcb, Lowinpcb;
169 #endif
170
171     memcpy((char *) newname, (char *) vp->name,
172            (int) vp->namelen * sizeof(oid));
173     /*
174      * find the "next" pseudo-connection 
175      */
176 #ifndef hpux11
177   Again:
178 #endif
179     LowState = -1;              /* UDP doesn't have 'State', but it's a useful flag */
180     UDP_Scan_Init();
181     for (;;) {
182 #ifdef hpux11
183         if ((i = UDP_Scan_Next(&udp)) == 0)
184             break;              /* Done */
185         cp = (u_char *) & udp.LocalAddress;
186 #else                           /* hpux11 */
187         if ((i = UDP_Scan_Next(&inpcb)) < 0)
188             goto Again;
189         if (i == 0)
190             break;              /* Done */
191         cp = (u_char *) & inpcb.inp_laddr.s_addr;
192 #endif                          /* hpux11 */
193         op = newname + 10;
194         *op++ = *cp++;
195         *op++ = *cp++;
196         *op++ = *cp++;
197         *op++ = *cp++;
198
199 #ifdef hpux11
200         newname[14] = (unsigned short) udp.LocalPort;
201 #else
202         newname[14] = ntohs(inpcb.inp_lport);
203 #endif
204
205         if (exact) {
206             if (snmp_oid_compare(newname, 15, name, *length) == 0) {
207                 memcpy((char *) lowest, (char *) newname,
208                        15 * sizeof(oid));
209                 LowState = 0;
210 #ifdef hpux11
211                 Lowudp = udp;
212 #else
213                 Lowinpcb = inpcb;
214 #endif
215                 break;          /* no need to search further */
216             }
217         } else {
218             if ((snmp_oid_compare(newname, 15, name, *length) > 0) &&
219                 ((LowState < 0)
220                  || (snmp_oid_compare(newname, 15, lowest, 15) < 0))) {
221                 /*
222                  * if new one is greater than input and closer to input than
223                  * previous lowest, save this one as the "next" one.
224                  */
225                 memcpy((char *) lowest, (char *) newname,
226                        15 * sizeof(oid));
227                 LowState = 0;
228 #ifdef hpux11
229                 Lowudp = udp;
230 #else
231                 Lowinpcb = inpcb;
232 #endif
233             }
234         }
235     }
236     if (LowState < 0)
237         return (NULL);
238     memcpy((char *) name, (char *) lowest,
239            ((int) vp->namelen + 10) * sizeof(oid));
240     *length = vp->namelen + 5;
241     *write_method = 0;
242     *var_len = sizeof(long);
243     switch (vp->magic) {
244     case UDPLOCALADDRESS:
245 #ifdef hpux11
246         return (u_char *) & Lowudp.LocalAddress;
247 #else
248         return (u_char *) & Lowinpcb.inp_laddr.s_addr;
249 #endif
250     case UDPLOCALPORT:
251 #ifdef hpux11
252         long_return = (unsigned short) Lowudp.LocalPort;
253 #else
254         long_return = ntohs(Lowinpcb.inp_lport);
255 #endif
256         return (u_char *) & long_return;
257     default:
258         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udpEntry\n",
259                     vp->magic));
260     }
261     return NULL;
262 }
263
264 #else                           /* solaris2 - udp */
265
266 static int
267 UDP_Cmp(void *addr, void *ep)
268 {
269     if (memcmp((mib2_udpEntry_t *) ep, (mib2_udpEntry_t *) addr,
270                sizeof(mib2_udpEntry_t)) == 0)
271         return (0);
272     else
273         return (1);
274 }
275
276 u_char         *
277 var_udpEntry(struct variable * vp,
278              oid * name,
279              size_t * length,
280              int exact, size_t * var_len, WriteMethod ** write_method)
281 {
282     oid             newname[MAX_OID_LEN], lowest[MAX_OID_LEN], *op;
283     u_char         *cp;
284
285 #define UDP_LISTEN_LENGTH 15
286 #define UDP_LOCADDR_OFF   10
287 #define UDP_LOCPORT_OFF   14
288     mib2_udpEntry_t Lowentry, Nextentry, entry;
289     req_e           req_type;
290     int             Found = 0;
291
292     memset(&Lowentry, 0, sizeof(Lowentry));
293     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
294     if (*length == UDP_LISTEN_LENGTH)   /* Assume that the input name is the lowest */
295         memcpy((char *) lowest, (char *) name,
296                UDP_LISTEN_LENGTH * sizeof(oid));
297     for (Nextentry.udpLocalAddress = (u_long) - 1, req_type = GET_FIRST;;
298          req_type = GET_NEXT) {
299         if (getMibstat
300             (MIB_UDP_LISTEN, &entry, sizeof(mib2_udpEntry_t), req_type,
301              &UDP_Cmp, &entry) != 0)
302             break;
303         if (entry.udpEntryInfo.ue_state != MIB2_UDP_idle)
304             continue;           /* we only want to get listen ports */
305         COPY_IPADDR(cp, (u_char *) & entry.udpLocalAddress, op,
306                     newname + UDP_LOCADDR_OFF);
307         newname[UDP_LOCPORT_OFF] = entry.udpLocalPort;
308
309         if (exact) {
310             if (snmp_oid_compare(newname, UDP_LISTEN_LENGTH, name, *length)
311                 == 0) {
312                 memcpy((char *) lowest, (char *) newname,
313                        UDP_LISTEN_LENGTH * sizeof(oid));
314                 Lowentry = entry;
315                 Found++;
316                 break;          /* no need to search further */
317             }
318         } else {
319             if ((snmp_oid_compare
320                  (newname, UDP_LISTEN_LENGTH, name, *length) > 0)
321                 && ((Nextentry.udpLocalAddress == (u_long) - 1)
322                     ||
323                     (snmp_oid_compare
324                      (newname, UDP_LISTEN_LENGTH, lowest,
325                       UDP_LISTEN_LENGTH) < 0)
326                     ||
327                     (snmp_oid_compare
328                      (name, *length, lowest, UDP_LISTEN_LENGTH) == 0))) {
329                 /*
330                  * if new one is greater than input and closer to input than
331                  * * previous lowest, and is not equal to it, save this one as
332                  * * the "next" one.
333                  */
334                 memcpy((char *) lowest, (char *) newname,
335                        UDP_LISTEN_LENGTH * sizeof(oid));
336                 Lowentry = entry;
337                 Found++;
338             }
339         }
340         Nextentry = entry;
341     }
342     if (Found == 0)
343         return (NULL);
344     memcpy((char *) name, (char *) lowest,
345            (vp->namelen + UDP_LISTEN_LENGTH -
346             UDP_LOCADDR_OFF) * sizeof(oid));
347     *length = vp->namelen + UDP_LISTEN_LENGTH - UDP_LOCADDR_OFF;
348     *write_method = 0;
349     *var_len = sizeof(long);
350     switch (vp->magic) {
351     case UDPLOCALADDRESS:
352         long_return = Lowentry.udpLocalAddress;
353         return (u_char *) & long_return;
354     case UDPLOCALPORT:
355         long_return = Lowentry.udpLocalPort;
356         return (u_char *) & long_return;
357     default:
358         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udpEntry\n",
359                     vp->magic));
360     }
361     return NULL;
362 }
363 #endif                          /* solaris2 - udp */
364
365
366         /*********************
367          *
368          *  Internal implementation functions
369          *
370          *********************/
371
372 #ifdef linux
373 static struct inpcb *udp_inpcb_list;
374 #endif
375
376 #ifndef solaris2
377
378 #ifdef hpux11
379 static int      udptab_size, udptab_current;
380 static mib_udpLsnEnt *udp = (mib_udpLsnEnt *) 0;
381 #else                           /* hpux11 */
382 static struct inpcb udp_inpcb, *udp_prev;
383 #ifdef PCB_TABLE
384 static struct inpcb *udp_head, *udp_next;
385 #endif
386 #if defined(CAN_USE_SYSCTL) && defined(UDPCTL_PCBLIST)
387 static char    *udpcb_buf = NULL;
388 static struct xinpgen *xig = NULL;
389 #endif                          /* !defined(CAN_USE_SYSCTL) || !define(UDPCTL_PCBLIST) */
390 #endif                          /* hpux11 */
391
392
393 static void
394 UDP_Scan_Init(void)
395 {
396 #ifdef hpux11
397
398     int             fd;
399     struct nmparms  p;
400     int             val;
401     unsigned int    ulen;
402     int             ret;
403
404     if (udp)
405         free(udp);
406     udp = (mib_udpLsnEnt *) 0;
407     udptab_size = 0;
408
409     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
410         p.objid = ID_udpLsnNumEnt;
411         p.buffer = (void *) &val;
412         ulen = sizeof(int);
413         p.len = &ulen;
414         if ((ret = get_mib_info(fd, &p)) == 0)
415             udptab_size = val;
416
417         if (udptab_size > 0) {
418             ulen = (unsigned) udptab_size *sizeof(mib_udpLsnEnt);
419             udp = (mib_udpLsnEnt *) malloc(ulen);
420             p.objid = ID_udpLsnTable;
421             p.buffer = (void *) udp;
422             p.len = &ulen;
423             if ((ret = get_mib_info(fd, &p)) < 0)
424                 udptab_size = 0;
425         }
426
427         close_mib(fd);
428     }
429
430     udptab_current = 0;
431
432 #else                           /* hpux11 */
433
434 #if !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST)
435 #ifdef PCB_TABLE
436     struct inpcbtable table;
437 #endif
438 #ifndef linux
439 #ifdef PCB_TABLE
440     auto_nlist(UDB_SYMBOL, (char *) &table, sizeof(table));
441     udp_next = table.inpt_queue.cqh_first;
442     udp_head = udp_prev =
443         (struct inpcb *) &((struct inpcbtable *)
444                            auto_nlist_value(UDB_SYMBOL))->inpt_queue.
445         cqh_first;
446 #else
447     auto_nlist(UDB_SYMBOL, (char *) &udp_inpcb, sizeof(udp_inpcb));
448 #if !(defined(freebsd2) || defined(netbsd1) || defined(openbsd2))
449     udp_prev = (struct inpcb *) auto_nlist_value(UDB_SYMBOL);
450 #endif
451 #endif
452 #else                           /* linux */
453     FILE           *in;
454     char            line[256];
455     struct inpcb  **pp;
456     struct timeval  now;
457     static unsigned long Time_Of_Last_Reload = 0;
458
459     /*
460      * save some cpu-cycles, and reload after 5 secs...
461      */
462     gettimeofday(&now, (struct timezone *) 0);
463     if (Time_Of_Last_Reload + 5 > now.tv_sec) {
464         udp_prev = udp_inpcb_list;
465         return;
466     }
467     Time_Of_Last_Reload = now.tv_sec;
468
469
470     if (!(in = fopen("/proc/net/udp", "r"))) {
471         snmp_log(LOG_ERR, "snmpd: cannot open /proc/net/udp ...\n");
472         udp_prev = 0;
473         return;
474     }
475
476     /*
477      * free old chain: 
478      */
479     while (udp_inpcb_list) {
480         struct inpcb   *p = udp_inpcb_list;
481         udp_inpcb_list = udp_inpcb_list->inp_next;
482         free(p);
483     }
484
485     /*
486      * scan proc-file and append: 
487      */
488
489     pp = &udp_inpcb_list;
490
491     while (line == fgets(line, sizeof(line), in)) {
492         struct inpcb    pcb, *nnew;
493         unsigned int    state, lport;
494
495         if (3 != sscanf(line, "%*d: %x:%x %*x:%*x %x",
496                         &pcb.inp_laddr.s_addr, &lport, &state))
497             continue;
498
499         if (state != 7)         /* fix me:  UDP_LISTEN ??? */
500             continue;
501
502         pcb.inp_lport = htons((unsigned short) (lport));
503         pcb.inp_fport = htons(pcb.inp_fport);
504
505         nnew = (struct inpcb *) malloc(sizeof(struct inpcb));
506         if (nnew == NULL)
507             break;
508         *nnew = pcb;
509         nnew->inp_next = 0;
510
511         *pp = nnew;
512         pp = &nnew->inp_next;
513     }
514
515     fclose(in);
516
517     /*
518      * first entry to go: 
519      */
520     udp_prev = udp_inpcb_list;
521 #endif                          /*linux */
522 #else                           /*  !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */
523     {
524         size_t          len;
525         int             sname[] =
526             { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_PCBLIST };
527
528         if (udpcb_buf) {
529             free(udpcb_buf);
530             udpcb_buf = NULL;
531         }
532         xig = NULL;
533
534         len = 0;
535         if (sysctl(sname, 4, 0, &len, 0, 0) < 0) {
536             return;
537         }
538         if ((udpcb_buf = malloc(len)) == NULL) {
539             return;
540         }
541         if (sysctl(sname, 4, udpcb_buf, &len, 0, 0) < 0) {
542             free(udpcb_buf);
543             udpcb_buf = NULL;
544             return;
545         }
546
547         xig = (struct xinpgen *) udpcb_buf;
548         xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
549         return;
550     }
551 #endif                          /*  !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */
552
553 #endif                          /* hpux11 */
554 }
555
556 #ifdef hpux11
557 static int
558 UDP_Scan_Next(mib_udpLsnEnt * RetUdp)
559 {
560     if (udptab_current < udptab_size) {
561         /*
562          * copy values 
563          */
564         *RetUdp = udp[udptab_current];
565         /*
566          * increment to point to next entry 
567          */
568         udptab_current++;
569         /*
570          * return success 
571          */
572         return (1);
573     }
574
575     /*
576      * return done 
577      */
578     return (0);
579 }
580 #else                           /* hpux11 */
581 static int
582 UDP_Scan_Next(struct inpcb *RetInPcb)
583 {
584 #if !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST)
585     register struct inpcb *next;
586
587 #ifndef linux
588 #ifdef PCB_TABLE
589     if (udp_next == udp_head)
590         return 0;
591 #else
592     if ((udp_inpcb.INP_NEXT_SYMBOL == NULL) ||
593         (udp_inpcb.INP_NEXT_SYMBOL ==
594          (struct inpcb *) auto_nlist_value(UDB_SYMBOL))) {
595         return (0);             /* "EOF" */
596     }
597 #endif
598
599 #ifdef PCB_TABLE
600     klookup((unsigned long) udp_next, (char *) &udp_inpcb,
601             sizeof(udp_inpcb));
602     udp_next = udp_inpcb.inp_queue.cqe_next;
603 #else
604     next = udp_inpcb.INP_NEXT_SYMBOL;
605
606     klookup((unsigned long) next, (char *) &udp_inpcb, sizeof(udp_inpcb));
607 #if !(defined(netbsd1) || defined(freebsd2) || defined(linux) || defined(openbsd2))
608     if (udp_inpcb.INP_PREV_SYMBOL != udp_prev)  /* ??? */
609         return (-1);            /* "FAILURE" */
610 #endif
611 #endif
612     *RetInPcb = udp_inpcb;
613 #if !(defined(netbsd1) || defined(freebsd2) || defined(openbsd2))
614     udp_prev = next;
615 #endif
616 #else                           /* linux */
617     if (!udp_prev)
618         return 0;
619
620     udp_inpcb = *udp_prev;
621     next = udp_inpcb.inp_next;
622     *RetInPcb = udp_inpcb;
623     udp_prev = next;
624 #endif                          /* linux */
625 #else                           /*  !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */
626     /*
627      * Are we done? 
628      */
629     if ((xig == NULL) || (xig->xig_len <= sizeof(struct xinpgen)))
630         return (0);
631
632     *RetInPcb = ((struct xinpcb *) xig)->xi_inp;
633
634     /*
635      * Prepare for Next read 
636      */
637     xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
638 #endif                          /*  !defined(CAN_USE_SYSCTL) || !defined(UDPCTL_PCBLIST) */
639     return (1);                 /* "OK" */
640 }
641 #endif                          /* hpux11 */
642 #endif                          /* solaris2 */
643
644 #else                           /* WIN32 */
645 #include <iphlpapi.h>
646
647 u_char         *
648 var_udpEntry(struct variable *vp,
649              oid * name,
650              size_t * length,
651              int exact, size_t * var_len, WriteMethod ** write_method)
652 {
653     oid             newname[MAX_OID_LEN], lowest[MAX_OID_LEN], *op;
654     u_char         *cp;
655     int             LowState = -1;
656     static PMIB_UDPTABLE pUdpTable = NULL;
657     DWORD           status = NO_ERROR;
658     DWORD           dwActualSize = 0;
659     UINT            i;
660     struct timeval  now;
661     static long     Time_Of_Last_Reload = 0;
662     struct in_addr  inadLocal;
663     memcpy((char *) newname, (char *) vp->name,
664            (int) vp->namelen * sizeof(oid));
665
666     /*
667      * save some cpu-cycles, and reload after 5 secs...
668      */
669     gettimeofday(&now, (struct timezone *) 0);
670     if ((Time_Of_Last_Reload + 5 <= now.tv_sec) || (pUdpTable == NULL)) {
671         if (pUdpTable != NULL)
672             free(pUdpTable);
673         Time_Of_Last_Reload = now.tv_sec;
674         /*
675          * query for the buffer size needed 
676          */
677         status = GetUdpTable(pUdpTable, &dwActualSize, TRUE);
678         if (status == ERROR_INSUFFICIENT_BUFFER) {
679             pUdpTable = (PMIB_UDPTABLE) malloc(dwActualSize);
680             if (pUdpTable != NULL) {
681                 /*
682                  * Get the sorted UDP table 
683                  */
684                 status = GetUdpTable(pUdpTable, &dwActualSize, TRUE);
685
686             }
687         }
688     }
689     if (status == NO_ERROR) {
690         for (i = 0; i < pUdpTable->dwNumEntries; ++i) {
691             inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;
692             cp = (u_char *) & pUdpTable->table[i].dwLocalAddr;
693
694             op = newname + 10;
695             *op++ = *cp++;
696             *op++ = *cp++;
697             *op++ = *cp++;
698             *op++ = *cp++;
699
700             newname[14] =
701                 ntohs((unsigned short) (0x0000FFFF & pUdpTable->table[i].
702                                         dwLocalPort));
703
704             if (exact) {
705                 if (snmp_oid_compare(newname, 15, name, *length) == 0) {
706                     memcpy((char *) lowest, (char *) newname,
707                            15 * sizeof(oid));
708                     LowState = 0;
709                     break;      /* no need to search further */
710                 }
711             } else {
712                 if (snmp_oid_compare(newname, 15, name, *length) > 0) {
713                     memcpy((char *) lowest, (char *) newname,
714                            15 * sizeof(oid));
715                     LowState = 0;
716                     inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;
717                     break;      /* As the table is sorted, no need to search further */
718                 }
719             }
720         }
721     }
722
723     if (LowState < 0) {
724         free(pUdpTable);
725         pUdpTable = NULL;
726         return (NULL);
727     }
728     memcpy((char *) name, (char *) lowest,
729            ((int) vp->namelen + 10) * sizeof(oid));
730     *length = vp->namelen + 5;
731     *write_method = 0;
732     *var_len = sizeof(long);
733     switch (vp->magic) {
734     case UDPLOCALADDRESS:
735         return (u_char *) & pUdpTable->table[i].dwLocalAddr;
736     case UDPLOCALPORT:
737         long_return =
738             ntohs((unsigned short) (0x0000FFFF & pUdpTable->table[i].
739                                     dwLocalPort));
740         return (u_char *) & long_return;
741     default:
742         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_udpEntry\n",
743                     vp->magic));
744     }
745     return NULL;
746 }
747
748 #endif                          /* WIN32 */
749
750 #endif /* BUILD_SNMP_UDP_MIB */