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

📄 sys-linux.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * add_fd - add an fd to the set that wait_input waits for. */void add_fd(int fd){    if (fd >= FD_SETSIZE)	fatal("internal error: file descriptor too large (%d)", fd);    FD_SET(fd, &in_fds);    if (fd > max_in_fd)	max_in_fd = fd;}/* * remove_fd - remove an fd from the set that wait_input waits for. */void remove_fd(int fd){    FD_CLR(fd, &in_fds);}/******************************************************************** * * read_packet - get a PPP packet from the serial device. */int read_packet (unsigned char *buf){    int len, nr;    len = PPP_MRU + PPP_HDRLEN;    if (new_style_driver) {	*buf++ = PPP_ALLSTATIONS;	*buf++ = PPP_UI;	len -= 2;    }    nr = -1;    if (ppp_fd >= 0) {	nr = read(ppp_fd, buf, len);	if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN	    && errno != EIO && errno != EINTR)	    error("read: %m");	if (nr < 0 && errno == ENXIO)	    return 0;    }    if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {	/* N.B. we read ppp_fd first since LCP packets come in there. */	nr = read(ppp_dev_fd, buf, len);	if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN	    && errno != EIO && errno != EINTR)	    error("read /dev/ppp: %m");	if (nr < 0 && errno == ENXIO)	    nr = 0;	if (nr == 0 && doing_multilink) {	    remove_fd(ppp_dev_fd);	    bundle_eof = 1;	}    }    if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)	nr = 0;    return (new_style_driver && nr > 0)? nr+2: nr;}/******************************************************************** * * get_loop_output - get outgoing packets from the ppp device, * and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */intget_loop_output(void){    int rv = 0;    int n;    if (new_style_driver) {	while ((n = read_packet(inpacket_buf)) > 0)	    if (loop_frame(inpacket_buf, n))		rv = 1;	return rv;    }    while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)	if (loop_chars(inbuf, n))	    rv = 1;    if (n == 0)	fatal("eof on loopback");    if (errno != EWOULDBLOCK && errno != EAGAIN)	fatal("read from loopback: %m(%d)", errno);    return rv;}/* * netif_set_mtu - set the MTU on the PPP network interface. */voidnetif_set_mtu(int unit, int mtu){    struct ifreq ifr;    memset (&ifr, '\0', sizeof (ifr));    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    ifr.ifr_mtu = mtu;    if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)	error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);}/* * netif_get_mtu - get the MTU on the PPP network interface. */intnetif_get_mtu(int unit){    struct ifreq ifr;    memset (&ifr, '\0', sizeof (ifr));    strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));    if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {	error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);	return 0;    }    return ifr.ifr_mtu;}/******************************************************************** * * tty_send_config - configure the transmit characteristics of * the ppp interface. */void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp){	int x;	if (!still_ppp())		return;	link_mtu = mtu;	if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {		if (errno != EIO && errno != ENOTTY)			error("Couldn't set transmit async character map: %m");		++error_count;		return;	}	x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)	    | (sync_serial? SC_SYNC: 0);	modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);}/******************************************************************** * * tty_set_xaccm - set the extended transmit ACCM for the interface. */void tty_set_xaccm (ext_accm accm){    if (!still_ppp())	return;    if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {	if ( ! ok_error (errno))	    warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);    }}/******************************************************************** * * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp){/* * If we were called because the link has gone down then there is nothing * which may be done. Just return without incident. */	if (!still_ppp())		return;/* * Set the receiver parameters */	if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {		if (errno != EIO && errno != ENOTTY)			error("Couldn't set channel receive MRU: %m");	}	if (new_style_driver && ppp_dev_fd >= 0	    && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)		error("Couldn't set MRU in generic PPP layer: %m");	if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {		if (errno != EIO && errno != ENOTTY)			error("Couldn't set channel receive asyncmap: %m");	}}/******************************************************************** * * ccp_test - ask kernel whether a given compression method * is acceptable for use. */intccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit){    struct ppp_option_data data;    memset (&data, '\0', sizeof (data));    data.ptr      = opt_ptr;    data.length   = opt_len;    data.transmit = for_transmit;    if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)	return 1;    return (errno == ENOBUFS)? 0: -1;}/******************************************************************** * * ccp_flags_set - inform kernel about the current state of CCP. */void ccp_flags_set (int unit, int isopen, int isup){	int x;	x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);	if (still_ppp() && ppp_dev_fd >= 0)		modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);}#ifdef PPP_FILTER/* * set_filters - set the active and pass filters in the kernel driver. */int set_filters(struct bpf_program *pass, struct bpf_program *active){	struct sock_fprog fp;	fp.len = pass->bf_len;	fp.filter = (struct sock_filter *) pass->bf_insns;	if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {		if (errno == ENOTTY)			warn("kernel does not support PPP filtering");		else			error("Couldn't set pass-filter in kernel: %m");		return 0;	}	fp.len = active->bf_len;	fp.filter = (struct sock_filter *) active->bf_insns;	if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {		error("Couldn't set active-filter in kernel: %m");		return 0;	}	return 1;}#endif /* PPP_FILTER *//******************************************************************** * * get_idle_time - return how long the link has been idle. */intget_idle_time(u, ip)    int u;    struct ppp_idle *ip;{    return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;}/******************************************************************** * * get_ppp_stats - return statistics for the link. */intget_ppp_stats(u, stats)    int u;    struct pppd_stats *stats;{    struct ifpppstatsreq req;    memset (&req, 0, sizeof (req));    req.stats_ptr = (caddr_t) &req.stats;    strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));    if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {	error("Couldn't get PPP statistics: %m");	return 0;    }    stats->bytes_in = req.stats.p.ppp_ibytes;    stats->bytes_out = req.stats.p.ppp_obytes;    stats->pkts_in = req.stats.p.ppp_ipackets;    stats->pkts_out = req.stats.p.ppp_opackets;    return 1;}/******************************************************************** * * 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. */int ccp_fatal_error (int unit){	int flags;	if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {		error("Couldn't read compression error flags: %m");		flags = 0;	}	return flags & SC_DC_FERROR;}/******************************************************************** * * path_to_procfs - find the path to the proc file system mount point */static char proc_path[MAXPATHLEN];static int proc_path_len;static char *path_to_procfs(const char *tail){    struct mntent *mntent;    FILE *fp;    if (proc_path_len == 0) {	/* Default the mount location of /proc */	strlcpy (proc_path, "/proc", sizeof(proc_path));	proc_path_len = 5;	fp = fopen(MOUNTED, "r");	if (fp != NULL) {	    while ((mntent = getmntent(fp)) != NULL) {		if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)		    continue;		if (strcmp(mntent->mnt_type, "proc") == 0) {		    strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));		    proc_path_len = strlen(proc_path);		    break;		}	    }	    fclose (fp);	}    }    strlcpy(proc_path + proc_path_len, tail,	    sizeof(proc_path) - proc_path_len);    return proc_path;}/* * /proc/net/route parsing stuff. */#define ROUTE_MAX_COLS	12FILE *route_fd = (FILE *) 0;static char route_buffer[512];static int route_dev_col, route_dest_col, route_gw_col;static int route_flags_col, route_mask_col;static int route_num_cols;static int open_route_table (void);static void close_route_table (void);static int read_route_table (struct rtentry *rt);/******************************************************************** * * close_route_table - close the interface to the route table */static void close_route_table (void){    if (route_fd != (FILE *) 0) {	fclose (route_fd);	route_fd = (FILE *) 0;    }}/******************************************************************** * * open_route_table - open the interface to the route table */static char route_delims[] = " \t\n";static int open_route_table (void){    char *path;    close_route_table();    path = path_to_procfs("/net/route");    route_fd = fopen (path, "r");    if (route_fd == NULL) {	error("can't open routing table %s: %m", path);	return 0;    }    route_dev_col = 0;		/* default to usual columns */    route_dest_col = 1;    route_gw_col = 2;    route_flags_col = 3;    route_mask_col = 7;    route_num_cols = 8;    /* parse header line */    if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {	char *p = route_buffer, *q;	int col;	for (col = 0; col < ROUTE_MAX_COLS; ++col) {	    int used = 1;	    if ((q = strtok(p, route_delims)) == 0)		break;	    if (strcasecmp(q, "iface") == 0)		route_dev_col = col;	    else if (strcasecmp(q, "destination") == 0)		route_dest_col = col;	    else if (strcasecmp(q, "gateway") == 0)		route_gw_col = col;	    else if (strcasecmp(q, "flags") == 0)		route_flags_col = col;	    else if (strcasecmp(q, "mask") == 0)		route_mask_col = col;	    else		used = 0;	    if (used && col >= route_num_cols)		route_num_cols = col + 1;	    p = NULL;	}    }    return 1;}/******************************************************************** * * read_route_table - read the next entry from the route table */static int read_route_table(struct rtentry *rt){    char *cols[ROUTE_MAX_COLS], *p;    int col;    memset (rt, '\0', sizeof (struct rtentry));    if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)	return 0;    p = route_buffer;    for (col = 0; col < route_num_cols; ++col) {	cols[col] = strtok(p, route_delims);	if (cols[col] == NULL)	    return 0;		/* didn't get enough columns */	p = NULL;    }    SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);    SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);    SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);    rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);    rt->rt_dev   = cols[route_dev_col];    return 1;}/******************************************************************** * * defaultroute_exists - determine if there is a default route */static int defaultroute_exists (struct rtentry *rt){    int result = 0;    if (!open_route_table())	return 0;    while (read_route_table(rt) != 0) {	if ((rt->rt_flags & RTF_UP) == 0)	    continue;	if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)	    continue;	if (SIN_ADDR(rt->rt_dst) == 0L) {	    result = 1;	    break;	}    }    close_route_table();    return result;}/* * have_route_to - determine if the system has any route to * a given IP address.  `addr' is in network byte order. * Return value is 1 if yes, 0 if no, -1 if don't know. * For demand mode to work properly, we have to ignore routes * through our own interface. */int have_route_to(u_int32_t addr){    struct rtentry rt;    int result = 0;    if (!open_route_table())	return -1;		/* don't know */    while (read_route_table(&rt)) {	if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)	    continue;	if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {	    result = 1;	    break;	}    }    close_route_table();    return result;}

⌨️ 快捷键说明

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