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);
1206 #if defined TIZEN_EXT
1207 if (!simplified_log)
1209 DBG("ipconfig %p index %d", ipconfig, index);
1216 * connman_ipconfig_ref:
1217 * @ipconfig: ipconfig structure
1219 * Increase reference counter of ipconfig
1221 struct connman_ipconfig *
1222 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1223 const char *file, int line, const char *caller)
1225 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1226 file, line, caller);
1228 __sync_fetch_and_add(&ipconfig->refcount, 1);
1234 * connman_ipconfig_unref:
1235 * @ipconfig: ipconfig structure
1237 * Decrease reference counter of ipconfig
1239 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1240 const char *file, int line, const char *caller)
1244 #if defined TIZEN_EXT
1245 if (!simplified_log)
1247 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1248 file, line, caller);
1250 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1253 if (__connman_ipconfig_disable(ipconfig) < 0)
1254 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1256 __connman_ipconfig_set_ops(ipconfig, NULL);
1258 connman_ipaddress_free(ipconfig->system);
1259 connman_ipaddress_free(ipconfig->address);
1260 g_free(ipconfig->last_dhcp_address);
1261 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1266 * connman_ipconfig_get_data:
1267 * @ipconfig: ipconfig structure
1269 * Get private data pointer
1271 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1276 return ipconfig->ops_data;
1280 * connman_ipconfig_set_data:
1281 * @ipconfig: ipconfig structure
1282 * @data: data pointer
1284 * Set private data pointer
1286 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1288 ipconfig->ops_data = data;
1292 * connman_ipconfig_get_index:
1293 * @ipconfig: ipconfig structure
1295 * Get interface index
1297 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1302 return ipconfig->index;
1306 * connman_ipconfig_set_ops:
1307 * @ipconfig: ipconfig structure
1308 * @ops: operation callbacks
1310 * Set the operation callbacks
1312 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1313 const struct connman_ipconfig_ops *ops)
1315 ipconfig->ops = ops;
1319 * connman_ipconfig_set_method:
1320 * @ipconfig: ipconfig structure
1321 * @method: configuration method
1323 * Set the configuration method
1325 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1326 enum connman_ipconfig_method method)
1328 ipconfig->method = method;
1333 enum connman_ipconfig_method __connman_ipconfig_get_method(
1334 struct connman_ipconfig *ipconfig)
1337 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1339 return ipconfig->method;
1342 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1344 switch (ipconfig->method) {
1345 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1346 case CONNMAN_IPCONFIG_METHOD_OFF:
1348 case CONNMAN_IPCONFIG_METHOD_AUTO:
1349 case CONNMAN_IPCONFIG_METHOD_FIXED:
1350 case CONNMAN_IPCONFIG_METHOD_DHCP:
1351 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1352 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1353 return connman_inet_set_address(ipconfig->index,
1355 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1356 return connman_inet_set_ipv6_address(
1357 ipconfig->index, ipconfig->address);
1363 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1370 switch (ipconfig->method) {
1371 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1372 case CONNMAN_IPCONFIG_METHOD_OFF:
1374 case CONNMAN_IPCONFIG_METHOD_AUTO:
1375 case CONNMAN_IPCONFIG_METHOD_FIXED:
1376 case CONNMAN_IPCONFIG_METHOD_DHCP:
1377 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1378 err = __connman_ipconfig_address_unset(ipconfig);
1379 connman_ipaddress_clear(ipconfig->address);
1387 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1394 #if defined TIZEN_EXT
1395 DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type);
1397 DBG("method %d", ipconfig->method);
1400 switch (ipconfig->method) {
1401 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1402 case CONNMAN_IPCONFIG_METHOD_OFF:
1404 case CONNMAN_IPCONFIG_METHOD_AUTO:
1405 case CONNMAN_IPCONFIG_METHOD_FIXED:
1406 case CONNMAN_IPCONFIG_METHOD_DHCP:
1407 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1408 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1409 err = connman_inet_clear_address(ipconfig->index,
1411 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1412 err = connman_inet_clear_ipv6_address(
1414 ipconfig->address->local,
1415 ipconfig->address->prefixlen);
1425 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1428 struct connman_ipdevice *ipdevice;
1430 if (!ipconfig || ipconfig->index < 0)
1433 ipdevice = g_hash_table_lookup(ipdevice_hash,
1434 GINT_TO_POINTER(ipconfig->index));
1438 g_free(ipdevice->pac);
1439 ipdevice->pac = g_strdup(url);
1444 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1446 struct connman_ipdevice *ipdevice;
1448 if (!ipconfig || ipconfig->index < 0)
1451 ipdevice = g_hash_table_lookup(ipdevice_hash,
1452 GINT_TO_POINTER(ipconfig->index));
1456 return ipdevice->pac;
1459 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1460 const char *address)
1465 g_free(ipconfig->last_dhcp_address);
1466 ipconfig->last_dhcp_address = g_strdup(address);
1469 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1474 return ipconfig->last_dhcp_address;
1477 void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
1483 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1484 ipconfig->last_dhcpv6_prefixes = prefixes;
1487 char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
1492 return ipconfig->last_dhcpv6_prefixes;
1495 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1497 struct connman_ipdevice *ipdevice;
1502 ipdevice = g_hash_table_lookup(ipdevice_hash,
1503 GINT_TO_POINTER(ipconfig->index));
1507 ifname = connman_inet_ifname(ipconfig->index);
1509 set_ipv6_state(ifname, false);
1514 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1516 struct connman_ipdevice *ipdevice;
1521 ipdevice = g_hash_table_lookup(ipdevice_hash,
1522 GINT_TO_POINTER(ipconfig->index));
1526 ifname = connman_inet_ifname(ipconfig->index);
1528 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1529 set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
1531 set_ipv6_state(ifname, true);
1536 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1538 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1541 enable_ipv6(ipconfig);
1544 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1546 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1549 disable_ipv6(ipconfig);
1552 bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1557 switch (ipconfig->method) {
1558 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1559 case CONNMAN_IPCONFIG_METHOD_OFF:
1561 case CONNMAN_IPCONFIG_METHOD_AUTO:
1562 case CONNMAN_IPCONFIG_METHOD_FIXED:
1563 case CONNMAN_IPCONFIG_METHOD_DHCP:
1564 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1571 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1573 struct connman_ipdevice *ipdevice;
1574 bool up = false, down = false;
1575 bool lower_up = false, lower_down = false;
1576 enum connman_ipconfig_type type;
1579 DBG("ipconfig %p", ipconfig);
1581 if (!ipconfig || ipconfig->index < 0)
1584 ipdevice = g_hash_table_lookup(ipdevice_hash,
1585 GINT_TO_POINTER(ipconfig->index));
1589 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1590 if (ipdevice->config_ipv4 == ipconfig)
1592 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1593 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1594 if (ipdevice->config_ipv6 == ipconfig)
1596 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1600 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1601 ipdevice->config_ipv4) {
1602 ipconfig_list = g_list_remove(ipconfig_list,
1603 ipdevice->config_ipv4);
1605 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1607 __connman_ipconfig_unref(ipdevice->config_ipv4);
1610 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1611 ipdevice->config_ipv6) {
1612 ipconfig_list = g_list_remove(ipconfig_list,
1613 ipdevice->config_ipv6);
1615 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1617 __connman_ipconfig_unref(ipdevice->config_ipv6);
1620 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1621 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1622 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1623 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1625 enable_ipv6(ipdevice->config_ipv6);
1627 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1629 if (ipdevice->flags & IFF_UP)
1634 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1635 (IFF_RUNNING | IFF_LOWER_UP))
1637 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1640 ifname = connman_inet_ifname(ipconfig->index);
1642 if (up && ipconfig->ops->up)
1643 ipconfig->ops->up(ipconfig, ifname);
1644 if (lower_up && ipconfig->ops->lower_up)
1645 ipconfig->ops->lower_up(ipconfig, ifname);
1647 if (lower_down && ipconfig->ops->lower_down)
1648 ipconfig->ops->lower_down(ipconfig, ifname);
1649 if (down && ipconfig->ops->down)
1650 ipconfig->ops->down(ipconfig, ifname);
1657 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1659 struct connman_ipdevice *ipdevice;
1660 #if defined TIZEN_EXT
1661 if (!simplified_log)
1663 DBG("ipconfig %p", ipconfig);
1665 if (!ipconfig || ipconfig->index < 0)
1668 ipdevice = g_hash_table_lookup(ipdevice_hash,
1669 GINT_TO_POINTER(ipconfig->index));
1673 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
1676 if (ipdevice->config_ipv4 == ipconfig) {
1677 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1679 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1680 __connman_ipconfig_unref(ipdevice->config_ipv4);
1681 ipdevice->config_ipv4 = NULL;
1685 if (ipdevice->config_ipv6 == ipconfig) {
1686 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1688 #if defined TIZEN_EXT
1689 if (ipdevice->config_ipv6->method ==
1690 CONNMAN_IPCONFIG_METHOD_AUTO)
1691 disable_ipv6(ipdevice->config_ipv6);
1693 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1694 __connman_ipconfig_unref(ipdevice->config_ipv6);
1695 ipdevice->config_ipv6 = NULL;
1702 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1705 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1707 case CONNMAN_IPCONFIG_METHOD_OFF:
1709 case CONNMAN_IPCONFIG_METHOD_FIXED:
1711 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1713 case CONNMAN_IPCONFIG_METHOD_DHCP:
1715 case CONNMAN_IPCONFIG_METHOD_AUTO:
1722 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1724 if (g_strcmp0(method, "off") == 0)
1725 return CONNMAN_IPCONFIG_METHOD_OFF;
1726 else if (g_strcmp0(method, "fixed") == 0)
1727 return CONNMAN_IPCONFIG_METHOD_FIXED;
1728 else if (g_strcmp0(method, "manual") == 0)
1729 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1730 else if (g_strcmp0(method, "dhcp") == 0)
1731 return CONNMAN_IPCONFIG_METHOD_DHCP;
1732 else if (g_strcmp0(method, "auto") == 0)
1733 return CONNMAN_IPCONFIG_METHOD_AUTO;
1735 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1738 static const char *privacy2string(int privacy)
1742 else if (privacy == 1)
1748 static int string2privacy(const char *privacy)
1750 if (g_strcmp0(privacy, "disabled") == 0)
1752 else if (g_strcmp0(privacy, "enabled") == 0)
1754 else if (g_strcmp0(privacy, "preferred") == 0)
1756 else if (g_strcmp0(privacy, "prefered") == 0)
1762 int __connman_ipconfig_ipv6_reset_privacy(struct connman_ipconfig *ipconfig)
1764 struct connman_ipdevice *ipdevice;
1770 ipdevice = g_hash_table_lookup(ipdevice_hash,
1771 GINT_TO_POINTER(ipconfig->index));
1775 err = __connman_ipconfig_ipv6_set_privacy(ipconfig, privacy2string(
1776 ipdevice->ipv6_privacy));
1781 int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
1789 privacy = string2privacy(value);
1791 ipconfig->ipv6_privacy_config = privacy;
1793 enable_ipv6(ipconfig);
1798 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1799 DBusMessageIter *iter)
1801 struct connman_ipaddress *append_addr = NULL;
1804 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1807 str = __connman_ipconfig_method2string(ipconfig->method);
1811 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1813 switch (ipconfig->method) {
1814 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1815 case CONNMAN_IPCONFIG_METHOD_OFF:
1818 case CONNMAN_IPCONFIG_METHOD_FIXED:
1819 append_addr = ipconfig->address;
1822 case CONNMAN_IPCONFIG_METHOD_AUTO:
1823 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1824 case CONNMAN_IPCONFIG_METHOD_DHCP:
1825 append_addr = ipconfig->system;
1826 #if defined TIZEN_EXT
1827 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1828 if (append_addr && append_addr->local == NULL)
1829 append_addr = ipconfig->address;
1837 if (append_addr->local) {
1839 struct in_addr netmask;
1842 connman_dbus_dict_append_basic(iter, "Address",
1843 DBUS_TYPE_STRING, &append_addr->local);
1845 addr = 0xffffffff << (32 - append_addr->prefixlen);
1846 netmask.s_addr = htonl(addr);
1847 mask = inet_ntoa(netmask);
1848 connman_dbus_dict_append_basic(iter, "Netmask",
1849 DBUS_TYPE_STRING, &mask);
1852 if (append_addr->gateway)
1853 connman_dbus_dict_append_basic(iter, "Gateway",
1854 DBUS_TYPE_STRING, &append_addr->gateway);
1856 #if defined TIZEN_EXT
1857 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
1859 server_ip = __connman_dhcp_get_server_address(ipconfig);
1861 connman_dbus_dict_append_basic(iter, "DHCPServerIP",
1862 DBUS_TYPE_STRING, &server_ip);
1865 connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
1866 DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
1871 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1872 DBusMessageIter *iter,
1873 struct connman_ipconfig *ipconfig_ipv4)
1875 struct connman_ipaddress *append_addr = NULL;
1876 const char *str, *privacy;
1878 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1881 str = __connman_ipconfig_method2string(ipconfig->method);
1885 if (ipconfig_ipv4 &&
1886 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1887 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1891 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1893 switch (ipconfig->method) {
1894 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1895 case CONNMAN_IPCONFIG_METHOD_OFF:
1898 case CONNMAN_IPCONFIG_METHOD_FIXED:
1899 append_addr = ipconfig->address;
1902 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1903 case CONNMAN_IPCONFIG_METHOD_DHCP:
1904 case CONNMAN_IPCONFIG_METHOD_AUTO:
1905 append_addr = ipconfig->system;
1906 #if defined TIZEN_EXT
1907 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1908 if (append_addr && append_addr->local == NULL)
1909 append_addr = ipconfig->address;
1917 if (append_addr->local) {
1918 connman_dbus_dict_append_basic(iter, "Address",
1919 DBUS_TYPE_STRING, &append_addr->local);
1920 connman_dbus_dict_append_basic(iter, "PrefixLength",
1922 &append_addr->prefixlen);
1925 if (append_addr->gateway)
1926 connman_dbus_dict_append_basic(iter, "Gateway",
1927 DBUS_TYPE_STRING, &append_addr->gateway);
1929 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1930 connman_dbus_dict_append_basic(iter, "Privacy",
1931 DBUS_TYPE_STRING, &privacy);
1934 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1935 DBusMessageIter *iter)
1937 const char *str, *privacy;
1939 str = __connman_ipconfig_method2string(ipconfig->method);
1943 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1945 switch (ipconfig->method) {
1946 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1947 case CONNMAN_IPCONFIG_METHOD_OFF:
1948 case CONNMAN_IPCONFIG_METHOD_DHCP:
1950 case CONNMAN_IPCONFIG_METHOD_FIXED:
1951 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1952 case CONNMAN_IPCONFIG_METHOD_AUTO:
1956 if (!ipconfig->address)
1959 if (ipconfig->address->local) {
1960 connman_dbus_dict_append_basic(iter, "Address",
1961 DBUS_TYPE_STRING, &ipconfig->address->local);
1962 connman_dbus_dict_append_basic(iter, "PrefixLength",
1964 &ipconfig->address->prefixlen);
1967 if (ipconfig->address->gateway)
1968 connman_dbus_dict_append_basic(iter, "Gateway",
1969 DBUS_TYPE_STRING, &ipconfig->address->gateway);
1971 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1972 connman_dbus_dict_append_basic(iter, "Privacy",
1973 DBUS_TYPE_STRING, &privacy);
1976 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
1977 DBusMessageIter *iter)
1981 str = __connman_ipconfig_method2string(ipconfig->method);
1985 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1987 switch (ipconfig->method) {
1988 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1989 case CONNMAN_IPCONFIG_METHOD_OFF:
1990 case CONNMAN_IPCONFIG_METHOD_DHCP:
1991 case CONNMAN_IPCONFIG_METHOD_AUTO:
1993 case CONNMAN_IPCONFIG_METHOD_FIXED:
1994 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1998 if (!ipconfig->address)
2001 if (ipconfig->address->local) {
2003 struct in_addr netmask;
2006 connman_dbus_dict_append_basic(iter, "Address",
2007 DBUS_TYPE_STRING, &ipconfig->address->local);
2009 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2010 netmask.s_addr = htonl(addr);
2011 mask = inet_ntoa(netmask);
2012 connman_dbus_dict_append_basic(iter, "Netmask",
2013 DBUS_TYPE_STRING, &mask);
2016 if (ipconfig->address->gateway)
2017 connman_dbus_dict_append_basic(iter, "Gateway",
2018 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2021 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2022 DBusMessageIter *array)
2024 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2025 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2026 *privacy_string = NULL;
2027 int prefix_length = 0, privacy = 0;
2028 DBusMessageIter dict;
2031 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2034 dbus_message_iter_recurse(array, &dict);
2036 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2037 DBusMessageIter entry, value;
2041 dbus_message_iter_recurse(&dict, &entry);
2043 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2046 dbus_message_iter_get_basic(&entry, &key);
2047 dbus_message_iter_next(&entry);
2049 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2052 dbus_message_iter_recurse(&entry, &value);
2054 type = dbus_message_iter_get_arg_type(&value);
2056 if (g_str_equal(key, "Method")) {
2059 if (type != DBUS_TYPE_STRING)
2062 dbus_message_iter_get_basic(&value, &str);
2063 method = __connman_ipconfig_string2method(str);
2064 } else if (g_str_equal(key, "Address")) {
2065 if (type != DBUS_TYPE_STRING)
2068 dbus_message_iter_get_basic(&value, &address);
2069 } else if (g_str_equal(key, "PrefixLength")) {
2070 if (type != DBUS_TYPE_BYTE)
2073 dbus_message_iter_get_basic(&value, &prefix_length);
2075 if (prefix_length < 0 || prefix_length > 128)
2077 } else if (g_str_equal(key, "Netmask")) {
2078 if (type != DBUS_TYPE_STRING)
2081 dbus_message_iter_get_basic(&value, &netmask);
2082 } else if (g_str_equal(key, "Gateway")) {
2083 if (type != DBUS_TYPE_STRING)
2086 dbus_message_iter_get_basic(&value, &gateway);
2087 } else if (g_str_equal(key, "Privacy")) {
2088 if (type != DBUS_TYPE_STRING)
2091 dbus_message_iter_get_basic(&value, &privacy_string);
2092 privacy = string2privacy(privacy_string);
2095 dbus_message_iter_next(&dict);
2098 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2100 method, address, netmask, gateway, prefix_length,
2104 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2105 case CONNMAN_IPCONFIG_METHOD_FIXED:
2108 case CONNMAN_IPCONFIG_METHOD_OFF:
2109 ipconfig->method = method;
2110 #if defined TIZEN_EXT
2111 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2112 disable_ipv6(ipconfig);
2117 case CONNMAN_IPCONFIG_METHOD_AUTO:
2118 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2121 ipconfig->method = method;
2123 ipconfig->ipv6_privacy_config = privacy;
2124 #if defined TIZEN_EXT
2125 enable_ipv6(ipconfig);
2130 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2131 switch (ipconfig->type) {
2132 case CONNMAN_IPCONFIG_TYPE_IPV4:
2135 case CONNMAN_IPCONFIG_TYPE_IPV6:
2138 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2139 case CONNMAN_IPCONFIG_TYPE_ALL:
2144 if ((address && connman_inet_check_ipaddress(address)
2147 connman_inet_check_ipaddress(netmask)
2150 connman_inet_check_ipaddress(gateway)
2154 ipconfig->method = method;
2156 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2157 connman_ipaddress_set_ipv4(ipconfig->address,
2158 address, netmask, gateway);
2160 return connman_ipaddress_set_ipv6(
2161 ipconfig->address, address,
2162 prefix_length, gateway);
2166 case CONNMAN_IPCONFIG_METHOD_DHCP:
2167 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2170 ipconfig->method = method;
2177 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2178 DBusMessageIter *iter)
2180 struct connman_ipdevice *ipdevice;
2181 const char *method = "auto";
2183 connman_dbus_dict_append_basic(iter, "Method",
2184 DBUS_TYPE_STRING, &method);
2186 ipdevice = g_hash_table_lookup(ipdevice_hash,
2187 GINT_TO_POINTER(ipconfig->index));
2191 if (ipconfig->index >= 0) {
2192 char *ifname = connman_inet_ifname(ipconfig->index);
2194 connman_dbus_dict_append_basic(iter, "Interface",
2195 DBUS_TYPE_STRING, &ifname);
2200 if (ipdevice->address)
2201 connman_dbus_dict_append_basic(iter, "Address",
2202 DBUS_TYPE_STRING, &ipdevice->address);
2204 if (ipdevice->mtu > 0)
2205 connman_dbus_dict_append_basic(iter, "MTU",
2206 DBUS_TYPE_UINT16, &ipdevice->mtu);
2209 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2210 GKeyFile *keyfile, const char *identifier, const char *prefix)
2216 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2218 key = g_strdup_printf("%smethod", prefix);
2219 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2221 switch (ipconfig->type) {
2222 case CONNMAN_IPCONFIG_TYPE_IPV4:
2223 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2225 case CONNMAN_IPCONFIG_TYPE_IPV6:
2226 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2228 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2229 case CONNMAN_IPCONFIG_TYPE_ALL:
2230 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2234 ipconfig->method = __connman_ipconfig_string2method(method);
2236 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2237 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2239 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2243 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2244 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2247 pprefix = g_strdup_printf("%sprivacy", prefix);
2248 privacy = g_key_file_get_string(keyfile, identifier,
2250 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2255 pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2256 ipconfig->last_dhcpv6_prefixes =
2257 g_key_file_get_string_list(keyfile, identifier, pprefix,
2259 if (ipconfig->last_dhcpv6_prefixes && length == 0) {
2260 g_free(ipconfig->last_dhcpv6_prefixes);
2261 ipconfig->last_dhcpv6_prefixes = NULL;
2269 switch (ipconfig->method) {
2270 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2271 case CONNMAN_IPCONFIG_METHOD_OFF:
2274 case CONNMAN_IPCONFIG_METHOD_FIXED:
2275 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2277 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2278 ipconfig->address->prefixlen = g_key_file_get_integer(
2279 keyfile, identifier, key, NULL);
2282 key = g_strdup_printf("%slocal_address", prefix);
2283 g_free(ipconfig->address->local);
2284 ipconfig->address->local = g_key_file_get_string(
2285 keyfile, identifier, key, NULL);
2288 key = g_strdup_printf("%speer_address", prefix);
2289 g_free(ipconfig->address->peer);
2290 ipconfig->address->peer = g_key_file_get_string(
2291 keyfile, identifier, key, NULL);
2294 key = g_strdup_printf("%sbroadcast_address", prefix);
2295 g_free(ipconfig->address->broadcast);
2296 ipconfig->address->broadcast = g_key_file_get_string(
2297 keyfile, identifier, key, NULL);
2300 key = g_strdup_printf("%sgateway", prefix);
2301 g_free(ipconfig->address->gateway);
2302 ipconfig->address->gateway = g_key_file_get_string(
2303 keyfile, identifier, key, NULL);
2307 case CONNMAN_IPCONFIG_METHOD_AUTO:
2309 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2313 * If the last used method for IPv4 was AUTO then we
2314 * try first DHCP. We will try also to use the last
2315 * used DHCP address, if exits.
2317 __connman_ipconfig_set_method(ipconfig,
2318 CONNMAN_IPCONFIG_METHOD_DHCP);
2321 case CONNMAN_IPCONFIG_METHOD_DHCP:
2323 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2324 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2326 g_free(ipconfig->last_dhcp_address);
2327 ipconfig->last_dhcp_address = str;
2337 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2338 GKeyFile *keyfile, const char *identifier, const char *prefix)
2343 method = __connman_ipconfig_method2string(ipconfig->method);
2345 DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
2348 key = g_strdup_printf("%smethod", prefix);
2349 g_key_file_set_string(keyfile, identifier, key, method);
2353 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2354 const char *privacy;
2355 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2356 key = g_strdup_printf("%sprivacy", prefix);
2357 g_key_file_set_string(keyfile, identifier, key, privacy);
2360 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2361 if (ipconfig->last_dhcp_address &&
2362 strlen(ipconfig->last_dhcp_address) > 0)
2363 g_key_file_set_string(keyfile, identifier, key,
2364 ipconfig->last_dhcp_address);
2366 g_key_file_remove_key(keyfile, identifier, key, NULL);
2369 key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2370 if (ipconfig->last_dhcpv6_prefixes &&
2371 ipconfig->last_dhcpv6_prefixes[0]) {
2373 g_strv_length(ipconfig->last_dhcpv6_prefixes);
2375 g_key_file_set_string_list(keyfile, identifier, key,
2376 (const gchar **)ipconfig->last_dhcpv6_prefixes,
2379 g_key_file_remove_key(keyfile, identifier, key, NULL);
2383 switch (ipconfig->method) {
2384 case CONNMAN_IPCONFIG_METHOD_FIXED:
2385 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2387 case CONNMAN_IPCONFIG_METHOD_DHCP:
2388 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2389 if (ipconfig->last_dhcp_address &&
2390 strlen(ipconfig->last_dhcp_address) > 0)
2391 g_key_file_set_string(keyfile, identifier, key,
2392 ipconfig->last_dhcp_address);
2394 g_key_file_remove_key(keyfile, identifier, key, NULL);
2397 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2398 case CONNMAN_IPCONFIG_METHOD_OFF:
2399 case CONNMAN_IPCONFIG_METHOD_AUTO:
2403 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2404 if (ipconfig->address->prefixlen != 0)
2405 g_key_file_set_integer(keyfile, identifier,
2406 key, ipconfig->address->prefixlen);
2409 key = g_strdup_printf("%slocal_address", prefix);
2410 if (ipconfig->address->local)
2411 g_key_file_set_string(keyfile, identifier,
2412 key, ipconfig->address->local);
2415 key = g_strdup_printf("%speer_address", prefix);
2416 if (ipconfig->address->peer)
2417 g_key_file_set_string(keyfile, identifier,
2418 key, ipconfig->address->peer);
2421 key = g_strdup_printf("%sbroadcast_address", prefix);
2422 if (ipconfig->address->broadcast)
2423 g_key_file_set_string(keyfile, identifier,
2424 key, ipconfig->address->broadcast);
2427 key = g_strdup_printf("%sgateway", prefix);
2428 if (ipconfig->address->gateway)
2429 g_key_file_set_string(keyfile, identifier,
2430 key, ipconfig->address->gateway);
2432 g_key_file_remove_key(keyfile, identifier, key, NULL);
2438 int __connman_ipconfig_init(void)
2442 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2443 NULL, free_ipdevice);
2445 is_ipv6_supported = connman_inet_is_ipv6_supported();
2450 void __connman_ipconfig_cleanup(void)
2454 g_hash_table_destroy(ipdevice_hash);
2455 ipdevice_hash = NULL;