/* * Receive a SeND message from user space to be either send out by the kernel * or, with SeND ICMPv6 options removed, to be further processed by the icmp6 * input path. */ static int send_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct thread *td) { struct sockaddr_send *sendsrc; struct ifnet *ifp; int error; KASSERT(V_send_so == so, ("%s: socket %p not send socket %p", __func__, so, V_send_so)); sendsrc = (struct sockaddr_send *)nam; ifp = ifnet_byindex_ref(sendsrc->send_ifidx); if (ifp == NULL) { error = ENETUNREACH; goto err; } error = send_output(m, ifp, sendsrc->send_direction); if_rele(ifp); m = NULL; err: if (m != NULL) m_freem(m); return (error); }
int uinet_getifstat(const char *name, struct uinet_ifstat *stat) { struct uinet_config_if *ifcfg; struct ifnet *ifp; ifcfg = uinet_iffind_byname(name); if (NULL == ifcfg) { printf("could not find interface %s\n", name); return (EINVAL); } ifp = ifnet_byindex_ref(ifcfg->ifindex); if (NULL == ifp) { printf("could not find interface %s by index\n", name); return (EINVAL); } stat->ifi_ipackets = ifp->if_data.ifi_ipackets; stat->ifi_ierrors = ifp->if_data.ifi_ierrors; stat->ifi_opackets = ifp->if_data.ifi_opackets; stat->ifi_oerrors = ifp->if_data.ifi_oerrors; stat->ifi_collisions = ifp->if_data.ifi_collisions; stat->ifi_ibytes = ifp->if_data.ifi_ibytes; stat->ifi_obytes = ifp->if_data.ifi_obytes; stat->ifi_imcasts = ifp->if_data.ifi_imcasts; stat->ifi_omcasts = ifp->if_data.ifi_omcasts; stat->ifi_iqdrops = ifp->if_data.ifi_iqdrops; stat->ifi_noproto = ifp->if_data.ifi_noproto; stat->ifi_hwassist = ifp->if_data.ifi_hwassist; stat->ifi_epoch = ifp->if_data.ifi_epoch; stat->ifi_icopies = ifp->if_data.ifi_icopies; stat->ifi_izcopies = ifp->if_data.ifi_izcopies; stat->ifi_ocopies = ifp->if_data.ifi_ocopies; stat->ifi_ozcopies = ifp->if_data.ifi_ozcopies; if_rele(ifp); return (0); }
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; }