📄 if.c
字号:
*pPtrIfp = (*pPtrIfp)->if_next; /* Notify MIB-II of change */ if (_m2IfTableUpdate) _m2IfTableUpdate(ifp, M2_IF_TABLE_REMOVE, 0, 0); break; } pPtrIfp = &(*pPtrIfp)->if_next; } splx (s); }/********************************************************************************* ifIndexToIfp - obtain the ifnet pointer from the index** This function obtains the ifnet pointer from the if_index.* The interface index is unique for every new interface added.* * NOMANUAL** RETURNS ifnet/NULL*/struct ifnet * ifIndexToIfp ( int ifIndex /* index of the interface to find */ ) { register struct ifnet * pIfp; int s; s = splnet (); /* traverse the list of ifnet structures in the system */#ifdef VIRTUAL_STACK for (pIfp = _ifnet; pIfp != NULL; pIfp = pIfp->if_next)#else for (pIfp = ifnet; pIfp != NULL; pIfp = pIfp->if_next)#endif { if (pIfp->if_index == ifIndex) break; } splx (s); return (pIfp); }/* * 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)#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_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 && 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;#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next) #else for (ifp = ifnet; ifp; ifp = ifp->if_next) #endif if (ifp->if_flags & IFF_POINTOPOINT) for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family != addr->sa_family) continue; if (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; if (af == AF_LINK) { register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; /* eliminated need for ifnet_addrs array*/ if (ifIndexTest(sdl->sdl_index)) { ifp = ifIndexToIfp (sdl->sdl_index); if (ifp == NULL) { logMsg("ifa_ifwithnet: NULL ifp for index:%d\n", (int)sdl->sdl_index, 0, 0, 0, 0, 0); return(NULL); } for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next) if (ifa->ifa_addr->sa_family == af) break; return (ifa); } }#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { register char *cp, *cp2, *cp3; if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0) next: 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; 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;#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) if (ifa->ifa_addr->sa_family == af) return (ifa); return ((struct ifaddr *)0);}/* * 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_addrlist; ifa; ifa = ifa->ifa_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);}/* * Find an interface address for a specified destination or gateway */struct ifaddr *ifa_ifwithroute(flags, dst, gateway) int flags; struct sockaddr *dst, *gateway;{ register struct ifaddr *ifa; if ((flags & RTF_GATEWAY) == 0) { /* * If we are adding a route to an interface, * and the interface is a pt to pt link * we should search for the destination * as our clue to the interface. Otherwise * we can use the local address. */ ifa = 0; if (flags & RTF_HOST) ifa = ifa_ifwithdstaddr(dst); if (ifa == 0) ifa = ifa_ifwithaddr(gateway); } else { /* * If we are adding a route to a remote net * or host, the gateway may still be on the * other end of a pt to pt link. */ ifa = ifa_ifwithdstaddr(gateway); } if (ifa == 0) ifa = ifa_ifwithnet(gateway); if (ifa == 0) { struct rtentry *rt = rtalloc1(dst, 0); if (rt == 0) return (0); rt->rt_refcnt--; if ((ifa = rt->rt_ifa) == 0) return (0); } if (ifa->ifa_addr->sa_family != dst->sa_family) { struct ifaddr *oifa = ifa; ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); if (ifa == 0) ifa = oifa; } return (ifa);}/* free the interface address */voidifafree(ifa) register struct ifaddr *ifa;{ if (ifa == NULL) { #ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_EMERGENCY event */ WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 0, 1, WV_NETEVENT_IFAFREE_PANIC)#endif /* INCLUDE_WVNET */#endif panic("ifafree"); } if (ifa->ifa_refcnt == 0) { FREE(ifa, MT_IFADDR); } else ifa->ifa_refcnt--;}/* * 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)) {/* XXX - This event does not occur because this routine is never called * by the existing network stack. It is always replaced with the * arp_rtrequest routine for all Ethernet devices. #ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /@ WV_NET_WARNING event @/ WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_WARNING, 0, 5, WV_NETEVENT_LINKRTREQ_FAIL)#endif /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */ return; } if ((ifa = ifaof_ifpforaddr(dst, ifp))) { 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_down(ifp) register struct ifnet *ifp;{ register struct ifaddr *ifa;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 4, 12, WV_NETEVENT_IFDOWN_START, ifp)#endif /* INCLUDE_WVNET */#endif ifp->if_flags &= ~IFF_UP; for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) pfctlinput(PRC_IFDOWN, ifa->ifa_addr); if_qflush(&ifp->if_snd); if (rtIfaceMsgHook) (*rtIfaceMsgHook) (ifp);}/* * Mark an interface up and notify protocols of * the transition. * NOTE: must be called at splnet or equivalent. */voidif_up(ifp) register struct ifnet *ifp;{#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_VERBOSE event */ WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_VERBOSE, 5, 13, WV_NETEVENT_IFUP_START, ifp)#endif /* INCLUDE_WVNET */#endif ifp->if_flags |= IFF_UP;#ifdef notyet { register struct ifaddr *ifa; /* this has no effect on IP, and will kill all ISO connections XXX */ for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) pfctlinput(PRC_IFUP, ifa->ifa_addr); }#endif if (rtIfaceMsgHook) (*rtIfaceMsgHook) (ifp);}/* * Flush an interface queue. */voidif_qflush(ifq) register struct ifqueue *ifq;{ register struct mbuf *m, *n; n = ifq->ifq_head; while ((m = n)) { n = m->m_act; m_freem(m); } ifq->ifq_head = 0; ifq->ifq_tail = 0; ifq->ifq_len = 0;}void if_slowtimoRestart ( int stackNum ) { netJobAdd ((FUNCPTR)if_slowtimo, stackNum, 0, 0, 0, 0); }/* * Handle interface watchdog timer routines. Called * from softclock, we decrement timers (if set) and * call the appropriate interface routine on expiration. */void if_slowtimo (#ifdef VIRTUAL_STACK int stackNum#endif /* VIRTUAL_STACK */ ) { register struct ifnet *ifp; int s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -