?? sys-linux.c
字號(hào):
* sifvjcomp - config tcp header compression */int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid){ u_int x = get_flags(ppp_dev_fd); if (vjcomp) { if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { if (! ok_error (errno)) error("ioctl(PPPIOCSMAXCID): %m(%d)", errno); vjcomp = 0; } } x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP; x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID; set_flags (ppp_dev_fd, x); return 1;}/******************************************************************** * * sifup - Config the interface up and enable IP packets to pass. */int sifup(int u){ struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); return 0; } ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); return 0; } if_is_up++; return 1;}/******************************************************************** * * sifdown - Disable the indicated protocol and config the interface * down if there are no remaining protocols. */int sifdown (int u){ struct ifreq ifr; if (if_is_up && --if_is_up > 0) return 1; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); return 0; } ifr.ifr_flags &= ~IFF_UP; ifr.ifr_flags |= IFF_POINTOPOINT; if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); return 0; } return 1;}/******************************************************************** * * sifaddr - Config the interface IP addresses and netmask. */int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask){ struct ifreq ifr; struct rtentry rt; memset (&ifr, '\0', sizeof (ifr)); memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (ifr.ifr_addr, AF_INET); SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));/* * Set our IP address */ SIN_ADDR(ifr.ifr_addr) = our_adr; if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { if (errno != EEXIST) { if (! ok_error (errno)) error("ioctl(SIOCSIFADDR): %m(%d)", errno); } else { warn("ioctl(SIOCSIFADDR): Address already exists"); } return (0); }/* * Set the gateway address */ SIN_ADDR(ifr.ifr_dstaddr) = his_adr; if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); return (0); } /* * Set the netmask. * For recent kernels, force the netmask to 255.255.255.255. */ if (kernel_version >= KVERSION(2,1,16)) net_mask = ~0L; if (net_mask != 0) { SIN_ADDR(ifr.ifr_netmask) = net_mask; if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); return (0); } }/* * Add the device route */ if (kernel_version < KVERSION(2,1,16)) { SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; SIN_ADDR(rt.rt_gateway) = 0L; SIN_ADDR(rt.rt_dst) = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = -1L; } if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { if (! ok_error (errno)) error("ioctl(SIOCADDRT) device route: %m(%d)", errno); return (0); } } /* set ip_dynaddr in demand mode if address changes */ if (demand && tune_kernel && !dynaddr_set && our_old_addr && our_old_addr != our_adr) { /* set ip_dynaddr if possible */ char *path; int fd; path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { if (write(fd, "1", 1) != 1) error("Couldn't enable dynamic IP addressing: %m"); close(fd); } dynaddr_set = 1; /* only 1 attempt */ } our_old_addr = 0; return 1;}/******************************************************************** * * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr){ struct ifreq ifr; if (kernel_version < KVERSION(2,1,16)) {/* * Delete the route through the device */ struct rtentry rt; memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; SIN_ADDR(rt.rt_gateway) = 0; SIN_ADDR(rt.rt_dst) = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = -1L; } if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp() && ! ok_error (errno)) error("ioctl(SIOCDELRT) device route: %m(%d)", errno); return (0); } } /* This way it is possible to have an IPX-only or IPv6-only interface */ memset(&ifr, 0, sizeof(ifr)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) { error("ioctl(SIOCSIFADDR): %m(%d)", errno); return 0; } } our_old_addr = our_adr; return 1;}#ifdef INET6/******************************************************************** * * sif6addr - Config the interface with an IPv6 link-local address */int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64){ struct in6_ifreq ifr6; struct ifreq ifr; struct in6_rtmsg rt6; if (sock6_fd < 0) { errno = -sock6_fd; error("IPv6 socket creation failed: %m"); return 0; } memset(&ifr, 0, sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { error("sif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); return 0; } /* Local interface */ memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = 10; if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { error("sif6addr: ioctl(SIOCSIFADDR): %m (%d)", errno); return 0; } /* Route to remote host */ memset(&rt6, 0, sizeof(rt6)); IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); rt6.rtmsg_flags = RTF_UP; rt6.rtmsg_dst_len = 10; rt6.rtmsg_ifindex = ifr.ifr_ifindex; rt6.rtmsg_metric = 1; if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { error("sif6addr: ioctl(SIOCADDRT): %m (%d)", errno); return 0; } return 1;}/******************************************************************** * * cif6addr - Remove IPv6 address from interface */int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64){ struct ifreq ifr; struct in6_ifreq ifr6; if (sock6_fd < 0) { errno = -sock6_fd; error("IPv6 socket creation failed: %m"); return 0; } memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { error("cif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); return 0; } memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = 10; if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { if (errno != EADDRNOTAVAIL) { if (! ok_error (errno)) error("cif6addr: ioctl(SIOCDIFADDR): %m (%d)", errno); } else { warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); } return (0); } return 1;}#endif /* INET6 *//* * get_pty - get a pty master/slave pair and chown the slave side * to the uid given. Assumes slave_name points to >= 16 bytes of space.intget_pty(master_fdp, slave_fdp, slave_name, uid) int *master_fdp; int *slave_fdp; char *slave_name; int uid;{ int i, mfd, sfd = -1; char pty_name[16]; struct termios tios;#ifdef TIOCGPTN /* * Try the unix98 way first. */ mfd = open("/dev/ptmx", O_RDWR); if (mfd >= 0) { int ptn; if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); chmod(pty_name, S_IRUSR | S_IWUSR);#ifdef TIOCSPTLCK ptn = 0; if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) warn("Couldn't unlock pty slave %s: %m", pty_name);#endif if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) warn("Couldn't open pty slave %s: %m", pty_name); } }#endif /* TIOCGPTN */ if (sfd < 0) { /* the old way - scan through the pty name space */ for (i = 0; i < 64; ++i) { slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", 'p' + i / 16, i % 16); mfd = open(pty_name, O_RDWR, 0); if (mfd >= 0) { pty_name[5] = 't'; sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); if (sfd >= 0) { fchown(sfd, uid, -1); fchmod(sfd, S_IRUSR | S_IWUSR); break; } close(mfd); } } } if (sfd < 0) return 0; strlcpy(slave_name, pty_name, 16); *master_fdp = mfd; *slave_fdp = sfd; if (tcgetattr(sfd, &tios) == 0) { tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); tios.c_cflag |= CS8 | CREAD | CLOCAL; tios.c_iflag = IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) warn("couldn't set attributes on pty: %m"); } else warn("couldn't get attributes on pty: %m"); return 1;}/******************************************************************** * * open_loopback - open the device we use for getting packets * in demand mode. Under Linux, we use a pty master/slave pair. */intopen_ppp_loopback(void){ int flags; looped = 1; if (new_style_driver) { /* allocate ourselves a ppp unit */ if (make_ppp_unit() < 0) die(1); set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC); set_kdebugflag(kdebugflag); ppp_fd = -1; return ppp_dev_fd; } if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) fatal("No free pty for loopback"); SYSDEBUG(("using %s for loopback", loop_name)); set_ppp_fd(slave_fd); flags = fcntl(master_fd, F_GETFL); if (flags == -1 || fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set master loopback to nonblock: %m(%d)", errno); flags = fcntl(ppp_fd, F_GETFL); if (flags == -1 || fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set slave loopback to nonblock: %m(%d)", errno); if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) fatal("ioctl(TIOCSETD): %m(%d)", errno);/* * Find out which interface we were given. */ if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);/* * Enable debug in the driver if requested. */ set_kdebugflag (kdebugflag); return master_fd;}/******************************************************************** * * restore_loop - reattach the ppp unit to the loopback. * * The kernel ppp driver automatically reattaches the ppp unit to * the loopback if the serial port is set to a line discipline other * than ppp, or if it detects a modem hangup. The former will happen * in disestablish_ppp if the latter hasn't already happened, so we * shouldn't need to do anything. * * Just to be sure, set the real serial port to the normal discipline. */static voidrestore_loop(void){ looped = 1; if (new_style_driver) { set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC); return; } if (ppp_fd != slave_fd) { (void) ioctl(ppp_fd, TIOCSETD, &tty_disc); set_ppp_fd(slave_fd); }}/******************************************************************** * * sifnpmode - Set the mode for handling packets for a given NP. */intsifnpmode(u, proto, mode) int u; int proto; enum NPmode mode;{ struct npioctl npi; npi.protocol = proto; npi.mode = mode; if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { if (! ok_error (errno)) error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)", proto, mode, errno); return 0; } return 1;}/******************************************************************** * * sipxfaddr - Config the interface IPX networknumber */int sipxfaddr (int unit, unsigned long int network, unsigned char * node ){ int result = 1;#ifdef IPX_CHANGE int skfd; struct ifreq ifr; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; skfd = socket (AF_IPX, SOCK_DGRAM, 0); if (skfd < 0) { if (! ok_error (errno)) dbglog("socket(AF_IPX): %m (%d)", errno); result = 0;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -