|
|
1.1 root 1: /* udp.c - MIB realization of the UDP group */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/snmp/RCS/udp.c,v 7.3 90/04/23 00:08:20 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/snmp/RCS/udp.c,v 7.3 90/04/23 00:08:20 mrose Exp $
9: *
10: * Contributed by NYSERNet Inc. This work was partially supported by the
11: * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
12: * Center of the U.S. Air Force Systems Command under contract number
13: * F30602-88-C-0016.
14: *
15: *
16: * $Log: udp.c,v $
17: * Revision 7.3 90/04/23 00:08:20 mrose
18: * touch-up
19: *
20: * Revision 7.2 90/04/18 08:52:09 mrose
21: * oid_normalize
22: *
23: * Revision 7.1 90/02/27 18:50:10 mrose
24: * unix stuff
25: *
26: * Revision 7.0 89/11/23 22:23:38 mrose
27: * Release 6.0
28: *
29: */
30:
31: /*
32: * NOTICE
33: *
34: * Acquisition, use, and distribution of this module and related
35: * materials are subject to the restrictions of a license agreement.
36: * Consult the Preface in the User's Manual for the full terms of
37: * this agreement.
38: *
39: */
40:
41:
42: #include <stdio.h>
43: #include "mib.h"
44:
45: #include "internet.h"
46: #ifdef BSD44
47: #include <machine/machparam.h>
48: #endif
49: #include <net/route.h>
50: #include <sys/socketvar.h>
51: #include <netinet/in_systm.h>
52: #include <netinet/ip.h>
53: #include <netinet/in_pcb.h>
54: #include <netinet/ip_var.h>
55: #include <netinet/udp.h>
56: #include <netinet/udp_var.h>
57:
58: /* */
59:
60: static struct udpstat udpstat;
61:
62: /* */
63:
64: #ifdef BSD44
65: #define udpInDatagrams 1
66: #define udpNoPorts 2
67: #endif
68: #define udpInErrors 3
69: #ifdef BSD44
70: #define udpOutDatagrams 4
71: #endif
72:
73:
74: static int o_udp (oi, v, offset)
75: OI oi;
76: register struct type_SNMP_VarBind *v;
77: int offset;
78: {
79: int ifvar;
80: register struct udpstat *udps = &udpstat;
81: register OID oid = oi -> oi_name;
82: register OT ot = oi -> oi_type;
83: static int lastq = -1;
84:
85: ifvar = (int) ot -> ot_info;
86: switch (offset) {
87: case type_SNMP_PDUs_get__request:
88: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
89: || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
90: return int_SNMP_error__status_noSuchName;
91: break;
92:
93: case type_SNMP_PDUs_get__next__request:
94: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
95: OID new;
96:
97: if ((new = oid_extend (oid, 1)) == NULLOID)
98: return int_SNMP_error__status_genErr;
99: new -> oid_elements[new -> oid_nelem - 1] = 0;
100:
101: if (v -> name)
102: free_SNMP_ObjectName (v -> name);
103: v -> name = new;
104: }
105: else
106: return NOTOK;
107: break;
108:
109: default:
110: return int_SNMP_error__status_genErr;
111: }
112:
113: if (quantum != lastq) {
114: lastq = quantum;
115:
116: if (getkmem (nl + N_UDPSTAT, (caddr_t) udps, sizeof *udps) == NOTOK)
117: return int_SNMP_error__status_genErr;
118: }
119:
120: switch (ifvar) {
121: #ifdef udpInDatagrams
122: case udpInDatagrams:
123: return o_integer (oi, v, udps -> udps_ipackets);
124: #endif
125:
126: #ifdef udpNoPorts
127: case udpNoPorts:
128: return o_integer (oi, v, udps -> udps_noport);
129: #endif
130:
131: case udpInErrors:
132: return o_integer (oi, v, udps -> udps_hdrops
133: + udps -> udps_badsum
134: + udps -> udps_badlen);
135:
136: #ifdef udpOutDatagrams
137: case udpOutDatagrams:
138: return o_integer (oi, v, udps -> udps_opackets);
139: #endif
140:
141: default:
142: return int_SNMP_error__status_noSuchName;
143: }
144: }
145:
146: /* */
147:
148: struct udptab {
149: #define UT_SIZE 5 /* object instance */
150: unsigned int ut_instance[UT_SIZE];
151:
152: struct inpcb ut_pcb; /* protocol control block */
153:
154: struct socket ut_socb; /* socket info */
155:
156: struct udptab *ut_next;
157: };
158:
159: static struct udptab *uts = NULL;
160:
161:
162: struct udptab *get_udpent ();
163:
164: /* */
165:
166: #define udpLocalAddress 0
167: #define udpLocalPort 1
168: #define unixUdpRemAddress 2
169: #define unixUdpRemPort 3
170: #define unixUdpSendQ 4
171: #define unixUdpRecvQ 5
172:
173:
174: static int o_udp_listen (oi, v, offset)
175: OI oi;
176: register struct type_SNMP_VarBind *v;
177: int offset;
178: {
179: int ifvar;
180: register int i;
181: register unsigned int *ip,
182: *jp;
183: register struct udptab *ut;
184: struct sockaddr_in netaddr;
185: register OID oid = oi -> oi_name;
186: OID new;
187: register OT ot = oi -> oi_type;
188:
189: if (get_listeners () == NOTOK)
190: return int_SNMP_error__status_genErr;
191:
192: ifvar = (int) ot -> ot_info;
193: switch (offset) {
194: case type_SNMP_PDUs_get__request:
195: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + UT_SIZE)
196: return int_SNMP_error__status_noSuchName;
197: if ((ut = get_udpent (oid -> oid_elements + oid -> oid_nelem
198: - UT_SIZE, 0)) == NULL)
199: return int_SNMP_error__status_noSuchName;
200: break;
201:
202: case type_SNMP_PDUs_get__next__request:
203: if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
204: && i < UT_SIZE) {
205: for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
206: jp > ip;
207: jp--)
208: if (*jp != 0)
209: break;
210: if (jp == ip)
211: oid -> oid_nelem = ot -> ot_name -> oid_nelem;
212: else {
213: if ((new = oid_normalize (oid, UT_SIZE - i, 65536)) == NULLOID)
214: return int_SNMP_error__status_genErr;
215: if (v -> name)
216: free_SNMP_ObjectName (v -> name);
217: v -> name = oid = new;
218: }
219: }
220:
221: if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
222: if ((ut = uts) == NULL)
223: return NOTOK;
224:
225: if ((new = oid_extend (oid, UT_SIZE)) == NULLOID)
226: return int_SNMP_error__status_genErr;
227: ip = new -> oid_elements + new -> oid_nelem - UT_SIZE;
228: jp = ut -> ut_instance;
229: for (i = UT_SIZE; i > 0; i--)
230: *ip++ = *jp++;
231:
232: if (v -> name)
233: free_SNMP_ObjectName (v -> name);
234: v -> name = new;
235: }
236: else {
237: if ((ut = get_udpent (ip = oid -> oid_elements
238: + oid -> oid_nelem - UT_SIZE, 1))
239: == NULL)
240: return NOTOK;
241:
242: jp = ut -> ut_instance;
243: for (i = UT_SIZE; i > 0; i--)
244: *ip++ = *jp++;
245: }
246: break;
247:
248: default:
249: return int_SNMP_error__status_genErr;
250: }
251:
252: switch (ifvar) {
253: case udpLocalAddress:
254: netaddr.sin_addr = ut -> ut_pcb.inp_laddr; /* struct copy */
255: return o_ipaddr (oi, v, &netaddr);
256:
257: case udpLocalPort:
258: return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_lport) & 0xffff);
259:
260: case unixUdpRemAddress:
261: netaddr.sin_addr = ut -> ut_pcb.inp_faddr; /* struct copy */
262: return o_ipaddr (oi, v, &netaddr);
263:
264: case unixUdpRemPort:
265: return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_fport) & 0xffff);
266:
267: case unixUdpSendQ:
268: return o_integer (oi, v, ut -> ut_socb.so_snd.sb_cc);
269:
270: case unixUdpRecvQ:
271: return o_integer (oi, v, ut -> ut_socb.so_rcv.sb_cc);
272:
273: default:
274: return int_SNMP_error__status_noSuchName;
275: }
276: }
277:
278: /* */
279:
280: static int ut_compar (a, b)
281: struct udptab **a,
282: **b;
283: {
284: return elem_cmp ((*a) -> ut_instance, UT_SIZE,
285: (*b) -> ut_instance, UT_SIZE);
286: }
287:
288:
289: static int get_listeners () {
290: register int i;
291: register unsigned int *cp;
292: register struct udptab *us,
293: *up,
294: **usp;
295: register struct inpcb *ip;
296: struct inpcb *head,
297: udb,
298: zdb;
299: struct nlist nzs;
300: register struct nlist *nz = &nzs;
301: static int first_time = 1;
302: static int lastq = -1;
303:
304: if (quantum == lastq)
305: return OK;
306: lastq = quantum;
307:
308: for (us = uts; us; us = up) {
309: up = us -> ut_next;
310:
311: free ((char *) us);
312: }
313: uts = NULL;
314:
315: if (getkmem (nl + N_UDB, (char *) &udb, sizeof udb) == NOTOK)
316: return NOTOK;
317: head = (struct inpcb *) nl[N_UDB].n_value;
318:
319: usp = &uts, i = 0;
320: ip = &udb;
321: while (ip -> inp_next != head) {
322: register struct udptab *uz;
323: OIDentifier oids;
324:
325: if ((us = (struct udptab *) calloc (1, sizeof *us)) == NULL)
326: adios (NULLCP, "out of memory");
327:
328: nz -> n_name = "struct inpcb",
329: nz -> n_value = (unsigned long) ip -> inp_next;
330: if (getkmem (nz, (caddr_t) &us -> ut_pcb, sizeof us -> ut_pcb)
331: == NOTOK)
332: return NOTOK;
333: ip = &us -> ut_pcb;
334:
335: nz ->n_name = "struct socket",
336: nz -> n_value = (unsigned long) ip -> inp_socket;
337: if (getkmem (nz, (caddr_t) &us -> ut_socb, sizeof us -> ut_socb)
338: == NOTOK)
339: return NOTOK;
340:
341: cp = us -> ut_instance;
342: cp += ipaddr2oid (cp, &ip -> inp_laddr);
343: *cp++ = ntohs (ip -> inp_lport) & 0xffff;
344:
345: for (uz = uts; uz; uz = uz -> ut_next)
346: if (elem_cmp (uz -> ut_instance, UT_SIZE,
347: us -> ut_instance, UT_SIZE) == 0)
348: break;
349: if (uz) {
350: if (first_time) {
351: oids.oid_elements = us -> ut_instance;
352: oids.oid_nelem = UT_SIZE;
353: advise (LLOG_EXCEPTIONS, NULLCP,
354: "duplicate listeners: %s", sprintoid (&oids));
355: }
356:
357: *(ip = &zdb) = us -> ut_pcb; /* struct copy */
358: free ((char *) us);
359: continue;
360: }
361: *usp = us, usp = &us -> ut_next, i++;
362:
363: if (debug && first_time) {
364: oids.oid_elements = us -> ut_instance;
365: oids.oid_nelem = UT_SIZE;
366: advise (LLOG_DEBUG, NULLCP,
367: "add listener: %s", sprintoid (&oids));
368: }
369: }
370: first_time = 0;
371:
372: if (i > 1) {
373: register struct udptab **base,
374: **use;
375:
376: if ((base = (struct udptab **) malloc ((unsigned) (i * sizeof *base)))
377: == NULL)
378: adios (NULLCP, "out of memory");
379:
380: use = base;
381: for (us = uts; us; us = us -> ut_next)
382: *use++ = us;
383:
384: qsort ((char *) base, i, sizeof *base, ut_compar);
385:
386: usp = base;
387: us = uts = *usp++;
388:
389: while (usp < use) {
390: us -> ut_next = *usp;
391: us = *usp++;
392: }
393: us -> ut_next = NULL;
394:
395: free ((char *) base);
396: }
397:
398: return OK;
399: }
400:
401: /* */
402:
403: static struct udptab *get_udpent (ip, isnext)
404: register unsigned int *ip;
405: int isnext;
406: {
407: register struct udptab *ut;
408:
409: for (ut = uts; ut; ut = ut -> ut_next)
410: switch (elem_cmp (ut -> ut_instance, UT_SIZE, ip, UT_SIZE)) {
411: case 0:
412: return (isnext ? ut -> ut_next : ut);
413:
414: case 1:
415: return (isnext ? ut : NULL);
416: }
417:
418: return NULL;
419: }
420:
421: /* */
422:
423: init_udp () {
424: register OT ot;
425:
426: #ifdef udpInDatagrams
427: if (ot = text2obj ("udpInDatagrams"))
428: ot -> ot_getfnx = o_udp,
429: ot -> ot_info = (caddr_t) udpInDatagrams;
430: #endif
431: #ifdef udpNoPorts
432: if (ot = text2obj ("udpNoPorts"))
433: ot -> ot_getfnx = o_udp,
434: ot -> ot_info = (caddr_t) udpNoPorts;
435: #endif
436: if (ot = text2obj ("udpInErrors"))
437: ot -> ot_getfnx = o_udp,
438: ot -> ot_info = (caddr_t) udpInErrors;
439: #ifdef udpOutDatagrams
440: if (ot = text2obj ("udpOutDatagrams"))
441: ot -> ot_getfnx = o_udp,
442: ot -> ot_info = (caddr_t) udpOutDatagrams;
443: #endif
444:
445: if (ot = text2obj ("udpLocalAddress"))
446: ot -> ot_getfnx = o_udp_listen,
447: ot -> ot_info = (caddr_t) udpLocalAddress;
448: if (ot = text2obj ("udpLocalPort"))
449: ot -> ot_getfnx = o_udp_listen,
450: ot -> ot_info = (caddr_t) udpLocalPort;
451:
452: if (ot = text2obj ("unixUdpRemAddress"))
453: ot -> ot_getfnx = o_udp_listen,
454: ot -> ot_info = (caddr_t) unixUdpRemAddress;
455: if (ot = text2obj ("unixUdpRemPort"))
456: ot -> ot_getfnx = o_udp_listen,
457: ot -> ot_info = (caddr_t) unixUdpRemPort;
458: if (ot = text2obj ("unixUdpSendQ"))
459: ot -> ot_getfnx = o_udp_listen,
460: ot -> ot_info = (caddr_t) unixUdpSendQ;
461: if (ot = text2obj ("unixUdpRecvQ"))
462: ot -> ot_getfnx = o_udp_listen,
463: ot -> ot_info = (caddr_t) unixUdpRecvQ;
464: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.