static int sysctl_ifdata(SYSCTL_HANDLER_ARGS) /* XXX bad syntax! */ { int *name = (int *)arg1; int error; u_int namelen = arg2; struct ifnet *ifp; struct ifmibdata ifmd; size_t dlen; char *dbuf; if (namelen != 2) return EINVAL; if (name[0] <= 0) return (ENOENT); ifp = ifnet_byindex_ref(name[0]); if (ifp == NULL) return (ENOENT); switch(name[1]) { default: error = ENOENT; goto out; 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(data); #undef COPY ifmd.ifmd_flags = ifp->if_flags | ifp->if_drv_flags; 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) goto out; error = SYSCTL_IN(req, &ifmd, sizeof ifmd); if (error) goto out; #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) goto out; error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); if (error) goto out; break; case IFDATA_DRIVERNAME: /* 20 is enough for 64bit ints */ dlen = strlen(ifp->if_dname) + 20 + 1; if ((dbuf = malloc(dlen, M_TEMP, M_NOWAIT)) == NULL) { error = ENOMEM; goto out; } if (ifp->if_dunit == IF_DUNIT_NONE) strcpy(dbuf, ifp->if_dname); else sprintf(dbuf, "%s%d", ifp->if_dname, ifp->if_dunit); error = SYSCTL_OUT(req, dbuf, strlen(dbuf) + 1); if (error == 0 && req->newptr != NULL) error = EPERM; free(dbuf, M_TEMP); goto out; } out: if_rele(ifp); return error; }
int make_ifmibdata(struct ifnet *ifp, int *name, struct sysctl_req *req) { struct ifmibdata ifmd; int error = 0; switch(name[1]) { default: error = ENOENT; break; case IFDATA_GENERAL: bzero(&ifmd, sizeof(ifmd)); /* * Make sure the interface is in use */ if (ifnet_is_attached(ifp, 0)) { snprintf(ifmd.ifmd_name, sizeof(ifmd.ifmd_name), "%s%d", ifp->if_name, ifp->if_unit); #define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld COPY(pcount); COPY(flags); if_data_internal_to_if_data64(ifp, &ifp->if_data, &ifmd.ifmd_data); #undef COPY ifmd.ifmd_snd_len = IFCQ_LEN(&ifp->if_snd); ifmd.ifmd_snd_maxlen = IFCQ_MAXLEN(&ifp->if_snd); ifmd.ifmd_snd_drops = ifp->if_snd.ifcq_dropcnt.packets; } error = SYSCTL_OUT(req, &ifmd, sizeof ifmd); if (error || !req->newptr) break; #ifdef IF_MIB_WR error = SYSCTL_IN(req, &ifmd, sizeof ifmd); if (error) break; #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 #endif /* IF_MIB_WR */ break; case IFDATA_LINKSPECIFIC: error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen); if (error || !req->newptr) break; #ifdef IF_MIB_WR error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); if (error) break; #endif /* IF_MIB_WR */ break; case IFDATA_SUPPLEMENTAL: { struct ifmibdata_supplemental *ifmd_supp; if ((ifmd_supp = _MALLOC(sizeof (*ifmd_supp), M_TEMP, M_NOWAIT | M_ZERO)) == NULL) { error = ENOMEM; break; } if_copy_traffic_class(ifp, &ifmd_supp->ifmd_traffic_class); if_copy_data_extended(ifp, &ifmd_supp->ifmd_data_extended); if_copy_packet_stats(ifp, &ifmd_supp->ifmd_packet_stats); if_copy_rxpoll_stats(ifp, &ifmd_supp->ifmd_rxpoll_stats); error = SYSCTL_OUT(req, ifmd_supp, sizeof (*ifmd_supp)); _FREE(ifmd_supp, M_TEMP); break; } } return error; }
int make_ifmibdata(struct ifnet *ifp, int *name, struct sysctl_req *req) { struct ifmibdata ifmd; int error = 0; switch(name[1]) { default: error = ENOENT; break; case IFDATA_GENERAL: bzero(&ifmd, sizeof(ifmd)); /* * Make sure the interface is in use */ if (ifnet_is_attached(ifp, 0)) { snprintf(ifmd.ifmd_name, sizeof(ifmd.ifmd_name), "%s%d", ifp->if_name, ifp->if_unit); #define COPY(fld) ifmd.ifmd_##fld = ifp->if_##fld COPY(pcount); COPY(flags); if_data_internal_to_if_data64(ifp, &ifp->if_data, &ifmd.ifmd_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) break; #ifdef IF_MIB_WR error = SYSCTL_IN(req, &ifmd, sizeof ifmd); if (error) break; #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 #endif /* IF_MIB_WR */ break; case IFDATA_LINKSPECIFIC: error = SYSCTL_OUT(req, ifp->if_linkmib, ifp->if_linkmiblen); if (error || !req->newptr) break; #ifdef IF_MIB_WR error = SYSCTL_IN(req, ifp->if_linkmib, ifp->if_linkmiblen); if (error) break; #endif /* IF_MIB_WR */ break; case IFDATA_SUPPLEMENTAL: { struct if_traffic_class if_tc; if_copy_traffic_class(ifp, &if_tc); error = SYSCTL_OUT(req, &if_tc, sizeof(struct if_traffic_class)); break; } } return error; }
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_indexlim || !ifindex2ifnet[name[0]] || ifnet_addrs[name[0] - 1] == NULL) return ENOENT; ifp = ifnet_addrs[name[0] - 1]->ifa_ifp; switch(name[1]) { default: return ENOENT; case IFDATA_GENERAL: ifnlen = snprintf(workbuf, sizeof(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; }