summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-12-29 09:24:44 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-12-29 09:24:44 +0000
commit4d548bbc88c744342a51ae80498dfa9640546c2d (patch)
tree3c0f6be54aabb6a0c45fb71a1377b809c72a1304 /usr.sbin/snmpd
parent497914f08894369ccc1d40e8aeeee5a07b05aa6e (diff)
add the IP-MIB ipAddrTable. it requires to encode the ipv4 addresses
in the OIDs as the table index. the next step is to simplify the common mib implementation regarding the special requirements of these strange snmp tables.
Diffstat (limited to 'usr.sbin/snmpd')
-rw-r--r--usr.sbin/snmpd/kroute.c121
-rw-r--r--usr.sbin/snmpd/mib.c107
-rw-r--r--usr.sbin/snmpd/mib.h14
-rw-r--r--usr.sbin/snmpd/mps.c38
-rw-r--r--usr.sbin/snmpd/smi.c7
-rw-r--r--usr.sbin/snmpd/snmpd.h18
6 files changed, 273 insertions, 32 deletions
diff --git a/usr.sbin/snmpd/kroute.c b/usr.sbin/snmpd/kroute.c
index 0897bc1b0eb..de03c1a5b72 100644
--- a/usr.sbin/snmpd/kroute.c
+++ b/usr.sbin/snmpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.4 2007/12/28 16:59:31 reyk Exp $ */
+/* $OpenBSD: kroute.c,v 1.5 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -85,6 +85,11 @@ struct kif *kif_update(u_short, int, struct if_data *,
struct sockaddr_dl *);
int kif_validate(u_short);
+int ka_compare(struct kif_addr *, struct kif_addr *);
+struct kif_addr *ka_insert(u_short, struct kif_addr *);
+struct kif_addr *ka_find(struct in_addr *);
+int ka_remove(struct kif_addr *);
+
u_int16_t rtlabel_name2id(const char *);
const char *rtlabel_id2name(u_int16_t);
void rtlabel_unref(u_int16_t);
@@ -97,6 +102,8 @@ void get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
void if_change(u_short, int, struct if_data *);
void if_newaddr(u_short, struct sockaddr_in *, struct sockaddr_in *,
struct sockaddr_in *);
+void if_deladdr(u_short, struct sockaddr_in *, struct sockaddr_in *,
+ struct sockaddr_in *);
void if_announce(void *);
int send_rtmsg(int, int, struct kroute *);
@@ -112,6 +119,10 @@ RB_HEAD(kif_tree, kif_node) kit;
RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare)
RB_GENERATE(kif_tree, kif_node, entry, kif_compare)
+RB_HEAD(ka_tree, kif_addr) kat;
+RB_PROTOTYPE(ka_tree, kif_addr, node, ka_compare)
+RB_GENERATE(ka_tree, kif_addr, node, ka_compare)
+
int
kif_init(void)
{
@@ -230,6 +241,12 @@ kif_compare(struct kif_node *a, struct kif_node *b)
return (a->k.if_index - b->k.if_index);
}
+int
+ka_compare(struct kif_addr *a, struct kif_addr *b)
+{
+ return (memcmp(&a->addr, &b->addr, sizeof(struct in_addr)));
+}
+
/* tree management */
struct kroute_node *
kroute_find(in_addr_t prefix, u_int8_t prefixlen)
@@ -258,7 +275,6 @@ kroute_matchgw(struct kroute_node *kr, struct in_addr nh)
return (NULL);
}
-
int
kroute_insert(struct kroute_node *kr)
{
@@ -361,7 +377,7 @@ kr_getif(u_short if_index)
struct kif_node *kn;
if (if_index == 0)
- kn = RB_ROOT(&kit);
+ kn = RB_MIN(kif_tree, &kit);
else
kn = kif_find(if_index);
if (kn == NULL)
@@ -376,7 +392,7 @@ kr_getnextif(u_short if_index)
struct kif_node *kn;
if (if_index == 0) {
- kn = RB_ROOT(&kit);
+ kn = RB_MIN(kif_tree, &kit);
return (&kn->k);
}
@@ -421,7 +437,7 @@ kif_remove(struct kif_node *kif)
while ((ka = TAILQ_FIRST(&kif->addrs)) != NULL) {
TAILQ_REMOVE(&kif->addrs, ka, entry);
- free(ka);
+ ka_remove(ka);
}
free(kif);
@@ -512,6 +528,64 @@ kroute_match(in_addr_t key)
return (NULL);
}
+struct kif_addr *
+ka_insert(u_short if_index, struct kif_addr *ka)
+{
+ if (ka->addr.s_addr == INADDR_ANY)
+ return (ka);
+ ka->if_index = if_index;
+ return (RB_INSERT(ka_tree, &kat, ka));
+}
+
+struct kif_addr *
+ka_find(struct in_addr *in)
+{
+ struct kif_addr ka;
+
+ ka.addr.s_addr = in->s_addr;
+ return (RB_FIND(ka_tree, &kat, &ka));
+}
+
+int
+ka_remove(struct kif_addr *ka)
+{
+ RB_REMOVE(ka_tree, &kat, ka);
+ free(ka);
+ return (0);
+}
+
+struct kif_addr *
+kr_getaddr(struct in_addr *in)
+{
+ struct kif_addr *ka;
+
+ if (in == NULL)
+ ka = RB_MIN(ka_tree, &kat);
+ else
+ ka = ka_find(in);
+ if (ka == NULL)
+ return (NULL);
+
+ return (ka);
+}
+
+struct kif_addr *
+kr_getnextaddr(struct in_addr *in)
+{
+ struct kif_addr *ka;
+
+ if (in == NULL)
+ return (RB_MIN(ka_tree, &kat));
+
+ if ((ka = ka_find(in)) == NULL)
+ return (NULL);
+ ka = RB_NEXT(ka_tree, &kat, ka);
+ if (ka == NULL)
+ return (NULL);
+
+ return (ka);
+}
+
/* misc */
int
protect_lo(void)
@@ -641,6 +715,8 @@ if_newaddr(u_short if_index, struct sockaddr_in *ifa, struct sockaddr_in *mask,
if_index);
return;
}
+ if (ka_find(&ifa->sin_addr) != NULL)
+ return;
if ((ka = calloc(1, sizeof(struct kif_addr))) == NULL)
fatal("if_newaddr");
ka->addr = ifa->sin_addr;
@@ -654,6 +730,28 @@ if_newaddr(u_short if_index, struct sockaddr_in *ifa, struct sockaddr_in *mask,
ka->dstbrd.s_addr = INADDR_NONE;
TAILQ_INSERT_TAIL(&kif->addrs, ka, entry);
+ ka_insert(if_index, ka);
+}
+
+void
+if_deladdr(u_short if_index, struct sockaddr_in *ifa, struct sockaddr_in *mask,
+ struct sockaddr_in *brd)
+{
+ struct kif_node *kif;
+ struct kif_addr *ka;
+
+ if (ifa == NULL || ifa->sin_family != AF_INET)
+ return;
+ if ((kif = kif_find(if_index)) == NULL) {
+ log_warnx("if_newaddr: corresponding if %i not found",
+ if_index);
+ return;
+ }
+ if ((ka = ka_find(&ifa->sin_addr)) == NULL)
+ return;
+
+ TAILQ_REMOVE(&kif->addrs, ka, entry);
+ ka_remove(ka);
}
void
@@ -1052,6 +1150,19 @@ add:
if_change(ifm.ifm_index, ifm.ifm_flags,
&ifm.ifm_data);
break;
+ case RTM_DELADDR:
+ ifam = (struct ifa_msghdr *)rtm;
+ if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
+ RTA_BRD)) == 0)
+ break;
+ sa = (struct sockaddr *)(ifam + 1);
+ get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
+
+ if_deladdr(ifam->ifam_index,
+ (struct sockaddr_in *)rti_info[RTAX_IFA],
+ (struct sockaddr_in *)rti_info[RTAX_NETMASK],
+ (struct sockaddr_in *)rti_info[RTAX_BRD]);
+ break;
case RTM_NEWADDR:
ifam = (struct ifa_msghdr *)rtm;
if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
diff --git a/usr.sbin/snmpd/mib.c b/usr.sbin/snmpd/mib.c
index 11ff6916d91..6afa434226e 100644
--- a/usr.sbin/snmpd/mib.c
+++ b/usr.sbin/snmpd/mib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.c,v 1.15 2007/12/28 16:59:31 reyk Exp $ */
+/* $OpenBSD: mib.c,v 1.16 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -956,6 +956,9 @@ int mib_ipreasmfails(struct oid *, struct ber_oid *, struct ber_element **);
int mib_ipfragfails(struct oid *, struct ber_oid *, struct ber_element **);
int mib_iproutingdiscards(struct oid *, struct ber_oid *,
struct ber_element **);
+int mib_ipaddr(struct oid *, struct ber_oid *, struct ber_element **);
+struct ber_oid *
+ mib_ipaddrtable(struct oid *, struct ber_oid *, struct ber_oid *);
static struct oid ip_mib[] = {
{ MIB(ipMIB), OID_MIB },
@@ -973,19 +976,25 @@ static struct oid ip_mib[] = {
{ MIB(ipOutRequests), OID_RD, mib_ipstat },
{ MIB(ipOutDiscards), OID_RD, mib_ipstat },
{ MIB(ipOutNoRoutes), OID_RD, mib_ipstat },
- { MIB(ipReasmTimeout), OID_RD, mps_getint, NULL, IPFRAGTTL },
+ { MIB(ipReasmTimeout), OID_RD, mps_getint, NULL,
+ NULL, IPFRAGTTL },
{ MIB(ipReasmReqds), OID_RD, mib_ipstat },
{ MIB(ipReasmOKs), OID_RD, mib_ipstat },
{ MIB(ipReasmFails), OID_RD, mib_ipreasmfails },
{ MIB(ipFragOKs), OID_RD, mib_ipstat },
{ MIB(ipFragFails), OID_RD, mib_ipfragfails },
{ MIB(ipFragCreates), OID_RD, mib_ipstat },
+ { MIB(ipAdEntAddr), OID_TRD, mib_ipaddr, NULL,
+ mib_ipaddrtable },
+ { MIB(ipAdEntIfIndex), OID_TRD, mib_ipaddr, NULL,
+ mib_ipaddrtable },
+ { MIB(ipAdEntNetMask), OID_TRD, mib_ipaddr, NULL,
+ mib_ipaddrtable },
+ { MIB(ipAdEntBcastAddr), OID_TRD, mib_ipaddr, NULL,
+ mib_ipaddrtable },
+ { MIB(ipAdEntReasmMaxSize), OID_TRD, mib_ipaddr, NULL,
+ mib_ipaddrtable },
#ifdef notyet
- { MIB(ipAdEntAddr) },
- { MIB(ipAdEntIfIndex) },
- { MIB(ipAdEntNetMask) },
- { MIB(ipAdEntBcastAddr) },
- { MIB(ipAdEntReasmMaxSize) },
{ MIB(ipNetToMediaIfIndex) },
{ MIB(ipNetToMediaPhysAddress) },
{ MIB(ipNetToMediaNetAddress) },
@@ -1175,6 +1184,90 @@ mib_iproutingdiscards(struct oid *oid, struct ber_oid *o,
return (0);
}
+struct ber_oid *
+mib_ipaddrtable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
+{
+ u_int32_t col, id;
+ struct oid a, b;
+ struct in_addr addr;
+ struct kif_addr *ka;
+
+ bcopy(&oid->o_id, no, sizeof(*no));
+ id = oid->o_oidlen - 1;
+
+ if (o->bo_n >= oid->o_oidlen) {
+ /*
+ * Compare the requested and the matched OID to see
+ * if we have to iterate to the next element.
+ */
+ bzero(&a, sizeof(a));
+ bcopy(o, &a.o_id, sizeof(struct ber_oid));
+ bzero(&b, sizeof(b));
+ bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
+ b.o_oidlen--;
+ b.o_flags |= OID_TABLE;
+ if (smi_oid_cmp(&a, &b) == 0) {
+ col = oid->o_oid[id];
+ o->bo_id[id] = col;
+ bcopy(o, no, sizeof(*no));
+ }
+ }
+
+ mps_decodeinaddr(no, &addr, OIDIDX_ipAddr + 1);
+ if (addr.s_addr == INADDR_ANY)
+ ka = kr_getaddr(NULL);
+ else
+ ka = kr_getnextaddr(&addr);
+ addr.s_addr = ka == NULL ? 0 : ka->addr.s_addr;
+ mps_encodeinaddr(no, &addr, OIDIDX_ipAddr + 1);
+ smi_oidlen(o);
+
+ return (no);
+}
+
+int
+mib_ipaddr(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+ struct ber_element *ber = *elm;
+ struct kif_addr *ka;
+ struct in_addr addr;
+ u_int32_t val;
+
+ mps_decodeinaddr(o, &addr, OIDIDX_ipAddr + 1);
+ ka = kr_getaddr(&addr);
+ if (ka == NULL)
+ return (1);
+
+ /* write OID */
+ ber = ber_add_oid(ber, o);
+
+ switch (o->bo_id[OIDIDX_ipAddr]) {
+ case 1:
+ val = addr.s_addr;
+ ber = ber_add_nstring(ber, (char *)&val, sizeof(u_int32_t));
+ ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
+ break;
+ case 2:
+ ber = ber_add_integer(ber, ka->if_index);
+ break;
+ case 3:
+ val = ka->mask.s_addr;
+ ber = ber_add_nstring(ber, (char *)&val, sizeof(u_int32_t));
+ ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
+ break;
+ case 4:
+ ber = ber_add_integer(ber, ka->dstbrd.s_addr ? 1 : 0);
+ break;
+ case 5:
+ ber = ber_add_integer(ber, IP_MAXPACKET);
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
/*
* Import all MIBs
*/
diff --git a/usr.sbin/snmpd/mib.h b/usr.sbin/snmpd/mib.h
index 2f32741fdbb..8a895419e07 100644
--- a/usr.sbin/snmpd/mib.h
+++ b/usr.sbin/snmpd/mib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.h,v 1.9 2007/12/28 16:27:51 reyk Exp $ */
+/* $OpenBSD: mib.h,v 1.10 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -197,11 +197,13 @@
#define MIB_ipFragCreates MIB_ipMIB, 19
#define MIB_ipAddrTable MIB_ipMIB, 20
#define MIB_ipAddrEntry MIB_ipAddrTable, 1
-#define MIB_ipAdEntAddr MIB_ipAddrEntry, 2
-#define MIB_ipAdEntIfIndex MIB_ipAddrEntry, 3
-#define MIB_ipAdEntNetMask MIB_ipAddrEntry, 4
-#define MIB_ipAdEntBcastAddr MIB_ipAddrEntry, 5
-#define MIB_ipAdEntReasmMaxSize MIB_ipAddrEntry, 6
+#define OIDIDX_ipAddr 9
+#define OIDIDX_ipAddrEntry 10
+#define MIB_ipAdEntAddr MIB_ipAddrEntry, 1
+#define MIB_ipAdEntIfIndex MIB_ipAddrEntry, 2
+#define MIB_ipAdEntNetMask MIB_ipAddrEntry, 3
+#define MIB_ipAdEntBcastAddr MIB_ipAddrEntry, 4
+#define MIB_ipAdEntReasmMaxSize MIB_ipAddrEntry, 5
#define MIB_ipNetToMediaTable MIB_ipMIB, 22
#define MIB_ipNetToMediaEntry MIB_ipNetToMediaTable, 1
#define MIB_ipNetToMediaIfIndex MIB_ipNetToMediaEntry, 1
diff --git a/usr.sbin/snmpd/mps.c b/usr.sbin/snmpd/mps.c
index ba5ddda0743..fd8562d21c1 100644
--- a/usr.sbin/snmpd/mps.c
+++ b/usr.sbin/snmpd/mps.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mps.c,v 1.7 2007/12/28 16:59:31 reyk Exp $ */
+/* $OpenBSD: mps.c,v 1.8 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -172,10 +172,11 @@ mps_getnextreq(struct ber_element *root, struct ber_oid *o)
return (NULL);
if (value->o_flags & OID_TABLE) {
/* Get the next table row for this column */
- if (mps_table(value, o, &no) == NULL)
- return (NULL);
- bcopy(&no, o, sizeof(*o));
- ret = value->o_get(value, o, &ber);
+ if (mps_table(value, o, &no) != NULL) {
+ bcopy(&no, o, sizeof(*o));
+ ret = value->o_get(value, o, &ber);
+ } else
+ ret = 1;
switch (ret) {
case 0:
return (ber);
@@ -185,6 +186,7 @@ mps_getnextreq(struct ber_element *root, struct ber_oid *o)
break;
}
}
+ next:
for (next = value; next != NULL;) {
next = smi_next(next);
if (next == NULL)
@@ -198,7 +200,7 @@ mps_getnextreq(struct ber_element *root, struct ber_oid *o)
if (next->o_flags & OID_TABLE) {
/* Get the next table row for this column */
if (mps_table(next, o, &no) == NULL)
- return (NULL);
+ return (ber);
bcopy(&no, o, sizeof(*o));
if ((ret = next->o_get(next, o, &ber)) != 0)
return (NULL);
@@ -247,9 +249,12 @@ mps_table(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
* see mib_sysor() as an example.
*/
+ if (oid->o_table != NULL)
+ return (oid->o_table(oid, o, no));
+
+ bcopy(&oid->o_id, no, sizeof(*no));
id = oid->o_oidlen - 1;
subid = oid->o_oidlen;
- bcopy(&oid->o_id, no, sizeof(*no));
if (o->bo_n >= oid->o_oidlen) {
/*
@@ -282,3 +287,22 @@ mps_table(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
return (no);
}
+
+void
+mps_encodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset)
+{
+ o->bo_n = offset;
+ o->bo_id[o->bo_n++] = addr->s_addr & 0xff;
+ o->bo_id[o->bo_n++] = (addr->s_addr >> 8) & 0xff;
+ o->bo_id[o->bo_n++] = (addr->s_addr >> 16) & 0xff;
+ o->bo_id[o->bo_n++] = (addr->s_addr >> 24) & 0xff;
+}
+
+void
+mps_decodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset)
+{
+ addr->s_addr = ((o->bo_id[offset] & 0xff)) |
+ ((o->bo_id[offset + 1] & 0xff) << 8) |
+ ((o->bo_id[offset + 2] & 0xff) << 16) |
+ ((o->bo_id[offset + 3] & 0xff) << 24);
+}
diff --git a/usr.sbin/snmpd/smi.c b/usr.sbin/snmpd/smi.c
index 83f8414a46b..da20de7d414 100644
--- a/usr.sbin/snmpd/smi.c
+++ b/usr.sbin/snmpd/smi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smi.c,v 1.1 2007/12/28 16:59:31 reyk Exp $ */
+/* $OpenBSD: smi.c,v 1.2 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -86,7 +86,7 @@ smi_oidstring(struct ber_oid *o, char *buf, size_t len)
bzero(buf, len);
bcopy(o, &key.o_id, sizeof(struct ber_oid));
- key.o_flags |= OID_TABLE; /* do not match wildcards */
+ key.o_flags |= OID_KEY; /* do not match wildcards */
if (env->sc_flags & SNMPD_F_NONAMES)
lookup = 0;
@@ -161,6 +161,7 @@ smi_mibtree(struct oid *oids)
decl->o_flags = oid->o_flags;
decl->o_get = oid->o_get;
decl->o_set = oid->o_set;
+ decl->o_table = oid->o_table;
decl->o_val = oid->o_val;
decl->o_data = oid->o_data;
}
@@ -225,7 +226,7 @@ smi_oid_cmp(struct oid *a, struct oid *b)
* (it will match any sub-elements)
*/
if ((b->o_flags & OID_TABLE) &&
- (a->o_flags & OID_TABLE) == 0)
+ (a->o_flags & OID_KEY) == 0)
return (0);
return (a->o_oidlen - b->o_oidlen);
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index 78eb9732da5..6d4c7c8fb4a 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.7 2007/12/28 16:59:31 reyk Exp $ */
+/* $OpenBSD: snmpd.h,v 1.8 2007/12/29 09:24:43 reyk Exp $ */
/*
* Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
@@ -160,10 +160,13 @@ struct kroute {
};
struct kif_addr {
- TAILQ_ENTRY(kif_addr) entry;
+ u_short if_index;
struct in_addr addr;
struct in_addr mask;
struct in_addr dstbrd;
+
+ TAILQ_ENTRY(kif_addr) entry;
+ RB_ENTRY(kif_addr) node;
};
struct kif {
@@ -199,10 +202,12 @@ struct oid {
u_int o_flags;
- int (*o_get)(struct oid *, struct ber_oid *,
+ int (*o_get)(struct oid *, struct ber_oid *,
struct ber_element **);
- int (*o_set)(struct oid *, struct ber_oid *,
+ int (*o_set)(struct oid *, struct ber_oid *,
struct ber_element **);
+ struct ber_oid *(*o_table)(struct oid *, struct ber_oid *,
+ struct ber_oid *);
long long o_val;
void *o_data;
@@ -217,6 +222,7 @@ struct oid {
#define OID_DYNAMIC 0x08 /* free allocated data */
#define OID_TABLE 0x10 /* dynamic sub-elements */
#define OID_MIB 0x20 /* root-OID of a supported MIB */
+#define OID_KEY 0x40 /* lookup tables */
#define OID_RS (OID_RD|OID_IFSET)
#define OID_WS (OID_WR|OID_IFSET)
@@ -375,6 +381,8 @@ u_int kr_ifnumber(void);
u_long kr_iflastchange(void);
struct kif *kr_getif(u_short);
struct kif *kr_getnextif(u_short);
+struct kif_addr *kr_getaddr(struct in_addr *);
+struct kif_addr *kr_getnextaddr(struct in_addr *);
/* snmpe.c */
pid_t snmpe(struct snmpd *, int [2]);
@@ -396,6 +404,8 @@ int mps_setint(struct oid *, struct ber_oid *,
struct ber_element **);
int mps_getts(struct oid *, struct ber_oid *,
struct ber_element **);
+void mps_encodeinaddr(struct ber_oid *, struct in_addr *, int);
+void mps_decodeinaddr(struct ber_oid *, struct in_addr *, int);
/* smi.c */
int smi_init(void);