|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T u
Length: 9122 (0x23a2) Types: TextFile Names: »udp.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/snmp/udp.c«
/* udp.c - MIB realization of the UDP group */ #ifndef lint static char *rcsid = "$Header: /f/osi/snmp/RCS/udp.c,v 7.0 89/11/23 22:23:38 mrose Rel $"; #endif /* * $Header: /f/osi/snmp/RCS/udp.c,v 7.0 89/11/23 22:23:38 mrose Rel $ * * Contributed by NYSERNet Inc. This work was partially supported by the * U.S. Defense Advanced Research Projects Agency and the Rome Air Development * Center of the U.S. Air Force Systems Command under contract number * F30602-88-C-0016. * * * $Log: udp.c,v $ * Revision 7.0 89/11/23 22:23:38 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <stdio.h> #include "mib.h" #include "internet.h" #ifdef BSD44 #include <machine/machparam.h> #endif #include <net/route.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/in_pcb.h> #include <netinet/ip_var.h> #include <netinet/udp.h> #include <netinet/udp_var.h> /* \f */ static struct udpstat udpstat; /* \f */ #ifdef BSD44 #define udpInDatagrams 1 #define udpNoPorts 2 #endif #define udpInErrors 3 #ifdef BSD44 #define udpOutDatagrams 4 #endif static int o_udp (oi, v, offset) OI oi; register struct type_SNMP_VarBind *v; int offset; { int ifvar; register struct udpstat *udps = &udpstat; register OID oid = oi -> oi_name; register OT ot = oi -> oi_type; static int lastq = -1; ifvar = (int) ot -> ot_info; switch (offset) { case type_SNMP_PDUs_get__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 || oid -> oid_elements[oid -> oid_nelem - 1] != 0) return int_SNMP_error__status_noSuchName; break; case type_SNMP_PDUs_get__next__request: if (oid -> oid_nelem > ot -> ot_name -> oid_nelem + 1) return int_SNMP_error__status_noSuchName; if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { OID new; if ((new = oid_extend (oid, 1)) == NULLOID) return int_SNMP_error__status_genErr; new -> oid_elements[new -> oid_nelem - 1] = 0; if (v -> name) free_SNMP_ObjectName (v -> name); v -> name = new; } else return NOTOK; break; default: return int_SNMP_error__status_genErr; } if (quantum != lastq) { lastq = quantum; if (getkmem (nl + N_UDPSTAT, (caddr_t) udps, sizeof *udps) == NOTOK) return int_SNMP_error__status_genErr; } switch (ifvar) { #ifdef udpInDatagrams case udpInDatagrams: return o_integer (oi, v, udps -> udps_ipackets); #endif #ifdef udpNoPorts case udpNoPorts: return o_integer (oi, v, udps -> udps_noport); #endif case udpInErrors: return o_integer (oi, v, udps -> udps_hdrops + udps -> udps_badsum + udps -> udps_badlen); #ifdef udpOutDatagrams case udpOutDatagrams: return o_integer (oi, v, udps -> udps_opackets); #endif default: return int_SNMP_error__status_noSuchName; } } /* \f */ struct udptab { #define UT_SIZE 5 /* object instance */ unsigned int ut_instance[UT_SIZE]; struct inpcb ut_pcb; /* protocol control block */ struct udptab *ut_next; }; static struct udptab *uts = NULL; struct udptab *get_udpent (); /* \f */ #define udpLocalAddress 0 #define udpLocalPort 1 static int o_udp_listen (oi, v, offset) OI oi; register struct type_SNMP_VarBind *v; int offset; { int ifvar; register int i; register unsigned int *ip, *jp; register struct udptab *ut; struct sockaddr_in netaddr; register OID oid = oi -> oi_name; register OT ot = oi -> oi_type; if (get_listeners () == NOTOK) return int_SNMP_error__status_genErr; ifvar = (int) ot -> ot_info; switch (offset) { case type_SNMP_PDUs_get__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + UT_SIZE) return int_SNMP_error__status_noSuchName; if ((ut = get_udpent (oid -> oid_elements + oid -> oid_nelem - UT_SIZE, 0)) == NULL) return int_SNMP_error__status_noSuchName; break; case type_SNMP_PDUs_get__next__request: if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + UT_SIZE && oid -> oid_nelem != ot -> ot_name -> oid_nelem) return int_SNMP_error__status_noSuchName; if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { OID new; if ((ut = uts) == NULL) return NOTOK; if ((new = oid_extend (oid, UT_SIZE)) == NULLOID) return int_SNMP_error__status_genErr; ip = new -> oid_elements + new -> oid_nelem - UT_SIZE; jp = ut -> ut_instance; for (i = UT_SIZE; i > 0; i--) *ip++ = *jp++; if (v -> name) free_SNMP_ObjectName (v -> name); v -> name = new; } else { if ((ut = get_udpent (ip = oid -> oid_elements + oid -> oid_nelem - UT_SIZE, 1)) == NULL) return NOTOK; jp = ut -> ut_instance; for (i = UT_SIZE; i > 0; i--) *ip++ = *jp++; } break; default: return int_SNMP_error__status_genErr; } switch (ifvar) { case udpLocalAddress: netaddr.sin_addr = ut -> ut_pcb.inp_laddr; /* struct copy */ return o_ipaddr (oi, v, &netaddr); case udpLocalPort: return o_integer (oi, v, ut -> ut_pcb.inp_lport & 0xffff); default: return int_SNMP_error__status_noSuchName; } } /* \f */ static int ut_compar (a, b) struct udptab **a, **b; { return elem_cmp ((*a) -> ut_instance, UT_SIZE, (*b) -> ut_instance, UT_SIZE); } static int get_listeners () { register int i; register unsigned int *cp; register struct udptab *us, *up, **usp; register struct inpcb *ip; struct inpcb *head, udb, zdb; struct nlist nzs; register struct nlist *nz = &nzs; static int first_time = 1; static int lastq = -1; if (quantum == lastq) return OK; lastq = quantum; for (us = uts; us; us = up) { up = us -> ut_next; free ((char *) us); } uts = NULL; if (getkmem (nl + N_UDB, (char *) &udb, sizeof udb) == NOTOK) return NOTOK; head = (struct inpcb *) nl[N_UDB].n_value; usp = &uts, i = 0; ip = &udb; while (ip -> inp_next != head) { register struct udptab *uz; OIDentifier oids; if ((us = (struct udptab *) calloc (1, sizeof *us)) == NULL) adios (NULLCP, "out of memory"); nz -> n_name = "struct inpcb", nz -> n_value = (unsigned long) ip -> inp_next; if (getkmem (nz, (caddr_t) &us -> ut_pcb, sizeof us -> ut_pcb) == NOTOK) return NOTOK; ip = &us -> ut_pcb; cp = us -> ut_instance; cp += ipaddr2oid (cp, &us -> ut_pcb.inp_laddr); *cp++ = us -> ut_pcb.inp_lport & 0xffff; for (uz = uts; uz; uz = uz -> ut_next) if (elem_cmp (uz -> ut_instance, UT_SIZE, us -> ut_instance, UT_SIZE) == 0) break; if (uz) { if (first_time) { oids.oid_elements = us -> ut_instance; oids.oid_nelem = UT_SIZE; advise (LLOG_EXCEPTIONS, NULLCP, "duplicate listeners: %s", sprintoid (&oids)); } *(ip = &zdb) = us -> ut_pcb; /* struct copy */ free ((char *) us); continue; } *usp = us, usp = &us -> ut_next, i++; if (debug && first_time) { oids.oid_elements = us -> ut_instance; oids.oid_nelem = UT_SIZE; advise (LLOG_DEBUG, NULLCP, "add listener: %s", sprintoid (&oids)); } } first_time = 0; if (i > 1) { register struct udptab **base, **use; if ((base = (struct udptab **) malloc ((unsigned) (i * sizeof *base))) == NULL) adios (NULLCP, "out of memory"); use = base; for (us = uts; us; us = us -> ut_next) *use++ = us; qsort ((char *) base, i, sizeof *base, ut_compar); usp = base; us = uts = *usp++; while (usp < use) { us -> ut_next = *usp; us = *usp++; } us -> ut_next = NULL; free ((char *) base); } return OK; } /* \f */ static struct udptab *get_udpent (ip, isnext) register unsigned int *ip; int isnext; { register struct udptab *ut; for (ut = uts; ut; ut = ut -> ut_next) switch (elem_cmp (ut -> ut_instance, UT_SIZE, ip, UT_SIZE)) { case 0: return (isnext ? ut -> ut_next : ut); case 1: return (isnext ? ut : NULL); } return NULL; } /* \f */ init_udp () { register OT ot; #ifdef udpInDatagrams if (ot = text2obj ("udpInDatagrams")) ot -> ot_getfnx = o_udp, ot -> ot_info = (caddr_t) udpInDatagrams; #endif #ifdef udpNoPorts if (ot = text2obj ("udpNoPorts")) ot -> ot_getfnx = o_udp, ot -> ot_info = (caddr_t) udpNoPorts; #endif if (ot = text2obj ("udpInErrors")) ot -> ot_getfnx = o_udp, ot -> ot_info = (caddr_t) udpInErrors; #ifdef udpOutDatagrams if (ot = text2obj ("udpOutDatagrams")) ot -> ot_getfnx = o_udp, ot -> ot_info = (caddr_t) udpOutDatagrams; #endif if (ot = text2obj ("udpLocalAddress")) ot -> ot_getfnx = o_udp_listen, ot -> ot_info = (caddr_t) udpLocalAddress; if (ot = text2obj ("udpLocalPort")) ot -> ot_getfnx = o_udp_listen, ot -> ot_info = (caddr_t) udpLocalPort; }