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

📄 if.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Mark an interface down and notify protocols of * the transition. Change routes. * NOTE: must be called at splnet or eqivalent. */if_down(ifp)	register struct ifnet *ifp;{	register struct ifaddr *ifa;	ifp->if_flags &= ~IFF_UP;	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {		pfctlinput(PRC_ROUTEDEAD, (caddr_t)&ifa->ifa_addr);	}}/* * Handle interface watchdog timer routines.  Called * from softclock, we decrement timers (if set) and * call the appropriate interface routine on expiration. */if_slowtimo(){	register struct ifnet *ifp;	int saveaffinity;	for (ifp = ifnet; ifp; ifp = ifp->if_next) {		if (ifp->if_timer == 0 || --ifp->if_timer)			continue;		if (ifp->if_watchdog){			CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);			(*ifp->if_watchdog)(ifp->if_unit);			RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);		}	}	timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);}/* * Map interface name to * interface structure pointer. */struct ifnet *ifunit(name)	register char *name;{	register char *cp, *cp2;	register struct ifnet *ifp;	int unit;	for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)		if (*cp >= '0' && *cp <= '9')			break;	if (*cp == '\0' || cp == name + IFNAMSIZ)		return ((struct ifnet *)0);	for (unit = 0, cp2 = cp; cp2 < name + IFNAMSIZ && *cp2; cp2++)		unit = unit * 10 + (*cp2 - '0');	for (ifp = ifnet; ifp; ifp = ifp->if_next) {	        if ((unsigned)(cp - name) != strlen(ifp->if_name))		        continue;		/*		 * Following lines for se/ln compatibility		 */		if (((unsigned)(cp - name) == 2) && (!bcmp(name, "se", 2))) {			if (bcmp(ifp->if_name, "ln", 2))				continue;		} else {			if (bcmp(ifp->if_name, name, (unsigned)(cp - name)))				continue;		}		if (unit == ifp->if_unit)			break;	}	return (ifp);}/* *  From an ifp, generate the name of an interface. */ifname(ifp, name)    struct ifnet *ifp;    char *name;{    register int i = 0, unit = ifp->if_unit;    char digits[6], *p = ifp->if_name;    /*     *  Copy the interfaces base name (assume everythings ok).     */    while (*p)	*name++ = *p++;    /*     *  Calculate the unit's digits in reverse order.     */    do {	digits[i++] = (unit % 10) + '0';	unit = unit/10;    } while (unit);    /*     * Append the digits in reverse order.  This will     * result in a correct number.     */    while (i--)	*name++ = digits[i];    *name = '\0';}/* * Interface ioctls. */ifioctl(so, cmd, data)	struct socket *so;	int cmd;	caddr_t data;{	register struct ifnet *ifp;	register struct ifreq *ifr;	int saveaffinity;	int error;	int s;	int owner = 0; /* SMP */	switch (cmd) {	case SIOCSCREENON:	case SIOCSCREEN:	case SIOCSCREENSTATS:		return(screen_control(so, cmd, data, (struct ifnet *)0));	case SIOCGIFCONF:		if (smp_owner(&so->lk_socket)){			smp_unlock(&so->lk_socket);			owner=1;		}		error = ifconf(cmd,data);		if (owner) {			SO_LOCK(so);		}		return (error);#if defined(INET) && ( NETHER > 0 || NFDDI > 0)	case SIOCSARP:	case SIOCDARP:		if (!suser())			return (u.u_error);		/* FALL THROUGH */	case SIOCGARP:		return (arpioctl(cmd, data));#endif	}	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 SIOCSIFFLAGS:		if (!suser())			return (u.u_error);		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {			s = splnet();			/*			 * must obey lock ordering			 */			if (smp_owner(&so->lk_socket)){			  so->ref = 32;			  owner = 1;			  smp_unlock(&so->lk_socket);			}			if_down(ifp);			if (owner){			  smp_lock(&so->lk_socket,LK_RETRY);			  so->ref = 0;			  owner = 0;			}			splx(s);		}		if ((ifr->ifr_flags & IFF_802HDR) &&		    (ifp->if_type == IFT_ETHER)) {			s = splnet();			ifp->if_type = IFT_ISO88023;			ifp->if_flags &= (IFF_NOTRAILERS|IFF_802HDR);			ifp->if_mtu = ETHERMTU - sizeof (struct llc);			splx(s);		}		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |			(ifr->ifr_flags &~ IFF_CANTCHANGE);		/* Note that we don't do an affinity flag check here as		 * an optimization where if set, we could go to the driver 		 * without unlocking.  The reason we do not do that here, 		 * is that so far, the network drivers can sleep for DECnet. 		 * When we eleminate sleeps in the drivers, we can delete the		 * owner check and unlocks here.		 */		if (smp_owner(&so->lk_socket)){			so->ref = 8;			owner = 1;			smp_unlock(&so->lk_socket);		}	        if (ifp->if_ioctl){			CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);			(void) (*ifp->if_ioctl)(ifp, cmd, data);			RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);		}		if (owner){			smp_lock(&so->lk_socket,LK_RETRY);			so->ref = 0;			owner = 0;		}		break;	case SIOCSIFMETRIC:		if (!suser())			return (u.u_error);		ifp->if_metric = ifr->ifr_metric;		break;        case SIOCENABLBACK:        case SIOCDISABLBACK:	case SIOCSPHYSADDR: 	case SIOCDELMULTI: 	case SIOCADDMULTI: 	case SIOCRDZCTRS:	case SIOCIFRESET:	case SIOCEEUPDATE:		if(!suser())			return(u.u_error);		/* FALL THROUGH */	case SIOCRDCTRS:        case SIOCRPHYSADDR: 		if (ifp->if_ioctl == 0)			return (EOPNOTSUPP);		if (smp_owner(&so->lk_socket)){			owner = 1;			so->ref = 8;			smp_unlock(&so->lk_socket);			}		CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);		error = (*ifp->if_ioctl)(ifp, cmd, data);		RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);		if (owner){			smp_lock(&so->lk_socket,LK_RETRY);			so->ref = 0;			owner = 0;			}		return(error);	case SIOCARPREQ:		if (suser())			if (nINET == 1)				return (arpwhohas(ifp,ifr->ifr_addr.sa_data));			else				return (ENETDOWN);		else			return (EACCES);	/*	 * protocol specific ioctls that must deal with the interface	 * are handled in the default case by the protocol specific	 * usrreq routine.	 */	default:  		if (so->so_proto == 0)  {			mprintf("ifioctl: no socket proto\n");			return (EOPNOTSUPP);		}		return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,			cmd, data, ifp));	}	return (0);}/* * Return interface configuration * of system.  List may be used * in later ioctl's (above) to get * other information. *//*ARGSUSED*/ifconf(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;	struct ifreq *u_sptr, *u_tmp ;	int space = ifc->ifc_len;	int space_tmp = ifc->ifc_len;	int s;	int error;	KM_ALLOC( u_sptr, struct ifreq *, space, KM_TEMP, KM_CLEAR);	u_tmp = u_sptr;	ifrp = ifc->ifc_req;	for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {		ifname(ifp, ifr.ifr_name);		if ((ifa = ifp->if_addrlist) == 0) {			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));			/* bcopy((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); */			bcopy((caddr_t)&ifr, (caddr_t)u_sptr, sizeof (ifr)); 			space -= sizeof (ifr), u_sptr++;		} else 		    for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {			ifr.ifr_addr = ifa->ifa_addr;			bcopy((caddr_t)&ifr, (caddr_t)u_sptr, sizeof (ifr));			space -= sizeof (ifr), u_sptr++;		}	}	error =copyout((caddr_t)u_tmp, (caddr_t)ifrp, ifc->ifc_len-space);	KM_FREE(u_tmp, KM_TEMP);	ifc->ifc_len -= space;	return (error);}

⌨️ 快捷键说明

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