/* unixd.c - daemon for UNIX MIB */
static char *rcsid
= "$Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $";
* $Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $
* 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.13 91/03/09 11:57:58 mrose
* Revision 7.12 91/02/22 09:44:55 mrose
* Revision 7.11 91/01/11 15:35:40 mrose
* Revision 7.10 91/01/08 12:48:55 mrose
* Revision 7.9 90/12/18 10:14:22 mrose
* Revision 7.8 90/10/17 11:57:41 mrose
* Revision 7.7 90/07/09 14:49:48 mrose
* Revision 7.6 90/03/06 13:51:01 mrose
* Revision 7.5 90/02/23 17:48:05 mrose
* Revision 7.4 90/02/19 15:54:09 mrose
* Revision 7.3 90/02/19 15:39:08 mrose
* Revision 7.2 90/02/17 17:19:01 mrose
* Revision 7.1 90/02/17 10:42:20 mrose
* Revision 7.0 90/02/17 10:36:48 mrose
* *** empty log message ***
* 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
static int nbits
= FD_SETSIZE
;
"unixd.log", NULLCP
, NULLCP
, LLOG_FATAL
| LLOG_EXCEPTIONS
| LLOG_NOTICE
,
LLOG_FATAL
, -1, LLOGCLS
| LLOGCRT
| LLOGZER
, NOTOK
static LLog
*pgm_log
= &_pgm_log
;
static char *myname
= "unixd";
static int smux_fd
= NOTOK
;
static int rock_and_roll
= 0;
static int dont_bother_anymore
= 0;
static OID subtree
= NULLOID
;
static struct smuxEntry
*se
= NULL
;
void adios (), advise ();
/* set fd's for other purposes here... */
rfds
= ifds
; /* struct copy */
if (smux_fd
== NOTOK
&& !dont_bother_anymore
)
if ((n
= xselect (nfds
, &rfds
, &wfds
, NULLFD
, secs
)) == NOTOK
)
adios ("failed", "xselect");
/* check fd's for other purposes here... */
if (smux_fd
== NOTOK
&& !dont_bother_anymore
) {
if ((smux_fd
= smux_init (debug
)) == NOTOK
)
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_init: %s [%s]",
smux_error (smux_errno
), smux_info
);
if (FD_ISSET (smux_fd
, &rfds
))
if (FD_ISSET (smux_fd
, &wfds
))
if (myname
= rindex (*vec
, '/'))
if (myname
== NULL
|| *myname
== NULL
)
if (strncmp (myname
, "smux.", 5) == 0 && myname
[5] != NULL
)
ll_hdinit (pgm_log
, myname
);
for (vec
++; ap
= *vec
; vec
++) {
adios (NULLCP
, "-%s: unknown switch", ap
);
adios (NULLCP
, "usage: %s [switches]", myname
);
nbits
= getdtablesize ();
if (debug
== 0 && !(debug
= isatty (2))) {
for (i
= 0; i
< 5; i
++) {
if ((sd
= open ("/dev/null", O_RDWR
)) == NOTOK
)
adios ("/dev/null", "unable to read");
(void) dup2 (sd
, 0), (void) close (sd
);
advise (LLOG_EXCEPTIONS
, "failed", "setsid");
if ((sd
= open ("/dev/tty", O_RDWR
)) != NOTOK
) {
(void) ioctl (sd
, TIOCNOTTY
, NULLCP
);
(void) signal (SIGINT
, SIG_IGN
);
(void) signal (SIGQUIT
, SIG_IGN
);
ll_dbinit (pgm_log
, myname
);
#ifndef sun /* damn YP... */
for (sd
= 3; sd
< nbits
; sd
++)
if (pgm_log
-> ll_fd
!= sd
)
(void) signal (SIGPIPE
, SIG_IGN
);
ll_hdinit (pgm_log
, myname
);
(void) sprintf (file
, "/etc/%s.pid", myname
);
if (fp
= fopen (file
, "w")) {
(void) fprintf (fp
, "%d\n", getpid ());
advise (LLOG_NOTICE
, NULLCP
, "starting");
static struct nlist nl
[] = {
register struct nlist
*nz
;
if ((se
= getsmuxEntrybyname ("unixd")) == NULL
)
adios (NULLCP
, "no SMUX entry for \"%s\"", "unixd");
if (readobjects ("unixd.defs") == NOTOK
)
adios (NULLCP
, "readobjects: %s", PY_pepy
);
if ((ot
= text2obj ("mbuf")) == NULL
)
adios (NULLCP
, "text2obj (\"%s\") fails", "mbuf");
if (nlist ("/vmunix", nl
) == NOTOK
)
adios ("/vmunix", "unable to nlist");
for (nz
= nl
; nz
-> n_name
; nz
++)
advise (LLOG_EXCEPTIONS
, NULLCP
, "\"%s\" not in /vmunix (warning)",
if ((kd
= open ("/dev/kmem", O_RDONLY
)) == NOTOK
)
adios ("/vmunix", "unable to read");
init_unix (); /* UNIX-specific enterprise */
if ((smux_fd
= smux_init (debug
)) == NOTOK
)
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_init: %s [%s]",
smux_error (smux_errno
), smux_info
);
if (smux_simple_open (&se
-> se_identity
, "SMUX UNIX daemon",
se
-> se_password
, strlen (se
-> se_password
))
if (smux_errno
== inProgress
)
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_simple_open: %s [%s]",
smux_error (smux_errno
), smux_info
);
advise (LLOG_NOTICE
, NULLCP
, "SMUX open: %s \"%s\"",
oid2ode (&se
-> se_identity
), se
-> se_name
);
if (smux_register (subtree
, -1, readOnly
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_register: %s [%s]",
smux_error (smux_errno
), smux_info
);
advise (LLOG_NOTICE
, NULLCP
, "SMUX register: readOnly %s in=%d",
struct type_SNMP_SMUX__PDUs
*event
;
if (smux_wait (&event
, NOTOK
) == NOTOK
) {
if (smux_errno
== inProgress
)
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_wait: %s [%s]",
smux_error (smux_errno
), smux_info
);
switch (event
-> offset
) {
case type_SNMP_SMUX__PDUs_registerResponse
:
struct type_SNMP_RRspPDU
*rsp
= event
-> un
.registerResponse
;
if (rsp
-> parm
== int_SNMP_RRspPDU_failure
) {
advise (LLOG_NOTICE
, NULLCP
,
"SMUX registration of %s failed",
(void) smux_close (goingDown
);
advise (LLOG_NOTICE
, NULLCP
,
"SMUX register: readOnly %s out=%d",
oid2ode (subtree
), rsp
-> parm
);
if (smux_trap (int_SNMP_generic__trap_coldStart
,
0, (struct type_SNMP_VarBindList
*) 0) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_trap: %s [%s]",
smux_error (smux_errno
), smux_info
);
case type_SNMP_SMUX__PDUs_get__request
:
case type_SNMP_SMUX__PDUs_get__next__request
:
get_smux (event
-> un
.get__request
, event
-> offset
);
case type_SNMP_SMUX__PDUs_close
:
advise (LLOG_NOTICE
, NULLCP
, "SMUX close: %s",
smux_error (event
-> un
.close
-> parm
));
case type_SNMP_SMUX__PDUs_simple
:
case type_SNMP_SMUX__PDUs_registerRequest
:
case type_SNMP_SMUX__PDUs_get__response
:
case type_SNMP_SMUX__PDUs_trap
:
advise (LLOG_EXCEPTIONS
, NULLCP
, "unexpectedOperation: %d",
(void) smux_close (protocolError
);
case type_SNMP_SMUX__PDUs_set__request
:
case type_SNMP_SMUX__PDUs_commitOrRollback
:
advise (LLOG_EXCEPTIONS
, NULLCP
, "badOperation: %d",
(void) smux_close (protocolError
);
static get_smux (pdu
, offset
)
register struct type_SNMP_GetRequest__PDU
*pdu
;
register struct type_SNMP_VarBindList
*vp
;
quantum
= pdu
-> request__id
;
for (vp
= pdu
-> variable__bindings
; vp
; vp
= vp
-> next
) {
register struct type_SNMP_VarBind
*v
= vp
-> VarBind
;
if (offset
== type_SNMP_SMUX__PDUs_get__next__request
) {
if ((oi
= name2inst (v
-> name
)) == NULLOI
&& (oi
= next2inst (v
-> name
)) == NULLOI
)
if ((ot
= oi
-> oi_type
) -> ot_getfnx
== NULLIFP
)
if ((oi
= name2inst (v
-> name
)) == NULLOI
|| (ot
= oi
-> oi_type
) -> ot_getfnx
== NULLIFP
) {
pdu
-> error__status
= int_SNMP_error__status_noSuchName
;
switch (ot
-> ot_access
) {
if (offset
== type_SNMP_SMUX__PDUs_get__next__request
)
if (offset
== type_SNMP_SMUX__PDUs_set__request
) {
pdu
-> error__status
= int_SNMP_error__status_noSuchName
;
switch (status
= (*ot
-> ot_getfnx
) (oi
, v
, offset
)) {
case NOTOK
: /* get-next wants a bump */
if ((ot
= ot
-> ot_next
) == NULLOT
) {
int_SNMP_error__status_noSuchName
;
oi
-> oi_name
= (oi
-> oi_type
= ot
) -> ot_name
;
case int_SNMP_error__status_noError
:
pdu
-> error__status
= status
;
pdu
-> error__index
= idx
;
if (smux_response (pdu
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_response: %s [%s]",
smux_error (smux_errno
), smux_info
);
struct type_SNMP_SMUX__PDUs
*event
;
switch (event
-> offset
) {
case type_SNMP_SMUX__PDUs_set__request
:
register struct type_SNMP_GetRequest__PDU
*pdu
=
event
-> un
.get__response
;
pdu
-> error__status
= int_SNMP_error__status_noSuchName
;
pdu
-> error__index
= pdu
-> variable__bindings
? 1 : 0;
if (smux_response (pdu
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "smux_response: %s [%s]",
smux_error (smux_errno
), smux_info
);
case type_SNMP_SMUX__PDUs_commitOrRollback
:
struct type_SNMP_SOutPDU
*cor
= event
-> un
.commitOrRollback
;
if (cor
-> parm
== int_SNMP_SOutPDU_commit
) {
/* "should not happen" */
(void) smux_close (protocolError
);
static struct mbstat mbstat
;
#define mbufFreeClusters 2
#if !defined(BSD43) && !defined(BSD44)
static int o_mbuf (oi
, v
, offset
)
register struct type_SNMP_VarBind
*v
;
register struct mbstat
*m
= &mbstat
;
register OID oid
= oi
-> oi_name
;
register OT ot
= oi
-> oi_type
;
ifvar
= (int) ot
-> ot_info
;
case type_SNMP_SMUX__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_SMUX__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_MBSTAT
, (caddr_t
) m
, sizeof *m
) == NOTOK
)
return (offset
== type_SNMP_PDUs_get__next__request
? NOTOK
: int_SNMP_error__status_genErr
);
return o_integer (oi
, v
, m
-> m_mbufs
);
return o_integer (oi
, v
, m
-> m_clusters
);
return o_integer (oi
, v
, m
-> m_clfree
);
return o_integer (oi
, v
, m
-> m_drops
);
return o_integer (oi
, v
, m
-> m_wait
);
return o_integer (oi
, v
, m
-> m_drain
);
return o_integer (oi
, v
, m
-> m_mbfree
);
return int_SNMP_error__status_noSuchName
;
static int o_mbufType (oi
, v
, offset
)
register struct type_SNMP_VarBind
*v
;
register struct mbstat
*m
= &mbstat
;
register OID oid
= oi
-> oi_name
;
register OT ot
= oi
-> oi_type
;
ifvar
= (int) ot
-> ot_info
;
case type_SNMP_SMUX__PDUs_get__request
:
if (oid
-> oid_nelem
!= ot
-> ot_name
-> oid_nelem
+ 1)
return int_SNMP_error__status_noSuchName
;
if ((ifnum
= oid
-> oid_elements
[oid
-> oid_nelem
- 1])
>= sizeof m
-> m_mtypes
/ sizeof m
-> m_mtypes
[0])
return int_SNMP_error__status_noSuchName
;
case type_SNMP_SMUX__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] = ifnum
;
free_SNMP_ObjectName (v
-> name
);
oid
= new; /* for hack... */
int i
= ot
-> ot_name
-> oid_nelem
;
if ((ifnum
= oid
-> oid_elements
[i
] + 1)
>= sizeof m
-> m_mtypes
/ sizeof m
-> m_mtypes
[0])
oid
-> oid_elements
[i
] = ifnum
;
oid
-> oid_nelem
= i
+ 1;
return int_SNMP_error__status_genErr
;
if (getkmem (nl
+ N_MBSTAT
, (caddr_t
) m
, sizeof *m
) == NOTOK
)
return (offset
== type_SNMP_PDUs_get__next__request
? NOTOK
: int_SNMP_error__status_genErr
);
/* hack to compress table size... */
if (offset
== type_SNMP_SMUX__PDUs_get__next__request
&& m
-> m_mtypes
[ifnum
] == 0)
return o_integer (oi
, v
, ifnum
);
return o_integer (oi
, v
, m
-> m_mtypes
[ifnum
]);
return int_SNMP_error__status_noSuchName
;
if (ot
= text2obj ("mbufS"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufS
;
if (ot
= text2obj ("mbufClusters"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufClusters
;
if (ot
= text2obj ("mbufFreeClusters"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufFreeClusters
;
if (ot
= text2obj ("mbufDrops"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufDrops
;
if (ot
= text2obj ("mbufWaits"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufWaits
;
if (ot
= text2obj ("mbufDrains"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufDrains
;
if (ot
= text2obj ("mbufFrees"))
ot
-> ot_getfnx
= o_mbuf
,
ot
-> ot_info
= (caddr_t
) mbufFrees
;
if (ot
= text2obj ("mbufType"))
ot
-> ot_getfnx
= o_mbufType
,
ot
-> ot_info
= (caddr_t
) mbufType
;
if (ot
= text2obj ("mbufAllocates"))
ot
-> ot_getfnx
= o_mbufType
,
ot
-> ot_info
= (caddr_t
) mbufAllocates
;
int getkmem (n
, buffer
, cc
)
advise (LLOG_EXCEPTIONS
, NULLCP
, "\"%s\" not in /vmunix", n
-> n_name
);
if (lseek (kd
, (long) n
-> n_value
, L_SET
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, "failed", "lseek of 0x%x for \"%s\" in kmem",
(long) n
-> n_value
, n
-> n_name
);
if (read (kd
, buffer
, cc
) != cc
) {
advise (LLOG_EXCEPTIONS
, "failed", "read of \"%s\" from kmem",
_ll_log (pgm_log
, LLOG_FATAL
, ap
);
_ll_log (pgm_log
, code
, ap
);
void advise (code
, what
, fmt
)
advise (code
, what
, fmt
);