#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_mib.h>
SYSCTL_DECL(_net_link_generic);
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)
{
int *name = (int *)arg1;
int error;
u_int namelen = arg2;
struct ifnet *ifp;
struct ifmibdata ifmd;
if (namelen != 2)
return EINVAL;
ifnet_lock();
if (name[0] <= 0 || name[0] > if_index ||
ifindex2ifnet[name[0]] == NULL) {
ifnet_unlock();
return ENOENT;
}
ifp = ifindex2ifnet[name[0]];
switch(name[1]) {
default:
ifnet_unlock();
return ENOENT;
case IFDATA_GENERAL:
bzero(&ifmd, sizeof(ifmd));
strlcpy(ifmd.ifmd_name, ifp->if_xname, sizeof(ifmd.ifmd_name));
#define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld
COPY(pcount);
COPY(flags);
COPY(data);
#undef COPY
#define COPY_DATA(name) IFNET_STAT_GET(ifp, name, ifmd.ifmd_data.ifi_##name)
COPY_DATA(ipackets);
COPY_DATA(ierrors);
COPY_DATA(opackets);
COPY_DATA(oerrors);
COPY_DATA(collisions);
COPY_DATA(ibytes);
COPY_DATA(obytes);
COPY_DATA(imcasts);
COPY_DATA(omcasts);
COPY_DATA(iqdrops);
COPY_DATA(noproto);
COPY_DATA(oqdrops);
#undef COPY_DATA
ifmd.ifmd_snd_maxlen = ifp->if_snd.altq_maxlen;
#ifdef notyet
ifmd.ifmd_snd_len = ifp->if_snd.ifq_len;
ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops;
#endif
error = SYSCTL_OUT(req, &ifmd, sizeof ifmd);
if (error || !req->newptr) {
ifnet_unlock();
return error;
}
error = SYSCTL_IN(req, &ifmd, sizeof ifmd);
if (error) {
ifnet_unlock();
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);
#undef COPY
#define COPY_DATA(name) IFNET_STAT_SET(ifp, name, ifmd.ifmd_data.ifi_##name)
COPY_DATA(ipackets);
COPY_DATA(ierrors);
COPY_DATA(opackets);
COPY_DATA(oerrors);
COPY_DATA(collisions);
COPY_DATA(ibytes);
COPY_DATA(obytes);
COPY_DATA(imcasts);
COPY_DATA(omcasts);
COPY_DATA(iqdrops);
COPY_DATA(noproto);
COPY_DATA(oqdrops);
#undef COPY_DATA
#ifdef notyet
ifp->if_snd.ifq_maxlen = ifmd.ifmd_snd_maxlen;
ifp->if_snd.ifq_drops = ifmd.ifmd_snd_drops;
#endif
break;
case IFDATA_LINKSPECIFIC:
error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen);
if (error || !req->newptr) {
ifnet_unlock();
return error;
}
error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen);
if (error) {
ifnet_unlock();
return error;
}
}
ifnet_unlock();
return 0;
}
SYSCTL_NODE(_net_link_generic, IFMIB_IFDATA, ifdata, CTLFLAG_RW,
sysctl_ifdata, "Interface table");