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; }
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; }
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; }
/* 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; }
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; }
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; }
/* * 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; }
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; }