|
|
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;
}