diff options
author | wollman <wollman@FreeBSD.org> | 1996-07-30 19:17:07 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1996-07-30 19:17:07 +0000 |
commit | 50a3e4ed9e414f69f86253ea0bf631d402af6571 (patch) | |
tree | 4f7f2207dece54c4dfd55fd09f5b29f637e49009 /sys/net | |
parent | f05fb79839f2c2e939d63287e153b80b22336408 (diff) | |
download | FreeBSD-src-50a3e4ed9e414f69f86253ea0bf631d402af6571.zip FreeBSD-src-50a3e4ed9e414f69f86253ea0bf631d402af6571.tar.gz |
Add better support for retrieving management information from network
interfaces. This creates two new tables in the net.link.generic branch
of the MIB; one contains (essentially) `ifdata' structures, and the other
contains a blob provided by the interface (and presumably used to
implement link-layer-specific MIB variables). A number of things
have been moved around in the `ifnet' and `ifdata' structures, so
NEW VERSIONS OF ifconfig(8) AND routed(8) ARE REQUIRED. (A simple
recompile is all that's necessary.)
I have a sample program which uses this interface for those interested
in making use of it.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 6 | ||||
-rw-r--r-- | sys/net/if.h | 30 | ||||
-rw-r--r-- | sys/net/if_mib.c | 150 | ||||
-rw-r--r-- | sys/net/if_mib.h | 78 |
4 files changed, 254 insertions, 10 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 59f568d..912b8a5 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if.c 8.3 (Berkeley) 1/4/94 - * $Id: if.c,v 1.33 1996/07/11 16:32:26 wollman Exp $ + * $Id: if.c,v 1.34 1996/07/24 19:59:53 wollman Exp $ */ #include <sys/param.h> @@ -90,8 +90,8 @@ ifinit(dummy) if_slowtimo(0); } -static int if_index = 0; -static struct ifaddr **ifnet_addrs; +int if_index = 0; +struct ifaddr **ifnet_addrs; /* diff --git a/sys/net/if.h b/sys/net/if.h index 9b95cf5..4171ca9 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if.h 8.1 (Berkeley) 6/10/93 - * $Id: if.h,v 1.30 1996/07/22 20:06:01 wollman Exp $ + * $Id: if.h,v 1.31 1996/07/23 14:44:46 wollman Exp $ */ #ifndef _NET_IF_H_ @@ -85,6 +85,8 @@ struct if_data { u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ u_char ifi_addrlen; /* media address length */ u_char ifi_hdrlen; /* media header length */ + u_char ifi_recvquota; /* polling quota for receive intrs */ + u_char ifi_xmitquota; /* polling quota for xmit intrs */ u_long ifi_mtu; /* maximum transmission unit */ u_long ifi_metric; /* routing metric (external only) */ u_long ifi_baudrate; /* linespeed */ @@ -100,6 +102,8 @@ struct if_data { u_long ifi_omcasts; /* packets sent via multicast */ u_long ifi_iqdrops; /* dropped on input, this interface */ u_long ifi_noproto; /* destined for unsupported protocol */ + u_long ifi_recvtiming; /* usec spent receiving when timing */ + u_long ifi_xmittiming; /* usec spent xmitting when timing */ struct timeval ifi_lastchange; /* time of last administrative change */ }; @@ -132,8 +136,9 @@ struct ifnet { short if_unit; /* sub-unit for lower level driver */ short if_timer; /* time 'til if_watchdog called */ short if_flags; /* up/down, broadcast, etc. */ - u_char if_recvquota, if_sendquota; /* quotas for send, receive */ - u_char if_ipending; /* interrupts pending */ + int if_ipending; /* interrupts pending */ + void *if_linkmib; /* link-type-specific MIB data */ + size_t if_linkmiblen; /* length of above data */ struct if_data if_data; /* procedure handles */ int (*if_output) /* output routine (enqueue) */ @@ -147,9 +152,9 @@ struct ifnet { __P((struct ifnet *, int, caddr_t)); void (*if_watchdog) /* timer routine */ __P((struct ifnet *)); - void (*if_poll_recv) /* polled receive routine */ + int (*if_poll_recv) /* polled receive routine */ __P((struct ifnet *, int *)); - void (*if_poll_xmit) /* polled transmit routine */ + int (*if_poll_xmit) /* polled transmit routine */ __P((struct ifnet *, int *)); void (*if_poll_intren) /* polled interrupt reenable routine */ __P((struct ifnet *)); @@ -177,6 +182,8 @@ struct ifnet { #define if_iqdrops if_data.ifi_iqdrops #define if_noproto if_data.ifi_noproto #define if_lastchange if_data.ifi_lastchange +#define if_recvquota if_data.ifi_recvquota +#define if_xmitquota if_data.ifi_xmitquota #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0) #define IFF_UP 0x1 /* interface is up */ @@ -219,8 +226,8 @@ struct ifnet { #define IFI_XMIT 2 /* I want to transmit */ /* - * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1) - * input routines have queues of messages stored on ifqueue structures + * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) + * are queues of messages stored on ifqueue structures * (defined above). Entries are added to and deleted from these structures * by these macros, which should be called with ipl raised to splimp(). */ @@ -400,6 +407,8 @@ struct ifconf { extern struct ifnet *ifnet; extern int ifqmaxlen; extern struct ifnet loif[]; +extern int if_index; +extern struct ifaddr **ifnet_addrs; void ether_ifattach __P((struct ifnet *)); void ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *)); @@ -417,6 +426,13 @@ int ifioctl __P((struct socket *, int, caddr_t, struct proc *)); int ifpromisc __P((struct ifnet *, int)); struct ifnet *ifunit __P((char *)); +int if_poll_recv_slow __P((struct ifnet *ifp, int *quotap)); +void if_poll_xmit_slow __P((struct ifnet *ifp, int *quotap)); +void if_poll_throttle __P((void)); +void if_poll_unthrottle __P((void *)); +void if_poll_init __P((void)); +void if_poll __P((void)); + struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *)); struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *)); struct ifaddr *ifa_ifwithnet __P((struct sockaddr *)); diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c new file mode 100644 index 0000000..bb14745 --- /dev/null +++ b/sys/net/if_mib.c @@ -0,0 +1,150 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/errno.h> +#include <sys/sysctl.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_mib.h> +#include <net/if_types.h> + +/* + * A sysctl(3) MIB for generic interface information. This information + * is exported in the net.link.generic branch, which has the following + * structure: + * + * net.link.generic .system - system-wide control variables + * and statistics (node) + * .ifdata.<ifindex>.general + * - what's in `struct ifdata' + * plus some other info + * .ifdata.<ifindex>.linkspecific + * - a link-type-specific data + * structure (as might be used + * by an SNMP agent + * + * Perhaps someday we will make addresses accessible via this interface + * as well (then there will be four such...). The reason that the + * index comes before the last element in the name is because it + * seems more orthogonal that way, particularly with the possibility + * of other per-interface data living down here as well (e.g., integrated + * services stuff). + */ + +SYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system, CTLFLAG_RW, 0, + "Variables global to all interfaces"); +SYSCTL_INT(_net_link_generic_system, IFMIB_IFCOUNT, ifcount, CTLFLAG_RD, + &if_index, 0, "Number of configured interfaces"); + +static int +sysctl_ifdata SYSCTL_HANDLER_ARGS /* XXX bad syntax! */ +{ + int *name = (int *)arg1; + int error, ifnlen; + u_int namelen = arg2; + struct ifnet *ifp; + char workbuf[64]; + struct ifmibdata ifmd; + + if (namelen != 2) + return EINVAL; + + if (name[0] <= 0 || name[0] > if_index) + return ENOENT; + + ifp = ifnet_addrs[name[0] - 1]->ifa_ifp; + + switch(name[1]) { + default: + return ENOENT; + + case IFDATA_GENERAL: + ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); + if(ifnlen + 1 > sizeof ifmd.ifmd_name) { + return ENAMETOOLONG; + } else { + strcpy(ifmd.ifmd_name, workbuf); + } + +#define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld + COPY(pcount); + COPY(flags); + COPY(data); +#undef COPY + ifmd.ifmd_snd_len = ifp->if_snd.ifq_len; + ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen; + ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops; + + error = SYSCTL_OUT(req, &ifmd, sizeof ifmd); + if (error || !req->newptr) + return error; + + error = SYSCTL_IN(req, &ifmd, sizeof ifmd); + if (error) + return error; + +#define DONTCOPY(fld) ifmd.ifmd_data.ifi_##fld = ifp->if_data.ifi_##fld + DONTCOPY(type); + DONTCOPY(physical); + DONTCOPY(addrlen); + DONTCOPY(hdrlen); + DONTCOPY(mtu); + DONTCOPY(metric); + DONTCOPY(baudrate); +#undef DONTCOPY +#define COPY(fld) ifp->if_##fld = ifmd.ifmd_##fld + COPY(data); + ifp->if_snd.ifq_maxlen = ifmd.ifmd_snd_maxlen; + ifp->if_snd.ifq_drops = ifmd.ifmd_snd_drops; +#undef COPY + break; + + case IFDATA_LINKSPECIFIC: + error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen); + if (error || !req->newptr) + return error; + + error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); + if (error) + return error; + + } + return 0; +} + +SYSCTL_NODE(_net_link_generic, IFMIB_IFDATA, ifdata, CTLFLAG_RW, + sysctl_ifdata, "Interface table"); + diff --git a/sys/net/if_mib.h b/sys/net/if_mib.h new file mode 100644 index 0000000..1e48ee7 --- /dev/null +++ b/sys/net/if_mib.h @@ -0,0 +1,78 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef _NET_IF_MIB_H +#define _NET_IF_MIB_H 1 + +struct ifmibdata { + char ifmd_name[IFNAMSIZ]; /* name of interface */ + int ifmd_pcount; /* number of promiscuous listeners */ + int ifmd_flags; /* interface flags */ + struct if_data ifmd_data; /* generic information and statistics */ + int ifmd_snd_len; /* instantaneous length of send queue */ + int ifmd_snd_maxlen; /* maximum length of send queue */ + int ifmd_snd_drops; /* number of drops in send queue */ +}; + +/* + * sysctl MIB tags at the net.link.generic level + */ +#define IFMIB_SYSTEM 1 /* non-interface-specific */ +#define IFMIB_IFDATA 2 /* per-interface data table */ + +/* + * MIB tags for the various net.link.generic.ifdata tables + */ +#define IFDATA_GENERAL 1 /* generic stats for all kinds of ifaces */ +#define IFDATA_LINKSPECIFIC 2 /* specific to the type of interface */ + +/* + * MIB tags at the net.link.generic.system level + */ +#define IFMIB_IFCOUNT 1 /* number of interfaces configured */ + +/* + * MIB tags as the net.link level + * All of the other values are IFT_* names defined in if_types.h. + */ +#define NETLINK_GENERIC 0 /* functions not specific to a type of iface */ + +/* + * The reason why the IFDATA_LINKSPECIFIC stuff is not under the + * net.link.<iftype> branches is twofold: + * 1) It's easier to code this way, and doesn't require duplication. + * 2) The fourth level under net.link.<iftype> is <pf>; that is to say, + * the net.link.<iftype> tree instruments the adaptation layers between + * <iftype> and a particular protocol family (e.g., net.link.ether.inet + * instruments ARP). This does not really leave room for anything else + * that needs to have a well-known number. + */ +#endif /* _NET_IF_MIB_H */ |