static int extract_ip(DBusMessageIter *array, int family, struct connection_data *data) { DBusMessageIter dict; char *address = NULL, *gateway = NULL, *netmask = NULL, *peer = NULL; unsigned char prefix_len; if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY) return -EINVAL; dbus_message_iter_recurse(array, &dict); while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; const char *key; dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_recurse(&entry, &value); if (g_str_equal(key, "Address") == TRUE) { dbus_message_iter_get_basic(&value, &address); DBG("address %s", address); } else if (g_str_equal(key, "Netmask") == TRUE) { dbus_message_iter_get_basic(&value, &netmask); DBG("netmask %s", netmask); } else if (g_str_equal(key, "PrefixLength") == TRUE) { dbus_message_iter_get_basic(&value, &netmask); DBG("prefix length %s", netmask); } else if (g_str_equal(key, "Peer") == TRUE) { dbus_message_iter_get_basic(&value, &peer); DBG("peer %s", peer); } else if (g_str_equal(key, "Gateway") == TRUE) { dbus_message_iter_get_basic(&value, &gateway); DBG("gateway %s", gateway); } dbus_message_iter_next(&dict); } data->ip = connman_ipaddress_alloc(family); if (data->ip == NULL) return -ENOMEM; switch (family) { case AF_INET: connman_ipaddress_set_ipv4(data->ip, address, netmask, gateway); break; case AF_INET6: prefix_len = atoi(netmask); connman_ipaddress_set_ipv6(data->ip, address, prefix_len, gateway); break; default: return -EINVAL; } connman_ipaddress_set_peer(data->ip, peer); return 0; }
static int oc_notify(DBusMessage *msg, struct vpn_provider *provider) { DBusMessageIter iter, dict; const char *reason, *key, *value; char *domain = NULL; char *addressv4 = NULL, *addressv6 = NULL; char *netmask = NULL, *gateway = NULL; unsigned char prefix_len = 0; struct connman_ipaddress *ipaddress; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &reason); dbus_message_iter_next(&iter); if (!provider) { connman_error("No provider found"); return VPN_STATE_FAILURE; } if (strcmp(reason, "connect")) return VPN_STATE_DISCONNECT; domain = g_strdup(vpn_provider_get_string(provider, "VPN.Domain")); dbus_message_iter_recurse(&iter, &dict); while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry; dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_get_basic(&entry, &value); if (strcmp(key, "CISCO_CSTP_OPTIONS")) DBG("%s = %s", key, value); if (!strcmp(key, "VPNGATEWAY")) gateway = g_strdup(value); if (!strcmp(key, "INTERNAL_IP4_ADDRESS")) addressv4 = g_strdup(value); if (!strcmp(key, "INTERNAL_IP6_ADDRESS")) { addressv6 = g_strdup(value); prefix_len = 128; } if (!strcmp(key, "INTERNAL_IP4_NETMASK")) netmask = g_strdup(value); if (!strcmp(key, "INTERNAL_IP6_NETMASK")) { char *sep; /* The netmask contains the address and the prefix */ sep = strchr(value, '/'); if (sep != NULL) { unsigned char ip_len = sep - value; addressv6 = g_strndup(value, ip_len); prefix_len = (unsigned char) strtol(sep + 1, NULL, 10); } } if (!strcmp(key, "INTERNAL_IP4_DNS") || !strcmp(key, "INTERNAL_IP6_DNS")) vpn_provider_set_nameservers(provider, value); if (!strcmp(key, "CISCO_PROXY_PAC")) vpn_provider_set_pac(provider, value); if (domain == NULL && !strcmp(key, "CISCO_DEF_DOMAIN")) { g_free(domain); domain = g_strdup(value); } if (g_str_has_prefix(key, "CISCO_SPLIT_INC") == TRUE || g_str_has_prefix(key, "CISCO_IPV6_SPLIT_INC") == TRUE) vpn_provider_append_route(provider, key, value); dbus_message_iter_next(&dict); } DBG("%p %p", addressv4, addressv6); if (addressv4 != NULL) ipaddress = connman_ipaddress_alloc(AF_INET); else if (addressv6 != NULL) ipaddress = connman_ipaddress_alloc(AF_INET6); else ipaddress = NULL; if (ipaddress == NULL) { g_free(addressv4); g_free(addressv6); g_free(netmask); g_free(gateway); g_free(domain); return VPN_STATE_FAILURE; } if (addressv4 != NULL) connman_ipaddress_set_ipv4(ipaddress, addressv4, netmask, gateway); else connman_ipaddress_set_ipv6(ipaddress, addressv6, prefix_len, gateway); vpn_provider_set_ipaddress(provider, ipaddress); vpn_provider_set_domain(provider, domain); g_free(addressv4); g_free(addressv6); g_free(netmask); g_free(gateway); g_free(domain); connman_ipaddress_free(ipaddress); return VPN_STATE_CONNECT; }