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;
1161 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1162 if (!ipv6config->address) {
1167 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1169 DBG("ipconfig %p index %d method %s", ipv6config, index,
1170 __connman_ipconfig_method2string(ipv6config->method));
1176 * connman_ipconfig_create:
1178 * Allocate a new ipconfig structure.
1180 * Returns: a newly-allocated #connman_ipconfig structure
1182 struct connman_ipconfig *__connman_ipconfig_create(int index,
1183 enum connman_ipconfig_type type)
1185 struct connman_ipconfig *ipconfig;
1187 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1188 return create_ipv6config(index);
1190 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1194 ipconfig->refcount = 1;
1196 ipconfig->index = index;
1197 ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
1199 ipconfig->address = connman_ipaddress_alloc(AF_INET);
1200 if (!ipconfig->address) {
1205 ipconfig->system = connman_ipaddress_alloc(AF_INET);
1207 DBG("ipconfig %p index %d", ipconfig, index);
1214 * connman_ipconfig_ref:
1215 * @ipconfig: ipconfig structure
1217 * Increase reference counter of ipconfig
1219 struct connman_ipconfig *
1220 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1221 const char *file, int line, const char *caller)
1223 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1224 file, line, caller);
1226 __sync_fetch_and_add(&ipconfig->refcount, 1);
1232 * connman_ipconfig_unref:
1233 * @ipconfig: ipconfig structure
1235 * Decrease reference counter of ipconfig
1237 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1238 const char *file, int line, const char *caller)
1243 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1244 file, line, caller);
1246 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1249 if (__connman_ipconfig_disable(ipconfig) < 0)
1250 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1252 __connman_ipconfig_set_ops(ipconfig, NULL);
1254 connman_ipaddress_free(ipconfig->system);
1255 connman_ipaddress_free(ipconfig->address);
1256 g_free(ipconfig->last_dhcp_address);
1257 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1262 * connman_ipconfig_get_data:
1263 * @ipconfig: ipconfig structure
1265 * Get private data pointer
1267 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1272 return ipconfig->ops_data;
1276 * connman_ipconfig_set_data:
1277 * @ipconfig: ipconfig structure
1278 * @data: data pointer
1280 * Set private data pointer
1282 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1284 ipconfig->ops_data = data;
1288 * connman_ipconfig_get_index:
1289 * @ipconfig: ipconfig structure
1291 * Get interface index
1293 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1298 return ipconfig->index;
1302 * connman_ipconfig_set_ops:
1303 * @ipconfig: ipconfig structure
1304 * @ops: operation callbacks
1306 * Set the operation callbacks
1308 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1309 const struct connman_ipconfig_ops *ops)
1311 ipconfig->ops = ops;
1315 * connman_ipconfig_set_method:
1316 * @ipconfig: ipconfig structure
1317 * @method: configuration method
1319 * Set the configuration method
1321 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1322 enum connman_ipconfig_method method)
1324 ipconfig->method = method;
1329 enum connman_ipconfig_method __connman_ipconfig_get_method(
1330 struct connman_ipconfig *ipconfig)
1333 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1335 return ipconfig->method;
1338 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1340 switch (ipconfig->method) {
1341 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1342 case CONNMAN_IPCONFIG_METHOD_OFF:
1344 case CONNMAN_IPCONFIG_METHOD_AUTO:
1345 case CONNMAN_IPCONFIG_METHOD_FIXED:
1346 case CONNMAN_IPCONFIG_METHOD_DHCP:
1347 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1348 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1349 return connman_inet_set_address(ipconfig->index,
1351 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1352 return connman_inet_set_ipv6_address(
1353 ipconfig->index, ipconfig->address);
1359 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1366 switch (ipconfig->method) {
1367 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1368 case CONNMAN_IPCONFIG_METHOD_OFF:
1370 case CONNMAN_IPCONFIG_METHOD_AUTO:
1371 case CONNMAN_IPCONFIG_METHOD_FIXED:
1372 case CONNMAN_IPCONFIG_METHOD_DHCP:
1373 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1374 err = __connman_ipconfig_address_unset(ipconfig);
1375 connman_ipaddress_clear(ipconfig->address);
1383 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1390 #if defined TIZEN_EXT
1391 DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type);
1393 DBG("method %d", ipconfig->method);
1396 switch (ipconfig->method) {
1397 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1398 case CONNMAN_IPCONFIG_METHOD_OFF:
1400 case CONNMAN_IPCONFIG_METHOD_AUTO:
1401 case CONNMAN_IPCONFIG_METHOD_FIXED:
1402 case CONNMAN_IPCONFIG_METHOD_DHCP:
1403 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1404 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1405 err = connman_inet_clear_address(ipconfig->index,
1407 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1408 err = connman_inet_clear_ipv6_address(
1410 ipconfig->address->local,
1411 ipconfig->address->prefixlen);
1421 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1424 struct connman_ipdevice *ipdevice;
1426 if (!ipconfig || ipconfig->index < 0)
1429 ipdevice = g_hash_table_lookup(ipdevice_hash,
1430 GINT_TO_POINTER(ipconfig->index));
1434 g_free(ipdevice->pac);
1435 ipdevice->pac = g_strdup(url);
1440 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1442 struct connman_ipdevice *ipdevice;
1444 if (!ipconfig || ipconfig->index < 0)
1447 ipdevice = g_hash_table_lookup(ipdevice_hash,
1448 GINT_TO_POINTER(ipconfig->index));
1452 return ipdevice->pac;
1455 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1456 const char *address)
1461 g_free(ipconfig->last_dhcp_address);
1462 ipconfig->last_dhcp_address = g_strdup(address);
1465 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1470 return ipconfig->last_dhcp_address;
1473 void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
1479 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1480 ipconfig->last_dhcpv6_prefixes = prefixes;
1483 char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
1488 return ipconfig->last_dhcpv6_prefixes;
1491 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1493 struct connman_ipdevice *ipdevice;
1498 ipdevice = g_hash_table_lookup(ipdevice_hash,
1499 GINT_TO_POINTER(ipconfig->index));
1503 ifname = connman_inet_ifname(ipconfig->index);
1505 set_ipv6_state(ifname, false);
1510 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1512 struct connman_ipdevice *ipdevice;
1517 ipdevice = g_hash_table_lookup(ipdevice_hash,
1518 GINT_TO_POINTER(ipconfig->index));
1522 ifname = connman_inet_ifname(ipconfig->index);
1524 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1525 set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
1527 set_ipv6_state(ifname, true);
1532 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1534 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1537 enable_ipv6(ipconfig);
1540 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1542 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1545 disable_ipv6(ipconfig);
1548 bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1553 switch (ipconfig->method) {
1554 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1555 case CONNMAN_IPCONFIG_METHOD_OFF:
1557 case CONNMAN_IPCONFIG_METHOD_AUTO:
1558 case CONNMAN_IPCONFIG_METHOD_FIXED:
1559 case CONNMAN_IPCONFIG_METHOD_DHCP:
1560 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1567 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1569 struct connman_ipdevice *ipdevice;
1570 bool up = false, down = false;
1571 bool lower_up = false, lower_down = false;
1572 enum connman_ipconfig_type type;
1575 DBG("ipconfig %p", ipconfig);
1577 if (!ipconfig || ipconfig->index < 0)
1580 ipdevice = g_hash_table_lookup(ipdevice_hash,
1581 GINT_TO_POINTER(ipconfig->index));
1585 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1586 if (ipdevice->config_ipv4 == ipconfig)
1588 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1589 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1590 if (ipdevice->config_ipv6 == ipconfig)
1592 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1596 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1597 ipdevice->config_ipv4) {
1598 ipconfig_list = g_list_remove(ipconfig_list,
1599 ipdevice->config_ipv4);
1601 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1603 __connman_ipconfig_unref(ipdevice->config_ipv4);
1606 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1607 ipdevice->config_ipv6) {
1608 ipconfig_list = g_list_remove(ipconfig_list,
1609 ipdevice->config_ipv6);
1611 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1613 __connman_ipconfig_unref(ipdevice->config_ipv6);
1616 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1617 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1618 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1619 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1621 enable_ipv6(ipdevice->config_ipv6);
1623 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1625 if (ipdevice->flags & IFF_UP)
1630 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1631 (IFF_RUNNING | IFF_LOWER_UP))
1633 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1636 ifname = connman_inet_ifname(ipconfig->index);
1638 if (up && ipconfig->ops->up)
1639 ipconfig->ops->up(ipconfig, ifname);
1640 if (lower_up && ipconfig->ops->lower_up)
1641 ipconfig->ops->lower_up(ipconfig, ifname);
1643 if (lower_down && ipconfig->ops->lower_down)
1644 ipconfig->ops->lower_down(ipconfig, ifname);
1645 if (down && ipconfig->ops->down)
1646 ipconfig->ops->down(ipconfig, ifname);
1653 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1655 struct connman_ipdevice *ipdevice;
1657 DBG("ipconfig %p", ipconfig);
1659 if (!ipconfig || ipconfig->index < 0)
1662 ipdevice = g_hash_table_lookup(ipdevice_hash,
1663 GINT_TO_POINTER(ipconfig->index));
1667 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
1670 if (ipdevice->config_ipv4 == ipconfig) {
1671 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1673 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1674 __connman_ipconfig_unref(ipdevice->config_ipv4);
1675 ipdevice->config_ipv4 = NULL;
1679 if (ipdevice->config_ipv6 == ipconfig) {
1680 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1682 #if defined TIZEN_EXT
1683 if (ipdevice->config_ipv6->method ==
1684 CONNMAN_IPCONFIG_METHOD_AUTO)
1685 disable_ipv6(ipdevice->config_ipv6);
1687 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1688 __connman_ipconfig_unref(ipdevice->config_ipv6);
1689 ipdevice->config_ipv6 = NULL;
1696 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1699 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1701 case CONNMAN_IPCONFIG_METHOD_OFF:
1703 case CONNMAN_IPCONFIG_METHOD_FIXED:
1705 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1707 case CONNMAN_IPCONFIG_METHOD_DHCP:
1709 case CONNMAN_IPCONFIG_METHOD_AUTO:
1716 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1718 if (g_strcmp0(method, "off") == 0)
1719 return CONNMAN_IPCONFIG_METHOD_OFF;
1720 else if (g_strcmp0(method, "fixed") == 0)
1721 return CONNMAN_IPCONFIG_METHOD_FIXED;
1722 else if (g_strcmp0(method, "manual") == 0)
1723 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1724 else if (g_strcmp0(method, "dhcp") == 0)
1725 return CONNMAN_IPCONFIG_METHOD_DHCP;
1726 else if (g_strcmp0(method, "auto") == 0)
1727 return CONNMAN_IPCONFIG_METHOD_AUTO;
1729 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1732 static const char *privacy2string(int privacy)
1736 else if (privacy == 1)
1742 static int string2privacy(const char *privacy)
1744 if (g_strcmp0(privacy, "disabled") == 0)
1746 else if (g_strcmp0(privacy, "enabled") == 0)
1748 else if (g_strcmp0(privacy, "preferred") == 0)
1750 else if (g_strcmp0(privacy, "prefered") == 0)
1756 int __connman_ipconfig_ipv6_reset_privacy(struct connman_ipconfig *ipconfig)
1758 struct connman_ipdevice *ipdevice;
1764 ipdevice = g_hash_table_lookup(ipdevice_hash,
1765 GINT_TO_POINTER(ipconfig->index));
1769 err = __connman_ipconfig_ipv6_set_privacy(ipconfig, privacy2string(
1770 ipdevice->ipv6_privacy));
1775 int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
1783 privacy = string2privacy(value);
1785 ipconfig->ipv6_privacy_config = privacy;
1787 enable_ipv6(ipconfig);
1792 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1793 DBusMessageIter *iter)
1795 struct connman_ipaddress *append_addr = NULL;
1798 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1801 str = __connman_ipconfig_method2string(ipconfig->method);
1805 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1807 switch (ipconfig->method) {
1808 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1809 case CONNMAN_IPCONFIG_METHOD_OFF:
1812 case CONNMAN_IPCONFIG_METHOD_FIXED:
1813 append_addr = ipconfig->address;
1816 case CONNMAN_IPCONFIG_METHOD_AUTO:
1817 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1818 case CONNMAN_IPCONFIG_METHOD_DHCP:
1819 append_addr = ipconfig->system;
1820 #if defined TIZEN_EXT
1821 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1822 if (append_addr && append_addr->local == NULL)
1823 append_addr = ipconfig->address;
1831 if (append_addr->local) {
1833 struct in_addr netmask;
1836 connman_dbus_dict_append_basic(iter, "Address",
1837 DBUS_TYPE_STRING, &append_addr->local);
1839 addr = 0xffffffff << (32 - append_addr->prefixlen);
1840 netmask.s_addr = htonl(addr);
1841 mask = inet_ntoa(netmask);
1842 connman_dbus_dict_append_basic(iter, "Netmask",
1843 DBUS_TYPE_STRING, &mask);
1846 if (append_addr->gateway)
1847 connman_dbus_dict_append_basic(iter, "Gateway",
1848 DBUS_TYPE_STRING, &append_addr->gateway);
1850 #if defined TIZEN_EXT
1851 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
1853 server_ip = __connman_dhcp_get_server_address(ipconfig);
1855 connman_dbus_dict_append_basic(iter, "DHCPServerIP",
1856 DBUS_TYPE_STRING, &server_ip);
1859 connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
1860 DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
1865 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1866 DBusMessageIter *iter,
1867 struct connman_ipconfig *ipconfig_ipv4)
1869 struct connman_ipaddress *append_addr = NULL;
1870 const char *str, *privacy;
1872 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1875 str = __connman_ipconfig_method2string(ipconfig->method);
1879 if (ipconfig_ipv4 &&
1880 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1881 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1885 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1887 switch (ipconfig->method) {
1888 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1889 case CONNMAN_IPCONFIG_METHOD_OFF:
1892 case CONNMAN_IPCONFIG_METHOD_FIXED:
1893 append_addr = ipconfig->address;
1896 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1897 case CONNMAN_IPCONFIG_METHOD_DHCP:
1898 case CONNMAN_IPCONFIG_METHOD_AUTO:
1899 append_addr = ipconfig->system;
1900 #if defined TIZEN_EXT
1901 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1902 if (append_addr && append_addr->local == NULL)
1903 append_addr = ipconfig->address;
1911 if (append_addr->local) {
1912 connman_dbus_dict_append_basic(iter, "Address",
1913 DBUS_TYPE_STRING, &append_addr->local);
1914 connman_dbus_dict_append_basic(iter, "PrefixLength",
1916 &append_addr->prefixlen);
1919 if (append_addr->gateway)
1920 connman_dbus_dict_append_basic(iter, "Gateway",
1921 DBUS_TYPE_STRING, &append_addr->gateway);
1923 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1924 connman_dbus_dict_append_basic(iter, "Privacy",
1925 DBUS_TYPE_STRING, &privacy);
1928 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1929 DBusMessageIter *iter)
1931 const char *str, *privacy;
1933 str = __connman_ipconfig_method2string(ipconfig->method);
1937 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1939 switch (ipconfig->method) {
1940 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1941 case CONNMAN_IPCONFIG_METHOD_OFF:
1942 case CONNMAN_IPCONFIG_METHOD_DHCP:
1944 case CONNMAN_IPCONFIG_METHOD_FIXED:
1945 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1946 case CONNMAN_IPCONFIG_METHOD_AUTO:
1950 if (!ipconfig->address)
1953 if (ipconfig->address->local) {
1954 connman_dbus_dict_append_basic(iter, "Address",
1955 DBUS_TYPE_STRING, &ipconfig->address->local);
1956 connman_dbus_dict_append_basic(iter, "PrefixLength",
1958 &ipconfig->address->prefixlen);
1961 if (ipconfig->address->gateway)
1962 connman_dbus_dict_append_basic(iter, "Gateway",
1963 DBUS_TYPE_STRING, &ipconfig->address->gateway);
1965 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1966 connman_dbus_dict_append_basic(iter, "Privacy",
1967 DBUS_TYPE_STRING, &privacy);
1970 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
1971 DBusMessageIter *iter)
1975 str = __connman_ipconfig_method2string(ipconfig->method);
1979 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1981 switch (ipconfig->method) {
1982 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1983 case CONNMAN_IPCONFIG_METHOD_OFF:
1984 case CONNMAN_IPCONFIG_METHOD_DHCP:
1985 case CONNMAN_IPCONFIG_METHOD_AUTO:
1987 case CONNMAN_IPCONFIG_METHOD_FIXED:
1988 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1992 if (!ipconfig->address)
1995 if (ipconfig->address->local) {
1997 struct in_addr netmask;
2000 connman_dbus_dict_append_basic(iter, "Address",
2001 DBUS_TYPE_STRING, &ipconfig->address->local);
2003 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2004 netmask.s_addr = htonl(addr);
2005 mask = inet_ntoa(netmask);
2006 connman_dbus_dict_append_basic(iter, "Netmask",
2007 DBUS_TYPE_STRING, &mask);
2010 if (ipconfig->address->gateway)
2011 connman_dbus_dict_append_basic(iter, "Gateway",
2012 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2015 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2016 DBusMessageIter *array)
2018 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2019 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2020 *privacy_string = NULL;
2021 int prefix_length = 0, privacy = 0;
2022 DBusMessageIter dict;
2025 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2028 dbus_message_iter_recurse(array, &dict);
2030 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2031 DBusMessageIter entry, value;
2035 dbus_message_iter_recurse(&dict, &entry);
2037 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2040 dbus_message_iter_get_basic(&entry, &key);
2041 dbus_message_iter_next(&entry);
2043 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2046 dbus_message_iter_recurse(&entry, &value);
2048 type = dbus_message_iter_get_arg_type(&value);
2050 if (g_str_equal(key, "Method")) {
2053 if (type != DBUS_TYPE_STRING)
2056 dbus_message_iter_get_basic(&value, &str);
2057 method = __connman_ipconfig_string2method(str);
2058 } else if (g_str_equal(key, "Address")) {
2059 if (type != DBUS_TYPE_STRING)
2062 dbus_message_iter_get_basic(&value, &address);
2063 } else if (g_str_equal(key, "PrefixLength")) {
2064 if (type != DBUS_TYPE_BYTE)
2067 dbus_message_iter_get_basic(&value, &prefix_length);
2069 if (prefix_length < 0 || prefix_length > 128)
2071 } else if (g_str_equal(key, "Netmask")) {
2072 if (type != DBUS_TYPE_STRING)
2075 dbus_message_iter_get_basic(&value, &netmask);
2076 } else if (g_str_equal(key, "Gateway")) {
2077 if (type != DBUS_TYPE_STRING)
2080 dbus_message_iter_get_basic(&value, &gateway);
2081 } else if (g_str_equal(key, "Privacy")) {
2082 if (type != DBUS_TYPE_STRING)
2085 dbus_message_iter_get_basic(&value, &privacy_string);
2086 privacy = string2privacy(privacy_string);
2089 dbus_message_iter_next(&dict);
2092 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2094 method, address, netmask, gateway, prefix_length,
2098 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2099 case CONNMAN_IPCONFIG_METHOD_FIXED:
2102 case CONNMAN_IPCONFIG_METHOD_OFF:
2103 ipconfig->method = method;
2104 #if defined TIZEN_EXT
2105 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2106 disable_ipv6(ipconfig);
2111 case CONNMAN_IPCONFIG_METHOD_AUTO:
2112 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2115 ipconfig->method = method;
2117 ipconfig->ipv6_privacy_config = privacy;
2118 #if defined TIZEN_EXT
2119 enable_ipv6(ipconfig);
2124 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2125 switch (ipconfig->type) {
2126 case CONNMAN_IPCONFIG_TYPE_IPV4:
2129 case CONNMAN_IPCONFIG_TYPE_IPV6:
2132 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2133 case CONNMAN_IPCONFIG_TYPE_ALL:
2138 if ((address && connman_inet_check_ipaddress(address)
2141 connman_inet_check_ipaddress(netmask)
2144 connman_inet_check_ipaddress(gateway)
2148 ipconfig->method = method;
2150 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2151 connman_ipaddress_set_ipv4(ipconfig->address,
2152 address, netmask, gateway);
2154 return connman_ipaddress_set_ipv6(
2155 ipconfig->address, address,
2156 prefix_length, gateway);
2160 case CONNMAN_IPCONFIG_METHOD_DHCP:
2161 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2164 ipconfig->method = method;
2171 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2172 DBusMessageIter *iter)
2174 struct connman_ipdevice *ipdevice;
2175 const char *method = "auto";
2177 connman_dbus_dict_append_basic(iter, "Method",
2178 DBUS_TYPE_STRING, &method);
2180 ipdevice = g_hash_table_lookup(ipdevice_hash,
2181 GINT_TO_POINTER(ipconfig->index));
2185 if (ipconfig->index >= 0) {
2186 char *ifname = connman_inet_ifname(ipconfig->index);
2188 connman_dbus_dict_append_basic(iter, "Interface",
2189 DBUS_TYPE_STRING, &ifname);
2194 if (ipdevice->address)
2195 connman_dbus_dict_append_basic(iter, "Address",
2196 DBUS_TYPE_STRING, &ipdevice->address);
2198 if (ipdevice->mtu > 0)
2199 connman_dbus_dict_append_basic(iter, "MTU",
2200 DBUS_TYPE_UINT16, &ipdevice->mtu);
2203 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2204 GKeyFile *keyfile, const char *identifier, const char *prefix)
2210 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2212 key = g_strdup_printf("%smethod", prefix);
2213 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2215 switch (ipconfig->type) {
2216 case CONNMAN_IPCONFIG_TYPE_IPV4:
2217 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2219 case CONNMAN_IPCONFIG_TYPE_IPV6:
2220 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2222 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2223 case CONNMAN_IPCONFIG_TYPE_ALL:
2224 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2228 ipconfig->method = __connman_ipconfig_string2method(method);
2230 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2231 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2233 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2237 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2238 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2241 pprefix = g_strdup_printf("%sprivacy", prefix);
2242 privacy = g_key_file_get_string(keyfile, identifier,
2244 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2249 pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2250 ipconfig->last_dhcpv6_prefixes =
2251 g_key_file_get_string_list(keyfile, identifier, pprefix,
2253 if (ipconfig->last_dhcpv6_prefixes && length == 0) {
2254 g_free(ipconfig->last_dhcpv6_prefixes);
2255 ipconfig->last_dhcpv6_prefixes = NULL;
2263 switch (ipconfig->method) {
2264 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2265 case CONNMAN_IPCONFIG_METHOD_OFF:
2268 case CONNMAN_IPCONFIG_METHOD_FIXED:
2269 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2271 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2272 ipconfig->address->prefixlen = g_key_file_get_integer(
2273 keyfile, identifier, key, NULL);
2276 key = g_strdup_printf("%slocal_address", prefix);
2277 g_free(ipconfig->address->local);
2278 ipconfig->address->local = g_key_file_get_string(
2279 keyfile, identifier, key, NULL);
2282 key = g_strdup_printf("%speer_address", prefix);
2283 g_free(ipconfig->address->peer);
2284 ipconfig->address->peer = g_key_file_get_string(
2285 keyfile, identifier, key, NULL);
2288 key = g_strdup_printf("%sbroadcast_address", prefix);
2289 g_free(ipconfig->address->broadcast);
2290 ipconfig->address->broadcast = g_key_file_get_string(
2291 keyfile, identifier, key, NULL);
2294 key = g_strdup_printf("%sgateway", prefix);
2295 g_free(ipconfig->address->gateway);
2296 ipconfig->address->gateway = g_key_file_get_string(
2297 keyfile, identifier, key, NULL);
2301 case CONNMAN_IPCONFIG_METHOD_AUTO:
2303 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2307 * If the last used method for IPv4 was AUTO then we
2308 * try first DHCP. We will try also to use the last
2309 * used DHCP address, if exits.
2311 __connman_ipconfig_set_method(ipconfig,
2312 CONNMAN_IPCONFIG_METHOD_DHCP);
2315 case CONNMAN_IPCONFIG_METHOD_DHCP:
2317 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2318 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2320 g_free(ipconfig->last_dhcp_address);
2321 ipconfig->last_dhcp_address = str;
2331 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2332 GKeyFile *keyfile, const char *identifier, const char *prefix)
2337 method = __connman_ipconfig_method2string(ipconfig->method);
2339 DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
2342 key = g_strdup_printf("%smethod", prefix);
2343 g_key_file_set_string(keyfile, identifier, key, method);
2347 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2348 const char *privacy;
2349 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2350 key = g_strdup_printf("%sprivacy", prefix);
2351 g_key_file_set_string(keyfile, identifier, key, privacy);
2354 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2355 if (ipconfig->last_dhcp_address &&
2356 strlen(ipconfig->last_dhcp_address) > 0)
2357 g_key_file_set_string(keyfile, identifier, key,
2358 ipconfig->last_dhcp_address);
2360 g_key_file_remove_key(keyfile, identifier, key, NULL);
2363 key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2364 if (ipconfig->last_dhcpv6_prefixes &&
2365 ipconfig->last_dhcpv6_prefixes[0]) {
2367 g_strv_length(ipconfig->last_dhcpv6_prefixes);
2369 g_key_file_set_string_list(keyfile, identifier, key,
2370 (const gchar **)ipconfig->last_dhcpv6_prefixes,
2373 g_key_file_remove_key(keyfile, identifier, key, NULL);
2377 switch (ipconfig->method) {
2378 case CONNMAN_IPCONFIG_METHOD_FIXED:
2379 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2381 case CONNMAN_IPCONFIG_METHOD_DHCP:
2382 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2383 if (ipconfig->last_dhcp_address &&
2384 strlen(ipconfig->last_dhcp_address) > 0)
2385 g_key_file_set_string(keyfile, identifier, key,
2386 ipconfig->last_dhcp_address);
2388 g_key_file_remove_key(keyfile, identifier, key, NULL);
2391 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2392 case CONNMAN_IPCONFIG_METHOD_OFF:
2393 case CONNMAN_IPCONFIG_METHOD_AUTO:
2397 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2398 if (ipconfig->address->prefixlen != 0)
2399 g_key_file_set_integer(keyfile, identifier,
2400 key, ipconfig->address->prefixlen);
2403 key = g_strdup_printf("%slocal_address", prefix);
2404 if (ipconfig->address->local)
2405 g_key_file_set_string(keyfile, identifier,
2406 key, ipconfig->address->local);
2409 key = g_strdup_printf("%speer_address", prefix);
2410 if (ipconfig->address->peer)
2411 g_key_file_set_string(keyfile, identifier,
2412 key, ipconfig->address->peer);
2415 key = g_strdup_printf("%sbroadcast_address", prefix);
2416 if (ipconfig->address->broadcast)
2417 g_key_file_set_string(keyfile, identifier,
2418 key, ipconfig->address->broadcast);
2421 key = g_strdup_printf("%sgateway", prefix);
2422 if (ipconfig->address->gateway)
2423 g_key_file_set_string(keyfile, identifier,
2424 key, ipconfig->address->gateway);
2426 g_key_file_remove_key(keyfile, identifier, key, NULL);
2432 int __connman_ipconfig_init(void)
2436 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2437 NULL, free_ipdevice);
2439 is_ipv6_supported = connman_inet_is_ipv6_supported();
2444 void __connman_ipconfig_cleanup(void)
2448 g_hash_table_destroy(ipdevice_hash);
2449 ipdevice_hash = NULL;