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

📄 sys-linux.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
		ok = 0;	    /* The modification levels must be legal */	    if (driver_modification < 3) {		if (driver_modification >= 2) {		    /* we can cope with 2.2.0 and above */		    driver_is_old = 1;		} else {		    ok = 0;		}	    }	    close (s);	    if (!ok) {		slprintf(route_buffer, sizeof(route_buffer),			 "Sorry - PPP driver version %d.%d.%d is out of date\n",			 driver_version, driver_modification, driver_patch);		no_ppp_msg = route_buffer;	    }	}    }    return ok;}/******************************************************************** * * Update the wtmp file with the appropriate user name and tty device. */void logwtmp (const char *line, const char *name, const char *host){    struct utmp ut, *utp;    pid_t  mypid = getpid();#if __GLIBC__ < 2    int    wtmp;#endif/* * Update the signon database for users. * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 */    utmpname(_PATH_UTMP);    setutent();    while ((utp = getutent()) && (utp->ut_pid != mypid))	/* nothing */;    if (utp)	memcpy(&ut, utp, sizeof(ut));    else	/* some gettys/telnetds don't initialize utmp... */	memset(&ut, 0, sizeof(ut));    if (ut.ut_id[0] == 0)	strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));    strncpy(ut.ut_user, name, sizeof(ut.ut_user));    strncpy(ut.ut_line, line, sizeof(ut.ut_line));    time(&ut.ut_time);    ut.ut_type = USER_PROCESS;    ut.ut_pid  = mypid;    /* Insert the host name if one is supplied */    if (*host)	strncpy (ut.ut_host, host, sizeof(ut.ut_host));    /* Insert the IP address of the remote system if IP is enabled */    if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)	memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,		 sizeof(ut.ut_addr));    /* CL: Makes sure that the logout works */    if (*host == 0 && *name==0)	ut.ut_host[0]=0;    pututline(&ut);    endutent();/* * Update the wtmp file. */#if __GLIBC__ >= 2    updwtmp(_PATH_WTMP, &ut);#else    wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);    if (wtmp >= 0) {	flock(wtmp, LOCK_EX);	if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))	    warn("error writing %s: %m", _PATH_WTMP);	flock(wtmp, LOCK_UN);	close (wtmp);    }#endif}/******************************************************************** * * sifvjcomp - config tcp header compression */int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid){	u_int x;	if (vjcomp) {		if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)			error("Couldn't set up TCP header compression: %m");		vjcomp = 0;	}	x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);	modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, 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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	}	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	    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 (line %d)", __LINE__);	    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 (line %d)", __LINE__);	    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 (line %d)", __LINE__);	    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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	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 (line %d)", __LINE__);	}	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);	modify_flags(ppp_dev_fd, 0, 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 f

⌨️ 快捷键说明

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