Пример #1
0
int
ifconfig(char *name, int flags, char *addr, char *netmask)
{
	int s;
	struct ifreq ifr;
	struct in_addr in_addr, in_netmask, in_broadaddr;

	/* Open a raw socket to the kernel */
	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		goto err;

	/* Set interface name */
	strncpy(ifr.ifr_name, name, IFNAMSIZ);

	/* Set interface flags */
	ifr.ifr_flags = flags;
	if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
		goto err;

	/* Set IP address */
	if (addr) {
		inet_aton(addr, &in_addr);
		sin_addr(&ifr.ifr_addr).s_addr = in_addr.s_addr;
		ifr.ifr_addr.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFADDR, &ifr) < 0)
			goto err;
	}

	/* Set IP netmask and broadcast */
	if (addr && netmask) {
		inet_aton(netmask, &in_netmask);
		sin_addr(&ifr.ifr_netmask).s_addr = in_netmask.s_addr;
		ifr.ifr_netmask.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0)
			goto err;

		in_broadaddr.s_addr = (in_addr.s_addr & in_netmask.s_addr) | ~in_netmask.s_addr;
		sin_addr(&ifr.ifr_broadaddr).s_addr = in_broadaddr.s_addr;
		ifr.ifr_broadaddr.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFBRDADDR, &ifr) < 0)
			goto err;
	}

	close(s);

	return 0;

