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

📄 sys-linux.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 5 页
字号:
 */void ccp_flags_set (int unit, int isopen, int isup){    if (still_ppp()) {	int x = get_flags(ppp_dev_fd);	x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;	x = isup?   x | SC_CCP_UP   : x &~ SC_CCP_UP;	set_flags (ppp_dev_fd, x);    }}/******************************************************************** * * 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;    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 x = get_flags(ppp_dev_fd);    return x & 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;}/******************************************************************** * * sifdefaultroute - assign a default route through the address given. */int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway){    struct rtentry rt;    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {	u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);	if (old_gateway != gateway)	    error("not replacing existing default route to %s [%I]",		  rt.rt_dev, old_gateway);	return 0;    }    memset (&rt, '\0', sizeof (rt));    SET_SA_FAMILY (rt.rt_dst,     AF_INET);    SET_SA_FAMILY (rt.rt_gateway, AF_INET);    if (kernel_version > KVERSION(2,1,0)) {	SET_SA_FAMILY (rt.rt_genmask, AF_INET);	SIN_ADDR(rt.rt_genmask) = 0L;    }    SIN_ADDR(rt.rt_gateway) = gateway;        rt.rt_flags = RTF_UP | RTF_GATEWAY;    if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {	if ( ! ok_error ( errno ))	    error("default route ioctl(SIOCADDRT): %m(%d)", errno);	return 0;    }    default_route_gateway = gateway;    return 1;}/******************************************************************** * * cifdefaultroute - delete a default route through the address given. */int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway){    struct rtentry rt;    default_route_gateway = 0;    memset (&rt, '\0', sizeof (rt));    SET_SA_FAMILY (rt.rt_dst,     AF_INET);    SET_SA_FAMILY (rt.rt_gateway, AF_INET);    if (kernel_version > KVERSION(2,1,0)) {	SET_SA_FAMILY (rt.rt_genmask, AF_INET);	SIN_ADDR(rt.rt_genmask) = 0L;    }    SIN_ADDR(rt.rt_gateway) = gateway;        rt.rt_flags = RTF_UP | RTF_GATEWAY;    if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {	if (still_ppp()) {	    if ( ! ok_error ( errno ))		error("default route ioctl(SIOCDELRT): %m (%d)", errno);	    return 0;	}    }    return 1;}/******************************************************************** * * sifproxyarp - Make a proxy ARP entry for the peer. */int sifproxyarp (int unit, u_int32_t his_adr){    struct arpreq arpreq;    char *forw_path;    if (has_proxy_arp == 0) {	memset (&arpreq, '\0', sizeof(arpreq));    	SET_SA_FAMILY(arpreq.arp_pa, AF_INET);	SIN_ADDR(arpreq.arp_pa) = his_adr;	arpreq.arp_flags = ATF_PERM | ATF_PUBL;/* * Get the hardware address of an interface on the same subnet * as our local address. */	if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,			    sizeof(proxy_arp_dev))) {	    error("Cannot determine ethernet address for proxy ARP");	    return 0;	}	strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));	if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {	    if ( ! ok_error ( errno ))		error("ioctl(SIOCSARP): %m(%d)", errno);	    return 0;	}	proxy_arp_addr = his_adr;	has_proxy_arp = 1;	if (tune_kernel) {	    forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");	    if (forw_path != 0) {		int fd = open(forw_path, O_WRONLY);		if (fd >= 0) {		    if (write(fd, "1", 1) != 1)			error("Couldn't enable IP forwarding: %m");		    close(fd);		}	    }	}    }    return 1;}/******************************************************************** * * cifproxyarp - Delete the proxy ARP entry for the peer. */int cifproxyarp (int unit, u_int32_t his_adr){    struct arpreq arpreq;    if (has_proxy_arp) {	has_proxy_arp = 0;	memset (&arpreq, '\0', sizeof(arpreq));	SET_SA_FAMILY(arpreq.arp_pa, AF_INET);	SIN_ADDR(arpreq.arp_pa) = his_adr;	arpreq.arp_flags = ATF_PERM | ATF_PUBL;	strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));	if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {	    if ( ! ok_error ( errno ))		warn("ioctl(SIOCDARP): %m(%d)", errno);	    return 0;	}    }    return 1;}     /******************************************************************** * * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */static int get_ether_addr (u_int32_t ipaddr,			   struct sockaddr *hwaddr,			   char *name, int namelen){    struct ifreq *ifr, *ifend;    u_int32_t ina, mask;    char *aliasp;    struct ifreq ifreq;    struct ifconf ifc;    struct ifreq ifs[MAX_IFS];        ifc.ifc_len = sizeof(ifs);    ifc.ifc_req = ifs;    if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {	if ( ! ok_error ( errno ))	    error("ioctl(SIOCGIFCONF): %m(%d)", errno);	return 0;    }    SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",		ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));/* * Scan through looking for an interface with an Internet * address on the same subnet as `ipaddr'. */    ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));    for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {	if (ifr->ifr_addr.sa_family == AF_INET) {	    ina = SIN_ADDR(ifr->ifr_addr);	    strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));            SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",			ifreq.ifr_name));/* * Check that the interface is up, and not point-to-point * nor loopback. */	    if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)		continue;	    if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)		continue;/* * Get its netmask and check that it's on the right subnet. */	    if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)	        continue;	    mask = SIN_ADDR(ifreq.ifr_addr);	    SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",			ip_ntoa(ina), ntohl(mask)));	    if (((ipaddr ^ ina) & mask) != 0)	        continue;	    break;	}    }        if (ifr >= ifend)        return 0;    strlcpy(name, ifreq.ifr_name, namelen);    /* trim off the :1 in eth0:1 */    aliasp = strchr(name, ':');    if (aliasp != 0)	*aliasp = 0;    info("found interface %s for proxy arp", name);/* * Now get the hardware address. */    memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));    if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) {        error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);        return 0;    }    memcpy (hwaddr,

⌨️ 快捷键说明

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