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

📄 sys-linux.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	}     }/* *  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;    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;    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;	tios.c_iflag  = IGNPAR | CLOCAL;	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 */	ifunit = -1;	if (ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit) < 0)	    fatal("Couldn't create PPP unit: %m");	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. */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;    }    else {	memset (&ifr, '\0', sizeof (ifr));	strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));	memcpy (sipx->sipx_node, node, IPX_NODE_LEN);	sipx->sipx_family  = AF_IPX;	sipx->sipx_port    = 0;	sipx->sipx_network = htonl (network);	sipx->sipx_type    = IPX_FRAME_ETHERII;	sipx->sipx_action  = IPX_CRTITF;/* *  Set the IPX device */	if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {	    result = 0;	    if (errno != EEXIST) {		if (! ok_error (errno))		    dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);	    }	    else {		warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");	    }	}	close (skfd);    }#endif    return result;}/******************************************************************** * * cipxfaddr - Clear the information for the IPX network. The IPX routes *	       are removed and the device is no longer able to pass IPX *	       frames. */int cipxfaddr (int unit){    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;    }    else {	memset (&ifr, '\0', sizeof (ifr));	strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));	sipx->sipx_type    = IPX_FRAME_ETHERII;	sipx->sipx_action  = IPX_DLTITF;	sipx->sipx_family  = AF_IPX;/* *  Set the IPX device */	if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {	    if (! ok_error (errno))		info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);	    result = 0;	}	close (skfd);    }#endif    return result;}/* * Use the hostname as part of the random number seed. */intget_host_seed(){    int h;    char *p = hostname;    h = 407;    for (p = hostname; *p != 0; ++p)	h = h * 37 + *p;    return h;}/******************************************************************** * * sys_check_options - check the options that the user specified */intsys_check_options(void){#ifdef IPX_CHANGE/* * Disable the IPX protocol if the support is not present in the kernel. */    char *path;    if (ipxcp_protent.enabled_flag) {	struct stat stat_buf;        if ((path = path_to_procfs("/net/ipx_interface")) == 0	    || lstat(path, &stat_buf) < 0) {	    error("IPX support is not present in the kernel\n");	    ipxcp_protent.enabled_flag = 0;	}    }#endif    if (demand && driver_is_old) {	option_error("demand dialling is not supported by kernel driver "		     "version %d.%d.%d", driver_version, driver_modification,		     driver_patch);	return 0;    }    return 1;}

⌨️ 快捷键说明

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