err:
	close(s);
	perror(name);
	return errno;
}
Пример #2
0
static int
route_manip(int cmd, char *ifname, int metric, char *dst, char *gateway, char *genmask)
{
	int s;
	struct rtentry rt;

	/* Open a raw socket to the kernel */
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		goto err;
	}

	/* Fill in rtentry */
	memset(&rt, 0, sizeof(rt));
	if (dst) {
		inet_aton(dst, &sin_addr(&rt.rt_dst));
	}
	if (gateway) {
		inet_aton(gateway, &sin_addr(&rt.rt_gateway));
	}
	if (genmask) {
		inet_aton(genmask, &sin_addr(&rt.rt_genmask));
	}
	rt.rt_metric = metric;
	rt.rt_flags = RTF_UP;
	if (sin_addr(&rt.rt_gateway).s_addr) {
		rt.rt_flags |= RTF_GATEWAY;
	}
	if (sin_addr(&rt.rt_genmask).s_addr == INADDR_BROADCAST) {
		rt.rt_flags |= RTF_HOST;
	}
	rt.rt_dev = ifname;

	/* Force address family to AF_INET */
	rt.rt_dst.sa_family = AF_INET;
	rt.rt_gateway.sa_family = AF_INET;
	rt.rt_genmask.sa_family = AF_INET;

	if (ioctl(s, cmd, &rt) < 0) {
		goto err;
	}

	close(s);
	return 0;

 err:
	close(s);
	return errno;
}
Пример #3
0
static int
route_add(const struct in_addr inetaddr, struct rtentry *rt)
{
    char buf[256], dev[64], rdev[64];
    u_int32_t dest, mask, gateway, flags, bestmask = 0;
    int metric;

    FILE *f = fopen("/proc/net/route", "r");
    if (f == NULL) {
        route_msg("%s: /proc/net/route: %s", strerror(errno), __FUNCTION__);
        return -1;
    }

    rt->rt_gateway.sa_family = 0;

    while (fgets(buf, sizeof(buf), f))
    {
        if (sscanf(buf, "%63s %x %x %x %*s %*s %d %x", dev, &dest,
                   &gateway, &flags, &metric, &mask) != 6)
            continue;
        if ((flags & RTF_UP) == (RTF_UP) && (inetaddr.s_addr & mask) == dest &&
                (dest || strncmp(dev, "ppp", 3)) /* avoid default via pppX to avoid on-demand loops*/)
        {
            if ((mask | bestmask) == bestmask && rt->rt_gateway.sa_family)
                continue;
            bestmask = mask;

            sin_addr(&rt->rt_gateway).s_addr = gateway;
            rt->rt_gateway.sa_family = AF_INET;
            rt->rt_flags = flags;
            rt->rt_metric = metric;
            strncpy(rdev, dev, sizeof(rdev));

            if (mask == INADDR_BROADCAST)
                break;
        }
    }

    fclose(f);

    /* check for no route */
    if (rt->rt_gateway.sa_family != AF_INET)
    {
        /* route_msg("%s: no route to host", __FUNCTION__); */
        return -1;
    }

    /* check for existing route to this host,
     * add if missing based on the existing routes */
    if (rt->rt_flags & RTF_HOST)
    {
        /* route_msg("%s: not adding existing route", __FUNCTION__); */
        return -1;
    }

    sin_addr(&rt->rt_dst) = inetaddr;
    rt->rt_dst.sa_family = AF_INET;

    sin_addr(&rt->rt_genmask).s_addr = INADDR_BROADCAST;
    rt->rt_genmask.sa_family = AF_INET;

    rt->rt_flags &= RTF_GATEWAY;
    rt->rt_flags |= RTF_UP | RTF_HOST;

    rt->rt_metric++;
    rt->rt_dev = strdup(rdev);

    if (!rt->rt_dev)
    {
        /* route_msg("%s: no memory", __FUNCTION__); */
        return -1;
    }

    if (!route_ctrl(SIOCADDRT, rt))
        return 0;

    free(rt->rt_dev), rt->rt_dev = NULL;

    return -1;
}
Пример #4
0
/* static */ int
route_add(const struct in_addr inetaddr, int any_dgw, struct rtentry *rt)
{
	char buf[256], dev[64], rdev[64];
	u_int32_t dest, mask, gateway, flags, bestmask = 0;
	u_int32_t metric, metric_min = UINT_MAX;

	FILE *fp = fopen("/proc/net/route", "r");
	if (!fp) {
		/* route_msg("%s: /proc/net/route: %s", strerror(errno), __FUNCTION__); */
		return -1;
	}

	rt->rt_gateway.sa_family = 0;

	while (fgets(buf, sizeof(buf), fp)) {
		if (sscanf(buf, "%63s %x %x %x %*s %*s %d %x",
			dev, &dest, &gateway, &flags, &metric, &mask) != 6)
			continue;
		
		if ((flags & RTF_UP) != RTF_UP)
			continue;
		
		if (!any_dgw) {
			/* use only physical WAN/MAN interface */
			if (strncmp(dev, "eth", 3) != 0 &&
			    strncmp(dev, "apcli", 5) != 0 &&
			    strncmp(dev, "wwan", 4) != 0 &&
			    strncmp(dev, "weth", 4) != 0)
				continue;
			
			if ( (inetaddr.s_addr & mask) == dest && gateway ) {
				if ((mask | bestmask) == bestmask && rt->rt_gateway.sa_family)
					continue;
				
				bestmask = mask;
				
				sin_addr(&rt->rt_gateway).s_addr = gateway;
				rt->rt_gateway.sa_family = AF_INET;
				rt->rt_flags = flags;
				rt->rt_metric = (dest) ? metric : 0;
				strncpy(rdev, dev, sizeof(rdev));
				
				if (mask == INADDR_BROADCAST)
					break;
			}
		} else {
			/* skip lo and LAN */
			if (strcmp(dev, "lo") == 0 ||
			    strcmp(dev, "br0") == 0)
				continue;
			
			if ( !dest && !mask && gateway && metric < metric_min ) {
				metric_min = metric;
				
				sin_addr(&rt->rt_gateway).s_addr = gateway;
				rt->rt_gateway.sa_family = AF_INET;
				rt->rt_flags = flags;
				rt->rt_metric = 0;
				strncpy(rdev, dev, sizeof(rdev));
			}
		}
	}

	fclose(fp);

	/* check for no route */
	if (rt->rt_gateway.sa_family != AF_INET) 
	{
		/* route_msg("%s: no route to host", __FUNCTION__); */
		return -1;
	}

	/* check for existing route to this host,
	 * add if missing based on the existing routes */
	if (rt->rt_flags & RTF_HOST)
	{
		/* route_msg("%s: not adding existing route", __FUNCTION__); */
		return -1;
	}

	sin_addr(&rt->rt_dst) = inetaddr;
	rt->rt_dst.sa_family = AF_INET;

	sin_addr(&rt->rt_genmask).s_addr = INADDR_BROADCAST;
	rt->rt_genmask.sa_family = AF_INET;

	rt->rt_flags &= RTF_GATEWAY;
	rt->rt_flags |= RTF_UP | RTF_HOST;

	rt->rt_metric++;
	rt->rt_dev = strdup(rdev);

	if (!rt->rt_dev)
	{
		/* route_msg("%s: no memory", __FUNCTION__); */
		return -1;
	}

	if (!route_ctrl(SIOCADDRT, rt))
		return 0;

	free(rt->rt_dev);
	memset(rt, 0, sizeof(*rt));

	return -1;
}
Пример #5
0
int
ifconfig(char *ifname, int flags, char *addr, char *mask)
{
	int sockfd, ret = 0;
	struct ifreq ifr;
	struct in_addr addr_in, mask_in;

	/* Open a socket to the kernel */
	if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		return -1;

	/* Set interface name */
	memset(&ifr, 0, sizeof(ifr));
	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

	/* Get interface flags */
	if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
		ret = errno;
		goto err;
	}

	/* Set interface flags */
	if (!flags)
		ifr.ifr_flags &= ~(IFF_UP);
	else
		ifr.ifr_flags |= flags;

	if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
		ret = errno;
		goto err;
	}

	/* Set IP address */
	if (addr) {
		if (!inet_aton(addr, &addr_in))
			addr_in.s_addr = INADDR_ANY;
		sin_addr(&ifr.ifr_addr).s_addr = addr_in.s_addr;
		ifr.ifr_addr.sa_family = AF_INET;
		if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
			ret = errno;
			goto err;
		}
	}

	/* Set IP netmask and broadcast */
	if (addr && mask) {
		if (!inet_aton(mask, &mask_in))
			mask_in.s_addr = INADDR_ANY;
		if (addr_in.s_addr != INADDR_ANY && mask_in.s_addr != INADDR_ANY) {
			sin_addr(&ifr.ifr_netmask).s_addr = mask_in.s_addr;
			ifr.ifr_netmask.sa_family = AF_INET;
			if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
				ret = errno;
				goto err;
			}
			
			sin_addr(&ifr.ifr_broadaddr).s_addr = htonl((ntohl(addr_in.s_addr) & ntohl(mask_in.s_addr)) | ~(ntohl(mask_in.s_addr)));
			ifr.ifr_broadaddr.sa_family = AF_INET;
			if (ioctl(sockfd, SIOCSIFBRDADDR, &ifr) < 0) {
				ret = errno;
				goto err;
			}
		}
	}

