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

📄 sys-next.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 3 页
字号:
{    int len;    if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) {	if (errno == EWOULDBLOCK || errno == EINTR) {	    SYSDEBUG(("read: %m"));	    return -1;	}	fatal("read: %m");    }    return len;}/* * ppp_send_config - configure the transmit characteristics of * the ppp interface. */voidppp_send_config(unit, mtu, asyncmap, pcomp, accomp)    int unit, mtu;    u_int32_t asyncmap;    int pcomp, accomp;{    u_int x;    struct ifreq ifr;    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    ifr.ifr_mtu = mtu;    if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0)	fatal("ioctl(SIOCSIFMTU): %m");    if (ioctl(ttyfd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0)	fatal("ioctl(PPPIOCSASYNCMAP): %m");    if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCGFLAGS): %m");    x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT;    x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC;    if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCSFLAGS): %m");}/* * ppp_set_xaccm - set the extended transmit ACCM for the interface. */voidppp_set_xaccm(unit, accm)    int unit;    ext_accm accm;{    if (ioctl(ttyfd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY)	warn("ioctl(PPPIOCSXASYNCMAP): %m");}/* * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. */voidppp_recv_config(unit, mru, asyncmap, pcomp, accomp)    int unit, mru;    u_int32_t asyncmap;    int pcomp, accomp;{    int x;    if (ioctl(ttyfd, PPPIOCSMRU, (caddr_t) &mru) < 0)	fatal("ioctl(PPPIOCSMRU): %m");    if (ioctl(ttyfd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0)	fatal("ioctl(PPPIOCSRASYNCMAP): %m");    if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCGFLAGS): %m");    x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;    if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	fatal("ioctl(PPPIOCSFLAGS): %m");}/* * ccp_test - ask kernel whether a given compression method * is acceptable for use. */intccp_test(unit, opt_ptr, opt_len, for_transmit)    int unit, opt_len, for_transmit;    u_char *opt_ptr;{    struct ppp_option_data data;    data.ptr = opt_ptr;    data.length = opt_len;    data.transmit = for_transmit;    if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)	return 1;    return (errno == ENOBUFS)? 0: -1;}/* * ccp_flags_set - inform kernel about the current state of CCP. */voidccp_flags_set(unit, isopen, isup)    int unit, isopen, isup;{    int x;    if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPPIOCGFLAGS): %m");	return;    }    x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN;    x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP;    if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0)	error("ioctl(PPPIOCSFLAGS): %m");}/* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, * 0 otherwise.  This is necessary because of patent nonsense. */intccp_fatal_error(unit)    int unit;{    int x;    if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPPIOCGFLAGS): %m");	return 0;    }    return x & SC_DC_FERROR;}/* * sifvjcomp - config tcp header compression */intsifvjcomp(u, vjcomp, cidcomp, maxcid)    int u, vjcomp, cidcomp, maxcid;{    u_int x;    if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPIOCGFLAGS): %m");	return 0;    }    x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP;    x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID;    if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {	error("ioctl(PPPIOCSFLAGS): %m");	return 0;    }    if (ioctl(ttyfd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {	error("ioctl(PPPIOCSFLAGS): %m");	return 0;    }    return 1;}/* * sifup - Config the interface up and enable IP packets to pass. */#ifndef SC_ENABLE_IP#define SC_ENABLE_IP	0x100	/* compat for old versions of kernel code */#endifintsifup(u)    int u;{    struct ifreq ifr;    u_int x;    struct npioctl npi;    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {	error("ioctl (SIOCGIFFLAGS): %m");	return 0;    }    ifr.ifr_flags |= IFF_UP;    if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {	error("ioctl(SIOCSIFFLAGS): %m");	return 0;    }    if_is_up = 1;    npi.protocol = PPP_IP;    npi.mode = NPMODE_PASS;    if (ioctl(ttyfd, PPPIOCSNPMODE, &npi) < 0) {	if (errno != ENOTTY) {	    error("ioctl(PPPIOCSNPMODE): %m");	    return 0;	}	/* for backwards compatibility */	if (ioctl(ttyfd, PPPIOCGFLAGS, (caddr_t) &x) < 0) {	    error("ioctl (PPPIOCGFLAGS): %m");	    return 0;	}	x |= SC_ENABLE_IP;	if (ioctl(ttyfd, PPPIOCSFLAGS, (caddr_t) &x) < 0) {	    error("ioctl(PPPIOCSFLAGS): %m");	    return 0;	}    }    return 1;}/* * sifdown - Config the interface down and disable IP. */intsifdown(u)    int u;{    struct ifreq ifr;    u_int x;    int rv;    struct npioctl npi;    rv = 1;    npi.protocol = PPP_IP;    npi.mode = NPMODE_ERROR;    ioctl(ttyfd, PPPIOCSNPMODE, (caddr_t) &npi);    /* ignore errors, because ttyfd might have been closed by now. */    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {	error("ioctl (SIOCGIFFLAGS): %m");	rv = 0;    } else {	ifr.ifr_flags &= ~IFF_UP;	if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {	    error("ioctl(SIOCSIFFLAGS): %m");	    rv = 0;	} else	    if_is_up = 0;    }    return rv;}/* * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, * if it exists. */#define SET_SA_FAMILY(addr, family)		\    BZERO((char *) &(addr), sizeof(addr));	\    addr.sa_family = (family); /* * sifaddr - Config the interface IP addresses and netmask. */intsifaddr(u, o, h, m)    int u;    u_int32_t o, h, m;{    int ret;    struct ifreq ifr;    ret = 1;    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));    SET_SA_FAMILY(ifr.ifr_addr, AF_INET);    ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;    if (ioctl(sockfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {	error("ioctl(SIOCAIFADDR): %m");	ret = 0;    }    ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h;    if (ioctl(sockfd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {	error("ioctl(SIOCSIFDSTADDR): %m");	ret = 0;    }    if (m != 0) {	((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m;	info("Setting interface mask to %s\n", ip_ntoa(m));	if (ioctl(sockfd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {	    error("ioctl(SIOCSIFNETMASK): %m");	    ret = 0;	}    }    return ret;}/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. * * N.B.: under NextStep, you can't *delete* an address on an interface, * so we change it to 0.0.0.0...  A real hack.  But it simplifies * reconnection on the server side. */intcifaddr(u, o, h)    int u;    u_int32_t o, h;{    struct rtentry rt;#if 1    h = o = 0L;    (void) sifaddr(u, o, h, 0L);#endif    SET_SA_FAMILY(rt.rt_dst, AF_INET);    ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h;    SET_SA_FAMILY(rt.rt_gateway, AF_INET);    ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o;    rt.rt_flags = RTF_HOST;    if (ioctl(sockfd, SIOCDELRT, (caddr_t) &rt) < 0) {	error("ioctl(SIOCDELRT): %m");	return 0;    }    return 1;}/* * sifdefaultroute - assign a default route through the address given. */intsifdefaultroute(u, l, g)    int u;    u_int32_t l, g;{    return dodefaultroute(g, 's');}/* * cifdefaultroute - delete a default route through the address given. */intcifdefaultroute(u, l, g)    int u;    u_int32_t l, g;{    return dodefaultroute(g, 'c');}/* * dodefaultroute - talk to a routing socket to add/delete a default route. */intdodefaultroute(g, cmd)    u_int32_t g;    int cmd;{    struct rtentry rt;    SET_SA_FAMILY(rt.rt_dst, AF_INET);    ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = 0L;    SET_SA_FAMILY(rt.rt_gateway, AF_INET);    ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;    rt.rt_flags = RTF_GATEWAY;    if (ioctl(sockfd, (cmd == 's') ? SIOCADDRT : SIOCDELRT, &rt) < 0) {	error("%cifdefaultroute: ioctl(%s): %m", cmd,	       (cmd == 's') ? "SIOCADDRT" : "SIOCDELRT");	return 0;    }    default_route_gateway = (cmd == 's')? g: 0;    return 1;}/* * sifproxyarp - Make a proxy ARP entry for the peer. */intsifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    struct arpreq arpreq;    BZERO(&arpreq, sizeof(arpreq));    /*     * Get the hardware address of an interface on the same subnet     * as our local address.     */    if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {	error("Cannot determine ethernet address for proxy ARP");	return 0;    }    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;    arpreq.arp_flags = ATF_PERM | ATF_PUBL;    if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {	error("ioctl(SIOCSARP): %m");	return 0;    }    proxy_arp_addr = hisaddr;    return 1;}/* * cifproxyarp - Delete the proxy ARP entry for the peer. */intcifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    struct arpreq arpreq;    BZERO(&arpreq, sizeof(arpreq));    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;    if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {	warn("ioctl(SIOCDARP): %m");	return 0;    }    proxy_arp_addr = 0;    return 1;}/* * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */#define MAX_IFS		32intget_ether_addr(ipaddr, hwaddr)    u_int32_t ipaddr;    struct sockaddr *hwaddr;{    struct ifreq *ifr, *ifend, *ifp;    u_int32_t ina, mask;    struct ether_addr dla;    struct ifreq ifreq;    struct ifconf ifc;    struct ifreq ifs[MAX_IFS];    struct hostent *hostent;    ifc.ifc_len = sizeof(ifs);    ifc.ifc_req = ifs;    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {	error("ioctl(SIOCGIFCONF): %m");	return 0;    }    /*     * Scan through looking for an interface with an Internet     * address on the same subnet as `ipaddr'.     */    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)		((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) {	if (ifr->ifr_addr.sa_family == AF_INET) {	    ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;	    strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));	    /*	     * Check that the interface is up, and not point-to-point	     * or loopback.	     */	    if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)		continue;	    if ((ifreq.ifr_flags &		 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))		 != (IFF_UP|IFF_BROADCAST))		continue;	    /*	     * Get its netmask and check that it's on the right subnet.	     */	    if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)		continue;	    mask = ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr;	    if ((ipaddr & mask) != (ina & mask))		continue;	    break;	}    }    if (ifr >= ifend)	return 0;    info("found interface %s for proxy arp", ifr->ifr_name);    /*     * Get the hostname and look for an entry using the ethers database.     * Under NeXTStep this is the best we can do for now.     */    if ((hostent = gethostbyaddr((char*)&ina, sizeof(ina), AF_INET)) == NULL)	return 0;    if (ether_by_host(hostent->h_name, &dla)) {	info("Add entry for %s in /etc/ethers", hostent->h_name);	return 0;	/* it's not there */    }    hwaddr->sa_family = AF_UNSPEC;    BCOPY(&dla, hwaddr->sa_data, sizeof(dla));    return 1;}static intether_by_host(hostname, etherptr)    char *hostname;    struct ether_addr *etherptr;{    struct ether_addr *thisptr;    void *conn;    ni_id root;    ni_namelist val;    char path[256];    if (!ether_hostton(hostname, etherptr))	return 0;    /*     * We shall now try and     * find the address in the     * top domain of netinfo.     */    slprintf(path, sizeof(path), "/machines/%s", hostname);    if (ni_open((void *)0, "/", &conn)     || ni_root(conn, &root)     || ni_pathsearch(conn, &root, path)     || ni_lookupprop(conn, &root, "en_address", &val))	return 1;    /*     * Now we can convert the returned string into an ethernet address.     */    strlcpy(path, val.ni_namelist_val[0], sizeof(path));    ni_free(conn);    if ((thisptr = (struct ether_addr*)ether_aton(path)) == NULL)	return 1;    BCOPY(thisptr, etherptr, sizeof(struct ether_addr));    return 0;}/* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'.  If we find any, we OR in their netmask to the * user-specified netmask. */u_int32_tGetMask(addr)    u_int32_t addr;{    u_int32_t mask, nmask, ina;    struct ifreq *ifr, *ifend, ifreq;    struct ifconf ifc;    struct ifreq ifs[MAX_IFS];    addr = ntohl(addr);    if (IN_CLASSA(addr))	/* determine network mask for address class */	nmask = IN_CLASSA_NET;    else if (IN_CLASSB(addr))	nmask = IN_CLASSB_NET;    else	nmask = IN_CLASSC_NET;    /* class D nets are disallowed by bad_ip_adrs */    mask = netmask | htonl(nmask);    /*

⌨️ 快捷键说明

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