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;
}
Beispiel #3
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;
}