if_mib.c revision 181803
117651Speter/*- 2254069Sdelphij * Copyright 1996 Massachusetts Institute of Technology 3131380Stjr * 417651Speter * Permission to use, copy, modify, and distribute this software and 517651Speter * its documentation for any purpose and without fee is hereby 650476Speter * granted, provided that both the above copyright notice and this 717651Speter * permission notice appear in all copies, that both the above 8131380Stjr * copyright notice and this permission notice appear in all 9131380Stjr * supporting documentation, and that the name of M.I.T. not be used 1017651Speter * in advertising or publicity pertaining to distribution of the 1117651Speter * software without specific, written prior permission. M.I.T. makes 1217651Speter * no representations about the suitability of this software for any 1317651Speter * purpose. It is provided "as is" without express or implied 14205471Sdelphij * warranty. 15205471Sdelphij * 1617651Speter * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 17205471Sdelphij * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 18237691Sdelphij * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19205471Sdelphij * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 20205471Sdelphij * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21205471Sdelphij * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22205471Sdelphij * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 23205471Sdelphij * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24254069Sdelphij * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25205471Sdelphij * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26205471Sdelphij * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27205471Sdelphij * SUCH DAMAGE. 28205471Sdelphij * 29205471Sdelphij * $FreeBSD: head/sys/net/if_mib.c 181803 2008-08-17 23:27:27Z bz $ 30205471Sdelphij */ 31205471Sdelphij 32237691Sdelphij#include <sys/param.h> 33237691Sdelphij#include <sys/systm.h> 34237691Sdelphij#include <sys/kernel.h> 35237691Sdelphij#include <sys/socket.h> 36237691Sdelphij#include <sys/sysctl.h> 37205471Sdelphij#include <sys/vimage.h> 38205471Sdelphij 39205471Sdelphij#include <net/if.h> 40145490Skientzle#include <net/if_mib.h> 41205471Sdelphij 42205471Sdelphij/* 43145490Skientzle * A sysctl(3) MIB for generic interface information. This information 44145490Skientzle * is exported in the net.link.generic branch, which has the following 45205471Sdelphij * structure: 46145490Skientzle * 47237691Sdelphij * net.link.generic .system - system-wide control variables 48145490Skientzle * and statistics (node) 49205471Sdelphij * .ifdata.<ifindex>.general 50237691Sdelphij * - what's in `struct ifdata' 51205471Sdelphij * plus some other info 52205471Sdelphij * .ifdata.<ifindex>.linkspecific 53205471Sdelphij * - a link-type-specific data 54205471Sdelphij * structure (as might be used 55205471Sdelphij * by an SNMP agent 56237691Sdelphij * 57237691Sdelphij * Perhaps someday we will make addresses accessible via this interface 58237691Sdelphij * as well (then there will be four such...). The reason that the 59237691Sdelphij * index comes before the last element in the name is because it 60237691Sdelphij * seems more orthogonal that way, particularly with the possibility 61237691Sdelphij * of other per-interface data living down here as well (e.g., integrated 62237691Sdelphij * services stuff). 63237691Sdelphij */ 64237691Sdelphij 65237691SdelphijSYSCTL_DECL(_net_link_generic); 66237691SdelphijSYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system, CTLFLAG_RW, 0, 67237691Sdelphij "Variables global to all interfaces"); 68237691SdelphijSYSCTL_INT(_net_link_generic_system, IFMIB_IFCOUNT, ifcount, CTLFLAG_RD, 69237691Sdelphij &if_index, 0, "Number of configured interfaces"); 70237691Sdelphij 71237691Sdelphijstatic int 72237691Sdelphijsysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */ 73237691Sdelphij{ 74237691Sdelphij int *name = (int *)arg1; 75237691Sdelphij int error; 76237691Sdelphij u_int namelen = arg2; 77237691Sdelphij struct ifnet *ifp; 78237691Sdelphij struct ifmibdata ifmd; 79237691Sdelphij size_t dlen; 80237691Sdelphij char *dbuf; 81254069Sdelphij 82237691Sdelphij if (namelen != 2) 83237691Sdelphij return EINVAL; 84237691Sdelphij 85237691Sdelphij if (name[0] <= 0 || name[0] > V_if_index || 86237691Sdelphij ifnet_byindex(name[0]) == NULL) 87237691Sdelphij return ENOENT; 88237691Sdelphij 89237691Sdelphij ifp = ifnet_byindex(name[0]); 90237691Sdelphij 91237691Sdelphij switch(name[1]) { 92237691Sdelphij default: 93237691Sdelphij return ENOENT; 94205471Sdelphij 95205471Sdelphij case IFDATA_GENERAL: 96205471Sdelphij bzero(&ifmd, sizeof(ifmd)); 97205471Sdelphij strlcpy(ifmd.ifmd_name, ifp->if_xname, sizeof(ifmd.ifmd_name)); 98205471Sdelphij 99205471Sdelphij#define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld 100205471Sdelphij COPY(pcount); 101145490Skientzle COPY(data); 102205471Sdelphij#undef COPY 103205471Sdelphij ifmd.ifmd_flags = ifp->if_flags | ifp->if_drv_flags; 104205471Sdelphij ifmd.ifmd_snd_len = ifp->if_snd.ifq_len; 105205471Sdelphij ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen; 106205471Sdelphij ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops; 107145490Skientzle 108254069Sdelphij error = SYSCTL_OUT(req, &ifmd, sizeof ifmd); 109145490Skientzle if (error || !req->newptr) 110145490Skientzle return error; 111205471Sdelphij 112237691Sdelphij error = SYSCTL_IN(req, &ifmd, sizeof ifmd); 113205471Sdelphij if (error) 114205471Sdelphij return error; 115205471Sdelphij 116237691Sdelphij#define DONTCOPY(fld) ifmd.ifmd_data.ifi_##fld = ifp->if_data.ifi_##fld 117237691Sdelphij DONTCOPY(type); 118237691Sdelphij DONTCOPY(physical); 119145490Skientzle DONTCOPY(addrlen); 120237691Sdelphij DONTCOPY(hdrlen); 121237691Sdelphij DONTCOPY(mtu); 122237691Sdelphij DONTCOPY(metric); 123237691Sdelphij DONTCOPY(baudrate); 124205471Sdelphij#undef DONTCOPY 125205471Sdelphij#define COPY(fld) ifp->if_##fld = ifmd.ifmd_##fld 12617651Speter COPY(data); 127205471Sdelphij ifp->if_snd.ifq_maxlen = ifmd.ifmd_snd_maxlen; 128205471Sdelphij ifp->if_snd.ifq_drops = ifmd.ifmd_snd_drops; 129205471Sdelphij#undef COPY 130157046Sdes break; 131205471Sdelphij 132157046Sdes case IFDATA_LINKSPECIFIC: 133237691Sdelphij error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen); 134237691Sdelphij if (error || !req->newptr) 135237691Sdelphij return error; 136205471Sdelphij 137205471Sdelphij error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); 138157046Sdes if (error) 139205471Sdelphij return error; 140157046Sdes 141145490Skientzle case IFDATA_DRIVERNAME: 142205471Sdelphij /* 20 is enough for 64bit ints */ 143145490Skientzle dlen = strlen(ifp->if_dname) + 20 + 1; 144145490Skientzle if ((dbuf = malloc(dlen, M_TEMP, M_NOWAIT)) == NULL) 145205471Sdelphij return (ENOMEM); 146205471Sdelphij if (ifp->if_dunit == IF_DUNIT_NONE) 147145490Skientzle strcpy(dbuf, ifp->if_dname); 148205471Sdelphij else 149205471Sdelphij sprintf(dbuf, "%s%d", ifp->if_dname, ifp->if_dunit); 150205471Sdelphij 151205471Sdelphij error = SYSCTL_OUT(req, dbuf, strlen(dbuf) + 1); 152205471Sdelphij if (error == 0 && req->newptr != NULL) 15317651Speter error = EPERM; 15417651Speter free(dbuf, M_TEMP); 155131380Stjr return (error); 156131380Stjr } 157131380Stjr return 0; 158131380Stjr} 159131380Stjr 160131380StjrSYSCTL_NODE(_net_link_generic, IFMIB_IFDATA, ifdata, CTLFLAG_RW, 161131380Stjr sysctl_ifdata, "Interface table"); 162131380Stjr 163131380Stjr