📄 iflib.c
字号:
STATUS ifFlagChange ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int flags, /* the flag to be changed */ BOOL on /* TRUE=turn on, FALSE=turn off */ ) { int oldFlags; if (ifFlagGet (interfaceName, &oldFlags) == ERROR) { return (ERROR); } if (on) oldFlags |= flags; else oldFlags &= ~flags; return (ifFlagSet (interfaceName, oldFlags)); }/********************************************************************************* ifFlagSet - specify the flags for a network interface** This routine changes the flags for a specified network interface.* Any combination of the following flags can be specified:** .iP "IFF_UP (0x1)" 20* Brings the network up or down.* .iP "IFF_DEBUG (0x4)"* Turns on debugging for the driver interface if supported.* .iP "IFF_LOOPBACK (0x8)"* Set for a loopback network.* .iP "IFF_NOTRAILERS (0x20)"* Always set (VxWorks does not use the trailer protocol).* .iP "IFF_PROMISC (0x100)"* Tells the driver to accept all packets, not just broadcast packets and* packets addressed to itself. * .iP "IFF_ALLMULTI (0x200)"* Tells the driver to accept all multicast packets.* .iP "IFF_NOARP (0x80)"* Disables ARP for the interface.* .LP** NOTE* The following flags can only be set at interface initialization time.* Specifying these flags does not change any settings in the interface* data structure.** .iP "IFF_POINTOPOINT (0x10)" 20* Identifies a point-to-point interface such as PPP or SLIP.* .iP "IFF_RUNNING (0x40)"* Set when the device turns on.* .iP "IFF_BROADCAST (0x2)"* Identifies a broadcast interface.* .LP** RETURNS: OK or ERROR.** SEE ALSO: ifFlagChange(), ifFlagGet()*/STATUS ifFlagSet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int flags /* network flags */ ) { return (ifIoctl (interfaceName, SIOCSIFFLAGS, flags)); }/********************************************************************************* ifFlagGet - get the network interface flags** This routine gets the flags for a specified network interface.* The flags are copied to the buffer <flags>.** RETURNS: OK or ERROR.** SEE ALSO: ifFlagSet()*/STATUS ifFlagGet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int *flags /* network flags returned here */ ) { return (ifIoctl (interfaceName, SIOCGIFFLAGS, (int)flags)); }/********************************************************************************* ifMetricSet - specify a network interface hop count** This routine configures <metric> for a network interface from the host* machine to the destination network. This information is used primarily by* the IP routing algorithm to compute the relative distance for a collection* of hosts connected to each interface. For example, a higher <metric> for* SLIP interfaces can be specified to discourage routing a packet to slower* serial line connections. Note that when <metric> is zero, the IP routing* algorithm allows for the direct sending of a packet having an IP network* address that is not necessarily the same as the local network address.** RETURNS: OK or ERROR.** SEE ALSO: ifMetricGet()*/STATUS ifMetricSet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int metric /* metric for this interface */ ) { return (ifIoctl (interfaceName, SIOCSIFMETRIC, metric)); }/********************************************************************************* ifMetricGet - get the metric for a network interface** This routine retrieves the metric for a specified network interface.* The metric is copied to the buffer <pMetric>.** RETURNS: OK or ERROR.** SEE ALSO: ifMetricSet()*/STATUS ifMetricGet ( char *interfaceName, /* name of the network interface, i.e. ei0 */ int *pMetric /* returned interface's metric */ ) { return (ifIoctl (interfaceName, SIOCGIFMETRIC, (int)pMetric)); }/********************************************************************************* ifIoctl - network interface ioctl front-end** Used to manipulate the characteristics of network interfaces* using socket specific ioctl functions SIOCSIFADDR, SIOCSIFBRDADDR, etc.* ifIoctl() accomplishes this by calling ifIoctlSet() and ifIoctlGet().** RETURNS: OK or ERROR*/LOCAL STATUS ifIoctl ( char *interfaceName, /* name of the interface, i.e. ei0 */ int code, /* ioctl function code */ int arg /* some argument */ ) { int status; int hostAddr; switch (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 (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 (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 which pass 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; char a_ip_dest[ INET_ADDR_LEN ]; char a_ip_gateway[ INET_ADDR_LEN ]; if (ifName == NULL) return (ERROR); deleted = 0; for (ifp = ifnet; ifp; ifp = ifp->if_next) { if (ifp->if_unit != unit || strcmp(ifName, ifp->if_name)) continue; /* * Find address for this interface, if it exists. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) if (ia->ia_ifp == ifp) break; 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; if (mRouteDelete (ifInetAddrToStr (ifa->ifa_addr,a_ip_dest), 0xffffffff, 0, RTF_HOST) == OK) ++deleted; inetAddr.sin_addr.s_addr = htonl (ia->ia_subnetmask) & ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; if (mRouteDelete (ifInetAddrToStr (&inetAddr,a_ip_dest), ia->ia_subnetmask, 0, 0) == OK) ++deleted; if (ifp->if_flags & IFF_POINTOPOINT) { if (routeDelete (ifInetAddrToStr (ifa->ifa_dstaddr,a_ip_dest), ifInetAddrToStr (ifa->ifa_addr,a_ip_gateway)) == OK) ++deleted; } } } return (deleted); }/********************************************************************************* ifunit - map an interface name to an interface structure pointer** This routine returns a pointer to a network interface structure for <name> or* NULL if no such interface exists. For example:* .CS* struct ifnet *pIf;* ...* pIf = ifunit ("ln0");* .CE* `pIf' points to the data structure that describes the first network interface* device if ln0 is mapped successfully.** RETURNS:* A pointer to the interface structure, or NULL if an interface is not* found.** SEE ALSO: etherLib*/struct ifnet *ifunit ( register char *ifname /* name of the interface */ ) { register char *cp; register struct ifnet *ifp; int unit; unsigned len; char *ep, c; char name [IFNAMSIZ]; strncpy (name, ifname, IFNAMSIZ); for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) if (*cp >= '0' && *cp <= '9') break; if (*cp == '\0' || cp == name + IFNAMSIZ) return ((struct ifnet *)0); /* * Save first char of unit, and pointer to it, * so we can put a null there to avoid matching * initial substrings of interface names. */ len = cp - name + 1; c = *cp; ep = cp; for (unit = 0; *cp >= '0' && *cp <= '9'; ) unit = unit * 10 + *cp++ - '0'; *ep = 0; for (ifp = ifnet; ifp; ifp = ifp->if_next) { if (bcmp(ifp->if_name, name, len)) continue; if (unit == ifp->if_unit) break; } *ep = c; return (ifp); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -