5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <net/if_arp.h>
30 #include <linux/if_link.h>
35 #define IFF_LOWER_UP 0x10000
39 #include <connman/ipaddress.h>
43 struct connman_ipconfig {
46 enum connman_ipconfig_type type;
48 const struct connman_ipconfig_ops *ops;
52 enum connman_ipconfig_method method;
53 struct connman_ipaddress *address;
54 struct connman_ipaddress *system;
56 int ipv6_privacy_config;
57 char *last_dhcp_address;
58 char **last_dhcpv6_prefixes;
61 struct connman_ipdevice {
82 struct connman_ipconfig *config_ipv4;
83 struct connman_ipconfig *config_ipv6;
89 static GHashTable *ipdevice_hash = NULL;
90 static GList *ipconfig_list = NULL;
91 static bool is_ipv6_supported = false;
93 void __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
98 connman_ipaddress_clear(ipconfig->address);
101 static void free_address_list(struct connman_ipdevice *ipdevice)
105 for (list = ipdevice->address_list; list; list = list->next) {
106 struct connman_ipaddress *ipaddress = list->data;
108 connman_ipaddress_free(ipaddress);
112 g_slist_free(ipdevice->address_list);
113 ipdevice->address_list = NULL;
116 static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
117 unsigned char prefixlen, const char *local)
121 for (list = ipdevice->address_list; list; list = list->next) {
122 struct connman_ipaddress *ipaddress = list->data;
124 if (g_strcmp0(ipaddress->local, local) == 0 &&
125 ipaddress->prefixlen == prefixlen)
132 const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type)
135 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
136 case CONNMAN_IPCONFIG_TYPE_ALL:
138 case CONNMAN_IPCONFIG_TYPE_IPV4:
140 case CONNMAN_IPCONFIG_TYPE_IPV6:
147 static const char *type2str(unsigned short type)
152 case ARPHRD_LOOPBACK:
165 static const char *scope2str(unsigned char scope)
177 static bool get_ipv6_state(gchar *ifname)
182 bool enabled = false;
185 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
187 path = g_strdup_printf(
188 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
193 f = fopen(path, "r");
198 if (fscanf(f, "%d", &disabled) > 0)
206 static void set_ipv6_state(gchar *ifname, bool enable)
212 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
214 path = g_strdup_printf(
215 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
220 f = fopen(path, "r+");
235 static int get_ipv6_privacy(gchar *ifname)
244 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
250 f = fopen(path, "r");
257 if (fscanf(f, "%d", &value) <= 0)
265 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
266 * The privacy extension is described in RFC 3041 and RFC 4941
268 static void set_ipv6_privacy(gchar *ifname, int value)
276 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
285 f = fopen(path, "r+");
292 fprintf(f, "%d", value);
296 static int get_rp_filter(void)
299 int value = -EINVAL, tmp;
301 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
304 if (fscanf(f, "%d", &tmp) == 1)
312 static void set_rp_filter(int value)
316 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
321 fprintf(f, "%d", value);
326 int __connman_ipconfig_set_rp_filter()
330 value = get_rp_filter();
337 connman_info("rp_filter set to 2 (loose mode routing), "
338 "old value was %d", value);
343 void __connman_ipconfig_unset_rp_filter(int old_value)
345 set_rp_filter(old_value);
347 connman_info("rp_filter restored to %d", old_value);
350 bool __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
355 return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
358 bool __connman_ipconfig_ipv6_is_enabled(struct connman_ipconfig *ipconfig)
360 struct connman_ipdevice *ipdevice;
367 ipdevice = g_hash_table_lookup(ipdevice_hash,
368 GINT_TO_POINTER(ipconfig->index));
372 ifname = connman_inet_ifname(ipconfig->index);
373 ret = get_ipv6_state(ifname);
379 static void free_ipdevice(gpointer data)
381 struct connman_ipdevice *ipdevice = data;
382 char *ifname = connman_inet_ifname(ipdevice->index);
384 connman_info("%s {remove} index %d", ifname, ipdevice->index);
386 if (ipdevice->config_ipv4) {
387 __connman_ipconfig_unref(ipdevice->config_ipv4);
388 ipdevice->config_ipv4 = NULL;
391 if (ipdevice->config_ipv6) {
392 __connman_ipconfig_unref(ipdevice->config_ipv6);
393 ipdevice->config_ipv6 = NULL;
396 free_address_list(ipdevice);
397 g_free(ipdevice->ipv4_gateway);
398 g_free(ipdevice->ipv6_gateway);
399 g_free(ipdevice->pac);
401 g_free(ipdevice->address);
403 set_ipv6_state(ifname, ipdevice->ipv6_enabled);
404 set_ipv6_privacy(ifname, ipdevice->ipv6_privacy);
410 static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
412 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
413 ipdevice->config_ipv6);
416 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
418 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
419 ipdevice->config_ipv6);
421 if (ipdevice->config_ipv4)
422 connman_inet_clear_address(ipdevice->index,
423 ipdevice->config_ipv4->address);
425 if (ipdevice->config_ipv6)
426 connman_inet_clear_ipv6_address(ipdevice->index,
427 ipdevice->config_ipv6->address->local,
428 ipdevice->config_ipv6->address->prefixlen);
431 static void update_stats(struct connman_ipdevice *ipdevice,
432 const char *ifname, struct rtnl_link_stats *stats)
434 struct connman_service *service;
436 if (stats->rx_packets == 0 && stats->tx_packets == 0)
439 connman_info("%s {RX} %u packets %u bytes", ifname,
440 stats->rx_packets, stats->rx_bytes);
441 connman_info("%s {TX} %u packets %u bytes", ifname,
442 stats->tx_packets, stats->tx_bytes);
444 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
447 service = __connman_service_lookup_from_index(ipdevice->index);
449 DBG("service %p", service);
454 ipdevice->rx_packets = stats->rx_packets;
455 ipdevice->tx_packets = stats->tx_packets;
456 ipdevice->rx_bytes = stats->rx_bytes;
457 ipdevice->tx_bytes = stats->tx_bytes;
458 ipdevice->rx_errors = stats->rx_errors;
459 ipdevice->tx_errors = stats->tx_errors;
460 ipdevice->rx_dropped = stats->rx_dropped;
461 ipdevice->tx_dropped = stats->tx_dropped;
463 __connman_service_notify(service,
464 ipdevice->rx_packets, ipdevice->tx_packets,
465 ipdevice->rx_bytes, ipdevice->tx_bytes,
466 ipdevice->rx_errors, ipdevice->tx_errors,
467 ipdevice->rx_dropped, ipdevice->tx_dropped);
470 void __connman_ipconfig_newlink(int index, unsigned short type,
471 unsigned int flags, const char *address,
473 struct rtnl_link_stats *stats)
475 struct connman_ipdevice *ipdevice;
476 GList *list, *ipconfig_copy;
478 bool up = false, down = false;
479 bool lower_up = false, lower_down = false;
482 DBG("index %d", index);
484 if (type == ARPHRD_LOOPBACK)
487 ifname = connman_inet_ifname(index);
489 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
493 ipdevice = g_try_new0(struct connman_ipdevice, 1);
497 ipdevice->index = index;
498 ipdevice->type = type;
500 ipdevice->ipv6_enabled = get_ipv6_state(ifname);
501 ipdevice->ipv6_privacy = get_ipv6_privacy(ifname);
503 ipdevice->address = g_strdup(address);
505 g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
507 connman_info("%s {create} index %d type %d <%s>", ifname,
508 index, type, type2str(type));
513 update_stats(ipdevice, ifname, stats);
515 if (flags == ipdevice->flags)
518 if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
525 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
526 (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
527 if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
528 (IFF_RUNNING | IFF_LOWER_UP))
530 else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
534 ipdevice->flags = flags;
536 str = g_string_new(NULL);
541 g_string_append(str, "UP");
543 g_string_append(str, "DOWN");
545 if (flags & IFF_RUNNING)
546 g_string_append(str, ",RUNNING");
548 if (flags & IFF_LOWER_UP)
549 g_string_append(str, ",LOWER_UP");
551 connman_info("%s {update} flags %u <%s>", ifname, flags, str->str);
553 g_string_free(str, TRUE);
555 ipconfig_copy = g_list_copy(ipconfig_list);
557 for (list = g_list_first(ipconfig_copy); list;
558 list = g_list_next(list)) {
559 struct connman_ipconfig *ipconfig = list->data;
561 if (index != ipconfig->index)
567 if (up && ipconfig->ops->up)
568 ipconfig->ops->up(ipconfig, ifname);
569 if (lower_up && ipconfig->ops->lower_up)
570 ipconfig->ops->lower_up(ipconfig, ifname);
572 if (lower_down && ipconfig->ops->lower_down)
573 ipconfig->ops->lower_down(ipconfig, ifname);
574 if (down && ipconfig->ops->down)
575 ipconfig->ops->down(ipconfig, ifname);
578 g_list_free(ipconfig_copy);
581 __connman_ipconfig_lower_up(ipdevice);
583 __connman_ipconfig_lower_down(ipdevice);
589 void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
591 struct connman_ipdevice *ipdevice;
595 DBG("index %d", index);
597 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
601 ifname = connman_inet_ifname(index);
603 update_stats(ipdevice, ifname, stats);
605 for (list = g_list_first(ipconfig_list); list;
606 list = g_list_next(list)) {
607 struct connman_ipconfig *ipconfig = list->data;
609 if (index != ipconfig->index)
612 ipconfig->index = -1;
617 if (ipconfig->ops->lower_down)
618 ipconfig->ops->lower_down(ipconfig, ifname);
619 if (ipconfig->ops->down)
620 ipconfig->ops->down(ipconfig, ifname);
625 __connman_ipconfig_lower_down(ipdevice);
627 g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
630 static inline gint check_duplicate_address(gconstpointer a, gconstpointer b)
632 const struct connman_ipaddress *addr1 = a;
633 const struct connman_ipaddress *addr2 = b;
635 if (addr1->prefixlen != addr2->prefixlen)
636 return addr2->prefixlen - addr1->prefixlen;
638 return g_strcmp0(addr1->local, addr2->local);
641 int __connman_ipconfig_newaddr(int index, int family, const char *label,
642 unsigned char prefixlen, const char *address)
644 struct connman_ipdevice *ipdevice;
645 struct connman_ipaddress *ipaddress;
646 enum connman_ipconfig_type type;
650 DBG("index %d", index);
652 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
656 ipaddress = connman_ipaddress_alloc(family);
660 ipaddress->prefixlen = prefixlen;
661 ipaddress->local = g_strdup(address);
663 if (g_slist_find_custom(ipdevice->address_list, ipaddress,
664 check_duplicate_address)) {
665 connman_ipaddress_free(ipaddress);
669 if (family == AF_INET)
670 type = CONNMAN_IPCONFIG_TYPE_IPV4;
671 else if (family == AF_INET6)
672 type = CONNMAN_IPCONFIG_TYPE_IPV6;
676 ipdevice->address_list = g_slist_prepend(ipdevice->address_list,
679 ifname = connman_inet_ifname(index);
680 connman_info("%s {add} address %s/%u label %s family %d",
681 ifname, address, prefixlen, label, family);
683 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
684 __connman_ippool_newaddr(index, address, prefixlen);
686 if (ipdevice->config_ipv4 && family == AF_INET)
687 connman_ipaddress_copy_address(ipdevice->config_ipv4->system,
690 else if (ipdevice->config_ipv6 && family == AF_INET6)
691 connman_ipaddress_copy_address(ipdevice->config_ipv6->system,
696 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
699 for (list = g_list_first(ipconfig_list); list;
700 list = g_list_next(list)) {
701 struct connman_ipconfig *ipconfig = list->data;
703 if (index != ipconfig->index)
706 if (type != ipconfig->type)
712 if (ipconfig->ops->ip_bound)
713 ipconfig->ops->ip_bound(ipconfig, ifname);
721 void __connman_ipconfig_deladdr(int index, int family, const char *label,
722 unsigned char prefixlen, const char *address)
724 struct connman_ipdevice *ipdevice;
725 struct connman_ipaddress *ipaddress;
726 enum connman_ipconfig_type type;
730 DBG("index %d", index);
732 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
736 ipaddress = find_ipaddress(ipdevice, prefixlen, address);
740 if (family == AF_INET)
741 type = CONNMAN_IPCONFIG_TYPE_IPV4;
742 else if (family == AF_INET6)
743 type = CONNMAN_IPCONFIG_TYPE_IPV6;
747 ipdevice->address_list = g_slist_remove(ipdevice->address_list,
750 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
751 __connman_ippool_deladdr(index, address, prefixlen);
753 connman_ipaddress_clear(ipaddress);
756 ifname = connman_inet_ifname(index);
757 connman_info("%s {del} address %s/%u label %s", ifname,
758 address, prefixlen, label);
760 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
763 if (g_slist_length(ipdevice->address_list) > 0)
766 for (list = g_list_first(ipconfig_list); list;
767 list = g_list_next(list)) {
768 struct connman_ipconfig *ipconfig = list->data;
770 if (index != ipconfig->index)
773 if (type != ipconfig->type)
779 if (ipconfig->ops->ip_release)
780 ipconfig->ops->ip_release(ipconfig, ifname);
787 void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
788 const char *dst, const char *gateway)
790 struct connman_ipdevice *ipdevice;
793 DBG("index %d", index);
795 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
799 ifname = connman_inet_ifname(index);
801 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
802 g_strcmp0(dst, "::") == 0)) {
804 enum connman_ipconfig_type type;
806 if (family == AF_INET6) {
807 type = CONNMAN_IPCONFIG_TYPE_IPV6;
808 g_free(ipdevice->ipv6_gateway);
809 ipdevice->ipv6_gateway = g_strdup(gateway);
811 if (ipdevice->config_ipv6 &&
812 ipdevice->config_ipv6->system) {
813 g_free(ipdevice->config_ipv6->system->gateway);
814 ipdevice->config_ipv6->system->gateway =
817 } else if (family == AF_INET) {
818 type = CONNMAN_IPCONFIG_TYPE_IPV4;
819 g_free(ipdevice->ipv4_gateway);
820 ipdevice->ipv4_gateway = g_strdup(gateway);
822 if (ipdevice->config_ipv4 &&
823 ipdevice->config_ipv4->system) {
824 g_free(ipdevice->config_ipv4->system->gateway);
825 ipdevice->config_ipv4->system->gateway =
831 for (config_list = g_list_first(ipconfig_list); config_list;
832 config_list = g_list_next(config_list)) {
833 struct connman_ipconfig *ipconfig = config_list->data;
835 if (index != ipconfig->index)
838 if (type != ipconfig->type)
844 if (ipconfig->ops->route_set)
845 ipconfig->ops->route_set(ipconfig, ifname);
849 connman_info("%s {add} route %s gw %s scope %u <%s>",
850 ifname, dst, gateway, scope, scope2str(scope));
856 void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
857 const char *dst, const char *gateway)
859 struct connman_ipdevice *ipdevice;
862 DBG("index %d", index);
864 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
868 ifname = connman_inet_ifname(index);
870 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
871 g_strcmp0(dst, "::") == 0)) {
873 enum connman_ipconfig_type type;
875 if (family == AF_INET6) {
876 type = CONNMAN_IPCONFIG_TYPE_IPV6;
877 g_free(ipdevice->ipv6_gateway);
878 ipdevice->ipv6_gateway = NULL;
880 if (ipdevice->config_ipv6 &&
881 ipdevice->config_ipv6->system) {
882 g_free(ipdevice->config_ipv6->system->gateway);
883 ipdevice->config_ipv6->system->gateway = NULL;
885 } else if (family == AF_INET) {
886 type = CONNMAN_IPCONFIG_TYPE_IPV4;
887 g_free(ipdevice->ipv4_gateway);
888 ipdevice->ipv4_gateway = NULL;
890 if (ipdevice->config_ipv4 &&
891 ipdevice->config_ipv4->system) {
892 g_free(ipdevice->config_ipv4->system->gateway);
893 ipdevice->config_ipv4->system->gateway = NULL;
898 for (config_list = g_list_first(ipconfig_list); config_list;
899 config_list = g_list_next(config_list)) {
900 struct connman_ipconfig *ipconfig = config_list->data;
902 if (index != ipconfig->index)
905 if (type != ipconfig->type)
911 if (ipconfig->ops->route_unset)
912 ipconfig->ops->route_unset(ipconfig, ifname);
916 connman_info("%s {del} route %s gw %s scope %u <%s>",
917 ifname, dst, gateway, scope, scope2str(scope));
923 void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
928 keys = g_hash_table_get_keys(ipdevice_hash);
932 for (list = g_list_first(keys); list; list = g_list_next(list)) {
933 int index = GPOINTER_TO_INT(list->data);
935 function(index, user_data);
941 enum connman_ipconfig_type __connman_ipconfig_get_config_type(
942 struct connman_ipconfig *ipconfig)
944 return ipconfig ? ipconfig->type : CONNMAN_IPCONFIG_TYPE_UNKNOWN;
947 unsigned short __connman_ipconfig_get_type_from_index(int index)
949 struct connman_ipdevice *ipdevice;
951 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
955 return ipdevice->type;
958 unsigned int __connman_ipconfig_get_flags_from_index(int index)
960 struct connman_ipdevice *ipdevice;
962 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
966 return ipdevice->flags;
969 const char *__connman_ipconfig_get_gateway_from_index(int index,
970 enum connman_ipconfig_type type)
972 struct connman_ipdevice *ipdevice;
974 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
978 if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
979 if (ipdevice->ipv4_gateway)
980 return ipdevice->ipv4_gateway;
982 if (ipdevice->config_ipv4 &&
983 ipdevice->config_ipv4->address)
984 return ipdevice->config_ipv4->address->gateway;
987 if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
988 if (ipdevice->ipv6_gateway)
989 return ipdevice->ipv6_gateway;
991 if (ipdevice->config_ipv6 &&
992 ipdevice->config_ipv6->address)
993 return ipdevice->config_ipv6->address->gateway;
999 void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
1001 ipconfig->index = index;
1004 const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
1006 if (!ipconfig->address)
1009 return ipconfig->address->local;
1012 void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig,
1013 const char *address)
1015 if (!ipconfig->address)
1018 g_free(ipconfig->address->local);
1019 ipconfig->address->local = g_strdup(address);
1022 const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
1024 if (!ipconfig->address)
1027 return ipconfig->address->peer;
1030 void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig,
1031 const char *address)
1033 if (!ipconfig->address)
1036 g_free(ipconfig->address->peer);
1037 ipconfig->address->peer = g_strdup(address);
1040 const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
1042 if (!ipconfig->address)
1045 return ipconfig->address->broadcast;
1048 void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig,
1049 const char *broadcast)
1051 if (!ipconfig->address)
1054 g_free(ipconfig->address->broadcast);
1055 ipconfig->address->broadcast = g_strdup(broadcast);
1058 const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
1060 if (!ipconfig->address)
1063 return ipconfig->address->gateway;
1066 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
1067 const char *gateway)
1071 if (!ipconfig->address)
1073 g_free(ipconfig->address->gateway);
1074 ipconfig->address->gateway = g_strdup(gateway);
1077 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
1079 struct connman_service *service;
1083 if (!ipconfig->address)
1086 service = __connman_service_lookup_from_index(ipconfig->index);
1090 DBG("type %d gw %s peer %s", ipconfig->type,
1091 ipconfig->address->gateway, ipconfig->address->peer);
1093 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6 ||
1094 ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1095 return __connman_connection_gateway_add(service,
1096 ipconfig->address->gateway,
1098 ipconfig->address->peer);
1103 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
1105 struct connman_service *service;
1109 service = __connman_service_lookup_from_index(ipconfig->index);
1111 __connman_connection_gateway_remove(service, ipconfig->type);
1114 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
1116 if (!ipconfig->address)
1119 return ipconfig->address->prefixlen;
1122 void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig,
1123 unsigned char prefixlen)
1125 if (!ipconfig->address)
1128 ipconfig->address->prefixlen = prefixlen;
1131 static struct connman_ipconfig *create_ipv6config(int index)
1133 struct connman_ipconfig *ipv6config;
1134 struct connman_ipdevice *ipdevice;
1136 DBG("index %d", index);
1138 ipv6config = g_try_new0(struct connman_ipconfig, 1);
1142 ipv6config->refcount = 1;
1144 ipv6config->index = index;
1145 ipv6config->enabled = false;
1146 ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
1148 if (!is_ipv6_supported)
1149 ipv6config->method = CONNMAN_IPCONFIG_METHOD_OFF;
1151 ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
1153 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1155 ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
1157 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1158 if (!ipv6config->address) {
1163 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1165 DBG("ipconfig %p method %s", ipv6config,
1166 __connman_ipconfig_method2string(ipv6config->method));
1172 * connman_ipconfig_create:
1174 * Allocate a new ipconfig structure.
1176 * Returns: a newly-allocated #connman_ipconfig structure
1178 struct connman_ipconfig *__connman_ipconfig_create(int index,
1179 enum connman_ipconfig_type type)
1181 struct connman_ipconfig *ipconfig;
1183 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1184 return create_ipv6config(index);
1186 DBG("index %d", index);
1188 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1192 ipconfig->refcount = 1;
1194 ipconfig->index = index;
1195 ipconfig->enabled = false;
1196 ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
1198 ipconfig->address = connman_ipaddress_alloc(AF_INET);
1199 if (!ipconfig->address) {
1204 ipconfig->system = connman_ipaddress_alloc(AF_INET);
1206 DBG("ipconfig %p", ipconfig);
1213 * connman_ipconfig_ref:
1214 * @ipconfig: ipconfig structure
1216 * Increase reference counter of ipconfig
1218 struct connman_ipconfig *
1219 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1220 const char *file, int line, const char *caller)
1222 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1223 file, line, caller);
1225 __sync_fetch_and_add(&ipconfig->refcount, 1);
1231 * connman_ipconfig_unref:
1232 * @ipconfig: ipconfig structure
1234 * Decrease reference counter of ipconfig
1236 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1237 const char *file, int line, const char *caller)
1242 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1243 file, line, caller);
1245 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1248 if (__connman_ipconfig_disable(ipconfig) < 0)
1249 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1251 __connman_ipconfig_set_ops(ipconfig, NULL);
1253 connman_ipaddress_free(ipconfig->system);
1254 connman_ipaddress_free(ipconfig->address);
1255 g_free(ipconfig->last_dhcp_address);
1256 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1261 * connman_ipconfig_get_data:
1262 * @ipconfig: ipconfig structure
1264 * Get private data pointer
1266 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1271 return ipconfig->ops_data;
1275 * connman_ipconfig_set_data:
1276 * @ipconfig: ipconfig structure
1277 * @data: data pointer
1279 * Set private data pointer
1281 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1283 ipconfig->ops_data = data;
1287 * connman_ipconfig_get_index:
1288 * @ipconfig: ipconfig structure
1290 * Get interface index
1292 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1297 return ipconfig->index;
1301 * connman_ipconfig_set_ops:
1302 * @ipconfig: ipconfig structure
1303 * @ops: operation callbacks
1305 * Set the operation callbacks
1307 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1308 const struct connman_ipconfig_ops *ops)
1310 ipconfig->ops = ops;
1314 * connman_ipconfig_set_method:
1315 * @ipconfig: ipconfig structure
1316 * @method: configuration method
1318 * Set the configuration method
1320 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1321 enum connman_ipconfig_method method)
1323 ipconfig->method = method;
1328 enum connman_ipconfig_method __connman_ipconfig_get_method(
1329 struct connman_ipconfig *ipconfig)
1332 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1334 return ipconfig->method;
1337 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1341 switch (ipconfig->method) {
1342 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1343 case CONNMAN_IPCONFIG_METHOD_OFF:
1345 case CONNMAN_IPCONFIG_METHOD_AUTO:
1346 case CONNMAN_IPCONFIG_METHOD_FIXED:
1347 case CONNMAN_IPCONFIG_METHOD_DHCP:
1348 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1349 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1350 return connman_inet_set_address(ipconfig->index,
1352 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1353 return connman_inet_set_ipv6_address(
1354 ipconfig->index, ipconfig->address);
1360 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1369 DBG("method %d", ipconfig->method);
1371 switch (ipconfig->method) {
1372 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1373 case CONNMAN_IPCONFIG_METHOD_OFF:
1375 case CONNMAN_IPCONFIG_METHOD_AUTO:
1376 case CONNMAN_IPCONFIG_METHOD_FIXED:
1377 case CONNMAN_IPCONFIG_METHOD_DHCP:
1378 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1379 err = __connman_ipconfig_address_unset(ipconfig);
1380 connman_ipaddress_clear(ipconfig->address);
1388 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1397 DBG("method %d", ipconfig->method);
1399 switch (ipconfig->method) {
1400 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1401 case CONNMAN_IPCONFIG_METHOD_OFF:
1403 case CONNMAN_IPCONFIG_METHOD_AUTO:
1404 case CONNMAN_IPCONFIG_METHOD_FIXED:
1405 case CONNMAN_IPCONFIG_METHOD_DHCP:
1406 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1407 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1408 err = connman_inet_clear_address(ipconfig->index,
1410 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1411 err = connman_inet_clear_ipv6_address(
1413 ipconfig->address->local,
1414 ipconfig->address->prefixlen);
1424 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1427 struct connman_ipdevice *ipdevice;
1429 DBG("ipconfig %p", ipconfig);
1431 if (!ipconfig || ipconfig->index < 0)
1434 ipdevice = g_hash_table_lookup(ipdevice_hash,
1435 GINT_TO_POINTER(ipconfig->index));
1439 g_free(ipdevice->pac);
1440 ipdevice->pac = g_strdup(url);
1445 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1447 struct connman_ipdevice *ipdevice;
1449 DBG("ipconfig %p", ipconfig);
1451 if (!ipconfig || ipconfig->index < 0)
1454 ipdevice = g_hash_table_lookup(ipdevice_hash,
1455 GINT_TO_POINTER(ipconfig->index));
1459 return ipdevice->pac;
1462 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1463 const char *address)
1468 g_free(ipconfig->last_dhcp_address);
1469 ipconfig->last_dhcp_address = g_strdup(address);
1472 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1477 return ipconfig->last_dhcp_address;
1480 void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
1486 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1487 ipconfig->last_dhcpv6_prefixes = prefixes;
1490 char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
1495 return ipconfig->last_dhcpv6_prefixes;
1498 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1500 struct connman_ipdevice *ipdevice;
1505 ipdevice = g_hash_table_lookup(ipdevice_hash,
1506 GINT_TO_POINTER(ipconfig->index));
1510 ifname = connman_inet_ifname(ipconfig->index);
1512 set_ipv6_state(ifname, false);
1517 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1519 struct connman_ipdevice *ipdevice;
1524 ipdevice = g_hash_table_lookup(ipdevice_hash,
1525 GINT_TO_POINTER(ipconfig->index));
1529 ifname = connman_inet_ifname(ipconfig->index);
1531 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1532 set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
1534 set_ipv6_state(ifname, true);
1539 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1541 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1544 enable_ipv6(ipconfig);
1547 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1549 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1552 disable_ipv6(ipconfig);
1555 bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1560 switch (ipconfig->method) {
1561 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1562 case CONNMAN_IPCONFIG_METHOD_OFF:
1564 case CONNMAN_IPCONFIG_METHOD_AUTO:
1565 case CONNMAN_IPCONFIG_METHOD_FIXED:
1566 case CONNMAN_IPCONFIG_METHOD_DHCP:
1567 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1574 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1576 struct connman_ipdevice *ipdevice;
1577 bool up = false, down = false;
1578 bool lower_up = false, lower_down = false;
1579 enum connman_ipconfig_type type;
1582 DBG("ipconfig %p", ipconfig);
1584 if (!ipconfig || ipconfig->index < 0)
1587 ipdevice = g_hash_table_lookup(ipdevice_hash,
1588 GINT_TO_POINTER(ipconfig->index));
1592 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1593 if (ipdevice->config_ipv4 == ipconfig)
1595 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1596 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1597 if (ipdevice->config_ipv6 == ipconfig)
1599 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1603 ipconfig->enabled = true;
1605 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1606 ipdevice->config_ipv4) {
1607 ipconfig_list = g_list_remove(ipconfig_list,
1608 ipdevice->config_ipv4);
1610 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1612 __connman_ipconfig_unref(ipdevice->config_ipv4);
1615 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1616 ipdevice->config_ipv6) {
1617 ipconfig_list = g_list_remove(ipconfig_list,
1618 ipdevice->config_ipv6);
1620 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1622 __connman_ipconfig_unref(ipdevice->config_ipv6);
1625 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1626 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1627 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1628 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1630 enable_ipv6(ipdevice->config_ipv6);
1632 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1634 if (ipdevice->flags & IFF_UP)
1639 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1640 (IFF_RUNNING | IFF_LOWER_UP))
1642 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1645 ifname = connman_inet_ifname(ipconfig->index);
1647 if (up && ipconfig->ops->up)
1648 ipconfig->ops->up(ipconfig, ifname);
1649 if (lower_up && ipconfig->ops->lower_up)
1650 ipconfig->ops->lower_up(ipconfig, ifname);
1652 if (lower_down && ipconfig->ops->lower_down)
1653 ipconfig->ops->lower_down(ipconfig, ifname);
1654 if (down && ipconfig->ops->down)
1655 ipconfig->ops->down(ipconfig, ifname);
1662 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1664 struct connman_ipdevice *ipdevice;
1666 DBG("ipconfig %p", ipconfig);
1668 if (!ipconfig || ipconfig->index < 0)
1671 ipdevice = g_hash_table_lookup(ipdevice_hash,
1672 GINT_TO_POINTER(ipconfig->index));
1676 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
1679 ipconfig->enabled = false;
1681 if (ipdevice->config_ipv4 == ipconfig) {
1682 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1684 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1685 __connman_ipconfig_unref(ipdevice->config_ipv4);
1686 ipdevice->config_ipv4 = NULL;
1690 if (ipdevice->config_ipv6 == ipconfig) {
1691 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1693 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1694 __connman_ipconfig_unref(ipdevice->config_ipv6);
1695 ipdevice->config_ipv6 = NULL;
1702 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1705 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1707 case CONNMAN_IPCONFIG_METHOD_OFF:
1709 case CONNMAN_IPCONFIG_METHOD_FIXED:
1711 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1713 case CONNMAN_IPCONFIG_METHOD_DHCP:
1715 case CONNMAN_IPCONFIG_METHOD_AUTO:
1722 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1724 if (g_strcmp0(method, "off") == 0)
1725 return CONNMAN_IPCONFIG_METHOD_OFF;
1726 else if (g_strcmp0(method, "fixed") == 0)
1727 return CONNMAN_IPCONFIG_METHOD_FIXED;
1728 else if (g_strcmp0(method, "manual") == 0)
1729 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1730 else if (g_strcmp0(method, "dhcp") == 0)
1731 return CONNMAN_IPCONFIG_METHOD_DHCP;
1732 else if (g_strcmp0(method, "auto") == 0)
1733 return CONNMAN_IPCONFIG_METHOD_AUTO;
1735 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1738 static const char *privacy2string(int privacy)
1742 else if (privacy == 1)
1748 static int string2privacy(const char *privacy)
1750 if (g_strcmp0(privacy, "disabled") == 0)
1752 else if (g_strcmp0(privacy, "enabled") == 0)
1754 else if (g_strcmp0(privacy, "preferred") == 0)
1756 else if (g_strcmp0(privacy, "prefered") == 0)
1762 int __connman_ipconfig_ipv6_reset_privacy(struct connman_ipconfig *ipconfig)
1764 struct connman_ipdevice *ipdevice;
1770 ipdevice = g_hash_table_lookup(ipdevice_hash,
1771 GINT_TO_POINTER(ipconfig->index));
1775 err = __connman_ipconfig_ipv6_set_privacy(ipconfig, privacy2string(
1776 ipdevice->ipv6_privacy));
1781 int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
1789 DBG("ipconfig %p privacy %s", ipconfig, value);
1791 privacy = string2privacy(value);
1793 ipconfig->ipv6_privacy_config = privacy;
1795 enable_ipv6(ipconfig);
1800 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1801 DBusMessageIter *iter)
1803 struct connman_ipaddress *append_addr = NULL;
1808 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1811 str = __connman_ipconfig_method2string(ipconfig->method);
1815 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1817 switch (ipconfig->method) {
1818 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1819 case CONNMAN_IPCONFIG_METHOD_OFF:
1820 case CONNMAN_IPCONFIG_METHOD_AUTO:
1823 case CONNMAN_IPCONFIG_METHOD_FIXED:
1824 append_addr = ipconfig->address;
1827 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1828 case CONNMAN_IPCONFIG_METHOD_DHCP:
1829 append_addr = ipconfig->system;
1836 if (append_addr->local) {
1838 struct in_addr netmask;
1841 connman_dbus_dict_append_basic(iter, "Address",
1842 DBUS_TYPE_STRING, &append_addr->local);
1844 addr = 0xffffffff << (32 - append_addr->prefixlen);
1845 netmask.s_addr = htonl(addr);
1846 mask = inet_ntoa(netmask);
1847 connman_dbus_dict_append_basic(iter, "Netmask",
1848 DBUS_TYPE_STRING, &mask);
1851 if (append_addr->gateway)
1852 connman_dbus_dict_append_basic(iter, "Gateway",
1853 DBUS_TYPE_STRING, &append_addr->gateway);
1856 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1857 DBusMessageIter *iter,
1858 struct connman_ipconfig *ipconfig_ipv4)
1860 struct connman_ipaddress *append_addr = NULL;
1861 const char *str, *privacy;
1865 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1868 str = __connman_ipconfig_method2string(ipconfig->method);
1872 if (ipconfig_ipv4 &&
1873 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1874 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1878 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1880 switch (ipconfig->method) {
1881 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1882 case CONNMAN_IPCONFIG_METHOD_OFF:
1885 case CONNMAN_IPCONFIG_METHOD_FIXED:
1886 append_addr = ipconfig->address;
1889 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1890 case CONNMAN_IPCONFIG_METHOD_DHCP:
1891 case CONNMAN_IPCONFIG_METHOD_AUTO:
1892 append_addr = ipconfig->system;
1899 if (append_addr->local) {
1900 connman_dbus_dict_append_basic(iter, "Address",
1901 DBUS_TYPE_STRING, &append_addr->local);
1902 connman_dbus_dict_append_basic(iter, "PrefixLength",
1904 &append_addr->prefixlen);
1907 if (append_addr->gateway)
1908 connman_dbus_dict_append_basic(iter, "Gateway",
1909 DBUS_TYPE_STRING, &append_addr->gateway);
1911 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1912 connman_dbus_dict_append_basic(iter, "Privacy",
1913 DBUS_TYPE_STRING, &privacy);
1916 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1917 DBusMessageIter *iter)
1919 const char *str, *privacy;
1923 str = __connman_ipconfig_method2string(ipconfig->method);
1927 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1929 switch (ipconfig->method) {
1930 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1931 case CONNMAN_IPCONFIG_METHOD_OFF:
1932 case CONNMAN_IPCONFIG_METHOD_DHCP:
1934 case CONNMAN_IPCONFIG_METHOD_FIXED:
1935 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1936 case CONNMAN_IPCONFIG_METHOD_AUTO:
1940 if (!ipconfig->address)
1943 if (ipconfig->address->local) {
1944 connman_dbus_dict_append_basic(iter, "Address",
1945 DBUS_TYPE_STRING, &ipconfig->address->local);
1946 connman_dbus_dict_append_basic(iter, "PrefixLength",
1948 &ipconfig->address->prefixlen);
1951 if (ipconfig->address->gateway)
1952 connman_dbus_dict_append_basic(iter, "Gateway",
1953 DBUS_TYPE_STRING, &ipconfig->address->gateway);
1955 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1956 connman_dbus_dict_append_basic(iter, "Privacy",
1957 DBUS_TYPE_STRING, &privacy);
1960 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
1961 DBusMessageIter *iter)
1967 str = __connman_ipconfig_method2string(ipconfig->method);
1971 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1973 switch (ipconfig->method) {
1974 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1975 case CONNMAN_IPCONFIG_METHOD_OFF:
1976 case CONNMAN_IPCONFIG_METHOD_DHCP:
1977 case CONNMAN_IPCONFIG_METHOD_AUTO:
1979 case CONNMAN_IPCONFIG_METHOD_FIXED:
1980 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1984 if (!ipconfig->address)
1987 if (ipconfig->address->local) {
1989 struct in_addr netmask;
1992 connman_dbus_dict_append_basic(iter, "Address",
1993 DBUS_TYPE_STRING, &ipconfig->address->local);
1995 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
1996 netmask.s_addr = htonl(addr);
1997 mask = inet_ntoa(netmask);
1998 connman_dbus_dict_append_basic(iter, "Netmask",
1999 DBUS_TYPE_STRING, &mask);
2002 if (ipconfig->address->gateway)
2003 connman_dbus_dict_append_basic(iter, "Gateway",
2004 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2007 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2008 DBusMessageIter *array)
2010 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2011 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2012 *privacy_string = NULL;
2013 int prefix_length = 0, privacy = 0;
2014 DBusMessageIter dict;
2017 DBG("ipconfig %p", ipconfig);
2019 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2022 dbus_message_iter_recurse(array, &dict);
2024 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2025 DBusMessageIter entry, value;
2029 dbus_message_iter_recurse(&dict, &entry);
2031 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2034 dbus_message_iter_get_basic(&entry, &key);
2035 dbus_message_iter_next(&entry);
2037 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2040 dbus_message_iter_recurse(&entry, &value);
2042 type = dbus_message_iter_get_arg_type(&value);
2044 if (g_str_equal(key, "Method")) {
2047 if (type != DBUS_TYPE_STRING)
2050 dbus_message_iter_get_basic(&value, &str);
2051 method = __connman_ipconfig_string2method(str);
2052 } else if (g_str_equal(key, "Address")) {
2053 if (type != DBUS_TYPE_STRING)
2056 dbus_message_iter_get_basic(&value, &address);
2057 } else if (g_str_equal(key, "PrefixLength")) {
2058 if (type != DBUS_TYPE_BYTE)
2061 dbus_message_iter_get_basic(&value, &prefix_length);
2063 if (prefix_length < 0 || prefix_length > 128)
2065 } else if (g_str_equal(key, "Netmask")) {
2066 if (type != DBUS_TYPE_STRING)
2069 dbus_message_iter_get_basic(&value, &netmask);
2070 } else if (g_str_equal(key, "Gateway")) {
2071 if (type != DBUS_TYPE_STRING)
2074 dbus_message_iter_get_basic(&value, &gateway);
2075 } else if (g_str_equal(key, "Privacy")) {
2076 if (type != DBUS_TYPE_STRING)
2079 dbus_message_iter_get_basic(&value, &privacy_string);
2080 privacy = string2privacy(privacy_string);
2083 dbus_message_iter_next(&dict);
2086 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2088 method, address, netmask, gateway, prefix_length,
2092 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2093 case CONNMAN_IPCONFIG_METHOD_FIXED:
2096 case CONNMAN_IPCONFIG_METHOD_OFF:
2097 ipconfig->method = method;
2101 case CONNMAN_IPCONFIG_METHOD_AUTO:
2102 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2105 ipconfig->method = method;
2107 ipconfig->ipv6_privacy_config = privacy;
2111 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2112 switch (ipconfig->type) {
2113 case CONNMAN_IPCONFIG_TYPE_IPV4:
2116 case CONNMAN_IPCONFIG_TYPE_IPV6:
2119 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2120 case CONNMAN_IPCONFIG_TYPE_ALL:
2125 if ((address && connman_inet_check_ipaddress(address)
2128 connman_inet_check_ipaddress(netmask)
2131 connman_inet_check_ipaddress(gateway)
2135 ipconfig->method = method;
2137 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2138 connman_ipaddress_set_ipv4(ipconfig->address,
2139 address, netmask, gateway);
2141 return connman_ipaddress_set_ipv6(
2142 ipconfig->address, address,
2143 prefix_length, gateway);
2147 case CONNMAN_IPCONFIG_METHOD_DHCP:
2148 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2151 ipconfig->method = method;
2158 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2159 DBusMessageIter *iter)
2161 struct connman_ipdevice *ipdevice;
2162 const char *method = "auto";
2164 connman_dbus_dict_append_basic(iter, "Method",
2165 DBUS_TYPE_STRING, &method);
2167 ipdevice = g_hash_table_lookup(ipdevice_hash,
2168 GINT_TO_POINTER(ipconfig->index));
2172 if (ipconfig->index >= 0) {
2173 char *ifname = connman_inet_ifname(ipconfig->index);
2175 connman_dbus_dict_append_basic(iter, "Interface",
2176 DBUS_TYPE_STRING, &ifname);
2181 if (ipdevice->address)
2182 connman_dbus_dict_append_basic(iter, "Address",
2183 DBUS_TYPE_STRING, &ipdevice->address);
2185 if (ipdevice->mtu > 0)
2186 connman_dbus_dict_append_basic(iter, "MTU",
2187 DBUS_TYPE_UINT16, &ipdevice->mtu);
2190 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2191 GKeyFile *keyfile, const char *identifier, const char *prefix)
2197 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2199 key = g_strdup_printf("%smethod", prefix);
2200 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2202 switch (ipconfig->type) {
2203 case CONNMAN_IPCONFIG_TYPE_IPV4:
2204 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2206 case CONNMAN_IPCONFIG_TYPE_IPV6:
2207 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2209 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2210 case CONNMAN_IPCONFIG_TYPE_ALL:
2211 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2215 ipconfig->method = __connman_ipconfig_string2method(method);
2217 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2218 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2220 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2224 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2225 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2228 pprefix = g_strdup_printf("%sprivacy", prefix);
2229 privacy = g_key_file_get_string(keyfile, identifier,
2231 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2236 pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2237 ipconfig->last_dhcpv6_prefixes =
2238 g_key_file_get_string_list(keyfile, identifier, pprefix,
2240 if (ipconfig->last_dhcpv6_prefixes && length == 0) {
2241 g_free(ipconfig->last_dhcpv6_prefixes);
2242 ipconfig->last_dhcpv6_prefixes = NULL;
2250 switch (ipconfig->method) {
2251 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2252 case CONNMAN_IPCONFIG_METHOD_OFF:
2255 case CONNMAN_IPCONFIG_METHOD_FIXED:
2256 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2258 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2259 ipconfig->address->prefixlen = g_key_file_get_integer(
2260 keyfile, identifier, key, NULL);
2263 key = g_strdup_printf("%slocal_address", prefix);
2264 g_free(ipconfig->address->local);
2265 ipconfig->address->local = g_key_file_get_string(
2266 keyfile, identifier, key, NULL);
2269 key = g_strdup_printf("%speer_address", prefix);
2270 g_free(ipconfig->address->peer);
2271 ipconfig->address->peer = g_key_file_get_string(
2272 keyfile, identifier, key, NULL);
2275 key = g_strdup_printf("%sbroadcast_address", prefix);
2276 g_free(ipconfig->address->broadcast);
2277 ipconfig->address->broadcast = g_key_file_get_string(
2278 keyfile, identifier, key, NULL);
2281 key = g_strdup_printf("%sgateway", prefix);
2282 g_free(ipconfig->address->gateway);
2283 ipconfig->address->gateway = g_key_file_get_string(
2284 keyfile, identifier, key, NULL);
2288 case CONNMAN_IPCONFIG_METHOD_DHCP:
2290 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2291 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2293 g_free(ipconfig->last_dhcp_address);
2294 ipconfig->last_dhcp_address = str;
2300 case CONNMAN_IPCONFIG_METHOD_AUTO:
2307 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2308 GKeyFile *keyfile, const char *identifier, const char *prefix)
2313 method = __connman_ipconfig_method2string(ipconfig->method);
2315 DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
2318 key = g_strdup_printf("%smethod", prefix);
2319 g_key_file_set_string(keyfile, identifier, key, method);
2323 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2324 const char *privacy;
2325 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2326 key = g_strdup_printf("%sprivacy", prefix);
2327 g_key_file_set_string(keyfile, identifier, key, privacy);
2330 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2331 if (ipconfig->last_dhcp_address &&
2332 strlen(ipconfig->last_dhcp_address) > 0)
2333 g_key_file_set_string(keyfile, identifier, key,
2334 ipconfig->last_dhcp_address);
2336 g_key_file_remove_key(keyfile, identifier, key, NULL);
2339 key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2340 if (ipconfig->last_dhcpv6_prefixes &&
2341 ipconfig->last_dhcpv6_prefixes[0]) {
2343 g_strv_length(ipconfig->last_dhcpv6_prefixes);
2345 g_key_file_set_string_list(keyfile, identifier, key,
2346 (const gchar **)ipconfig->last_dhcpv6_prefixes,
2349 g_key_file_remove_key(keyfile, identifier, key, NULL);
2353 switch (ipconfig->method) {
2354 case CONNMAN_IPCONFIG_METHOD_FIXED:
2355 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2357 case CONNMAN_IPCONFIG_METHOD_DHCP:
2358 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2359 if (ipconfig->last_dhcp_address &&
2360 strlen(ipconfig->last_dhcp_address) > 0)
2361 g_key_file_set_string(keyfile, identifier, key,
2362 ipconfig->last_dhcp_address);
2364 g_key_file_remove_key(keyfile, identifier, key, NULL);
2367 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2368 case CONNMAN_IPCONFIG_METHOD_OFF:
2369 case CONNMAN_IPCONFIG_METHOD_AUTO:
2373 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2374 if (ipconfig->address->prefixlen != 0)
2375 g_key_file_set_integer(keyfile, identifier,
2376 key, ipconfig->address->prefixlen);
2379 key = g_strdup_printf("%slocal_address", prefix);
2380 if (ipconfig->address->local)
2381 g_key_file_set_string(keyfile, identifier,
2382 key, ipconfig->address->local);
2385 key = g_strdup_printf("%speer_address", prefix);
2386 if (ipconfig->address->peer)
2387 g_key_file_set_string(keyfile, identifier,
2388 key, ipconfig->address->peer);
2391 key = g_strdup_printf("%sbroadcast_address", prefix);
2392 if (ipconfig->address->broadcast)
2393 g_key_file_set_string(keyfile, identifier,
2394 key, ipconfig->address->broadcast);
2397 key = g_strdup_printf("%sgateway", prefix);
2398 if (ipconfig->address->gateway)
2399 g_key_file_set_string(keyfile, identifier,
2400 key, ipconfig->address->gateway);
2406 int __connman_ipconfig_init(void)
2410 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2411 NULL, free_ipdevice);
2413 is_ipv6_supported = connman_inet_is_ipv6_supported();
2418 void __connman_ipconfig_cleanup(void)
2422 g_hash_table_destroy(ipdevice_hash);
2423 ipdevice_hash = NULL;