int ifc_configure(const char *ifname, in_addr_t address, in_addr_t gateway) { in_addr_t netmask = ~0; (void) gateway; ifc_init(); if (ifc_up(ifname)) { LOGE("%s() Failed to turn on interface %s: %s", __func__, ifname, strerror(errno)); ifc_close(); return -1; } if (ifc_set_addr(ifname, address)) { LOGE("%s() Failed to set ipaddr %s: %s", __func__, ipaddr_to_string(address), strerror(errno)); ifc_down(ifname); ifc_close(); return -1; } if (ifc_set_mask(ifname, netmask)) { LOGE("%s() failed to set netmask %s: %s", __func__, ipaddr_to_string(netmask), strerror(errno)); ifc_down(ifname); ifc_close(); return -1; } ifc_close(); return 0; }
int set_iface(const char *iface, int on) { int u4Count = 0; if(ifc_init() != 0) { LOGE("[%s] interface set %d failed", iface, on); return -1; } if(on) { while(ifc_up(iface) == -1) { LOGD("[%s] interface is not ready, wait %dus", iface, SET_IFACE_DELAY); sched_yield(); usleep(SET_IFACE_DELAY); if (++u4Count >= SET_IFACE_POLLING_LOOP) { LOGE("[%s] interface set %d failed", iface, on); ifc_close(); return -1; } } LOGD("[%s] interface is up", iface); init_iface(iface); } else { ifc_down(iface); LOGD("[%s] interface is down", iface); } ifc_close(); return 0; }
int META_WIFI_init(void) { int count = 100; if(1 == wifi_init){ ERR("wifi is already initilized.\n"); return true; } #if 0 if (!wifi_is_loaded()){ ERR("[META_WIFI] loading wifi driver ... ...\n"); if (wifi_insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) { ERR("[META_WIFI] failed to load wifi driver!!!\n"); goto error; } } #endif usleep(200000); wifi_set_power(1); sched_yield(); while (count-- > 0) { if (ifc_init() == 0) { if (ifc_up("wlan0") == 0) { ifc_close(); break; } ERR("[META_WIFI] ifc_up(wlan0) failed\n"); ifc_close(); } else { ERR("[META_WIFI] ifc_init() failed\n"); } usleep(100000); } if (count == 0) goto error; if (wifi_skfd == -1) wifi_skfd = openNetHandle(); if (wifi_skfd < 0) { META_WIFI_deinit(); goto error; } wifi_init = 1; return true; error: wifi_set_power(0); return false; }
int main(int argc, char **argv) { char *iname; int n; if(ifc_init()) { die("Cannot perform requested operation"); } if(argc == 1) { int result = dump_interfaces(); ifc_close(); return result; } if(argc < 3) usage(); iname = argv[1]; if(strlen(iname) > 16) usage(); argc -= 2; argv += 2; while(argc > 0) { for(n = 0; CMDS[n].name; n++){ if(!strcmp(argv[0], CMDS[n].name)) { char *cmdname = argv[0]; int nargs = CMDS[n].nargs; argv[0] = iname; if(argc < nargs) { fprintf(stderr, "not enough arguments for '%s'\n", cmdname); ifc_close(); exit(1); } if(call_func(CMDS[n].func, nargs, argv)) { fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); ifc_close(); exit(1); } argc -= nargs; argv += nargs; goto done; } } fprintf(stderr,"no such action '%s'\n", argv[0]); usage(); done: ; } ifc_close(); return 0; }
int doWimaxDhcpRequest(int *ipaddr, int *gateway, int *mask, int *dns1, int *dns2, int *server, int *lease) { if (ifc_init() < 0) return -1; if (do_dhcp(iface) < 0) { ifc_close(); return -1; } ifc_close(); get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease); return 0; }
int SoftapController::startDriver(char *iface) { int ret; if (mSock < 0) { LOGE("Softap driver start - failed to open socket"); return -1; } if (!iface || (iface[0] == '\0')) { LOGD("Softap driver start - wrong interface"); iface = mIface; } *mBuf = 0; ret = setCommand(iface, "START"); if (ret < 0) { LOGE("Softap driver start: %d", ret); return ret; } #ifdef HAVE_HOSTAPD ifc_init(); ret = ifc_up(iface); ifc_close(); #endif usleep(AP_DRIVER_START_DELAY); LOGD("Softap driver start: %d", ret); return ret; }
int SoftapController::startDriver(char *iface) { int ret; if (mSock < 0) { ALOGE("Softap driver start - failed to open socket"); return ResponseCode::OperationFailed; } if (!iface || (iface[0] == '\0')) { ALOGD("Softap driver start - wrong interface"); iface = mIface; } *mBuf = 0; ret = setCommand(iface, "START"); if (ret < 0) { ALOGE("Softap driver start: %d", ret); return ResponseCode::ServiceStartFailed; } #ifdef HAVE_HOSTAPD ifc_init(); ret = ifc_up(iface); ifc_close(); #endif usleep(AP_DRIVER_START_DELAY); ALOGD("Softap driver start: %d", ret); return ResponseCode::SoftapStatusResult; }
int do_dhcp_client_request(const char *iface, int *ipaddr, int *gateway, int *mask, int *dns1, int *dns2, int *server, int *lease) { LOGD("[%s] do_dhcp_client_request\n", iface); if (ifc_init() < 0) return -1; if (do_dhcp(iface) < 0) { ifc_close(); return -1; } ifc_close(); get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease); return 0; }
int do_dhcp_request(int *ipaddr, int *gateway, int *mask, int *dns1, int *dns2, int *server, int *lease) { /* For test driver, always report success */ if (strcmp(primary_iface, WIFI_TEST_INTERFACE) == 0) return 0; if (ifc_init() < 0) return -1; if (do_dhcp(primary_iface) < 0) { ifc_close(); return -1; } ifc_close(); get_dhcp_info(ipaddr, gateway, mask, dns1, dns2, server, lease); return 0; }
int ifc_configure(const char *ifname, in_addr_t address, in_addr_t netmask, in_addr_t gateway, in_addr_t dns1, in_addr_t dns2) { #if 0 char dns_prop_name[PROPERTY_KEY_MAX]; #endif ifc_init(); if (ifc_up(ifname)) { printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno)); ifc_close(); return -1; } if (ifc_set_addr(ifname, address)) { printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno)); ifc_close(); return -1; } if (ifc_set_mask(ifname, netmask)) { printerr("failed to set netmask %s: %s\n", ipaddr_to_string(netmask), strerror(errno)); ifc_close(); return -1; } if (ifc_create_default_route(ifname, gateway)) { printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno)); ifc_close(); return -1; } ifc_close(); #if 0 snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", ifname); property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : ""); snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", ifname); property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : ""); #endif return 0; }
int ifc_enable(const char *ifname) { int result; ifc_init(); result = ifc_up(ifname); ifc_close(); return result; }
void AndroidGetAddr() { if (ifc_init()) { return; } in_addr_t addr; ifc_get_info("tiwlan0", &addr, 0, 0); myAddr = addr; ifc_close(); }
int ifc_configure(const char *ifname, in_addr_t address, uint32_t prefixLength, in_addr_t gateway, in_addr_t dns1, in_addr_t dns2) { char dns_prop_name[PROPERTY_KEY_MAX]; ifc_init(); if (ifc_up(ifname)) { printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno)); ifc_close(); return -1; } if (ifc_set_addr(ifname, address)) { printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno)); ifc_close(); return -1; } if (ifc_set_prefixLength(ifname, prefixLength)) { printerr("failed to set prefixLength %d: %s\n", prefixLength, strerror(errno)); ifc_close(); return -1; } if (ifc_create_default_route(ifname, gateway)) { printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno)); ifc_close(); return -1; } ifc_close(); snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", ifname); property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : ""); snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", ifname); property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : ""); snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.gw", ifname); property_set(dns_prop_name, gateway ? ipaddr_to_string(gateway) : ""); return 0; }
int ifc_disable(const char *ifname) { int result; ifc_init(); result = ifc_down(ifname); ifc_set_addr(ifname, 0); ifc_close(); return result; }
/* * Clears IPv4 addresses on the specified interface. */ void ifc_clear_ipv4_addresses(const char *name) { unsigned count, addr; ifc_init(); for (count=0, addr=1;((addr != 0) && (count < 255)); count++) { if (ifc_get_addr(name, &addr) < 0) break; if (addr) ifc_set_addr(name, 0); } ifc_close(); }
int ifc_disable_allmc(const char *ifname) { int result; ifc_init(); result = ifc_set_flags(ifname, 0, IFF_ALLMULTI); ifc_close(); ALOGD("ifc_disable_allmc(%s) = %d", ifname, result); return result; }
/* * Sets the specified gateway as the default route for the named interface. * DEPRECATED */ int ifc_set_default_route(const char *ifname, in_addr_t gateway) { struct in_addr addr; int result; ifc_init(); addr.s_addr = gateway; if ((result = ifc_create_default_route(ifname, gateway)) < 0) { ALOGD("failed to add %s as default route for %s: %s", inet_ntoa(addr), ifname, strerror(errno)); } ifc_close(); return result; }
/* * Removes the default route for the named interface. */ int ifc_remove_default_route(const char *ifname) { struct rtentry rt; int result; ifc_init(); memset(&rt, 0, sizeof(rt)); rt.rt_dev = (void *)ifname; rt.rt_flags = RTF_UP|RTF_GATEWAY; init_sockaddr_in(&rt.rt_dst, 0); if ((result = ioctl(ifc_ctl_sock, SIOCDELRT, &rt)) < 0) { ALOGD("failed to remove default route for %s: %s", ifname, strerror(errno)); } ifc_close(); return result; }
int ifc_reset_connections(const char *ifname, const int reset_mask) { #ifdef HAVE_ANDROID_OS int result, success; in_addr_t myaddr = 0; struct ifreq ifr; struct in6_ifreq ifr6; if (reset_mask & RESET_IPV4_ADDRESSES) { /* IPv4. Clear connections on the IP address. */ ifc_init(); if (!(reset_mask & RESET_IGNORE_INTERFACE_ADDRESS)) { ifc_get_info(ifname, &myaddr, NULL, NULL); } ifc_init_ifr(ifname, &ifr); init_sockaddr_in(&ifr.ifr_addr, myaddr); result = ioctl(ifc_ctl_sock, SIOCKILLADDR, &ifr); ifc_close(); } else { result = 0; } if (reset_mask & RESET_IPV6_ADDRESSES) { /* * IPv6. On Linux, when an interface goes down it loses all its IPv6 * addresses, so we don't know which connections belonged to that interface * So we clear all unused IPv6 connections on the device by specifying an * empty IPv6 address. */ ifc_init6(); // This implicitly specifies an address of ::, i.e., kill all IPv6 sockets. memset(&ifr6, 0, sizeof(ifr6)); success = ioctl(ifc_ctl_sock6, SIOCKILLADDR, &ifr6); if (result == 0) { result = success; } ifc_close6(); } return result; #else return 0; #endif }
/* * Remove the routes associated with the named interface. */ int ifc_remove_host_routes(const char *name) { char ifname[64]; in_addr_t dest, gway, mask; int flags, refcnt, use, metric, mtu, win, irtt; struct rtentry rt; FILE *fp; struct in_addr addr; fp = fopen("/proc/net/route", "r"); if (fp == NULL) return -1; /* Skip the header line */ if (fscanf(fp, "%*[^\n]\n") < 0) { fclose(fp); return -1; } ifc_init(); for (;;) { int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", ifname, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, &mtu, &win, &irtt); if (nread != 11) { break; } if ((flags & (RTF_UP|RTF_HOST)) != (RTF_UP|RTF_HOST) || strcmp(ifname, name) != 0) { continue; } memset(&rt, 0, sizeof(rt)); rt.rt_dev = (void *)name; init_sockaddr_in(&rt.rt_dst, dest); init_sockaddr_in(&rt.rt_gateway, gway); init_sockaddr_in(&rt.rt_genmask, mask); addr.s_addr = dest; if (ioctl(ifc_ctl_sock, SIOCDELRT, &rt) < 0) { ALOGD("failed to remove route for %s to %s: %s", ifname, inet_ntoa(addr), strerror(errno)); } } fclose(fp); ifc_close(); return 0; }
int ifc_reset_connections(const char *ifname) { #ifdef HAVE_ANDROID_OS int result; in_addr_t myaddr; struct ifreq ifr; ifc_init(); ifc_get_info(ifname, &myaddr, NULL, NULL); ifc_init_ifr(ifname, &ifr); init_sockaddr_in(&ifr.ifr_addr, myaddr); result = ioctl(ifc_ctl_sock, SIOCKILLADDR, &ifr); ifc_close(); return result; #else return 0; #endif }
int ifc_act_on_ipv4_route(int action, const char *ifname, struct in_addr dst, int prefix_length, struct in_addr gw) { struct rtentry rt; int result; in_addr_t netmask; memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; rt.rt_dev = (void*) ifname; netmask = prefixLengthToIpv4Netmask(prefix_length); init_sockaddr_in(&rt.rt_genmask, netmask); init_sockaddr_in(&rt.rt_dst, dst.s_addr); rt.rt_flags = RTF_UP; if (prefix_length == 32) { rt.rt_flags |= RTF_HOST; } if (gw.s_addr != 0) { rt.rt_flags |= RTF_GATEWAY; init_sockaddr_in(&rt.rt_gateway, gw.s_addr); } ifc_init(); if (ifc_ctl_sock < 0) { return -errno; } result = ioctl(ifc_ctl_sock, action, &rt); if (result < 0) { if (errno == EEXIST) { result = 0; } else { result = -errno; } } ifc_close(); return result; }
int ifc_disable(const char *ifname) { unsigned addr, count; int result; ifc_init(); result = ifc_down(ifname); ifc_set_addr(ifname, 0); for (count=0, addr=1; ((addr != 0) && (count < 255)); count++) { if (ifc_get_addr(ifname, &addr) < 0) break; if (addr) ifc_set_addr(ifname, 0); } ifc_close(); return result; }
/* CHECK There are several error cases if PDP deactivation fails * 24.008: 8, 25, 36, 38, 39, 112 */ void requestDeactivateDefaultPDP(void *data, size_t datalen, RIL_Token t) { int e2napState = getE2napState(); int cid = atoi(((const char **) data)[0]); (void) datalen; if (cid != s_ActiveCID) { ALOGD("%s() Not tearing down cid:%d since cid:%d is active", __func__, cid, s_ActiveCID); goto done; } s_DeactCalled = 1; if (e2napState == E2NAP_STATE_CONNECTING) ALOGW("%s() Tear down connection while connection setup in progress", __func__); if (e2napState != E2NAP_STATE_DISCONNECTED) { if (disconnect()) goto error; e2napState = getE2napState(); if (e2napState != E2NAP_STATE_DISCONNECTED) goto error; /* Bring down the interface as well. */ if (ifc_init()) goto error; if (ifc_down(ril_iface)) goto error; ifc_close(); } done: RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); }
/* * Return the address of the default gateway * * TODO: factor out common code from this and remove_host_routes() * so that we only scan /proc/net/route in one place. * * DEPRECATED */ int ifc_get_default_route(const char *ifname) { char name[64]; in_addr_t dest, gway, mask; int flags, refcnt, use, metric, mtu, win, irtt; int result; FILE *fp; fp = fopen("/proc/net/route", "r"); if (fp == NULL) return 0; /* Skip the header line */ if (fscanf(fp, "%*[^\n]\n") < 0) { fclose(fp); return 0; } ifc_init(); result = 0; for (;;) { int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", name, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, &mtu, &win, &irtt); if (nread != 11) { break; } if ((flags & (RTF_UP|RTF_GATEWAY)) == (RTF_UP|RTF_GATEWAY) && dest == 0 && strcmp(ifname, name) == 0) { result = gway; break; } } fclose(fp); ifc_close(); return result; }
int getifaddrs(struct ifaddrs **ifap) { DIR *d; struct dirent *de; struct ifaddrs *ifa; struct ifaddrs *ifah = NULL; if (!ifap) return -1; *ifap = NULL; if (ifc_init()) return -1; d = opendir("/sys/class/net"); if (d == 0) return -1; while ((de = readdir(d))) { if (de->d_name[0] == '.') continue; ifa = get_interface(de->d_name, AF_INET); if (ifa != NULL) { ifa->ifa_next = ifah; ifah = ifa; } ifa = get_interface(de->d_name, AF_PACKET); if (ifa != NULL) { ifa->ifa_next = ifah; ifah = ifa; } } *ifap = ifah; closedir(d); ifc_close(); return 0; }
int SoftapController::stopDriver(char *iface) { int ret; if (mSock < 0) { LOGE("Softap driver stop - failed to open socket"); return -1; } if (!iface || (iface[0] == '\0')) { LOGD("Softap driver stop - wrong interface"); iface = mIface; } *mBuf = 0; #ifdef HAVE_HOSTAPD ifc_init(); ret = ifc_down(iface); ifc_close(); if (ret < 0) { LOGE("Softap %s down: %d", iface, ret); } #endif ret = setCommand(iface, "STOP"); LOGD("Softap driver stop: %d", ret); return ret; }
int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, int argc, char **argv) { if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (!strcmp(argv[1], "list")) { DIR *d; struct dirent *de; if (!(d = opendir("/sys/class/net"))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); return 0; } while((de = readdir(d))) { if (de->d_name[0] == '.') continue; cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); } closedir(d); cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); return 0; } else if (!strcmp(argv[1], "readrxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readrxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg; asprintf(&msg, "%lu", rx); cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "readtxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readtxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg = NULL; asprintf(&msg, "%lu", tx); cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "getthrottle")) { if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface getthrottle <interface> <rx|tx>", false); return 0; } int val = 0; int rc = 0; int voldRc = ResponseCode::InterfaceRxThrottleResult; if (!strcmp(argv[3], "rx")) { rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); } else { rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); voldRc = ResponseCode::InterfaceTxThrottleResult; } if (rc) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); } else { char *msg = NULL; asprintf(&msg, "%u", val); cli->sendMsg(voldRc, msg, false); free(msg); return 0; } return 0; } else if (!strcmp(argv[1], "setthrottle")) { if (argc != 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); return 0; } if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); } return 0; } else if (!strcmp(argv[1], "driver")) { int rc; char *rbuf; if (argc < 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface driver <interface> <cmd> <args>", false); return 0; } rc = sInterfaceCtrl->interfaceCommand(argc, argv, &rbuf); if (rc) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute command", true); } else { cli->sendMsg(ResponseCode::CommandOkay, rbuf, false); } return 0; } else { /* * These commands take a minimum of 3 arguments */ if (argc < 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } // 0 1 2 3 4 5 6 7 // interface route add/remove iface default/secondary dest prefix gateway if (!strcmp(argv[1], "route")) { int prefix_length = 0; if (argc < 8) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (sscanf(argv[6], "%d", &prefix_length) != 1) { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); return 0; } if (!strcmp(argv[2], "add")) { if (!strcmp(argv[4], "default")) { if (ifc_add_route(argv[3], argv[5], prefix_length, argv[7])) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route to default table", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Route added to default table", false); } } else if (!strcmp(argv[4], "secondary")) { return sSecondaryTableCtrl->addRoute(cli, argv[3], argv[5], prefix_length, argv[7]); } else { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route type, expecting 'default' or 'secondary'", false); return 0; } } else if (!strcmp(argv[2], "remove")) { if (!strcmp(argv[4], "default")) { if (ifc_remove_route(argv[3], argv[5], prefix_length, argv[7])) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route from default table", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Route removed from default table", false); } } else if (!strcmp(argv[4], "secondary")) { return sSecondaryTableCtrl->removeRoute(cli, argv[3], argv[5], prefix_length, argv[7]); } else { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route type, expecting 'default' or 'secondary'", false); return 0; } } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); } return 0; } if (!strcmp(argv[1], "getcfg")) { struct in_addr addr; int prefixLength; unsigned char hwaddr[6]; unsigned flags = 0; ifc_init(); memset(hwaddr, 0, sizeof(hwaddr)); if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); ifc_close(); return 0; } if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); } char *addr_s = strdup(inet_ntoa(addr)); const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; updown = (flags & IFF_UP) ? "up" : "down"; brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; running = (flags & IFF_RUNNING) ? " running" : ""; multi = (flags & IFF_MULTICAST) ? " multicast" : ""; char *flag_s; asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi); char *msg = NULL; asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], addr_s, prefixLength, flag_s); cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); free(addr_s); free(flag_s); free(msg); ifc_close(); return 0; } else if (!strcmp(argv[1], "setcfg")) { // arglist: iface [addr prefixLength] flags if (argc < 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } ALOGD("Setting iface cfg"); struct in_addr addr; unsigned flags = 0; int index = 5; ifc_init(); if (!inet_aton(argv[3], &addr)) { // Handle flags only case index = 3; } else { if (ifc_set_addr(argv[2], addr.s_addr)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); ifc_close(); return 0; } // Set prefix length on a non zero address if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); ifc_close(); return 0; } } /* Process flags */ for (int i = index; i < argc; i++) { char *flag = argv[i]; if (!strcmp(flag, "up")) { ALOGD("Trying to bring up %s", argv[2]); if (ifc_up(argv[2])) { ALOGE("Error upping interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); ifc_close(); return 0; } } else if (!strcmp(flag, "down")) { ALOGD("Trying to bring down %s", argv[2]); if (ifc_down(argv[2])) { ALOGE("Error downing interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); ifc_close(); return 0; } } else if (!strcmp(flag, "broadcast")) { // currently ignored } else if (!strcmp(flag, "multicast")) { // currently ignored } else if (!strcmp(flag, "running")) { // currently ignored } else if (!strcmp(flag, "loopback")) { // currently ignored } else if (!strcmp(flag, "point-to-point")) { // currently ignored } else { cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); ifc_close(); return 0; } } cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); ifc_close(); return 0; } else if (!strcmp(argv[1], "clearaddrs")) { // arglist: iface ALOGD("Clearing all IP addresses on %s", argv[2]); ifc_clear_addresses(argv[2]); cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false); return 0; } else if (!strcmp(argv[1], "ipv6privacyextensions")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface ipv6privacyextensions <interface> <enable|disable>", false); return 0; } char *tmp; asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", argv[2]); if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "2" : "0", 1) < 0) { free(tmp); cli->sendMsg(ResponseCode::OperationFailed, "Failed to set ipv6 privacy extensions", true); return 0; } free(tmp); cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false); return 0; } else if (!strcmp(argv[1], "ipv6")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface ipv6 <interface> <enable|disable>", false); return 0; } char *tmp; asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", argv[2]); if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "0" : "1", 1) < 0) { free(tmp); cli->sendMsg(ResponseCode::OperationFailed, "Failed to change IPv6 state", true); return 0; } free(tmp); cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false); return 0; } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); return 0; } } return 0; }
/* CHECK There are several error cases if PDP deactivation fails * 24.008: 8, 25, 36, 38, 39, 112 */ void requestDeactivateDefaultPDP(void *data, size_t datalen, RIL_Token t) { ATResponse *p_response = NULL; int enap = 0; int err, i; char *line; (void) data; (void) datalen; err = at_send_command_singleline("AT*ENAP?", "*ENAP:", &p_response); if (err != AT_NOERROR) goto error; line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &enap); if (err < 0) goto error; if (enap == ENAP_T_CONN_IN_PROG) LOGE("%s() Tear down connection while connection setup in progress", __func__); if (enap == ENAP_T_CONNECTED) { err = at_send_command("AT*ENAP=0"); /* TODO: can return CME error */ if (err != AT_NOERROR && at_get_error_type(err) != CME_ERROR) goto error; for (i = 0; i < MBM_ENAP_WAIT_TIME; i++) { at_response_free(p_response); p_response = NULL; err = at_send_command_singleline("AT*ENAP?", "*ENAP:", &p_response); if (err != AT_NOERROR) goto error; line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &enap); if (err < 0) goto error; if (enap == 0) break; sleep(1); } if (enap != ENAP_T_NOT_CONNECTED) goto error; /* Bring down the interface as well. */ if (ifc_init()) goto error; if (ifc_down(ril_iface)) goto error; ifc_close(); } RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); at_response_free(p_response); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); at_response_free(p_response); }
void* SetupData(void* t) { //this should never happen but let's check if(pppd_pid!=0 ) { LOGD(" waiting pppd to die"); int status=0; kill(pppd_pid, SIGTERM); waitpid(pppd_pid, &status, 0); } //reset ppp.dns property_set("net.ppp0.dns1", "0.0.0.0"); property_set("net.ppp0.dns2", "0.0.0.0"); strcpy(current_addr, "255.255.255.255"); pthread_t thread; pthread_create(&thread, NULL, pppd_thread, NULL); //wait for pppd connect if(ifc_init()) { LOGE("%s: IFC failed to init", logtime()); sleep(7); } else { clock_t start=clock(); //loop till timeout or connected while(1) { //check if ppp0 interface is up, if true break loop, else record dnschange value unsigned addr, mask, flags; ifc_get_info("ppp0", &addr, &mask, &flags); if(flags & 1) { struct in_addr in_addr = {.s_addr=addr}; strcpy(current_addr, inet_ntoa(in_addr)); LOGD("%s: IP: %s", logtime(),current_addr); break; } //if timeout goto error if ( (clock()-start)/CLOCKS_PER_SEC > 60 ){ LOGE("%s: ppp0 connect timed out, giving up", logtime()); ifc_close(); goto error; } int status, pid=pppd_pid; if(pid==0 || waitpid(pid, &status, WNOHANG)>0){ LOGE("%s: ppp0 connect timed out, giving up", logtime()); ifc_close(); goto error; } msleep(100); } } ifc_close(); //if ip-up exists wait for dns change char dns1[PROPERTY_VALUE_MAX]; char dns2[PROPERTY_VALUE_MAX]; struct stat sts; if(stat("/etc/ppp/ip-up", &sts)==0 && (S_ISREG(sts.st_mode) || S_ISLNK(sts.st_mode))) { clock_t start=clock(); while(1) { //check if dnschange changed property_get("net.ppp0.dns1", dns1, "0.0.0.0"); property_get("net.ppp0.dns2", dns2, "0.0.0.0"); if(strcmp(dns1, "0.0.0.0")!=0 && strcmp(dns2, "0.0.0.0")!=0) break; if((clock()-start)/CLOCKS_PER_SEC > 2) { LOGE("%s: timeout waiting for dns change", logtime()); break; } msleep(100); } } //check ppp.dns values and set defaults if suspect wrong property_get("net.ppp0.dns1", dns1, ""); if(strlen(dns1)<7 || strcmp(dns1,"0.0.0.0")==0 || strcmp(dns1, "10.11.12.13")==0) { LOGD("%s: DNS1: %s wrong setting to 8.8.8.8", logtime(),dns1); property_set("net.ppp0.dns1", "8.8.8.8"); } else { LOGD("%s: DNS1: %s", logtime(),dns1); } property_get("net.ppp0.dns2", dns2, ""); if(strlen(dns2)<7 || strcmp(dns2, "0.0.0.0")==0 || strcmp(dns2, "10.11.12.14")==0) { LOGD("%s: DNS2: %s wrong setting to 8.8.4.4", logtime(),dns2); property_set("net.ppp0.dns2", "8.8.4.4"); } else { LOGD("%s: DNS2: %s", logtime(),dns2); } char *response[3] = { "1", "ppp0", current_addr }; dataConnectionState=DATA_STATE_CONNECTED; RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); return NULL; error: dataConnectionState=DATA_STATE_DISCONNECTED; RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return NULL; }