⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
 */static voidif_qflush(ifq)	register struct ifqueue *ifq;{	register struct mbuf *m, *n;	n = ifq->ifq_head;	while ((m = n) != 0) {		n = m->m_act;		m_freem(m);	}	ifq->ifq_head = 0;	ifq->ifq_tail = 0;	ifq->ifq_len = 0;}/* * Handle interface watchdog timer routines.  Called * from softclock, we decrement timers (if set) and * call the appropriate interface routine on expiration. */static voidif_slowtimo(arg)	void *arg;{	register struct ifnet *ifp;	int s = splimp();	for (ifp = ifnet; ifp; ifp = ifp->if_next) {		if (ifp->if_timer == 0 || --ifp->if_timer)			continue;		if (ifp->if_watchdog)			(*ifp->if_watchdog)(ifp);	}	splx(s);	timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);}/* * Map interface name to * interface structure pointer. */struct ifnet *ifunit(name)	register char *name;{	register char *cp;	register struct ifnet *ifp;	int unit;	unsigned len;	char *ep, c;	for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)		if (*cp >= '0' && *cp <= '9')			break;	if (*cp == '\0' || cp == name + IFNAMSIZ)		return ((struct ifnet *)0);	/*	 * Save first char of unit, and pointer to it,	 * so we can put a null there to avoid matching	 * initial substrings of interface names.	 */	len = cp - name + 1;	c = *cp;	ep = cp;	for (unit = 0; *cp >= '0' && *cp <= '9'; )		unit = unit * 10 + *cp++ - '0';	if (*cp != '\0')		return 0;	/* no trailing garbage allowed */	*ep = 0;	for (ifp = ifnet; ifp; ifp = ifp->if_next) {		if (bcmp(ifp->if_name, name, len))			continue;		if (unit == ifp->if_unit)			break;	}	*ep = c;	return (ifp);}/* * Interface ioctls. */intifioctl(so, cmd, data, p)	struct socket *so;	int cmd;	caddr_t data;	struct proc *p;{	register struct ifnet *ifp;	register struct ifreq *ifr;	int error;	switch (cmd) {	case SIOCGIFCONF:	case OSIOCGIFCONF:		return (ifconf(cmd, data));	}	ifr = (struct ifreq *)data;	ifp = ifunit(ifr->ifr_name);	if (ifp == 0)		return (ENXIO);	switch (cmd) {	case SIOCGIFFLAGS:		ifr->ifr_flags = ifp->if_flags;		break;	case SIOCGIFMETRIC:		ifr->ifr_metric = ifp->if_metric;		break;	case SIOCGIFMTU:		ifr->ifr_mtu = ifp->if_mtu;		break;	case SIOCGIFPHYS:		ifr->ifr_phys = ifp->if_physical;		break;	case SIOCSIFFLAGS:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return (error);		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {			int s = splimp();			if_down(ifp);			splx(s);		}		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {			int s = splimp();			if_up(ifp);			splx(s);		}		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |			(ifr->ifr_flags &~ IFF_CANTCHANGE);		if (ifp->if_ioctl)			(void) (*ifp->if_ioctl)(ifp, cmd, data);		microtime(&ifp->if_lastchange);		break;	case SIOCSIFMETRIC:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return (error);		ifp->if_metric = ifr->ifr_metric;		microtime(&ifp->if_lastchange);		break;	case SIOCSIFPHYS:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return error;		if (!ifp->if_ioctl)		        return EOPNOTSUPP;		error = (*ifp->if_ioctl)(ifp, cmd, data);		if (error == 0)			microtime(&ifp->if_lastchange);		return(error);	case SIOCSIFMTU:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return (error);		if (ifp->if_ioctl == NULL)			return (EOPNOTSUPP);		/*		 * 72 was chosen below because it is the size of a TCP/IP		 * header (40) + the minimum mss (32).		 */		if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535)			return (EINVAL);		error = (*ifp->if_ioctl)(ifp, cmd, data);		if (error == 0)			microtime(&ifp->if_lastchange);		return(error);	case SIOCADDMULTI:	case SIOCDELMULTI:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return (error);		if (ifp->if_ioctl == NULL)			return (EOPNOTSUPP);		error = (*ifp->if_ioctl)(ifp, cmd, data);		if (error == 0 )		    	microtime(&ifp->if_lastchange);		return(error);        case SIOCSIFMEDIA:		error = suser(p->p_ucred, &p->p_acflag);		if (error)			return (error);		if (ifp->if_ioctl == 0)			return (EOPNOTSUPP);		error = (*ifp->if_ioctl)(ifp, cmd, data);		if (error == 0)			microtime(&ifp->if_lastchange);		return error;	case SIOCGIFMEDIA:		if (ifp->if_ioctl == 0)			return (EOPNOTSUPP);		return ((*ifp->if_ioctl)(ifp, cmd, data));	default:		if (so->so_proto == 0)			return (EOPNOTSUPP);#ifndef COMPAT_43		return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,								 data,								 ifp));#else	    {		int ocmd = cmd;		switch (cmd) {		case SIOCSIFDSTADDR:		case SIOCSIFADDR:		case SIOCSIFBRDADDR:		case SIOCSIFNETMASK:#if BYTE_ORDER != BIG_ENDIAN			if (ifr->ifr_addr.sa_family == 0 &&			    ifr->ifr_addr.sa_len < 16) {				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;				ifr->ifr_addr.sa_len = 16;			}#else			if (ifr->ifr_addr.sa_len == 0)				ifr->ifr_addr.sa_len = 16;#endif			break;		case OSIOCGIFADDR:			cmd = SIOCGIFADDR;			break;		case OSIOCGIFDSTADDR:			cmd = SIOCGIFDSTADDR;			break;		case OSIOCGIFBRDADDR:			cmd = SIOCGIFBRDADDR;			break;		case OSIOCGIFNETMASK:			cmd = SIOCGIFNETMASK;		}		error =  ((*so->so_proto->pr_usrreqs->pru_control)(so,								   cmd,								   data,								   ifp));		switch (ocmd) {		case OSIOCGIFADDR:		case OSIOCGIFDSTADDR:		case OSIOCGIFBRDADDR:		case OSIOCGIFNETMASK:			*(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;		}		return (error);	    }#endif	/*	 * RTEMS additions for setting/getting `tap' function	 */	case SIOCSIFTAP:		ifp->if_tap = ifr->ifr_tap;		return 0;	case SIOCGIFTAP:		ifr->ifr_tap = ifp->if_tap;		return 0;	}	return (0);}/* * Set/clear promiscuous mode on interface ifp based on the truth value * of pswitch.  The calls are reference counted so that only the first * "on" request actually has an effect, as does the final "off" request. * Results are undefined if the "off" and "on" requests are not matched. */intifpromisc(ifp, pswitch)	struct ifnet *ifp;	int pswitch;{	struct ifreq ifr;	if (pswitch) {		/*		 * If the device is not configured up, we cannot put it in		 * promiscuous mode.		 */		if ((ifp->if_flags & IFF_UP) == 0)			return (ENETDOWN);		if (ifp->if_pcount++ != 0)			return (0);		ifp->if_flags |= IFF_PROMISC;		log(LOG_INFO, "%s%d: promiscuous mode enabled\n",		    ifp->if_name, ifp->if_unit);	} else {		if (--ifp->if_pcount > 0)			return (0);		ifp->if_flags &= ~IFF_PROMISC;	}	ifr.ifr_flags = ifp->if_flags;	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));}/* * Return interface configuration * of system.  List may be used * in later ioctl's (above) to get * other information. *//*ARGSUSED*/static intifconf(cmd, data)	int cmd;	caddr_t data;{	register struct ifconf *ifc = (struct ifconf *)data;	register struct ifnet *ifp = ifnet;	register struct ifaddr *ifa;	struct ifreq ifr, *ifrp;	int space = ifc->ifc_len, error = 0;	ifrp = ifc->ifc_req;	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {		char workbuf[64];		int ifnlen;		ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);		if(ifnlen + 1 > sizeof ifr.ifr_name) {			error = ENAMETOOLONG;		} else {			strcpy(ifr.ifr_name, workbuf);		}		if ((ifa = ifp->if_addrlist) == 0) {			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,			    sizeof (ifr));			if (error)				break;			space -= sizeof (ifr), ifrp++;		} else		    for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {			register struct sockaddr *sa = ifa->ifa_addr;#ifdef COMPAT_43			if (cmd == OSIOCGIFCONF) {				struct osockaddr *osa =					 (struct osockaddr *)&ifr.ifr_addr;				ifr.ifr_addr = *sa;				osa->sa_family = sa->sa_family;				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,						sizeof (ifr));				ifrp++;			} else#endif			if (sa->sa_len <= sizeof(*sa)) {				ifr.ifr_addr = *sa;				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,						sizeof (ifr));				ifrp++;			} else {				space -= sa->sa_len - sizeof(*sa);				if (space < sizeof (ifr))					break;				error = copyout((caddr_t)&ifr, (caddr_t)ifrp,						sizeof (ifr.ifr_name));				if (error == 0)				    error = copyout((caddr_t)sa,				      (caddr_t)&ifrp->ifr_addr, sa->sa_len);				ifrp = (struct ifreq *)					(sa->sa_len + (caddr_t)&ifrp->ifr_addr);			}			if (error)				break;			space -= sizeof (ifr);		}	}	ifc->ifc_len -= space;	return (error);}SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -