/* udp.c - MIB realization of the UDP group */
static char *rcsid
= "$Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 mrose Interim $";
* $Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 mrose Interim $
* 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
* Revision 7.7 91/02/22 09:44:50 mrose
* Revision 7.6 91/01/08 12:48:51 mrose
* Revision 7.5 90/12/18 10:14:19 mrose
* Revision 7.4 90/10/02 09:55:03 mrose
* Revision 7.3 90/04/23 00:08:20 mrose
* Revision 7.2 90/04/18 08:52:09 mrose
* Revision 7.1 90/02/27 18:50:10 mrose
* Revision 7.0 89/11/23 22:23:38 mrose
* 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
#include <sys/socketvar.h>
#include <netinet/in_systm.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet/udp_var.h>
static struct udpstat udpstat
;
#define udpOutDatagrams 4
static int o_udp (oi
, v
, offset
)
register struct type_SNMP_VarBind
*v
;
register struct udpstat
*udps
= &udpstat
;
register OID oid
= oi
-> oi_name
;
register OT ot
= oi
-> oi_type
;
ifvar
= (int) ot
-> ot_info
;
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
;
case type_SNMP_PDUs_get__next__request
:
if (oid
-> oid_nelem
== ot
-> ot_name
-> oid_nelem
) {
if ((new = oid_extend (oid
, 1)) == NULLOID
)
new -> oid_elements
[new -> oid_nelem
- 1] = 0;
free_SNMP_ObjectName (v
-> name
);
return int_SNMP_error__status_genErr
;
if (getkmem (nl
+ N_UDPSTAT
, (caddr_t
) udps
, sizeof *udps
) == NOTOK
)
return o_integer (oi
, v
, udps
-> udps_ipackets
);
return o_integer (oi
, v
, udps
-> udps_noport
);
return o_integer (oi
, v
, udps
-> udps_hdrops
return o_integer (oi
, v
, udps
-> udps_opackets
);
return int_SNMP_error__status_noSuchName
;
#define UT_SIZE 5 /* object instance */
unsigned int ut_instance
[UT_SIZE
];
struct inpcb ut_pcb
; /* protocol control block */
struct socket ut_socb
; /* socket info */
static struct udptab
*uts
= NULL
;
static int flush_udp_cache
= 0;
struct udptab
*get_udpent ();
#define udpLocalAddress 0
#define unixUdpRemAddress 2
static int o_udp_listen (oi
, v
, offset
)
register struct type_SNMP_VarBind
*v
;
register unsigned int *ip
,
register struct udptab
*ut
;
struct sockaddr_in netaddr
;
register OID oid
= oi
-> oi_name
;
register OT ot
= oi
-> oi_type
;
if (get_listeners (offset
) == NOTOK
)
ifvar
= (int) ot
-> ot_info
;
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
return int_SNMP_error__status_noSuchName
;
case type_SNMP_PDUs_get__next__request
:
if ((i
= oid
-> oid_nelem
- ot
-> ot_name
-> oid_nelem
) != 0
for (jp
= (ip
= oid
-> oid_elements
+ ot
-> ot_name
-> oid_nelem
- 1) + i
;
oid
-> oid_nelem
= ot
-> ot_name
-> oid_nelem
;
if ((new = oid_normalize (oid
, UT_SIZE
- i
, 65536))
free_SNMP_ObjectName (v
-> name
);
oid
-> oid_nelem
= ot
-> ot_name
-> oid_nelem
+ UT_SIZE
;
if (oid
-> oid_nelem
== ot
-> ot_name
-> oid_nelem
) {
if ((new = oid_extend (oid
, UT_SIZE
)) == NULLOID
)
ip
= new -> oid_elements
+ new -> oid_nelem
- UT_SIZE
;
for (i
= UT_SIZE
; i
> 0; i
--)
free_SNMP_ObjectName (v
-> name
);
if ((ut
= get_udpent (ip
= oid
-> oid_elements
+ oid
-> oid_nelem
- UT_SIZE
, 1))
for (i
= UT_SIZE
; i
> 0; i
--)
return int_SNMP_error__status_genErr
;
netaddr
.sin_addr
= ut
-> ut_pcb
.inp_laddr
; /* struct copy */
return o_ipaddr (oi
, v
, &netaddr
);
return o_integer (oi
, v
, ntohs (ut
-> ut_pcb
.inp_lport
) & 0xffff);
netaddr
.sin_addr
= ut
-> ut_pcb
.inp_faddr
; /* struct copy */
return o_ipaddr (oi
, v
, &netaddr
);
return o_integer (oi
, v
, ntohs (ut
-> ut_pcb
.inp_fport
) & 0xffff);
return o_integer (oi
, v
, ut
-> ut_socb
.so_snd
.sb_cc
);
return o_integer (oi
, v
, ut
-> ut_socb
.so_rcv
.sb_cc
);
return int_SNMP_error__status_noSuchName
;
static int ut_compar (a
, b
)
return elem_cmp ((*a
) -> ut_instance
, UT_SIZE
,
(*b
) -> ut_instance
, UT_SIZE
);
static int get_listeners (offset
)
register unsigned int *cp
;
register struct udptab
*us
,
register struct inpcb
*ip
;
register struct nlist
*nz
= &nzs
;
static int first_time
= 1;
&& offset
== type_SNMP_PDUs_get__next__request
&& quantum
== lastq
+ 1) { /* XXX: caching! */
lastq
= quantum
, flush_udp_cache
= 0;
for (us
= uts
; us
; us
= up
) {
if (getkmem (nl
+ N_UDB
, (char *) &udb
, sizeof udb
) == NOTOK
)
head
= (struct inpcb
*) nl
[N_UDB
].n_value
;
while (ip
-> inp_next
!= head
) {
register struct udptab
*uz
;
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
)
nz
->n_name
= "struct socket",
nz
-> n_value
= (unsigned long) ip
-> inp_socket
;
if (getkmem (nz
, (caddr_t
) &us
-> ut_socb
, sizeof us
-> ut_socb
)
cp
+= ipaddr2oid (cp
, &ip
-> inp_laddr
);
*cp
++ = ntohs (ip
-> 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)
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 */
*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
));
register struct udptab
**base
,
if ((base
= (struct udptab
**) malloc ((unsigned) (i
* sizeof *base
)))
adios (NULLCP
, "out of memory");
for (us
= uts
; us
; us
= us
-> ut_next
)
qsort ((char *) base
, i
, sizeof *base
, ut_compar
);
static struct udptab
*get_udpent (ip
, isnext
)
register unsigned int *ip
;
register struct udptab
*ut
;
for (ut
= uts
; ut
; ut
= ut
-> ut_next
)
switch (elem_cmp (ut
-> ut_instance
, UT_SIZE
, ip
, UT_SIZE
)) {
if ((ut
= ut
-> ut_next
) == NULL
)
return (isnext
? ut
: NULL
);
if (ot
= text2obj ("udpInDatagrams"))
ot
-> ot_info
= (caddr_t
) udpInDatagrams
;
if (ot
= text2obj ("udpNoPorts"))
ot
-> ot_info
= (caddr_t
) udpNoPorts
;
if (ot
= text2obj ("udpInErrors"))
ot
-> ot_info
= (caddr_t
) udpInErrors
;
if (ot
= text2obj ("udpOutDatagrams"))
ot
-> ot_info
= (caddr_t
) udpOutDatagrams
;
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
;
if (ot
= text2obj ("unixUdpRemAddress"))
ot
-> ot_getfnx
= o_udp_listen
,
ot
-> ot_info
= (caddr_t
) unixUdpRemAddress
;
if (ot
= text2obj ("unixUdpRemPort"))
ot
-> ot_getfnx
= o_udp_listen
,
ot
-> ot_info
= (caddr_t
) unixUdpRemPort
;
if (ot
= text2obj ("unixUdpSendQ"))
ot
-> ot_getfnx
= o_udp_listen
,
ot
-> ot_info
= (caddr_t
) unixUdpSendQ
;
if (ot
= text2obj ("unixUdpRecvQ"))
ot
-> ot_getfnx
= o_udp_listen
,
ot
-> ot_info
= (caddr_t
) unixUdpRecvQ
;