err:
	close(sockfd);

	return ret;
}
Пример #6
0
int
route_add(const struct in_addr inetaddr, struct rtentry *rt)
{
	char buf[256], dev[64];
	int metric, flags;
	u_int32_t dest, mask;

	FILE *f = fopen("/proc/net/route", "r");
	if (f == NULL) {
	        l2tp_log (LOG_ERR, "/proc/net/route: %s", strerror(errno));
		return -1;
	}

	while (fgets(buf, sizeof(buf), f)) {
		if (sscanf(buf, "%63s %x %x %X %*s %*s %d %x", dev, &dest,
		    	&sin_addr(&rt->rt_gateway).s_addr, &flags, &metric, &mask) != 6)
			continue;
		if ((flags & RTF_UP) == (RTF_UP) && (inetaddr.s_addr & mask) == dest &&
		    (dest || strncmp(dev, "ppp", 3)) /* avoid default via pppX to avoid on-demand loops*/) {
			rt->rt_metric = metric + 1;
			rt->rt_gateway.sa_family = AF_INET;
			break;
		}
	}

	fclose(f);

	/* check for no route */
	if (rt->rt_gateway.sa_family != AF_INET) {
	        /* l2tp_log (LOG_ERR, "route_add: no route to host"); */
		return -1;
	}

	/* check for existing route to this host, 
	add if missing based on the existing routes */
	if (flags & RTF_HOST) {
	        /* l2tp_log (LOG_ERR, "route_add: not adding existing route"); */
		return -1;
	}

	sin_addr(&rt->rt_dst) = inetaddr;
	rt->rt_dst.sa_family = AF_INET;

	sin_addr(&rt->rt_genmask).s_addr = INADDR_BROADCAST;
	rt->rt_genmask.sa_family = AF_INET;

	rt->rt_flags = RTF_UP | RTF_HOST;
	if (flags & RTF_GATEWAY)
		rt->rt_flags |= RTF_GATEWAY;

	rt->rt_metric++;
	rt->rt_dev = strdup(dev);

	if (!rt->rt_dev) {
	        l2tp_log (LOG_ERR, "route_add: no memory");
		return -1;
	}

	if (!route_ctrl(SIOCADDRT, rt))
		return 0;

	free(rt->rt_dev);
	rt->rt_dev = NULL;

	return -1;
}
Пример #7
0
/*
 * Get the IP, Subnetmask, Geteway from WAN interface
 * and set to NV ram.
 */
