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

📄 if.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	count = (if_cloners_count < ifcr->ifcr_count) ?	    if_cloners_count : ifcr->ifcr_count;	for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;	     ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {		strncpy(outbuf, ifc->ifc_name, IFNAMSIZ);		outbuf[IFNAMSIZ - 1] = '\0';	/* sanity */		error = copyout(outbuf, dst, IFNAMSIZ);		if (error)			break;	}	return (error);}/* * Locate an interface based on a complete address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithaddr(addr)	register struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;#define	equal(a1, a2) \  (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)	    for (ifa = ifp->if_addrhead.tqh_first; ifa;		 ifa = ifa->ifa_link.tqe_next) {		if (ifa->ifa_addr->sa_family != addr->sa_family)			continue;		if (equal(addr, ifa->ifa_addr))			return (ifa);		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&		    /* IP6 doesn't have broadcast */		    ifa->ifa_broadaddr->sa_len != 0 &&		    equal(ifa->ifa_broadaddr, addr))			return (ifa);	}	return ((struct ifaddr *)0);}/* * Locate the point to point interface with a given destination address. *//*ARGSUSED*/struct ifaddr *ifa_ifwithdstaddr(addr)	register struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)	    if (ifp->if_flags & IFF_POINTOPOINT)		for (ifa = ifp->if_addrhead.tqh_first; ifa;		     ifa = ifa->ifa_link.tqe_next) {			if (ifa->ifa_addr->sa_family != addr->sa_family)				continue;			if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))				return (ifa);	}	return ((struct ifaddr *)0);}/* * Find an interface on a specific network.  If many, choice * is most specific found. */struct ifaddr *ifa_ifwithnet(addr)	struct sockaddr *addr;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	struct ifaddr *ifa_maybe = (struct ifaddr *) 0;	u_int af = addr->sa_family;	char *addr_data = addr->sa_data, *cplim;	/*	 * AF_LINK addresses can be looked up directly by their index number,	 * so do that if we can.	 */	if (af == AF_LINK) {	    register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;	    if (sdl->sdl_index && sdl->sdl_index <= if_index)		return (ifnet_addrs[sdl->sdl_index - 1]);	}	/*	 * Scan though each interface, looking for ones that have	 * addresses in this address family.	 */	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {		for (ifa = ifp->if_addrhead.tqh_first; ifa;		     ifa = ifa->ifa_link.tqe_next) {			register char *cp, *cp2, *cp3;			if (ifa->ifa_addr->sa_family != af)next:				continue;			if (#ifdef INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */			    addr->sa_family != AF_INET6 &&#endif			    ifp->if_flags & IFF_POINTOPOINT) {				/*				 * This is a bit broken as it doesn't				 * take into account that the remote end may				 * be a single node in the network we are				 * looking for.				 * The trouble is that we don't know the				 * netmask for the remote end.				 */				if (ifa->ifa_dstaddr != 0				    && equal(addr, ifa->ifa_dstaddr)) 					return (ifa);			} else {				/*				 * if we have a special address handler,				 * then use it instead of the generic one.				 */	          		if (ifa->ifa_claim_addr) {					if ((*ifa->ifa_claim_addr)(ifa, addr)) {						return (ifa);					} else {						continue;					}				}				/*				 * Scan all the bits in the ifa's address.				 * If a bit dissagrees with what we are				 * looking for, mask it with the netmask				 * to see if it really matters.				 * (A byte at a time)				 */				if (ifa->ifa_netmask == 0)					continue;				cp = addr_data;				cp2 = ifa->ifa_addr->sa_data;				cp3 = ifa->ifa_netmask->sa_data;				cplim = ifa->ifa_netmask->sa_len					+ (char *)ifa->ifa_netmask;				while (cp3 < cplim)					if ((*cp++ ^ *cp2++) & *cp3++)						goto next; /* next address! */				/*				 * If the netmask of what we just found				 * is more specific than what we had before				 * (if we had one) then remember the new one				 * before continuing to search				 * for an even better one.				 */				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 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 (0);	for (ifa = ifp->if_addrhead.tqh_first; ifa;	     ifa = ifa->ifa_link.tqe_next) {		if (ifa->ifa_addr->sa_family != af)			continue;		if (ifa_maybe == 0)			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;		}		if (ifp->if_flags & IFF_POINTOPOINT) {			if (equal(addr, ifa->ifa_dstaddr))				return (ifa);		} else {			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. */static 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;	ifa = ifaof_ifpforaddr(dst, ifp);	if (ifa) {		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 splnet or eqivalent. */voidif_unroute(ifp, flag, fam)	register struct ifnet *ifp;	int flag, fam;{	register struct ifaddr *ifa;	ifp->if_flags &= ~flag;	getmicrotime(&ifp->if_lastchange);	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)		if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))			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 splnet or eqivalent. */voidif_route(ifp, flag, fam)	register struct ifnet *ifp;	int flag, fam;{	register struct ifaddr *ifa;	ifp->if_flags |= flag;	getmicrotime(&ifp->if_lastchange);	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)		if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))			pfctlinput(PRC_IFUP, ifa->ifa_addr);	rt_ifmsg(ifp);#ifdef INET6	in6_if_up(ifp);#endif}/* * Mark an interface down and notify protocols of * the transition. * NOTE: must be called at splnet or eqivalent. */voidif_down(ifp)	register struct ifnet *ifp;{	if_unroute(ifp, IFF_UP, AF_UNSPEC);}/* * Mark an interface up and notify protocols of * the transition. * NOTE: must be called at splnet or eqivalent. */voidif_up(ifp)	register struct ifnet *ifp;{	if_route(ifp, IFF_UP, AF_UNSPEC);}/* * Flush an interface queue. */static voidif_qflush(ifq)#ifdef ALTQ	struct ifaltq *ifq;#else	register struct ifqueue *ifq;#endif{	register struct mbuf *m, *n;#ifdef ALTQ	if (ALTQ_IS_ENABLED(ifq))		ALTQ_PURGE(ifq);#endif	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.tqh_first; ifp; ifp = ifp->if_link.tqe_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(const char *name){	char namebuf[IFNAMSIZ + 1];	const char *cp;	struct ifnet *ifp;	int unit;	unsigned len, m;	char c;	len = strlen(name);	if (len < 2 || len > IFNAMSIZ)		return NULL;	cp = name + len - 1;	c = *cp;	if (c < '0' || c > '9')		return NULL;		/* trailing garbage */	unit = 0;	m = 1;	do {		if (cp == name)			return NULL;	/* no interface name */		unit += (c - '0') * m;		if (unit > 1000000)			return NULL;	/* number is unreasonable */		m *= 10;		c = *--cp;	} while (c >= '0' && c <= '9');	len = cp - name + 1;	bcopy(name, namebuf, len);	namebuf[len] = '\0';	/*	 * Now search all the interfaces for this name/number	 */	for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {		if (strcmp(ifp->if_name, namebuf))			continue;		if (unit == ifp->if_unit)			break;	}	return (ifp);}/* * 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);}// TEMP?#define _NAME(s) \  case s: return #s; break; char *_ioctl_name(u_long cmd){    static char unknown[32];    switch (cmd) {        _NAME(SIOCSHIWAT);        _NAME(SIOCGHIWAT);        _NAME(SIOCSLOWAT);        _NAME(SIOCGLOWAT);        _NAME(SIOCATMARK);        _NAME(SIOCSPGRP);        _NAME(SIOCGPGRP);        _NAME(SIOCADDRT);        _NAME(SIOCDELRT);//_NAME(SIOCGETVIFCNT);//_NAME(SIOCGETSGCNT);        _NAME(SIOCSIFADDR);        _NAME(OSIOCGIFADDR);        _NAME(SIOCGIFADDR);        _NAME(SIOCSIFDSTADDR);        _NAME(OSIOCGIFDSTADDR);        _NAME(SIOCGIFDSTADDR);        _NAME(SIOCSIFFLAGS);        _NAME(SIOCGIFFLAGS);        _NAME(OSIOCGIFBRDADDR);        _NAME(SIOCGIFBRDADDR);        _NAME(SIOCSIFBRDADDR);        _NAME(OSIOCGIFCONF);        _NAME(SIOCGIFCONF);        _NAME(OSIOCGIFNETMASK);        _NAME(SIOCGIFNETMASK);        _NAME(SIOCSIFNETMASK);        _NAME(SIOCGIFMETRIC);        _NAME(SIOCSIFMETRIC);        _NAME(SIOCDIFADDR);        _NAME(SIOCAIFADDR);        _NAME(SIOCALIFADDR);        _NAME(SIOCGLIFADDR);        _NAME(SIOCDLIFADDR);        _NAME(SIOCADDMULTI);        _NAME(SIOCDELMULTI);        _NAME(SIOCGIFMTU);        _NAME(SIOCSIFMTU);        _NAME(SIOCGIFPHYS);        _NAME(SIOCSIFPHYS);        _NAME(SIOCSIFMEDIA);        _NAME(SIOCGIFMEDIA);        _NAME(SIOCSIFPHYADDR  );        _NAME(SIOCGIFPSRCADDR);        _NAME(SIOCGIFPDSTADDR);        _NAME(SIOCDIFPHYADDR);        _NAME(SIOCSLIFPHYADDR);        _NAME(SIOCGLIFPHYADDR);        _NAME(SIOCSIFGENERIC);        _NAME(SIOCGIFGENERIC);        _NAME(SIOCGIFSTATUS);        _NAME(SIOCSIFLLADDR);        _NAME(SIOCIFCREATE);        _NAME(SIOCIFDESTROY);        _NAME(SIOCIFGCLONERS);        _NAME(FIONBIO);        _NAME(FIOASYNC);        _NAME(FIONREAD);        _NAME(SIOCGIFHWADDR);        _NAME(SIOCSIFHWADDR);        _NAME(SIOCGIFSTATSUD);        _NAME(SIOCGIFSTATS);    default:        diag_sprintf(unknown, "0x%08x", cmd);        return unknown;    }}// TEMP?/* * 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;	struct ifstat *ifs;	int error;	short oif_flags;        log(LOG_IOCTL, "%s: cmd: %s, data:\n", __FUNCTION__, _ioctl_name(cmd));	switch (cmd) {	case SIOCGIFCONF:	case OSIOCGIFCONF:		return (ifconf(cmd, data));	}	ifr = (struct ifreq *)data;	switch (cmd) {	case SIOCIFCREATE:	case SIOCIFDESTROY:		return ((cmd == SIOCIFCREATE) ?			if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :			if_clone_destroy(ifr->ifr_name));		case SIOCIFGCLONERS:		return (if_clone_list((struct if_clonereq *)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:		ifr->ifr_prevflags = ifp->if_flags;		if (ifp->if_flags & IFF_SMART) {			/* Smart drivers twiddle their own routes */		} else if (ifp->if_flags & IFF_UP &&		    (ifr->ifr_flags & IFF_UP) == 0) {			int s = splimp();			if_down(ifp);			splx(s);

⌨️ 快捷键说明

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