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

📄 if.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (ifa_maybe == 0 ||			    rn_refines((caddr_t)ifa->ifa_netmask,			    (caddr_t)ifa_maybe->ifa_netmask))				ifa_maybe = ifa;		}	return (ifa_maybe);}/* * Find an interface using a specific address family */struct ifaddr *ifa_ifwithaf(af)	register int af;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)		for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)			if (ifa->ifa_addr->sa_family == af)				return (ifa);	return (NULL);}/* * Find an interface address specific to an interface best matching * a given address. */struct ifaddr *ifaof_ifpforaddr(addr, ifp)	struct sockaddr *addr;	register struct ifnet *ifp;{	register struct ifaddr *ifa;	register char *cp, *cp2, *cp3;	register char *cplim;	struct ifaddr *ifa_maybe = 0;	u_int af = addr->sa_family;	if (af >= AF_MAX)		return (NULL);	for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {		if (ifa->ifa_addr->sa_family != af)			continue;		ifa_maybe = ifa;		if (ifa->ifa_netmask == 0) {			if (equal(addr, ifa->ifa_addr) ||			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))				return (ifa);			continue;		}		cp = addr->sa_data;		cp2 = ifa->ifa_addr->sa_data;		cp3 = ifa->ifa_netmask->sa_data;		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;		for (; cp3 < cplim; cp3++)			if ((*cp++ ^ *cp2++) & *cp3)				break;		if (cp3 == cplim)			return (ifa);	}	return (ifa_maybe);}/* * Default action when installing a route with a Link Level gateway. * Lookup an appropriate real ifa to point to. * This should be moved to /sys/net/link.c eventually. */voidlink_rtrequest(cmd, rt, sa)	int cmd;	register struct rtentry *rt;	struct sockaddr *sa;{	register struct ifaddr *ifa;	struct sockaddr *dst;	struct ifnet *ifp;	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))		return;	if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {		IFAFREE(rt->rt_ifa);		rt->rt_ifa = ifa;		ifa->ifa_refcnt++;		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)			ifa->ifa_rtrequest(cmd, rt, sa);	}}/* * Mark an interface down and notify protocols of * the transition. * NOTE: must be called at splsoftnet or equivalent. */voidif_down(ifp)	register struct ifnet *ifp;{	register struct ifaddr *ifa;	ifp->if_flags &= ~IFF_UP;	for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next)		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);	if_qflush(&ifp->if_snd);	rt_ifmsg(ifp);}/* * Mark an interface up and notify protocols of * the transition. * NOTE: must be called at splsoftnet or equivalent. */voidif_up(ifp)	register struct ifnet *ifp;{#ifdef notyet	register struct ifaddr *ifa;#endif	ifp->if_flags |= IFF_UP;#ifdef notyet	/* this has no effect on IP, and will kill all ISO connections XXX */	for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;	     ifa = ifa->ifa_list.tqe_next)		pfctlinput(PRC_IFUP, ifa->ifa_addr);#endif	rt_ifmsg(ifp);#ifdef INET6	in6_if_up(ifp);#endif}/* * Flush an interface queue. */voidif_qflush(ifq)	register struct ifqueue *ifq;{	register struct mbuf *m, *n;	n = ifq->ifq_head;	while ((m = n) != NULL) {		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. */voidif_slowtimo(arg)	void *arg;{	register struct ifnet *ifp;	int s = splimp();	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {		if (ifp->if_timer == 0 || --ifp->if_timer)			continue;		if (ifp->if_watchdog)			(*ifp->if_watchdog)(ifp);	}	splx(s);	timeout(if_slowtimo, NULL, hz / IFNET_SLOWHZ);}/* * Map interface name to * interface structure pointer. */struct ifnet *ifunit(name)	register char *name;{	register struct ifnet *ifp;	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)		if (strcmp(ifp->if_xname, name) == 0)			return (ifp);	return (NULL);}/* * Map interface name in a sockaddr_dl to * interface structure pointer. */struct ifnet *if_withname(sa)	struct sockaddr *sa;{	char ifname[IFNAMSIZ+1];	struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;	if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||	     (sdl->sdl_nlen > IFNAMSIZ) )		return NULL;	/*	 * ifunit wants a null-terminated name.  It may not be null-terminated	 * in the sockaddr.  We don't want to change the caller's sockaddr,	 * and there might not be room to put the trailing null anyway, so we	 * make a local copy that we know we can null terminate safely.	 */	bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);	ifname[sdl->sdl_nlen] = '\0';	return ifunit(ifname);}/* * Interface ioctls. */intifioctl(so, cmd, data, p)	struct socket *so;	u_long cmd;	caddr_t data;	struct proc *p;{	register struct ifnet *ifp;	register struct ifreq *ifr;	int error = 0;	short oif_flags;	switch (cmd) {	case SIOCGIFCONF:	case OSIOCGIFCONF:		return (ifconf(cmd, data));	}	ifr = (struct ifreq *)data;	ifp = ifunit(ifr->ifr_name);	if (ifp == 0)		return (ENXIO);	oif_flags = ifp->if_flags;	switch (cmd) {	case SIOCGIFFLAGS:		ifr->ifr_flags = ifp->if_flags;		break;	case SIOCGIFMETRIC:		ifr->ifr_metric = ifp->if_metric;		break;	case SIOCGIFDATA:		error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,		    sizeof(ifp->if_data));		break;	case SIOCSIFFLAGS:#ifndef __ECOS		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)			return (error);#endif		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);		break;	case SIOCSIFMETRIC:#ifndef __ECOS		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)			return (error);#endif		ifp->if_metric = ifr->ifr_metric;		break;	case SIOCADDMULTI:	case SIOCDELMULTI:	case SIOCSIFMEDIA:#ifndef __ECOS		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)			return (error);#endif		/* FALLTHROUGH */#ifdef SIOCGIFSTATS        case SIOCGIFSTATS:#ifdef SIOCGIFSTATSUD        case SIOCGIFSTATSUD:#endif#endif // SIOCGIFSTATS	case SIOCGIFMEDIA:		if (ifp->if_ioctl == 0)			return (EOPNOTSUPP);		error = (*ifp->if_ioctl)(ifp, cmd, data);		break;	default:		if (so->so_proto == 0)			return (EOPNOTSUPP);#if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,			(struct mbuf *) cmd, (struct mbuf *) data,			(struct mbuf *) ifp));#else	    {		u_long ocmd = cmd;		switch (cmd) {		case SIOCSIFADDR:		case SIOCSIFDSTADDR:		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_usrreq)(so, PRU_CONTROL,						    (struct mbuf *) cmd,						    (struct mbuf *) data,						    (struct mbuf *) ifp));		switch (ocmd) {		case OSIOCGIFADDR:		case OSIOCGIFDSTADDR:		case OSIOCGIFBRDADDR:		case OSIOCGIFNETMASK:			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;		}	    }#endif		break;	}	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {#ifdef INET6		if ((ifp->if_flags & IFF_UP) != 0) {			int s = splimp();			in6_if_up(ifp);			splx(s);		}#endif  	}	return (error);}/* * Return interface configuration * of system.  List may be used * in later ioctl's (above) to get * other information. *//*ARGSUSED*/intifconf(cmd, data)	u_long cmd;	caddr_t data;{	register struct ifconf *ifc = (struct ifconf *)data;	register struct ifnet *ifp;	register struct ifaddr *ifa;	struct ifreq ifr, *ifrp;	int space = ifc->ifc_len, error = 0;	/* If ifc->ifc_len is 0, fill it in with the needed size and return. */	if (space == 0) {		for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) {			register struct sockaddr *sa;			if ((ifa = ifp->if_addrlist.tqh_first) == 0)				space += sizeof (ifr);			else 				for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) {					sa = ifa->ifa_addr;#if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)					if (cmd != OSIOCGIFCONF)#endif					if (sa->sa_len > sizeof(*sa))						space += sa->sa_len -						    sizeof (*sa);					space += sizeof (ifr);				}		}		ifc->ifc_len = space;		return(0);	}	ifrp = ifc->ifc_req;	for (ifp = ifnet.tqh_first; space >= sizeof (ifr) && ifp != 0;	    ifp = ifp->if_list.tqe_next) {		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);		if ((ifa = ifp->if_addrlist.tqh_first) == 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 != 0;			    ifa = ifa->ifa_list.tqe_next) {				register struct sockaddr *sa = ifa->ifa_addr;#if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)				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);}

⌨️ 快捷键说明

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