void start_tmp_ppp(int num)
{

	int timeout = 5;
	char pppoeifname[15];
	char wanip[2][15] = { "wan_ipaddr", "wan_ipaddr_1" };
	char wanmask[2][15] = { "wan_netmask", "wan_netmask_1" };
	char wangw[2][15] = { "wan_gateway", "wan_gateway_1" };
	// char wanif[2][15]={"wan_ifname","wan_ifname_1"};
	// char *wan_ifname = nvram_safe_get("wan_ifname");
	struct ifreq ifr;
	int s;

	cprintf("start session %d\n", num);

	sprintf(pppoeifname, "pppoe_ifname%d", num);

	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		return;

	/*
	 * Wait for ppp0 to be created 
	 */
	while (ifconfig(nvram_safe_get(pppoeifname), IFUP, NULL, NULL)
	       && timeout--)
		sleep(1);

	strncpy(ifr.ifr_name, nvram_safe_get(pppoeifname), IFNAMSIZ);

	/*
	 * Set temporary IP address 
	 */
	timeout = 3;
	while (ioctl(s, SIOCGIFADDR, &ifr) && timeout--) {
		perror(nvram_safe_get(pppoeifname));
		printf("Wait %s inteface to init (1) ...\n",
		       nvram_safe_get(pppoeifname));
		sleep(1);
	};
	nvram_set(wanip[num], inet_ntoa(sin_addr(&(ifr.ifr_addr))));
	nvram_set(wanmask[num], "255.255.255.255");

	/*
	 * Set temporary P-t-P address 
	 */
	timeout = 3;
	while (ioctl(s, SIOCGIFDSTADDR, &ifr) && timeout--) {
		perror(nvram_safe_get(pppoeifname));
		printf("Wait %s inteface to init (2) ...\n",
		       nvram_safe_get(pppoeifname));
		sleep(1);
	}
	nvram_set(wangw[num], inet_ntoa(sin_addr(&(ifr.ifr_dstaddr))));

	start_wan_done(nvram_safe_get(pppoeifname));

	// if user press Connect" button from web, we must force to dial
	if (nvram_match("action_service", "start_pppoe")
	    || nvram_match("action_service", "start_pppoe_1")) {
		sleep(3);
		// force_to_dial(nvram_safe_get("action_service"));
		start_force_to_dial();
		nvram_unset("action_service");
	}

	close(s);
	cprintf("done session %d\n", num);
	return;
}
Пример #8
0
int ifconfig(char *name, int flags, char *addr, char *netmask)
{
	// char *down="down";
	// if (flags == IFUP)
	// down = "up";
	cprintf("ifconfig %s = %s/%s\n", name, addr, netmask);
	if (!ifexists(name)) {
		cprintf("interface %s does not exists, ignoring\n", name);
		return -1;
	}
	// if (addr==NULL)
	// addr="0.0.0.0";
	// int ret;
	// if (netmask==NULL)
	// {
	// ret = eval("ifconfig",name,addr,down);
	// }else
	// {
	// ret = eval("ifconfig",name,addr,"netmask",netmask,down);
	// }
	int s;
	struct ifreq ifr;
	struct in_addr in_addr, in_netmask, in_broadaddr;

	cprintf("ifconfig(): name=[%s] flags=[%s] addr=[%s] netmask=[%s]\n",
		name, flags == IFUP ? "IFUP" : "0", addr, netmask);

	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		goto err;
	cprintf("ifconfig(): socket opened\n");

	strncpy(ifr.ifr_name, name, IFNAMSIZ);
	cprintf("ifconfig(): set interface name\n");
	if (flags) {
		ifr.ifr_flags = flags;
		if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
			goto err;
	}
	cprintf("ifconfig(): interface flags configured\n");
	if (addr) {
		inet_aton(addr, &in_addr);
		sin_addr(&ifr.ifr_addr).s_addr = in_addr.s_addr;
		ifr.ifr_addr.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFADDR, &ifr) < 0)
			goto err;
	}
	cprintf("ifconfig() ip configured\n");

	if (addr && netmask) {
		inet_aton(netmask, &in_netmask);
		sin_addr(&ifr.ifr_netmask).s_addr = in_netmask.s_addr;
		ifr.ifr_netmask.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0)
			goto err;

		in_broadaddr.s_addr =
		    (in_addr.s_addr & in_netmask.s_addr) | ~in_netmask.s_addr;
		sin_addr(&ifr.ifr_broadaddr).s_addr = in_broadaddr.s_addr;
		ifr.ifr_broadaddr.sa_family = AF_INET;
		if (ioctl(s, SIOCSIFBRDADDR, &ifr) < 0)
			goto err;
	}
	cprintf("ifconfig() mask configured\n");

	close(s);
	cprintf("ifconfig() done()\n");
	return 0;

err:
	cprintf("ifconfig() done with error\n");
	close(s);
#ifndef HAVE_SILENCE
	perror(name);
#endif
	return errno;
	// return ret;
}