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;
51 enum connman_ipconfig_method method;
52 struct connman_ipaddress *address;
53 struct connman_ipaddress *system;
56 int dhcp_lease_duration;
59 int ipv6_privacy_config;
60 char *last_dhcp_address;
61 char **last_dhcpv6_prefixes;
64 struct connman_ipdevice {
85 struct connman_ipconfig *config_ipv4;
86 struct connman_ipconfig *config_ipv6;
92 static GHashTable *ipdevice_hash = NULL;
93 static GList *ipconfig_list = NULL;
94 static bool is_ipv6_supported = false;
96 void __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
101 connman_ipaddress_clear(ipconfig->address);
104 static void free_address_list(struct connman_ipdevice *ipdevice)
108 for (list = ipdevice->address_list; list; list = list->next) {
109 struct connman_ipaddress *ipaddress = list->data;
111 connman_ipaddress_free(ipaddress);
115 g_slist_free(ipdevice->address_list);
116 ipdevice->address_list = NULL;
119 static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
120 unsigned char prefixlen, const char *local)
124 for (list = ipdevice->address_list; list; list = list->next) {
125 struct connman_ipaddress *ipaddress = list->data;
127 if (g_strcmp0(ipaddress->local, local) == 0 &&
128 ipaddress->prefixlen == prefixlen)
135 const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type)
138 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
139 case CONNMAN_IPCONFIG_TYPE_ALL:
141 case CONNMAN_IPCONFIG_TYPE_IPV4:
143 case CONNMAN_IPCONFIG_TYPE_IPV6:
150 static const char *type2str(unsigned short type)
155 case ARPHRD_LOOPBACK:
168 static const char *scope2str(unsigned char scope)
180 static bool get_ipv6_state(gchar *ifname)
185 bool enabled = false;
188 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
190 path = g_strdup_printf(
191 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
196 f = fopen(path, "r");
201 if (fscanf(f, "%d", &disabled) > 0)
209 static void set_ipv6_state(gchar *ifname, bool enable)
215 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
217 path = g_strdup_printf(
218 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
223 f = fopen(path, "r+");
238 static int get_ipv6_privacy(gchar *ifname)
247 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
253 f = fopen(path, "r");
260 if (fscanf(f, "%d", &value) <= 0)
268 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
269 * The privacy extension is described in RFC 3041 and RFC 4941
271 static void set_ipv6_privacy(gchar *ifname, int value)
279 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
288 f = fopen(path, "r+");
295 fprintf(f, "%d", value);
299 static int get_rp_filter(void)
302 int value = -EINVAL, tmp;
304 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
307 if (fscanf(f, "%d", &tmp) == 1)
315 static void set_rp_filter(int value)
319 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
324 fprintf(f, "%d", value);
329 int __connman_ipconfig_set_rp_filter()
333 value = get_rp_filter();
340 connman_info("rp_filter set to 2 (loose mode routing), "
341 "old value was %d", value);
346 void __connman_ipconfig_unset_rp_filter(int old_value)
348 set_rp_filter(old_value);
350 connman_info("rp_filter restored to %d", old_value);
353 bool __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
358 return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
361 bool __connman_ipconfig_ipv6_is_enabled(struct connman_ipconfig *ipconfig)
363 struct connman_ipdevice *ipdevice;
370 ipdevice = g_hash_table_lookup(ipdevice_hash,
371 GINT_TO_POINTER(ipconfig->index));
375 ifname = connman_inet_ifname(ipconfig->index);
376 ret = get_ipv6_state(ifname);
382 static void free_ipdevice(gpointer data)
384 struct connman_ipdevice *ipdevice = data;
385 char *ifname = connman_inet_ifname(ipdevice->index);
387 connman_info("%s {remove} index %d", ifname, ipdevice->index);
389 if (ipdevice->config_ipv4) {
390 __connman_ipconfig_unref(ipdevice->config_ipv4);
391 ipdevice->config_ipv4 = NULL;
394 if (ipdevice->config_ipv6) {
395 __connman_ipconfig_unref(ipdevice->config_ipv6);
396 ipdevice->config_ipv6 = NULL;
399 free_address_list(ipdevice);
400 g_free(ipdevice->ipv4_gateway);
401 g_free(ipdevice->ipv6_gateway);
402 g_free(ipdevice->pac);
404 g_free(ipdevice->address);
407 set_ipv6_state(ifname, ipdevice->ipv6_enabled);
408 set_ipv6_privacy(ifname, ipdevice->ipv6_privacy);
415 static void update_stats(struct connman_ipdevice *ipdevice,
416 const char *ifname, struct rtnl_link_stats *stats)
418 struct connman_service *service;
420 if (stats->rx_packets == 0 && stats->tx_packets == 0)
423 connman_info("%s {RX} %u packets %u bytes", ifname,
424 stats->rx_packets, stats->rx_bytes);
425 connman_info("%s {TX} %u packets %u bytes", ifname,
426 stats->tx_packets, stats->tx_bytes);
428 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
431 service = __connman_service_lookup_from_index(ipdevice->index);
433 DBG("service %p", service);
438 ipdevice->rx_packets = stats->rx_packets;
439 ipdevice->tx_packets = stats->tx_packets;
440 ipdevice->rx_bytes = stats->rx_bytes;
441 ipdevice->tx_bytes = stats->tx_bytes;
442 ipdevice->rx_errors = stats->rx_errors;
443 ipdevice->tx_errors = stats->tx_errors;
444 ipdevice->rx_dropped = stats->rx_dropped;
445 ipdevice->tx_dropped = stats->tx_dropped;
447 __connman_service_notify(service,
448 ipdevice->rx_packets, ipdevice->tx_packets,
449 ipdevice->rx_bytes, ipdevice->tx_bytes,
450 ipdevice->rx_errors, ipdevice->tx_errors,
451 ipdevice->rx_dropped, ipdevice->tx_dropped);
454 void __connman_ipconfig_newlink(int index, unsigned short type,
455 unsigned int flags, const char *address,
457 struct rtnl_link_stats *stats)
459 struct connman_ipdevice *ipdevice;
460 GList *list, *ipconfig_copy;
462 bool up = false, down = false;
463 bool lower_up = false, lower_down = false;
466 DBG("index %d", index);
468 if (type == ARPHRD_LOOPBACK)
471 ifname = connman_inet_ifname(index);
473 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
477 ipdevice = g_try_new0(struct connman_ipdevice, 1);
481 ipdevice->index = index;
482 ipdevice->type = type;
484 ipdevice->ipv6_enabled = get_ipv6_state(ifname);
485 ipdevice->ipv6_privacy = get_ipv6_privacy(ifname);
487 ipdevice->address = g_strdup(address);
489 g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
491 connman_info("%s {create} index %d type %d <%s>", ifname,
492 index, type, type2str(type));
495 #if defined TIZEN_EXT
496 if (g_strcmp0(ipdevice->address, address) != 0) {
497 /* If an original address is built-in physical device,
498 * it's hardly get an address at a initial creation
500 g_free(ipdevice->address);
501 ipdevice->address = g_strdup(address);
507 update_stats(ipdevice, ifname, stats);
509 if (flags == ipdevice->flags)
512 if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
519 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
520 (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
521 if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
522 (IFF_RUNNING | IFF_LOWER_UP))
524 else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
528 ipdevice->flags = flags;
530 str = g_string_new(NULL);
535 g_string_append(str, "UP");
537 g_string_append(str, "DOWN");
539 if (flags & IFF_RUNNING)
540 g_string_append(str, ",RUNNING");
542 if (flags & IFF_LOWER_UP)
543 g_string_append(str, ",LOWER_UP");
545 connman_info("%s {update} flags %u <%s>", ifname, flags, str->str);
547 g_string_free(str, TRUE);
549 ipconfig_copy = g_list_copy(ipconfig_list);
551 for (list = g_list_first(ipconfig_copy); list;
552 list = g_list_next(list)) {
553 struct connman_ipconfig *ipconfig = list->data;
555 if (index != ipconfig->index)
561 if (up && ipconfig->ops->up)
562 ipconfig->ops->up(ipconfig, ifname);
563 if (lower_up && ipconfig->ops->lower_up)
564 ipconfig->ops->lower_up(ipconfig, ifname);
566 if (lower_down && ipconfig->ops->lower_down)
567 ipconfig->ops->lower_down(ipconfig, ifname);
568 if (down && ipconfig->ops->down)
569 ipconfig->ops->down(ipconfig, ifname);
572 g_list_free(ipconfig_copy);
578 void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
580 struct connman_ipdevice *ipdevice;
584 DBG("index %d", index);
586 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
590 ifname = connman_inet_ifname(index);
592 update_stats(ipdevice, ifname, stats);
594 for (list = g_list_first(ipconfig_list); list;
595 list = g_list_next(list)) {
596 struct connman_ipconfig *ipconfig = list->data;
598 if (index != ipconfig->index)
601 ipconfig->index = -1;
606 if (ipconfig->ops->lower_down)
607 ipconfig->ops->lower_down(ipconfig, ifname);
608 if (ipconfig->ops->down)
609 ipconfig->ops->down(ipconfig, ifname);
614 g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
617 static inline gint check_duplicate_address(gconstpointer a, gconstpointer b)
619 const struct connman_ipaddress *addr1 = a;
620 const struct connman_ipaddress *addr2 = b;
622 if (addr1->prefixlen != addr2->prefixlen)
623 return addr2->prefixlen - addr1->prefixlen;
625 return g_strcmp0(addr1->local, addr2->local);
628 int __connman_ipconfig_newaddr(int index, int family, const char *label,
629 unsigned char prefixlen, const char *address)
631 struct connman_ipdevice *ipdevice;
632 struct connman_ipaddress *ipaddress;
633 enum connman_ipconfig_type type;
637 DBG("index %d", index);
639 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
643 ipaddress = connman_ipaddress_alloc(family);
647 ipaddress->prefixlen = prefixlen;
648 ipaddress->local = g_strdup(address);
650 if (g_slist_find_custom(ipdevice->address_list, ipaddress,
651 check_duplicate_address)) {
652 connman_ipaddress_free(ipaddress);
656 if (family == AF_INET)
657 type = CONNMAN_IPCONFIG_TYPE_IPV4;
658 else if (family == AF_INET6)
659 type = CONNMAN_IPCONFIG_TYPE_IPV6;
663 ipdevice->address_list = g_slist_prepend(ipdevice->address_list,
666 ifname = connman_inet_ifname(index);
667 connman_info("%s {add} address %s/%u label %s family %d",
668 ifname, address, prefixlen, label, family);
670 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
671 __connman_ippool_newaddr(index, address, prefixlen);
673 if (ipdevice->config_ipv4 && family == AF_INET)
674 connman_ipaddress_copy_address(ipdevice->config_ipv4->system,
677 else if (ipdevice->config_ipv6 && family == AF_INET6)
678 connman_ipaddress_copy_address(ipdevice->config_ipv6->system,
683 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
686 for (list = g_list_first(ipconfig_list); list;
687 list = g_list_next(list)) {
688 struct connman_ipconfig *ipconfig = list->data;
690 if (index != ipconfig->index)
693 if (type != ipconfig->type)
699 if (ipconfig->ops->ip_bound)
700 ipconfig->ops->ip_bound(ipconfig, ifname);
708 void __connman_ipconfig_deladdr(int index, int family, const char *label,
709 unsigned char prefixlen, const char *address)
711 struct connman_ipdevice *ipdevice;
712 struct connman_ipaddress *ipaddress;
713 enum connman_ipconfig_type type;
717 DBG("index %d", index);
719 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
723 ipaddress = find_ipaddress(ipdevice, prefixlen, address);
727 if (family == AF_INET)
728 type = CONNMAN_IPCONFIG_TYPE_IPV4;
729 else if (family == AF_INET6)
730 type = CONNMAN_IPCONFIG_TYPE_IPV6;
734 ipdevice->address_list = g_slist_remove(ipdevice->address_list,
737 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
738 __connman_ippool_deladdr(index, address, prefixlen);
740 connman_ipaddress_clear(ipaddress);
743 ifname = connman_inet_ifname(index);
744 connman_info("%s {del} address %s/%u label %s", ifname,
745 address, prefixlen, label);
747 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
750 if (g_slist_length(ipdevice->address_list) > 0)
753 for (list = g_list_first(ipconfig_list); list;
754 list = g_list_next(list)) {
755 struct connman_ipconfig *ipconfig = list->data;
757 if (index != ipconfig->index)
760 if (type != ipconfig->type)
766 if (ipconfig->ops->ip_release)
767 ipconfig->ops->ip_release(ipconfig, ifname);
774 void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
775 const char *dst, const char *gateway)
777 struct connman_ipdevice *ipdevice;
780 DBG("index %d", index);
782 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
786 ifname = connman_inet_ifname(index);
788 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
789 g_strcmp0(dst, "::") == 0)) {
791 enum connman_ipconfig_type type;
793 if (family == AF_INET6) {
794 type = CONNMAN_IPCONFIG_TYPE_IPV6;
795 g_free(ipdevice->ipv6_gateway);
796 ipdevice->ipv6_gateway = g_strdup(gateway);
798 if (ipdevice->config_ipv6 &&
799 ipdevice->config_ipv6->system) {
800 g_free(ipdevice->config_ipv6->system->gateway);
801 ipdevice->config_ipv6->system->gateway =
804 } else if (family == AF_INET) {
805 type = CONNMAN_IPCONFIG_TYPE_IPV4;
806 g_free(ipdevice->ipv4_gateway);
807 ipdevice->ipv4_gateway = g_strdup(gateway);
809 if (ipdevice->config_ipv4 &&
810 ipdevice->config_ipv4->system) {
811 g_free(ipdevice->config_ipv4->system->gateway);
812 ipdevice->config_ipv4->system->gateway =
818 for (config_list = g_list_first(ipconfig_list); config_list;
819 config_list = g_list_next(config_list)) {
820 struct connman_ipconfig *ipconfig = config_list->data;
822 if (index != ipconfig->index)
825 if (type != ipconfig->type)
831 if (ipconfig->ops->route_set)
832 ipconfig->ops->route_set(ipconfig, ifname);
836 connman_info("%s {add} route %s gw %s scope %u <%s>",
837 ifname, dst, gateway, scope, scope2str(scope));
843 void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
844 const char *dst, const char *gateway)
846 struct connman_ipdevice *ipdevice;
849 DBG("index %d", index);
851 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
855 ifname = connman_inet_ifname(index);
857 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
858 g_strcmp0(dst, "::") == 0)) {
860 enum connman_ipconfig_type type;
862 if (family == AF_INET6) {
863 type = CONNMAN_IPCONFIG_TYPE_IPV6;
864 g_free(ipdevice->ipv6_gateway);
865 ipdevice->ipv6_gateway = NULL;
867 if (ipdevice->config_ipv6 &&
868 ipdevice->config_ipv6->system) {
869 g_free(ipdevice->config_ipv6->system->gateway);
870 ipdevice->config_ipv6->system->gateway = NULL;
872 } else if (family == AF_INET) {
873 type = CONNMAN_IPCONFIG_TYPE_IPV4;
874 g_free(ipdevice->ipv4_gateway);
875 ipdevice->ipv4_gateway = NULL;
877 if (ipdevice->config_ipv4 &&
878 ipdevice->config_ipv4->system) {
879 g_free(ipdevice->config_ipv4->system->gateway);
880 ipdevice->config_ipv4->system->gateway = NULL;
885 for (config_list = g_list_first(ipconfig_list); config_list;
886 config_list = g_list_next(config_list)) {
887 struct connman_ipconfig *ipconfig = config_list->data;
889 if (index != ipconfig->index)
892 if (type != ipconfig->type)
898 if (ipconfig->ops->route_unset)
899 ipconfig->ops->route_unset(ipconfig, ifname);
903 connman_info("%s {del} route %s gw %s scope %u <%s>",
904 ifname, dst, gateway, scope, scope2str(scope));
910 void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
915 keys = g_hash_table_get_keys(ipdevice_hash);
919 for (list = g_list_first(keys); list; list = g_list_next(list)) {
920 int index = GPOINTER_TO_INT(list->data);
922 function(index, user_data);
928 enum connman_ipconfig_type __connman_ipconfig_get_config_type(
929 struct connman_ipconfig *ipconfig)
931 return ipconfig ? ipconfig->type : CONNMAN_IPCONFIG_TYPE_UNKNOWN;
934 unsigned short __connman_ipconfig_get_type_from_index(int index)
936 struct connman_ipdevice *ipdevice;
938 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
942 return ipdevice->type;
945 unsigned int __connman_ipconfig_get_flags_from_index(int index)
947 struct connman_ipdevice *ipdevice;
949 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
953 return ipdevice->flags;
956 const char *__connman_ipconfig_get_gateway_from_index(int index,
957 enum connman_ipconfig_type type)
959 struct connman_ipdevice *ipdevice;
961 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
965 if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
966 if (ipdevice->ipv4_gateway)
967 return ipdevice->ipv4_gateway;
969 if (ipdevice->config_ipv4 &&
970 ipdevice->config_ipv4->address)
971 return ipdevice->config_ipv4->address->gateway;
974 if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
975 if (ipdevice->ipv6_gateway)
976 return ipdevice->ipv6_gateway;
978 if (ipdevice->config_ipv6 &&
979 ipdevice->config_ipv6->address)
980 return ipdevice->config_ipv6->address->gateway;
986 void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
988 ipconfig->index = index;
991 const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
993 if (!ipconfig->address)
996 return ipconfig->address->local;
999 void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig,
1000 const char *address)
1002 if (!ipconfig->address)
1005 g_free(ipconfig->address->local);
1006 ipconfig->address->local = g_strdup(address);
1009 const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
1011 if (!ipconfig->address)
1014 return ipconfig->address->peer;
1017 void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig,
1018 const char *address)
1020 if (!ipconfig->address)
1023 g_free(ipconfig->address->peer);
1024 ipconfig->address->peer = g_strdup(address);
1027 const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
1029 if (!ipconfig->address)
1032 return ipconfig->address->broadcast;
1035 void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig,
1036 const char *broadcast)
1038 if (!ipconfig->address)
1041 g_free(ipconfig->address->broadcast);
1042 ipconfig->address->broadcast = g_strdup(broadcast);
1045 const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
1047 if (!ipconfig->address)
1050 return ipconfig->address->gateway;
1053 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
1054 const char *gateway)
1058 if (!ipconfig->address)
1060 g_free(ipconfig->address->gateway);
1061 ipconfig->address->gateway = g_strdup(gateway);
1064 #if defined TIZEN_EXT
1065 void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig,
1066 int dhcp_lease_duration)
1068 ipconfig->dhcp_lease_duration = dhcp_lease_duration;
1072 #if defined TIZEN_EXT
1073 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service)
1075 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
1078 #if !defined TIZEN_EXT
1079 struct connman_service *service;
1084 if (!ipconfig->address)
1087 #if !defined TIZEN_EXT
1088 service = __connman_service_lookup_from_index(ipconfig->index);
1093 DBG("type %d gw %s peer %s", ipconfig->type,
1094 ipconfig->address->gateway, ipconfig->address->peer);
1096 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6 ||
1097 ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1098 return __connman_connection_gateway_add(service,
1099 ipconfig->address->gateway,
1101 ipconfig->address->peer);
1106 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
1108 struct connman_service *service;
1112 service = __connman_service_lookup_from_index(ipconfig->index);
1114 __connman_connection_gateway_remove(service, ipconfig->type);
1117 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
1119 if (!ipconfig->address)
1122 return ipconfig->address->prefixlen;
1125 void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig,
1126 unsigned char prefixlen)
1128 if (!ipconfig->address)
1131 ipconfig->address->prefixlen = prefixlen;
1134 static struct connman_ipconfig *create_ipv6config(int index)
1136 struct connman_ipconfig *ipv6config;
1137 struct connman_ipdevice *ipdevice;
1139 ipv6config = g_try_new0(struct connman_ipconfig, 1);
1143 ipv6config->refcount = 1;
1145 ipv6config->index = index;
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 #if !defined TIZEN_EXT
1156 ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
1158 ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy = 2;
1160 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1161 if (!ipv6config->address) {
1166 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1168 DBG("ipconfig %p index %d method %s", ipv6config, index,
1169 __connman_ipconfig_method2string(ipv6config->method));
1175 * connman_ipconfig_create:
1177 * Allocate a new ipconfig structure.
1179 * Returns: a newly-allocated #connman_ipconfig structure
1181 struct connman_ipconfig *__connman_ipconfig_create(int index,
1182 enum connman_ipconfig_type type)
1184 struct connman_ipconfig *ipconfig;
1186 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1187 return create_ipv6config(index);
1189 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1193 ipconfig->refcount = 1;
1195 ipconfig->index = index;
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 index %d", ipconfig, index);
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)
1339 switch (ipconfig->method) {
1340 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1341 case CONNMAN_IPCONFIG_METHOD_OFF:
1343 case CONNMAN_IPCONFIG_METHOD_AUTO:
1344 case CONNMAN_IPCONFIG_METHOD_FIXED:
1345 case CONNMAN_IPCONFIG_METHOD_DHCP:
1346 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1347 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1348 return connman_inet_set_address(ipconfig->index,
1350 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1351 return connman_inet_set_ipv6_address(
1352 ipconfig->index, ipconfig->address);
1358 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1365 switch (ipconfig->method) {
1366 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1367 case CONNMAN_IPCONFIG_METHOD_OFF:
1369 case CONNMAN_IPCONFIG_METHOD_AUTO:
1370 case CONNMAN_IPCONFIG_METHOD_FIXED:
1371 case CONNMAN_IPCONFIG_METHOD_DHCP:
1372 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1373 err = __connman_ipconfig_address_unset(ipconfig);
1374 connman_ipaddress_clear(ipconfig->address);
1382 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1389 #if defined TIZEN_EXT
1390 DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type);
1392 DBG("method %d", ipconfig->method);
1395 switch (ipconfig->method) {
1396 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1397 case CONNMAN_IPCONFIG_METHOD_OFF:
1399 case CONNMAN_IPCONFIG_METHOD_AUTO:
1400 case CONNMAN_IPCONFIG_METHOD_FIXED:
1401 case CONNMAN_IPCONFIG_METHOD_DHCP:
1402 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1403 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1404 err = connman_inet_clear_address(ipconfig->index,
1406 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1407 err = connman_inet_clear_ipv6_address(
1409 ipconfig->address->local,
1410 ipconfig->address->prefixlen);
1420 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1423 struct connman_ipdevice *ipdevice;
1425 if (!ipconfig || ipconfig->index < 0)
1428 ipdevice = g_hash_table_lookup(ipdevice_hash,
1429 GINT_TO_POINTER(ipconfig->index));
1433 g_free(ipdevice->pac);
1434 ipdevice->pac = g_strdup(url);
1439 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1441 struct connman_ipdevice *ipdevice;
1443 if (!ipconfig || ipconfig->index < 0)
1446 ipdevice = g_hash_table_lookup(ipdevice_hash,
1447 GINT_TO_POINTER(ipconfig->index));
1451 return ipdevice->pac;
1454 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1455 const char *address)
1460 g_free(ipconfig->last_dhcp_address);
1461 ipconfig->last_dhcp_address = g_strdup(address);
1464 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1469 return ipconfig->last_dhcp_address;
1472 void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
1478 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1479 ipconfig->last_dhcpv6_prefixes = prefixes;
1482 char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
1487 return ipconfig->last_dhcpv6_prefixes;
1490 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1492 struct connman_ipdevice *ipdevice;
1497 ipdevice = g_hash_table_lookup(ipdevice_hash,
1498 GINT_TO_POINTER(ipconfig->index));
1502 ifname = connman_inet_ifname(ipconfig->index);
1504 set_ipv6_state(ifname, false);
1509 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1511 struct connman_ipdevice *ipdevice;
1516 ipdevice = g_hash_table_lookup(ipdevice_hash,
1517 GINT_TO_POINTER(ipconfig->index));
1521 ifname = connman_inet_ifname(ipconfig->index);
1523 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1524 set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
1526 set_ipv6_state(ifname, true);
1531 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1533 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1536 enable_ipv6(ipconfig);
1539 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1541 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1544 disable_ipv6(ipconfig);
1547 bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1552 switch (ipconfig->method) {
1553 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1554 case CONNMAN_IPCONFIG_METHOD_OFF:
1556 case CONNMAN_IPCONFIG_METHOD_AUTO:
1557 case CONNMAN_IPCONFIG_METHOD_FIXED:
1558 case CONNMAN_IPCONFIG_METHOD_DHCP:
1559 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1566 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1568 struct connman_ipdevice *ipdevice;
1569 bool up = false, down = false;
1570 bool lower_up = false, lower_down = false;
1571 enum connman_ipconfig_type type;
1574 DBG("ipconfig %p", ipconfig);
1576 if (!ipconfig || ipconfig->index < 0)
1579 ipdevice = g_hash_table_lookup(ipdevice_hash,
1580 GINT_TO_POINTER(ipconfig->index));
1584 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1585 if (ipdevice->config_ipv4 == ipconfig)
1587 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1588 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1589 if (ipdevice->config_ipv6 == ipconfig)
1591 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1595 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1596 ipdevice->config_ipv4) {
1597 ipconfig_list = g_list_remove(ipconfig_list,
1598 ipdevice->config_ipv4);
1600 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1602 __connman_ipconfig_unref(ipdevice->config_ipv4);
1605 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1606 ipdevice->config_ipv6) {
1607 ipconfig_list = g_list_remove(ipconfig_list,
1608 ipdevice->config_ipv6);
1610 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1612 __connman_ipconfig_unref(ipdevice->config_ipv6);
1615 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1616 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1617 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1618 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1620 enable_ipv6(ipdevice->config_ipv6);
1622 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1624 if (ipdevice->flags & IFF_UP)
1629 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1630 (IFF_RUNNING | IFF_LOWER_UP))
1632 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1635 ifname = connman_inet_ifname(ipconfig->index);
1637 if (up && ipconfig->ops->up)
1638 ipconfig->ops->up(ipconfig, ifname);
1639 if (lower_up && ipconfig->ops->lower_up)
1640 ipconfig->ops->lower_up(ipconfig, ifname);
1642 if (lower_down && ipconfig->ops->lower_down)
1643 ipconfig->ops->lower_down(ipconfig, ifname);
1644 if (down && ipconfig->ops->down)
1645 ipconfig->ops->down(ipconfig, ifname);
1652 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1654 struct connman_ipdevice *ipdevice;
1656 DBG("ipconfig %p", ipconfig);
1658 if (!ipconfig || ipconfig->index < 0)
1661 ipdevice = g_hash_table_lookup(ipdevice_hash,
1662 GINT_TO_POINTER(ipconfig->index));
1666 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
1669 if (ipdevice->config_ipv4 == ipconfig) {
1670 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1672 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1673 __connman_ipconfig_unref(ipdevice->config_ipv4);
1674 ipdevice->config_ipv4 = NULL;
1678 if (ipdevice->config_ipv6 == ipconfig) {
1679 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1681 #if defined TIZEN_EXT
1682 if (ipdevice->config_ipv6->method ==
1683 CONNMAN_IPCONFIG_METHOD_AUTO)
1684 disable_ipv6(ipdevice->config_ipv6);
1686 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1687 __connman_ipconfig_unref(ipdevice->config_ipv6);
1688 ipdevice->config_ipv6 = NULL;
1695 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1698 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1700 case CONNMAN_IPCONFIG_METHOD_OFF:
1702 case CONNMAN_IPCONFIG_METHOD_FIXED:
1704 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1706 case CONNMAN_IPCONFIG_METHOD_DHCP:
1708 case CONNMAN_IPCONFIG_METHOD_AUTO:
1715 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1717 if (g_strcmp0(method, "off") == 0)
1718 return CONNMAN_IPCONFIG_METHOD_OFF;
1719 else if (g_strcmp0(method, "fixed") == 0)
1720 return CONNMAN_IPCONFIG_METHOD_FIXED;
1721 else if (g_strcmp0(method, "manual") == 0)
1722 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1723 else if (g_strcmp0(method, "dhcp") == 0)
1724 return CONNMAN_IPCONFIG_METHOD_DHCP;
1725 else if (g_strcmp0(method, "auto") == 0)
1726 return CONNMAN_IPCONFIG_METHOD_AUTO;
1728 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1731 static const char *privacy2string(int privacy)
1735 else if (privacy == 1)
1741 static int string2privacy(const char *privacy)
1743 if (g_strcmp0(privacy, "disabled") == 0)
1745 else if (g_strcmp0(privacy, "enabled") == 0)
1747 else if (g_strcmp0(privacy, "preferred") == 0)
1749 else if (g_strcmp0(privacy, "prefered") == 0)
1755 int __connman_ipconfig_ipv6_reset_privacy(struct connman_ipconfig *ipconfig)
1757 struct connman_ipdevice *ipdevice;
1763 ipdevice = g_hash_table_lookup(ipdevice_hash,
1764 GINT_TO_POINTER(ipconfig->index));
1768 err = __connman_ipconfig_ipv6_set_privacy(ipconfig, privacy2string(
1769 ipdevice->ipv6_privacy));
1774 int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
1782 privacy = string2privacy(value);
1784 ipconfig->ipv6_privacy_config = privacy;
1786 enable_ipv6(ipconfig);
1791 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1792 DBusMessageIter *iter)
1794 struct connman_ipaddress *append_addr = NULL;
1797 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1800 str = __connman_ipconfig_method2string(ipconfig->method);
1804 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1806 switch (ipconfig->method) {
1807 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1808 case CONNMAN_IPCONFIG_METHOD_OFF:
1811 case CONNMAN_IPCONFIG_METHOD_FIXED:
1812 append_addr = ipconfig->address;
1815 case CONNMAN_IPCONFIG_METHOD_AUTO:
1816 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1817 case CONNMAN_IPCONFIG_METHOD_DHCP:
1818 append_addr = ipconfig->system;
1819 #if defined TIZEN_EXT
1820 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1821 if (append_addr && append_addr->local == NULL)
1822 append_addr = ipconfig->address;
1830 if (append_addr->local) {
1832 struct in_addr netmask;
1835 connman_dbus_dict_append_basic(iter, "Address",
1836 DBUS_TYPE_STRING, &append_addr->local);
1838 addr = 0xffffffff << (32 - append_addr->prefixlen);
1839 netmask.s_addr = htonl(addr);
1840 mask = inet_ntoa(netmask);
1841 connman_dbus_dict_append_basic(iter, "Netmask",
1842 DBUS_TYPE_STRING, &mask);
1845 if (append_addr->gateway)
1846 connman_dbus_dict_append_basic(iter, "Gateway",
1847 DBUS_TYPE_STRING, &append_addr->gateway);
1849 #if defined TIZEN_EXT
1850 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
1852 server_ip = __connman_dhcp_get_server_address(ipconfig);
1854 connman_dbus_dict_append_basic(iter, "DHCPServerIP",
1855 DBUS_TYPE_STRING, &server_ip);
1858 connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
1859 DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
1864 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1865 DBusMessageIter *iter,
1866 struct connman_ipconfig *ipconfig_ipv4)
1868 struct connman_ipaddress *append_addr = NULL;
1869 const char *str, *privacy;
1871 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1874 str = __connman_ipconfig_method2string(ipconfig->method);
1878 if (ipconfig_ipv4 &&
1879 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1880 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1884 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1886 switch (ipconfig->method) {
1887 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1888 case CONNMAN_IPCONFIG_METHOD_OFF:
1891 case CONNMAN_IPCONFIG_METHOD_FIXED:
1892 append_addr = ipconfig->address;
1895 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1896 case CONNMAN_IPCONFIG_METHOD_DHCP:
1897 case CONNMAN_IPCONFIG_METHOD_AUTO:
1898 append_addr = ipconfig->system;
1899 #if defined TIZEN_EXT
1900 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1901 if (append_addr && append_addr->local == NULL)
1902 append_addr = ipconfig->address;
1910 if (append_addr->local) {
1911 connman_dbus_dict_append_basic(iter, "Address",
1912 DBUS_TYPE_STRING, &append_addr->local);
1913 connman_dbus_dict_append_basic(iter, "PrefixLength",
1915 &append_addr->prefixlen);
1918 if (append_addr->gateway)
1919 connman_dbus_dict_append_basic(iter, "Gateway",
1920 DBUS_TYPE_STRING, &append_addr->gateway);
1922 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1923 connman_dbus_dict_append_basic(iter, "Privacy",
1924 DBUS_TYPE_STRING, &privacy);
1927 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1928 DBusMessageIter *iter)
1930 const char *str, *privacy;
1932 str = __connman_ipconfig_method2string(ipconfig->method);
1936 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1938 switch (ipconfig->method) {
1939 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1940 case CONNMAN_IPCONFIG_METHOD_OFF:
1941 case CONNMAN_IPCONFIG_METHOD_DHCP:
1943 case CONNMAN_IPCONFIG_METHOD_FIXED:
1944 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1945 case CONNMAN_IPCONFIG_METHOD_AUTO:
1949 if (!ipconfig->address)
1952 if (ipconfig->address->local) {
1953 connman_dbus_dict_append_basic(iter, "Address",
1954 DBUS_TYPE_STRING, &ipconfig->address->local);
1955 connman_dbus_dict_append_basic(iter, "PrefixLength",
1957 &ipconfig->address->prefixlen);
1960 if (ipconfig->address->gateway)
1961 connman_dbus_dict_append_basic(iter, "Gateway",
1962 DBUS_TYPE_STRING, &ipconfig->address->gateway);
1964 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1965 connman_dbus_dict_append_basic(iter, "Privacy",
1966 DBUS_TYPE_STRING, &privacy);
1969 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
1970 DBusMessageIter *iter)
1974 str = __connman_ipconfig_method2string(ipconfig->method);
1978 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1980 switch (ipconfig->method) {
1981 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1982 case CONNMAN_IPCONFIG_METHOD_OFF:
1983 case CONNMAN_IPCONFIG_METHOD_DHCP:
1984 case CONNMAN_IPCONFIG_METHOD_AUTO:
1986 case CONNMAN_IPCONFIG_METHOD_FIXED:
1987 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1991 if (!ipconfig->address)
1994 if (ipconfig->address->local) {
1996 struct in_addr netmask;
1999 connman_dbus_dict_append_basic(iter, "Address",
2000 DBUS_TYPE_STRING, &ipconfig->address->local);
2002 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2003 netmask.s_addr = htonl(addr);
2004 mask = inet_ntoa(netmask);
2005 connman_dbus_dict_append_basic(iter, "Netmask",
2006 DBUS_TYPE_STRING, &mask);
2009 if (ipconfig->address->gateway)
2010 connman_dbus_dict_append_basic(iter, "Gateway",
2011 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2014 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2015 DBusMessageIter *array)
2017 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2018 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2019 *privacy_string = NULL;
2020 int prefix_length = 0, privacy = 0;
2021 DBusMessageIter dict;
2024 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2027 dbus_message_iter_recurse(array, &dict);
2029 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2030 DBusMessageIter entry, value;
2034 dbus_message_iter_recurse(&dict, &entry);
2036 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2039 dbus_message_iter_get_basic(&entry, &key);
2040 dbus_message_iter_next(&entry);
2042 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2045 dbus_message_iter_recurse(&entry, &value);
2047 type = dbus_message_iter_get_arg_type(&value);
2049 if (g_str_equal(key, "Method")) {
2052 if (type != DBUS_TYPE_STRING)
2055 dbus_message_iter_get_basic(&value, &str);
2056 method = __connman_ipconfig_string2method(str);
2057 } else if (g_str_equal(key, "Address")) {
2058 if (type != DBUS_TYPE_STRING)
2061 dbus_message_iter_get_basic(&value, &address);
2062 } else if (g_str_equal(key, "PrefixLength")) {
2063 if (type != DBUS_TYPE_BYTE)
2066 dbus_message_iter_get_basic(&value, &prefix_length);
2068 if (prefix_length < 0 || prefix_length > 128)
2070 } else if (g_str_equal(key, "Netmask")) {
2071 if (type != DBUS_TYPE_STRING)
2074 dbus_message_iter_get_basic(&value, &netmask);
2075 } else if (g_str_equal(key, "Gateway")) {
2076 if (type != DBUS_TYPE_STRING)
2079 dbus_message_iter_get_basic(&value, &gateway);
2080 } else if (g_str_equal(key, "Privacy")) {
2081 if (type != DBUS_TYPE_STRING)
2084 dbus_message_iter_get_basic(&value, &privacy_string);
2085 privacy = string2privacy(privacy_string);
2088 dbus_message_iter_next(&dict);
2091 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2093 method, address, netmask, gateway, prefix_length,
2097 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2098 case CONNMAN_IPCONFIG_METHOD_FIXED:
2101 case CONNMAN_IPCONFIG_METHOD_OFF:
2102 ipconfig->method = method;
2103 #if defined TIZEN_EXT
2104 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2105 disable_ipv6(ipconfig);
2109 case CONNMAN_IPCONFIG_METHOD_AUTO:
2110 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2113 ipconfig->method = method;
2115 ipconfig->ipv6_privacy_config = privacy;
2116 #if defined TIZEN_EXT
2117 enable_ipv6(ipconfig);
2121 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2122 switch (ipconfig->type) {
2123 case CONNMAN_IPCONFIG_TYPE_IPV4:
2126 case CONNMAN_IPCONFIG_TYPE_IPV6:
2129 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2130 case CONNMAN_IPCONFIG_TYPE_ALL:
2135 if ((address && connman_inet_check_ipaddress(address)
2138 connman_inet_check_ipaddress(netmask)
2141 connman_inet_check_ipaddress(gateway)
2145 ipconfig->method = method;
2147 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2148 connman_ipaddress_set_ipv4(ipconfig->address,
2149 address, netmask, gateway);
2151 return connman_ipaddress_set_ipv6(
2152 ipconfig->address, address,
2153 prefix_length, gateway);
2157 case CONNMAN_IPCONFIG_METHOD_DHCP:
2158 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2161 ipconfig->method = method;
2168 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2169 DBusMessageIter *iter)
2171 struct connman_ipdevice *ipdevice;
2172 const char *method = "auto";
2174 connman_dbus_dict_append_basic(iter, "Method",
2175 DBUS_TYPE_STRING, &method);
2177 ipdevice = g_hash_table_lookup(ipdevice_hash,
2178 GINT_TO_POINTER(ipconfig->index));
2182 if (ipconfig->index >= 0) {
2183 char *ifname = connman_inet_ifname(ipconfig->index);
2185 connman_dbus_dict_append_basic(iter, "Interface",
2186 DBUS_TYPE_STRING, &ifname);
2191 if (ipdevice->address)
2192 connman_dbus_dict_append_basic(iter, "Address",
2193 DBUS_TYPE_STRING, &ipdevice->address);
2195 if (ipdevice->mtu > 0)
2196 connman_dbus_dict_append_basic(iter, "MTU",
2197 DBUS_TYPE_UINT16, &ipdevice->mtu);
2200 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2201 GKeyFile *keyfile, const char *identifier, const char *prefix)
2207 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2209 key = g_strdup_printf("%smethod", prefix);
2210 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2212 switch (ipconfig->type) {
2213 case CONNMAN_IPCONFIG_TYPE_IPV4:
2214 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2216 case CONNMAN_IPCONFIG_TYPE_IPV6:
2217 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2219 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2220 case CONNMAN_IPCONFIG_TYPE_ALL:
2221 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2225 ipconfig->method = __connman_ipconfig_string2method(method);
2227 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2228 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2230 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2234 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2235 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2238 pprefix = g_strdup_printf("%sprivacy", prefix);
2239 privacy = g_key_file_get_string(keyfile, identifier,
2241 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2246 pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2247 ipconfig->last_dhcpv6_prefixes =
2248 g_key_file_get_string_list(keyfile, identifier, pprefix,
2250 if (ipconfig->last_dhcpv6_prefixes && length == 0) {
2251 g_free(ipconfig->last_dhcpv6_prefixes);
2252 ipconfig->last_dhcpv6_prefixes = NULL;
2260 switch (ipconfig->method) {
2261 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2262 case CONNMAN_IPCONFIG_METHOD_OFF:
2265 case CONNMAN_IPCONFIG_METHOD_FIXED:
2266 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2268 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2269 ipconfig->address->prefixlen = g_key_file_get_integer(
2270 keyfile, identifier, key, NULL);
2273 key = g_strdup_printf("%slocal_address", prefix);
2274 g_free(ipconfig->address->local);
2275 ipconfig->address->local = g_key_file_get_string(
2276 keyfile, identifier, key, NULL);
2279 key = g_strdup_printf("%speer_address", prefix);
2280 g_free(ipconfig->address->peer);
2281 ipconfig->address->peer = g_key_file_get_string(
2282 keyfile, identifier, key, NULL);
2285 key = g_strdup_printf("%sbroadcast_address", prefix);
2286 g_free(ipconfig->address->broadcast);
2287 ipconfig->address->broadcast = g_key_file_get_string(
2288 keyfile, identifier, key, NULL);
2291 key = g_strdup_printf("%sgateway", prefix);
2292 g_free(ipconfig->address->gateway);
2293 ipconfig->address->gateway = g_key_file_get_string(
2294 keyfile, identifier, key, NULL);
2298 case CONNMAN_IPCONFIG_METHOD_AUTO:
2300 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2304 * If the last used method for IPv4 was AUTO then we
2305 * try first DHCP. We will try also to use the last
2306 * used DHCP address, if exits.
2308 __connman_ipconfig_set_method(ipconfig,
2309 CONNMAN_IPCONFIG_METHOD_DHCP);
2312 case CONNMAN_IPCONFIG_METHOD_DHCP:
2314 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2315 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2317 g_free(ipconfig->last_dhcp_address);
2318 ipconfig->last_dhcp_address = str;
2328 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2329 GKeyFile *keyfile, const char *identifier, const char *prefix)
2334 method = __connman_ipconfig_method2string(ipconfig->method);
2336 DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
2339 key = g_strdup_printf("%smethod", prefix);
2340 g_key_file_set_string(keyfile, identifier, key, method);
2344 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2345 const char *privacy;
2346 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2347 key = g_strdup_printf("%sprivacy", prefix);
2348 g_key_file_set_string(keyfile, identifier, key, privacy);
2351 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2352 if (ipconfig->last_dhcp_address &&
2353 strlen(ipconfig->last_dhcp_address) > 0)
2354 g_key_file_set_string(keyfile, identifier, key,
2355 ipconfig->last_dhcp_address);
2357 g_key_file_remove_key(keyfile, identifier, key, NULL);
2360 key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2361 if (ipconfig->last_dhcpv6_prefixes &&
2362 ipconfig->last_dhcpv6_prefixes[0]) {
2364 g_strv_length(ipconfig->last_dhcpv6_prefixes);
2366 g_key_file_set_string_list(keyfile, identifier, key,
2367 (const gchar **)ipconfig->last_dhcpv6_prefixes,
2370 g_key_file_remove_key(keyfile, identifier, key, NULL);
2374 switch (ipconfig->method) {
2375 case CONNMAN_IPCONFIG_METHOD_FIXED:
2376 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2378 case CONNMAN_IPCONFIG_METHOD_DHCP:
2379 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2380 if (ipconfig->last_dhcp_address &&
2381 strlen(ipconfig->last_dhcp_address) > 0)
2382 g_key_file_set_string(keyfile, identifier, key,
2383 ipconfig->last_dhcp_address);
2385 g_key_file_remove_key(keyfile, identifier, key, NULL);
2388 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2389 case CONNMAN_IPCONFIG_METHOD_OFF:
2390 case CONNMAN_IPCONFIG_METHOD_AUTO:
2394 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2395 if (ipconfig->address->prefixlen != 0)
2396 g_key_file_set_integer(keyfile, identifier,
2397 key, ipconfig->address->prefixlen);
2400 key = g_strdup_printf("%slocal_address", prefix);
2401 if (ipconfig->address->local)
2402 g_key_file_set_string(keyfile, identifier,
2403 key, ipconfig->address->local);
2406 key = g_strdup_printf("%speer_address", prefix);
2407 if (ipconfig->address->peer)
2408 g_key_file_set_string(keyfile, identifier,
2409 key, ipconfig->address->peer);
2412 key = g_strdup_printf("%sbroadcast_address", prefix);
2413 if (ipconfig->address->broadcast)
2414 g_key_file_set_string(keyfile, identifier,
2415 key, ipconfig->address->broadcast);
2418 key = g_strdup_printf("%sgateway", prefix);
2419 if (ipconfig->address->gateway)
2420 g_key_file_set_string(keyfile, identifier,
2421 key, ipconfig->address->gateway);
2423 g_key_file_remove_key(keyfile, identifier, key, NULL);
2429 int __connman_ipconfig_init(void)
2433 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2434 NULL, free_ipdevice);
2436 is_ipv6_supported = connman_inet_is_ipv6_supported();
2441 void __connman_ipconfig_cleanup(void)
2445 g_hash_table_destroy(ipdevice_hash);
2446 ipdevice_hash = NULL;