📄 iflib.c
字号:
int code, /* ioctl function code */ int arg /* some argument */ ) { int status; int hostAddr; switch ((u_int) code) { case SIOCAIFADDR: case SIOCDIFADDR: case SIOCSIFADDR: case SIOCSIFBRDADDR: case SIOCSIFDSTADDR: /* verify Internet address is in correct format */ if ((hostAddr = (int) inet_addr ((char *)arg)) == ERROR && (hostAddr = hostGetByName ((char *)arg)) == ERROR) { return (ERROR); } status = ifIoctlSet (interfaceName, code, hostAddr); break; case SIOCSIFNETMASK: case SIOCSIFFLAGS: case SIOCSIFMETRIC: status = ifIoctlSet (interfaceName, code, arg); break; case SIOCGIFNETMASK: case SIOCGIFFLAGS: case SIOCGIFADDR: case SIOCGIFBRDADDR: case SIOCGIFDSTADDR: case SIOCGIFMETRIC: status = ifIoctlGet (interfaceName, code, (int *)arg); break; default: (void)errnoSet (EOPNOTSUPP); /* not supported operation */ status = ERROR; break; } return (status); }/********************************************************************************* ifIoctlSet - configure network interface** RETURNS: OK or ERROR*/LOCAL STATUS ifIoctlSet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int code, /* network interface ioctl function code */ int val /* value to be changed */ ) { struct ifreq ifr; strncpy (ifr.ifr_name, interfaceName, sizeof (ifr.ifr_name)); switch ((u_int) code) { case SIOCSIFFLAGS: ifr.ifr_flags = (short) val; break; case SIOCSIFMETRIC: ifr.ifr_metric = val; break; default: bzero ((caddr_t) &ifr.ifr_addr, sizeof (ifr.ifr_addr)); ifr.ifr_addr.sa_len = sizeof (struct sockaddr_in); ifr.ifr_addr.sa_family = AF_INET; ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = val; break; } return (ifIoctlCall (code, &ifr)); }/********************************************************************************* ifIoctlGet - retrieve information about the network interface** RETURNS: OK or ERROR*/LOCAL STATUS ifIoctlGet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int code, /* network interface ioctl function code */ int *val /* where to return result */ ) { struct ifreq ifr; strncpy (ifr.ifr_name, interfaceName, sizeof (ifr.ifr_name)); if (ifIoctlCall (code, &ifr) == ERROR) return (ERROR); switch ((u_int) code) { case SIOCGIFFLAGS: *val = ifr.ifr_flags; break; case SIOCGIFMETRIC: *val = ifr.ifr_metric; break; default: *val = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr; break; } return (OK); }/********************************************************************************* ifIoctlCall - make ioctl call to socket layer** ifIoctlCall creates a dummy socket to get access to the socket layer* ioctl routines in order to manipulate the interface specific* configurations.** RETURNS: OK or ERROR*/LOCAL STATUS ifIoctlCall ( int code, /* ioctl code */ struct ifreq *ifrp /* pointer to the interface ioctl request */ ) { int so; int status; if ((so = socket (AF_INET, SOCK_RAW, 0)) < 0) return (ERROR); status = ioctl (so, code, (int)ifrp); (void)close (so); if (status != 0) { if (status != ERROR) /* iosIoctl() can return ERROR */ (void)errnoSet (status); return (ERROR); } return (OK); }/********************************************************************************* ifRouteDelete - delete routes associated with a network interface** This routine deletes all routes that have been associated with the* specified interface. A route is associated with an interface if its * destination equals to the assigned address, or network number. This routine* does not remove routes to arbitrary destinations that through the* given interface.*** INTERNAL* This function only works for address families AF_INET** RETURNS:* The number of routes deleted, or ERROR if an interface is not specified.*/int ifRouteDelete ( char *ifName, /* name of the interface */ int unit /* unit number for this interface */ ) { FAST struct ifnet *ifp; FAST struct ifaddr *ifa; FAST struct in_ifaddr *ia = 0; int deleted; struct sockaddr_in inetAddr; if (ifName == NULL) return (ERROR); deleted = 0;#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif /* VIRTUAL_STACK */ { if (ifp->if_unit != unit || strcmp(ifName, ifp->if_name)) continue; for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { /* skip if address family does not belong to AF_INET */ if (ifa->ifa_addr->sa_family != AF_INET) continue; /* * Every element in the if_addrlist (type struct ifaddr) with * family AF_INET is actually the first part of a larger * in_ifaddr structure which includes the subnet mask. Access * that structure to use the mask value. */ ia = (struct in_ifaddr *) ifa; /* * The following is a sanity test. */#ifdef ROUTER_STACK /* UNNUMBERED_SUPPORT */ /* * This test is to prevent an ipDetach on an unnumbered interface * from removing the routes generated by the real interface if that * interface is still up. See ifUnnumberedSet for the definition * of "real interface." */ if (ifa == ifa_ifwithaddr (ifa->ifa_addr))#endif /* ROUTER_STACK */ { if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_addr)-> sin_addr.s_addr, 0, 0xffffffff, 0, RTF_HOST, M2_ipRouteProto_local) == OK) ++deleted; inetAddr.sin_addr.s_addr = htonl (ia->ia_subnetmask) & ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_addr)-> sin_addr.s_addr, 0, htonl(ia->ia_subnetmask), 0, 0, M2_ipRouteProto_local) == OK) ++deleted; } if (ifp->if_flags & (IFF_POINTOPOINT|IFF_UNNUMBERED)) { if (mRouteEntryDelete (((struct sockaddr_in*)ifa->ifa_dstaddr)-> sin_addr.s_addr, ((struct sockaddr_in*)ifa->ifa_addr)-> sin_addr.s_addr, 0x0, 0, RTF_HOST, M2_ipRouteProto_local) == OK) ++deleted;#ifdef ROUTER_STACK /* UNNUMBERED_SUPPORT */ else { _arpCmd (SIOCDARP, &(((struct sockaddr_in *) ifa->ifa_dstaddr)->sin_addr), NULL, NULL); deleted++; }#endif /* ROUTER_STACK */ } } } return (deleted); }/********************************************************************************* routeNodeDelete - delete the route associated with the network interface** This routine deletes the route that has been associated with the* specified interface. Only the following route is deleted:* \ml * \m -* the network route added when the interface address is initialized* \m -* the static route added by the administrator that passes through the interface* \m -* ARP routes passing through the interface* \me* * Routes added by routing protocols are not deleted.* For the Router stack, this routine first scans all duplicate routes* to determine which ones need to be deleted, and then processes the primary* route. This special handling is needed because the way the duplicate* routes are organized, deleting the primary route first might lead* to memory corruption.** INTERNAL* This function only works for address families AF_INET** RETURNS:* 0*/LOCAL int routeNodeDelete ( struct radix_node * pRoute, /* pointer to the node structure */ void * pArg /* pointer to the interface */ ) { struct ifnet * ifp = (struct ifnet *)((int *)pArg)[0]; int type = ((int *)pArg)[1]; int * pDeleted = (int *)((int *)pArg)[2]; struct rtentry * pRt; FAST struct sockaddr * destAddr = NULL; FAST struct sockaddr * gateAddr; char aStr [INET_ADDR_LEN];#ifdef ROUTER_STACK ROUTE_ENTRY * pHead; ROUTE_ENTRY * pDiffSave; ROUTE_ENTRY * pSameSave; ROUTE_ENTRY * pNext;#endif /* ROUTER_STACK */ pRt = (struct rtentry *)pRoute; destAddr = rt_key(pRt); /* get the destination address */ gateAddr = pRt->rt_gateway; /* get the gateway address */#ifdef DEBUG inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr); logMsg ("routeNodeDelete: Called for %s, if=%s%d, proto=%d, type = %s\n", (int)aStr, (int)(pRt->rt_ifp->if_name), pRt->rt_ifp->if_unit, RT_PROTO_GET (destAddr), (int)(type == RT_ARP ? "ARP" : "NON_ARP"), 0); #endif /* DEBUG */ /* Just return if it is an ARP entry and we are not interested in it */ if (type != RT_ARP && ((pRt->rt_flags & RTF_HOST) && (pRt->rt_flags & RTF_LLINFO) && (pRt->rt_flags & RTF_GATEWAY) == 0 && gateAddr && (gateAddr->sa_family == AF_LINK))) return(0); /* Just return if we want an ARP entry, but this is not */ if (type == RT_ARP && !((pRt->rt_flags & RTF_HOST) && (pRt->rt_flags & RTF_LLINFO) && (pRt->rt_flags & RTF_GATEWAY) == 0 && gateAddr && (gateAddr->sa_family == AF_LINK))) return(0); /* * If it is an ARP entry and it passes through the interface, * delete the ARP entry */ if ((pRt->rt_flags & RTF_HOST) && (pRt->rt_flags & RTF_LLINFO) && (pRt->rt_flags & RTF_GATEWAY) == 0 && gateAddr && (gateAddr->sa_family == AF_LINK)) { if(pRt->rt_ifp == ifp) { inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);#ifdef DEBUG logMsg ("routeNodeDelete: deleting ARP entry for %s\n", (int)aStr,0,0,0,0,0); #endif /* DEBUG */ _arpCmd (SIOCDARP, &((struct sockaddr_in *)destAddr)->sin_addr, NULL, NULL); /* Increment the deletion counter */ ++(*pDeleted); } return (0); }#ifdef ROUTER_STACK /* * Because of the way the duplicate route list is managed, we need to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -