int ifc_get_info(const char *name, in_addr_t *addr, int *prefixLength, unsigned *flags) { struct ifreq ifr; ifc_init_ifr(name, &ifr); if (addr != NULL) { if(ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr) < 0) { *addr = 0; } else { *addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; } } if (prefixLength != NULL) { if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) { *prefixLength = 0; } else { *prefixLength = ipv4NetmaskToPrefixLength( ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr); } } if (flags != NULL) { if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) { *flags = 0; } else { *flags = ifr.ifr_flags; } } return 0; }
int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection, char **setup_data_call_response) #endif { struct ipc_client *ipc_client; struct ipc_gprs_ip_configuration *ip_configuration; char *interface = NULL; char *ip; char *gateway; char *subnet_mask; in_addr_t subnet_mask_addr; char *dns1; char *dns2; char prop_name[PROPERTY_KEY_MAX]; int rc; ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client; ip_configuration = &(gprs_connection->ip_configuration); asprintf(&ip, "%i.%i.%i.%i", (ip_configuration->ip)[0], (ip_configuration->ip)[1], (ip_configuration->ip)[2], (ip_configuration->ip)[3]); // FIXME: gateway isn't reliable! asprintf(&gateway, "%i.%i.%i.%i", (ip_configuration->ip)[0], (ip_configuration->ip)[1], (ip_configuration->ip)[2], (ip_configuration->ip)[3]); // FIXME: subnet isn't reliable! asprintf(&subnet_mask, "255.255.255.255"); asprintf(&dns1, "%i.%i.%i.%i", (ip_configuration->dns1)[0], (ip_configuration->dns1)[1], (ip_configuration->dns1)[2], (ip_configuration->dns1)[3]); asprintf(&dns2, "%i.%i.%i.%i", (ip_configuration->dns2)[0], (ip_configuration->dns2)[1], (ip_configuration->dns2)[2], (ip_configuration->dns2)[3]); if(ipc_client_gprs_handlers_available(ipc_client)) { rc = ipc_client_gprs_activate(ipc_client); if(rc < 0) { // This is not a critical issue LOGE("Failed to activate interface!"); } } interface = ipc_client_gprs_get_iface(ipc_client, gprs_connection->cid); if(interface == NULL) { // This is not a critical issue, fallback to rmnet LOGE("Failed to get interface name!"); asprintf(&interface, "rmnet%d", gprs_connection->cid - 1); } if(gprs_connection->interface == NULL && interface != NULL) { gprs_connection->interface = strdup(interface); } LOGD("Using net interface: %s\n", interface); LOGD("GPRS configuration: iface: %s, ip:%s, " "gateway:%s, subnet_mask:%s, dns1:%s, dns2:%s", interface, ip, gateway, subnet_mask, dns1, dns2); subnet_mask_addr = inet_addr(subnet_mask); #if RIL_VERSION >= 6 rc = ifc_configure(interface, inet_addr(ip), ipv4NetmaskToPrefixLength(subnet_mask_addr), inet_addr(gateway), inet_addr(dns1), inet_addr(dns2)); #else rc = ifc_configure(interface, inet_addr(ip), subnet_mask_addr, inet_addr(gateway), inet_addr(dns1), inet_addr(dns2)); #endif if(rc < 0) { LOGE("ifc_configure failed"); free(interface); return -1; } snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns1", interface); property_set(prop_name, dns1); snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns2", interface); property_set(prop_name, dns2); snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.gw", interface); property_set(prop_name, gateway); #if RIL_VERSION >= 6 setup_data_call_response->status = 0; setup_data_call_response->cid = gprs_connection->cid; setup_data_call_response->active = 1; setup_data_call_response->type = strdup("IP"); setup_data_call_response->ifname = interface; setup_data_call_response->addresses = ip; setup_data_call_response->gateways = gateway; asprintf(&setup_data_call_response->dnses, "%s %s", dns1, dns2); #else asprintf(&(setup_data_call_response[0]), "%d", gprs_connection->cid); setup_data_call_response[1] = interface; setup_data_call_response[2] = ip; free(gateway); #endif free(subnet_mask); free(dns1); free(dns2); return 0; }
int decode_dhcp_msg(dhcp_msg *msg, int len, dhcp_info *info) { uint8_t *x; unsigned int opt; int optlen; memset(info, 0, sizeof(dhcp_info)); if (len < (DHCP_MSG_FIXED_SIZE + 4)) return -1; len -= (DHCP_MSG_FIXED_SIZE + 4); if (msg->options[0] != OPT_COOKIE1) return -1; if (msg->options[1] != OPT_COOKIE2) return -1; if (msg->options[2] != OPT_COOKIE3) return -1; if (msg->options[3] != OPT_COOKIE4) return -1; x = msg->options + 4; while (len > 2) { opt = *x++; if (opt == OPT_PAD) { len--; continue; } if (opt == OPT_END) { break; } optlen = *x++; len -= 2; if (optlen > len) { break; } switch(opt) { case OPT_SUBNET_MASK: if (optlen >= 4) { in_addr_t mask; memcpy(&mask, x, 4); info->prefixLength = ipv4NetmaskToPrefixLength(mask); } break; case OPT_GATEWAY: if (optlen >= 4) memcpy(&info->gateway, x, 4); break; case OPT_DNS: if (optlen >= 4) memcpy(&info->dns1, x + 0, 4); if (optlen >= 8) memcpy(&info->dns2, x + 4, 4); break; case OPT_LEASE_TIME: if (optlen >= 4) { memcpy(&info->lease, x, 4); info->lease = ntohl(info->lease); } break; case OPT_SERVER_ID: if (optlen >= 4) memcpy(&info->serveraddr, x, 4); break; case OPT_MESSAGE_TYPE: info->type = *x; break; default: break; } x += optlen; len -= optlen; } info->ipaddr = msg->yiaddr; return 0; }