5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <net/if_arp.h>
30 #include <linux/if_link.h>
35 #define IFF_LOWER_UP 0x10000
39 #include <connman/ipaddress.h>
43 struct connman_ipconfig {
46 enum connman_ipconfig_type type;
48 const struct connman_ipconfig_ops *ops;
52 enum connman_ipconfig_method method;
53 struct connman_ipaddress *address;
54 struct connman_ipaddress *system;
57 int dhcp_lease_duration;
60 int ipv6_privacy_config;
61 char *last_dhcp_address;
62 char **last_dhcpv6_prefixes;
65 struct connman_ipdevice {
86 struct connman_ipconfig *config_ipv4;
87 struct connman_ipconfig *config_ipv6;
93 static GHashTable *ipdevice_hash = NULL;
94 static GList *ipconfig_list = NULL;
95 static bool is_ipv6_supported = false;
97 void __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
102 connman_ipaddress_clear(ipconfig->address);
105 static void free_address_list(struct connman_ipdevice *ipdevice)
109 for (list = ipdevice->address_list; list; list = list->next) {
110 struct connman_ipaddress *ipaddress = list->data;
112 connman_ipaddress_free(ipaddress);
116 g_slist_free(ipdevice->address_list);
117 ipdevice->address_list = NULL;
120 static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
121 unsigned char prefixlen, const char *local)
125 for (list = ipdevice->address_list; list; list = list->next) {
126 struct connman_ipaddress *ipaddress = list->data;
128 if (g_strcmp0(ipaddress->local, local) == 0 &&
129 ipaddress->prefixlen == prefixlen)
136 const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type)
139 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
140 case CONNMAN_IPCONFIG_TYPE_ALL:
142 case CONNMAN_IPCONFIG_TYPE_IPV4:
144 case CONNMAN_IPCONFIG_TYPE_IPV6:
151 static const char *type2str(unsigned short type)
156 case ARPHRD_LOOPBACK:
169 static const char *scope2str(unsigned char scope)
181 static bool get_ipv6_state(gchar *ifname)
186 bool enabled = false;
189 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
191 path = g_strdup_printf(
192 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
197 f = fopen(path, "r");
202 if (fscanf(f, "%d", &disabled) > 0)
210 static void set_ipv6_state(gchar *ifname, bool enable)
216 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
218 path = g_strdup_printf(
219 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
224 f = fopen(path, "r+");
239 static int get_ipv6_privacy(gchar *ifname)
248 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
254 f = fopen(path, "r");
261 if (fscanf(f, "%d", &value) <= 0)
269 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
270 * The privacy extension is described in RFC 3041 and RFC 4941
272 static void set_ipv6_privacy(gchar *ifname, int value)
280 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
289 f = fopen(path, "r+");
296 fprintf(f, "%d", value);
300 static int get_rp_filter(void)
303 int value = -EINVAL, tmp;
305 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
308 if (fscanf(f, "%d", &tmp) == 1)
316 static void set_rp_filter(int value)
320 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
325 fprintf(f, "%d", value);
330 int __connman_ipconfig_set_rp_filter()
334 value = get_rp_filter();
341 connman_info("rp_filter set to 2 (loose mode routing), "
342 "old value was %d", value);
347 void __connman_ipconfig_unset_rp_filter(int old_value)
349 set_rp_filter(old_value);
351 connman_info("rp_filter restored to %d", old_value);
354 bool __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
359 return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
362 bool __connman_ipconfig_ipv6_is_enabled(struct connman_ipconfig *ipconfig)
364 struct connman_ipdevice *ipdevice;
371 ipdevice = g_hash_table_lookup(ipdevice_hash,
372 GINT_TO_POINTER(ipconfig->index));
376 ifname = connman_inet_ifname(ipconfig->index);
377 ret = get_ipv6_state(ifname);
383 static void free_ipdevice(gpointer data)
385 struct connman_ipdevice *ipdevice = data;
386 char *ifname = connman_inet_ifname(ipdevice->index);
388 connman_info("%s {remove} index %d", ifname, ipdevice->index);
390 if (ipdevice->config_ipv4) {
391 __connman_ipconfig_unref(ipdevice->config_ipv4);
392 ipdevice->config_ipv4 = NULL;
395 if (ipdevice->config_ipv6) {
396 __connman_ipconfig_unref(ipdevice->config_ipv6);
397 ipdevice->config_ipv6 = NULL;
400 free_address_list(ipdevice);
401 g_free(ipdevice->ipv4_gateway);
402 g_free(ipdevice->ipv6_gateway);
403 g_free(ipdevice->pac);
405 g_free(ipdevice->address);
407 set_ipv6_state(ifname, ipdevice->ipv6_enabled);
408 set_ipv6_privacy(ifname, ipdevice->ipv6_privacy);
414 static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
416 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
417 ipdevice->config_ipv6);
418 #if defined TIZEN_EXT
419 if (ipdevice->config_ipv6 != NULL &&
420 ipdevice->config_ipv6->enabled == TRUE)
423 char *ifname = connman_inet_ifname(ipdevice->index);
425 if (__connman_device_isfiltered(ifname) == FALSE) {
426 ipdevice->ipv6_enabled = get_ipv6_state(ifname);
427 set_ipv6_state(ifname, FALSE);
433 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
435 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
436 ipdevice->config_ipv6);
438 if (ipdevice->config_ipv4)
439 connman_inet_clear_address(ipdevice->index,
440 ipdevice->config_ipv4->address);
442 if (ipdevice->config_ipv6)
443 connman_inet_clear_ipv6_address(ipdevice->index,
444 ipdevice->config_ipv6->address->local,
445 ipdevice->config_ipv6->address->prefixlen);
448 static void update_stats(struct connman_ipdevice *ipdevice,
449 const char *ifname, struct rtnl_link_stats *stats)
451 struct connman_service *service;
453 if (stats->rx_packets == 0 && stats->tx_packets == 0)
456 connman_info("%s {RX} %u packets %u bytes", ifname,
457 stats->rx_packets, stats->rx_bytes);
458 connman_info("%s {TX} %u packets %u bytes", ifname,
459 stats->tx_packets, stats->tx_bytes);
461 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
464 service = __connman_service_lookup_from_index(ipdevice->index);
466 DBG("service %p", service);
471 ipdevice->rx_packets = stats->rx_packets;
472 ipdevice->tx_packets = stats->tx_packets;
473 ipdevice->rx_bytes = stats->rx_bytes;
474 ipdevice->tx_bytes = stats->tx_bytes;
475 ipdevice->rx_errors = stats->rx_errors;
476 ipdevice->tx_errors = stats->tx_errors;
477 ipdevice->rx_dropped = stats->rx_dropped;
478 ipdevice->tx_dropped = stats->tx_dropped;
480 __connman_service_notify(service,
481 ipdevice->rx_packets, ipdevice->tx_packets,
482 ipdevice->rx_bytes, ipdevice->tx_bytes,
483 ipdevice->rx_errors, ipdevice->tx_errors,
484 ipdevice->rx_dropped, ipdevice->tx_dropped);
487 void __connman_ipconfig_newlink(int index, unsigned short type,
488 unsigned int flags, const char *address,
490 struct rtnl_link_stats *stats)
492 struct connman_ipdevice *ipdevice;
493 GList *list, *ipconfig_copy;
495 bool up = false, down = false;
496 bool lower_up = false, lower_down = false;
499 DBG("index %d", index);
501 if (type == ARPHRD_LOOPBACK)
504 ifname = connman_inet_ifname(index);
506 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
510 ipdevice = g_try_new0(struct connman_ipdevice, 1);
514 ipdevice->index = index;
515 ipdevice->type = type;
517 ipdevice->ipv6_enabled = get_ipv6_state(ifname);
518 ipdevice->ipv6_privacy = get_ipv6_privacy(ifname);
520 ipdevice->address = g_strdup(address);
522 g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
524 connman_info("%s {create} index %d type %d <%s>", ifname,
525 index, type, type2str(type));
528 #if defined TIZEN_EXT
529 if (g_strcmp0(ipdevice->address, address) != 0) {
530 /* If an original address is built-in physical device,
531 * it's hardly get an address at a initial creation
533 g_free(ipdevice->address);
534 ipdevice->address = g_strdup(address);
540 update_stats(ipdevice, ifname, stats);
542 if (flags == ipdevice->flags)
545 if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
552 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
553 (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
554 if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
555 (IFF_RUNNING | IFF_LOWER_UP))
557 else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
561 ipdevice->flags = flags;
563 str = g_string_new(NULL);
568 g_string_append(str, "UP");
570 g_string_append(str, "DOWN");
572 if (flags & IFF_RUNNING)
573 g_string_append(str, ",RUNNING");
575 if (flags & IFF_LOWER_UP)
576 g_string_append(str, ",LOWER_UP");
578 connman_info("%s {update} flags %u <%s>", ifname, flags, str->str);
580 g_string_free(str, TRUE);
582 ipconfig_copy = g_list_copy(ipconfig_list);
584 for (list = g_list_first(ipconfig_copy); list;
585 list = g_list_next(list)) {
586 struct connman_ipconfig *ipconfig = list->data;
588 if (index != ipconfig->index)
594 if (up && ipconfig->ops->up)
595 ipconfig->ops->up(ipconfig, ifname);
596 if (lower_up && ipconfig->ops->lower_up)
597 ipconfig->ops->lower_up(ipconfig, ifname);
599 if (lower_down && ipconfig->ops->lower_down)
600 ipconfig->ops->lower_down(ipconfig, ifname);
601 if (down && ipconfig->ops->down)
602 ipconfig->ops->down(ipconfig, ifname);
605 g_list_free(ipconfig_copy);
608 __connman_ipconfig_lower_up(ipdevice);
610 __connman_ipconfig_lower_down(ipdevice);
616 void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
618 struct connman_ipdevice *ipdevice;
622 DBG("index %d", index);
624 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
628 ifname = connman_inet_ifname(index);
630 update_stats(ipdevice, ifname, stats);
632 for (list = g_list_first(ipconfig_list); list;
633 list = g_list_next(list)) {
634 struct connman_ipconfig *ipconfig = list->data;
636 if (index != ipconfig->index)
639 ipconfig->index = -1;
644 if (ipconfig->ops->lower_down)
645 ipconfig->ops->lower_down(ipconfig, ifname);
646 if (ipconfig->ops->down)
647 ipconfig->ops->down(ipconfig, ifname);
652 __connman_ipconfig_lower_down(ipdevice);
654 g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
657 static inline gint check_duplicate_address(gconstpointer a, gconstpointer b)
659 const struct connman_ipaddress *addr1 = a;
660 const struct connman_ipaddress *addr2 = b;
662 if (addr1->prefixlen != addr2->prefixlen)
663 return addr2->prefixlen - addr1->prefixlen;
665 return g_strcmp0(addr1->local, addr2->local);
668 int __connman_ipconfig_newaddr(int index, int family, const char *label,
669 unsigned char prefixlen, const char *address)
671 struct connman_ipdevice *ipdevice;
672 struct connman_ipaddress *ipaddress;
673 enum connman_ipconfig_type type;
677 DBG("index %d", index);
679 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
683 ipaddress = connman_ipaddress_alloc(family);
687 ipaddress->prefixlen = prefixlen;
688 ipaddress->local = g_strdup(address);
690 if (g_slist_find_custom(ipdevice->address_list, ipaddress,
691 check_duplicate_address)) {
692 connman_ipaddress_free(ipaddress);
696 if (family == AF_INET)
697 type = CONNMAN_IPCONFIG_TYPE_IPV4;
698 else if (family == AF_INET6)
699 type = CONNMAN_IPCONFIG_TYPE_IPV6;
703 ipdevice->address_list = g_slist_prepend(ipdevice->address_list,
706 ifname = connman_inet_ifname(index);
707 connman_info("%s {add} address %s/%u label %s family %d",
708 ifname, address, prefixlen, label, family);
710 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
711 __connman_ippool_newaddr(index, address, prefixlen);
713 if (ipdevice->config_ipv4 && family == AF_INET)
714 connman_ipaddress_copy_address(ipdevice->config_ipv4->system,
717 else if (ipdevice->config_ipv6 && family == AF_INET6)
718 connman_ipaddress_copy_address(ipdevice->config_ipv6->system,
723 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
726 for (list = g_list_first(ipconfig_list); list;
727 list = g_list_next(list)) {
728 struct connman_ipconfig *ipconfig = list->data;
730 if (index != ipconfig->index)
733 if (type != ipconfig->type)
739 if (ipconfig->ops->ip_bound)
740 ipconfig->ops->ip_bound(ipconfig, ifname);
748 void __connman_ipconfig_deladdr(int index, int family, const char *label,
749 unsigned char prefixlen, const char *address)
751 struct connman_ipdevice *ipdevice;
752 struct connman_ipaddress *ipaddress;
753 enum connman_ipconfig_type type;
757 DBG("index %d", index);
759 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
763 ipaddress = find_ipaddress(ipdevice, prefixlen, address);
767 if (family == AF_INET)
768 type = CONNMAN_IPCONFIG_TYPE_IPV4;
769 else if (family == AF_INET6)
770 type = CONNMAN_IPCONFIG_TYPE_IPV6;
774 ipdevice->address_list = g_slist_remove(ipdevice->address_list,
777 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
778 __connman_ippool_deladdr(index, address, prefixlen);
780 connman_ipaddress_clear(ipaddress);
783 ifname = connman_inet_ifname(index);
784 connman_info("%s {del} address %s/%u label %s", ifname,
785 address, prefixlen, label);
787 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
790 if (g_slist_length(ipdevice->address_list) > 0)
793 for (list = g_list_first(ipconfig_list); list;
794 list = g_list_next(list)) {
795 struct connman_ipconfig *ipconfig = list->data;
797 if (index != ipconfig->index)
800 if (type != ipconfig->type)
806 if (ipconfig->ops->ip_release)
807 ipconfig->ops->ip_release(ipconfig, ifname);
814 void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
815 const char *dst, const char *gateway)
817 struct connman_ipdevice *ipdevice;
820 DBG("index %d", index);
822 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
826 ifname = connman_inet_ifname(index);
828 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
829 g_strcmp0(dst, "::") == 0)) {
831 enum connman_ipconfig_type type;
833 if (family == AF_INET6) {
834 type = CONNMAN_IPCONFIG_TYPE_IPV6;
835 g_free(ipdevice->ipv6_gateway);
836 ipdevice->ipv6_gateway = g_strdup(gateway);
838 if (ipdevice->config_ipv6 &&
839 ipdevice->config_ipv6->system) {
840 g_free(ipdevice->config_ipv6->system->gateway);
841 ipdevice->config_ipv6->system->gateway =
844 } else if (family == AF_INET) {
845 type = CONNMAN_IPCONFIG_TYPE_IPV4;
846 g_free(ipdevice->ipv4_gateway);
847 ipdevice->ipv4_gateway = g_strdup(gateway);
849 if (ipdevice->config_ipv4 &&
850 ipdevice->config_ipv4->system) {
851 g_free(ipdevice->config_ipv4->system->gateway);
852 ipdevice->config_ipv4->system->gateway =
858 for (config_list = g_list_first(ipconfig_list); config_list;
859 config_list = g_list_next(config_list)) {
860 struct connman_ipconfig *ipconfig = config_list->data;
862 if (index != ipconfig->index)
865 if (type != ipconfig->type)
871 if (ipconfig->ops->route_set)
872 ipconfig->ops->route_set(ipconfig, ifname);
876 connman_info("%s {add} route %s gw %s scope %u <%s>",
877 ifname, dst, gateway, scope, scope2str(scope));
883 void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
884 const char *dst, const char *gateway)
886 struct connman_ipdevice *ipdevice;
889 DBG("index %d", index);
891 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
895 ifname = connman_inet_ifname(index);
897 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
898 g_strcmp0(dst, "::") == 0)) {
900 enum connman_ipconfig_type type;
902 if (family == AF_INET6) {
903 type = CONNMAN_IPCONFIG_TYPE_IPV6;
904 g_free(ipdevice->ipv6_gateway);
905 ipdevice->ipv6_gateway = NULL;
907 if (ipdevice->config_ipv6 &&
908 ipdevice->config_ipv6->system) {
909 g_free(ipdevice->config_ipv6->system->gateway);
910 ipdevice->config_ipv6->system->gateway = NULL;
912 } else if (family == AF_INET) {
913 type = CONNMAN_IPCONFIG_TYPE_IPV4;
914 g_free(ipdevice->ipv4_gateway);
915 ipdevice->ipv4_gateway = NULL;
917 if (ipdevice->config_ipv4 &&
918 ipdevice->config_ipv4->system) {
919 g_free(ipdevice->config_ipv4->system->gateway);
920 ipdevice->config_ipv4->system->gateway = NULL;
925 for (config_list = g_list_first(ipconfig_list); config_list;
926 config_list = g_list_next(config_list)) {
927 struct connman_ipconfig *ipconfig = config_list->data;
929 if (index != ipconfig->index)
932 if (type != ipconfig->type)
938 if (ipconfig->ops->route_unset)
939 ipconfig->ops->route_unset(ipconfig, ifname);
943 connman_info("%s {del} route %s gw %s scope %u <%s>",
944 ifname, dst, gateway, scope, scope2str(scope));
950 void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
955 keys = g_hash_table_get_keys(ipdevice_hash);
959 for (list = g_list_first(keys); list; list = g_list_next(list)) {
960 int index = GPOINTER_TO_INT(list->data);
962 function(index, user_data);
968 enum connman_ipconfig_type __connman_ipconfig_get_config_type(
969 struct connman_ipconfig *ipconfig)
971 return ipconfig ? ipconfig->type : CONNMAN_IPCONFIG_TYPE_UNKNOWN;
974 unsigned short __connman_ipconfig_get_type_from_index(int index)
976 struct connman_ipdevice *ipdevice;
978 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
982 return ipdevice->type;
985 unsigned int __connman_ipconfig_get_flags_from_index(int index)
987 struct connman_ipdevice *ipdevice;
989 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
993 return ipdevice->flags;
996 const char *__connman_ipconfig_get_gateway_from_index(int index,
997 enum connman_ipconfig_type type)
999 struct connman_ipdevice *ipdevice;
1001 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1005 if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
1006 if (ipdevice->ipv4_gateway)
1007 return ipdevice->ipv4_gateway;
1009 if (ipdevice->config_ipv4 &&
1010 ipdevice->config_ipv4->address)
1011 return ipdevice->config_ipv4->address->gateway;
1014 if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
1015 if (ipdevice->ipv6_gateway)
1016 return ipdevice->ipv6_gateway;
1018 if (ipdevice->config_ipv6 &&
1019 ipdevice->config_ipv6->address)
1020 return ipdevice->config_ipv6->address->gateway;
1026 void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
1028 ipconfig->index = index;
1031 const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
1033 if (!ipconfig->address)
1036 return ipconfig->address->local;
1039 void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig,
1040 const char *address)
1042 if (!ipconfig->address)
1045 g_free(ipconfig->address->local);
1046 ipconfig->address->local = g_strdup(address);
1049 const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
1051 if (!ipconfig->address)
1054 return ipconfig->address->peer;
1057 void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig,
1058 const char *address)
1060 if (!ipconfig->address)
1063 g_free(ipconfig->address->peer);
1064 ipconfig->address->peer = g_strdup(address);
1067 const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
1069 if (!ipconfig->address)
1072 return ipconfig->address->broadcast;
1075 void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig,
1076 const char *broadcast)
1078 if (!ipconfig->address)
1081 g_free(ipconfig->address->broadcast);
1082 ipconfig->address->broadcast = g_strdup(broadcast);
1085 const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
1087 if (!ipconfig->address)
1090 return ipconfig->address->gateway;
1093 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
1094 const char *gateway)
1098 if (!ipconfig->address)
1100 g_free(ipconfig->address->gateway);
1101 ipconfig->address->gateway = g_strdup(gateway);
1104 #if defined TIZEN_EXT
1105 void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig,
1106 int dhcp_lease_duration)
1108 ipconfig->dhcp_lease_duration = dhcp_lease_duration;
1112 #if defined TIZEN_EXT
1113 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service)
1115 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
1118 #if !defined TIZEN_EXT
1119 struct connman_service *service;
1124 if (!ipconfig->address)
1127 #if !defined TIZEN_EXT
1128 service = __connman_service_lookup_from_index(ipconfig->index);
1133 DBG("type %d gw %s peer %s", ipconfig->type,
1134 ipconfig->address->gateway, ipconfig->address->peer);
1136 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6 ||
1137 ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1138 return __connman_connection_gateway_add(service,
1139 ipconfig->address->gateway,
1141 ipconfig->address->peer);
1146 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
1148 struct connman_service *service;
1152 service = __connman_service_lookup_from_index(ipconfig->index);
1154 __connman_connection_gateway_remove(service, ipconfig->type);
1157 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
1159 if (!ipconfig->address)
1162 return ipconfig->address->prefixlen;
1165 void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig,
1166 unsigned char prefixlen)
1168 if (!ipconfig->address)
1171 ipconfig->address->prefixlen = prefixlen;
1174 static struct connman_ipconfig *create_ipv6config(int index)
1176 struct connman_ipconfig *ipv6config;
1177 struct connman_ipdevice *ipdevice;
1179 DBG("index %d", index);
1181 ipv6config = g_try_new0(struct connman_ipconfig, 1);
1185 ipv6config->refcount = 1;
1187 ipv6config->index = index;
1188 ipv6config->enabled = false;
1189 ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
1191 if (!is_ipv6_supported)
1192 ipv6config->method = CONNMAN_IPCONFIG_METHOD_OFF;
1194 ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
1196 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1198 ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
1200 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1201 if (!ipv6config->address) {
1206 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1208 DBG("ipconfig %p method %s", ipv6config,
1209 __connman_ipconfig_method2string(ipv6config->method));
1215 * connman_ipconfig_create:
1217 * Allocate a new ipconfig structure.
1219 * Returns: a newly-allocated #connman_ipconfig structure
1221 struct connman_ipconfig *__connman_ipconfig_create(int index,
1222 enum connman_ipconfig_type type)
1224 struct connman_ipconfig *ipconfig;
1226 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1227 return create_ipv6config(index);
1229 DBG("index %d", index);
1231 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1235 ipconfig->refcount = 1;
1237 ipconfig->index = index;
1238 ipconfig->enabled = false;
1239 ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
1241 ipconfig->address = connman_ipaddress_alloc(AF_INET);
1242 if (!ipconfig->address) {
1247 ipconfig->system = connman_ipaddress_alloc(AF_INET);
1249 DBG("ipconfig %p", ipconfig);
1256 * connman_ipconfig_ref:
1257 * @ipconfig: ipconfig structure
1259 * Increase reference counter of ipconfig
1261 struct connman_ipconfig *
1262 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1263 const char *file, int line, const char *caller)
1265 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1266 file, line, caller);
1268 __sync_fetch_and_add(&ipconfig->refcount, 1);
1274 * connman_ipconfig_unref:
1275 * @ipconfig: ipconfig structure
1277 * Decrease reference counter of ipconfig
1279 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1280 const char *file, int line, const char *caller)
1285 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1286 file, line, caller);
1288 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1291 if (__connman_ipconfig_disable(ipconfig) < 0)
1292 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1294 __connman_ipconfig_set_ops(ipconfig, NULL);
1296 connman_ipaddress_free(ipconfig->system);
1297 connman_ipaddress_free(ipconfig->address);
1298 g_free(ipconfig->last_dhcp_address);
1299 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1304 * connman_ipconfig_get_data:
1305 * @ipconfig: ipconfig structure
1307 * Get private data pointer
1309 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1314 return ipconfig->ops_data;
1318 * connman_ipconfig_set_data:
1319 * @ipconfig: ipconfig structure
1320 * @data: data pointer
1322 * Set private data pointer
1324 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1326 ipconfig->ops_data = data;
1330 * connman_ipconfig_get_index:
1331 * @ipconfig: ipconfig structure
1333 * Get interface index
1335 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1340 return ipconfig->index;
1344 * connman_ipconfig_set_ops:
1345 * @ipconfig: ipconfig structure
1346 * @ops: operation callbacks
1348 * Set the operation callbacks
1350 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1351 const struct connman_ipconfig_ops *ops)
1353 ipconfig->ops = ops;
1357 * connman_ipconfig_set_method:
1358 * @ipconfig: ipconfig structure
1359 * @method: configuration method
1361 * Set the configuration method
1363 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1364 enum connman_ipconfig_method method)
1366 ipconfig->method = method;
1371 enum connman_ipconfig_method __connman_ipconfig_get_method(
1372 struct connman_ipconfig *ipconfig)
1375 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1377 return ipconfig->method;
1380 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1384 switch (ipconfig->method) {
1385 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1386 case CONNMAN_IPCONFIG_METHOD_OFF:
1388 case CONNMAN_IPCONFIG_METHOD_AUTO:
1389 case CONNMAN_IPCONFIG_METHOD_FIXED:
1390 case CONNMAN_IPCONFIG_METHOD_DHCP:
1391 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1392 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1393 return connman_inet_set_address(ipconfig->index,
1395 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1396 return connman_inet_set_ipv6_address(
1397 ipconfig->index, ipconfig->address);
1403 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1412 DBG("method %d", ipconfig->method);
1414 switch (ipconfig->method) {
1415 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1416 case CONNMAN_IPCONFIG_METHOD_OFF:
1418 case CONNMAN_IPCONFIG_METHOD_AUTO:
1419 case CONNMAN_IPCONFIG_METHOD_FIXED:
1420 case CONNMAN_IPCONFIG_METHOD_DHCP:
1421 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1422 err = __connman_ipconfig_address_unset(ipconfig);
1423 connman_ipaddress_clear(ipconfig->address);
1431 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1440 DBG("method %d", ipconfig->method);
1442 switch (ipconfig->method) {
1443 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1444 case CONNMAN_IPCONFIG_METHOD_OFF:
1446 case CONNMAN_IPCONFIG_METHOD_AUTO:
1447 case CONNMAN_IPCONFIG_METHOD_FIXED:
1448 case CONNMAN_IPCONFIG_METHOD_DHCP:
1449 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1450 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1451 err = connman_inet_clear_address(ipconfig->index,
1453 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1454 err = connman_inet_clear_ipv6_address(
1456 ipconfig->address->local,
1457 ipconfig->address->prefixlen);
1467 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1470 struct connman_ipdevice *ipdevice;
1472 DBG("ipconfig %p", ipconfig);
1474 if (!ipconfig || ipconfig->index < 0)
1477 ipdevice = g_hash_table_lookup(ipdevice_hash,
1478 GINT_TO_POINTER(ipconfig->index));
1482 g_free(ipdevice->pac);
1483 ipdevice->pac = g_strdup(url);
1488 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1490 struct connman_ipdevice *ipdevice;
1492 DBG("ipconfig %p", ipconfig);
1494 if (!ipconfig || ipconfig->index < 0)
1497 ipdevice = g_hash_table_lookup(ipdevice_hash,
1498 GINT_TO_POINTER(ipconfig->index));
1502 return ipdevice->pac;
1505 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1506 const char *address)
1511 g_free(ipconfig->last_dhcp_address);
1512 ipconfig->last_dhcp_address = g_strdup(address);
1515 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1520 return ipconfig->last_dhcp_address;
1523 void __connman_ipconfig_set_dhcpv6_prefixes(struct connman_ipconfig *ipconfig,
1529 g_strfreev(ipconfig->last_dhcpv6_prefixes);
1530 ipconfig->last_dhcpv6_prefixes = prefixes;
1533 char **__connman_ipconfig_get_dhcpv6_prefixes(struct connman_ipconfig *ipconfig)
1538 return ipconfig->last_dhcpv6_prefixes;
1541 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1543 struct connman_ipdevice *ipdevice;
1548 ipdevice = g_hash_table_lookup(ipdevice_hash,
1549 GINT_TO_POINTER(ipconfig->index));
1553 ifname = connman_inet_ifname(ipconfig->index);
1555 set_ipv6_state(ifname, false);
1560 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1562 struct connman_ipdevice *ipdevice;
1567 ipdevice = g_hash_table_lookup(ipdevice_hash,
1568 GINT_TO_POINTER(ipconfig->index));
1572 ifname = connman_inet_ifname(ipconfig->index);
1574 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1575 set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
1577 set_ipv6_state(ifname, true);
1582 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1584 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1587 enable_ipv6(ipconfig);
1590 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1592 if (!ipconfig || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1595 disable_ipv6(ipconfig);
1598 bool __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1603 switch (ipconfig->method) {
1604 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1605 case CONNMAN_IPCONFIG_METHOD_OFF:
1607 case CONNMAN_IPCONFIG_METHOD_AUTO:
1608 case CONNMAN_IPCONFIG_METHOD_FIXED:
1609 case CONNMAN_IPCONFIG_METHOD_DHCP:
1610 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1617 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1619 struct connman_ipdevice *ipdevice;
1620 bool up = false, down = false;
1621 bool lower_up = false, lower_down = false;
1622 enum connman_ipconfig_type type;
1625 DBG("ipconfig %p", ipconfig);
1627 if (!ipconfig || ipconfig->index < 0)
1630 ipdevice = g_hash_table_lookup(ipdevice_hash,
1631 GINT_TO_POINTER(ipconfig->index));
1635 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1636 if (ipdevice->config_ipv4 == ipconfig)
1638 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1639 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1640 if (ipdevice->config_ipv6 == ipconfig)
1642 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1646 ipconfig->enabled = true;
1648 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1649 ipdevice->config_ipv4) {
1650 ipconfig_list = g_list_remove(ipconfig_list,
1651 ipdevice->config_ipv4);
1653 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1655 __connman_ipconfig_unref(ipdevice->config_ipv4);
1658 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1659 ipdevice->config_ipv6) {
1660 ipconfig_list = g_list_remove(ipconfig_list,
1661 ipdevice->config_ipv6);
1663 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1665 __connman_ipconfig_unref(ipdevice->config_ipv6);
1668 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1669 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1670 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1671 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1673 enable_ipv6(ipdevice->config_ipv6);
1675 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1677 if (ipdevice->flags & IFF_UP)
1682 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1683 (IFF_RUNNING | IFF_LOWER_UP))
1685 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1688 ifname = connman_inet_ifname(ipconfig->index);
1690 if (up && ipconfig->ops->up)
1691 ipconfig->ops->up(ipconfig, ifname);
1692 if (lower_up && ipconfig->ops->lower_up)
1693 ipconfig->ops->lower_up(ipconfig, ifname);
1695 if (lower_down && ipconfig->ops->lower_down)
1696 ipconfig->ops->lower_down(ipconfig, ifname);
1697 if (down && ipconfig->ops->down)
1698 ipconfig->ops->down(ipconfig, ifname);
1705 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1707 struct connman_ipdevice *ipdevice;
1709 DBG("ipconfig %p", ipconfig);
1711 if (!ipconfig || ipconfig->index < 0)
1714 ipdevice = g_hash_table_lookup(ipdevice_hash,
1715 GINT_TO_POINTER(ipconfig->index));
1719 if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
1722 ipconfig->enabled = false;
1724 if (ipdevice->config_ipv4 == ipconfig) {
1725 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1727 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1728 __connman_ipconfig_unref(ipdevice->config_ipv4);
1729 ipdevice->config_ipv4 = NULL;
1733 if (ipdevice->config_ipv6 == ipconfig) {
1734 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1736 #if defined TIZEN_EXT
1737 if (ipdevice->config_ipv6->method ==
1738 CONNMAN_IPCONFIG_METHOD_AUTO)
1739 disable_ipv6(ipdevice->config_ipv6);
1741 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1742 __connman_ipconfig_unref(ipdevice->config_ipv6);
1743 ipdevice->config_ipv6 = NULL;
1750 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1753 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1755 case CONNMAN_IPCONFIG_METHOD_OFF:
1757 case CONNMAN_IPCONFIG_METHOD_FIXED:
1759 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1761 case CONNMAN_IPCONFIG_METHOD_DHCP:
1763 case CONNMAN_IPCONFIG_METHOD_AUTO:
1770 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1772 if (g_strcmp0(method, "off") == 0)
1773 return CONNMAN_IPCONFIG_METHOD_OFF;
1774 else if (g_strcmp0(method, "fixed") == 0)
1775 return CONNMAN_IPCONFIG_METHOD_FIXED;
1776 else if (g_strcmp0(method, "manual") == 0)
1777 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1778 else if (g_strcmp0(method, "dhcp") == 0)
1779 return CONNMAN_IPCONFIG_METHOD_DHCP;
1780 else if (g_strcmp0(method, "auto") == 0)
1781 return CONNMAN_IPCONFIG_METHOD_AUTO;
1783 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1786 static const char *privacy2string(int privacy)
1790 else if (privacy == 1)
1796 static int string2privacy(const char *privacy)
1798 if (g_strcmp0(privacy, "disabled") == 0)
1800 else if (g_strcmp0(privacy, "enabled") == 0)
1802 else if (g_strcmp0(privacy, "preferred") == 0)
1804 else if (g_strcmp0(privacy, "prefered") == 0)
1810 int __connman_ipconfig_ipv6_reset_privacy(struct connman_ipconfig *ipconfig)
1812 struct connman_ipdevice *ipdevice;
1818 ipdevice = g_hash_table_lookup(ipdevice_hash,
1819 GINT_TO_POINTER(ipconfig->index));
1823 err = __connman_ipconfig_ipv6_set_privacy(ipconfig, privacy2string(
1824 ipdevice->ipv6_privacy));
1829 int __connman_ipconfig_ipv6_set_privacy(struct connman_ipconfig *ipconfig,
1837 DBG("ipconfig %p privacy %s", ipconfig, value);
1839 privacy = string2privacy(value);
1841 ipconfig->ipv6_privacy_config = privacy;
1843 enable_ipv6(ipconfig);
1848 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1849 DBusMessageIter *iter)
1851 struct connman_ipaddress *append_addr = NULL;
1853 #if defined TIZEN_EXT
1857 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1860 str = __connman_ipconfig_method2string(ipconfig->method);
1864 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1866 switch (ipconfig->method) {
1867 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1868 case CONNMAN_IPCONFIG_METHOD_OFF:
1869 case CONNMAN_IPCONFIG_METHOD_AUTO:
1872 case CONNMAN_IPCONFIG_METHOD_FIXED:
1873 append_addr = ipconfig->address;
1876 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1877 case CONNMAN_IPCONFIG_METHOD_DHCP:
1878 append_addr = ipconfig->system;
1879 #if defined TIZEN_EXT
1880 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1881 if (append_addr && append_addr->local == NULL)
1882 append_addr = ipconfig->address;
1890 if (append_addr->local) {
1892 struct in_addr netmask;
1895 connman_dbus_dict_append_basic(iter, "Address",
1896 DBUS_TYPE_STRING, &append_addr->local);
1898 addr = 0xffffffff << (32 - append_addr->prefixlen);
1899 netmask.s_addr = htonl(addr);
1900 mask = inet_ntoa(netmask);
1901 connman_dbus_dict_append_basic(iter, "Netmask",
1902 DBUS_TYPE_STRING, &mask);
1905 if (append_addr->gateway)
1906 connman_dbus_dict_append_basic(iter, "Gateway",
1907 DBUS_TYPE_STRING, &append_addr->gateway);
1909 #if defined TIZEN_EXT
1910 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
1912 server_ip = __connman_dhcp_get_server_address(ipconfig);
1914 connman_dbus_dict_append_basic(iter, "DHCPServerIP",
1915 DBUS_TYPE_STRING, &server_ip);
1918 connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
1919 DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
1924 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1925 DBusMessageIter *iter,
1926 struct connman_ipconfig *ipconfig_ipv4)
1928 struct connman_ipaddress *append_addr = NULL;
1929 const char *str, *privacy;
1930 #if defined TIZEN_EXT
1934 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1937 str = __connman_ipconfig_method2string(ipconfig->method);
1941 if (ipconfig_ipv4 &&
1942 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1943 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1947 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1949 switch (ipconfig->method) {
1950 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1951 case CONNMAN_IPCONFIG_METHOD_OFF:
1954 case CONNMAN_IPCONFIG_METHOD_FIXED:
1955 append_addr = ipconfig->address;
1958 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1959 case CONNMAN_IPCONFIG_METHOD_DHCP:
1960 case CONNMAN_IPCONFIG_METHOD_AUTO:
1961 append_addr = ipconfig->system;
1962 #if defined TIZEN_EXT
1963 /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
1964 if (append_addr && append_addr->local == NULL)
1965 append_addr = ipconfig->address;
1973 if (append_addr->local) {
1974 connman_dbus_dict_append_basic(iter, "Address",
1975 DBUS_TYPE_STRING, &append_addr->local);
1976 connman_dbus_dict_append_basic(iter, "PrefixLength",
1978 &append_addr->prefixlen);
1981 if (append_addr->gateway)
1982 connman_dbus_dict_append_basic(iter, "Gateway",
1983 DBUS_TYPE_STRING, &append_addr->gateway);
1985 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1986 connman_dbus_dict_append_basic(iter, "Privacy",
1987 DBUS_TYPE_STRING, &privacy);
1990 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1991 DBusMessageIter *iter)
1993 const char *str, *privacy;
1994 #if defined TIZEN_EXT
1998 str = __connman_ipconfig_method2string(ipconfig->method);
2002 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
2004 switch (ipconfig->method) {
2005 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2006 case CONNMAN_IPCONFIG_METHOD_OFF:
2007 case CONNMAN_IPCONFIG_METHOD_DHCP:
2009 case CONNMAN_IPCONFIG_METHOD_FIXED:
2010 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2011 case CONNMAN_IPCONFIG_METHOD_AUTO:
2015 if (!ipconfig->address)
2018 if (ipconfig->address->local) {
2019 connman_dbus_dict_append_basic(iter, "Address",
2020 DBUS_TYPE_STRING, &ipconfig->address->local);
2021 connman_dbus_dict_append_basic(iter, "PrefixLength",
2023 &ipconfig->address->prefixlen);
2026 if (ipconfig->address->gateway)
2027 connman_dbus_dict_append_basic(iter, "Gateway",
2028 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2030 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2031 connman_dbus_dict_append_basic(iter, "Privacy",
2032 DBUS_TYPE_STRING, &privacy);
2035 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
2036 DBusMessageIter *iter)
2039 #if defined TIZEN_EXT
2043 str = __connman_ipconfig_method2string(ipconfig->method);
2047 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
2049 switch (ipconfig->method) {
2050 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2051 case CONNMAN_IPCONFIG_METHOD_OFF:
2052 case CONNMAN_IPCONFIG_METHOD_DHCP:
2053 case CONNMAN_IPCONFIG_METHOD_AUTO:
2055 case CONNMAN_IPCONFIG_METHOD_FIXED:
2056 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2060 if (!ipconfig->address)
2063 if (ipconfig->address->local) {
2065 struct in_addr netmask;
2068 connman_dbus_dict_append_basic(iter, "Address",
2069 DBUS_TYPE_STRING, &ipconfig->address->local);
2071 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2072 netmask.s_addr = htonl(addr);
2073 mask = inet_ntoa(netmask);
2074 connman_dbus_dict_append_basic(iter, "Netmask",
2075 DBUS_TYPE_STRING, &mask);
2078 if (ipconfig->address->gateway)
2079 connman_dbus_dict_append_basic(iter, "Gateway",
2080 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2083 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2084 DBusMessageIter *array)
2086 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2087 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2088 *privacy_string = NULL;
2089 int prefix_length = 0, privacy = 0;
2090 DBusMessageIter dict;
2093 DBG("ipconfig %p", ipconfig);
2095 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2098 dbus_message_iter_recurse(array, &dict);
2100 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2101 DBusMessageIter entry, value;
2105 dbus_message_iter_recurse(&dict, &entry);
2107 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2110 dbus_message_iter_get_basic(&entry, &key);
2111 dbus_message_iter_next(&entry);
2113 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2116 dbus_message_iter_recurse(&entry, &value);
2118 type = dbus_message_iter_get_arg_type(&value);
2120 if (g_str_equal(key, "Method")) {
2123 if (type != DBUS_TYPE_STRING)
2126 dbus_message_iter_get_basic(&value, &str);
2127 method = __connman_ipconfig_string2method(str);
2128 } else if (g_str_equal(key, "Address")) {
2129 if (type != DBUS_TYPE_STRING)
2132 dbus_message_iter_get_basic(&value, &address);
2133 } else if (g_str_equal(key, "PrefixLength")) {
2134 if (type != DBUS_TYPE_BYTE)
2137 dbus_message_iter_get_basic(&value, &prefix_length);
2139 if (prefix_length < 0 || prefix_length > 128)
2141 } else if (g_str_equal(key, "Netmask")) {
2142 if (type != DBUS_TYPE_STRING)
2145 dbus_message_iter_get_basic(&value, &netmask);
2146 } else if (g_str_equal(key, "Gateway")) {
2147 if (type != DBUS_TYPE_STRING)
2150 dbus_message_iter_get_basic(&value, &gateway);
2151 } else if (g_str_equal(key, "Privacy")) {
2152 if (type != DBUS_TYPE_STRING)
2155 dbus_message_iter_get_basic(&value, &privacy_string);
2156 privacy = string2privacy(privacy_string);
2159 dbus_message_iter_next(&dict);
2162 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2164 method, address, netmask, gateway, prefix_length,
2168 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2169 case CONNMAN_IPCONFIG_METHOD_FIXED:
2172 case CONNMAN_IPCONFIG_METHOD_OFF:
2173 ipconfig->method = method;
2174 #if defined TIZEN_EXT
2175 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2176 disable_ipv6(ipconfig);
2180 case CONNMAN_IPCONFIG_METHOD_AUTO:
2181 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2184 ipconfig->method = method;
2186 ipconfig->ipv6_privacy_config = privacy;
2187 #if defined TIZEN_EXT
2188 enable_ipv6(ipconfig);
2192 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2193 switch (ipconfig->type) {
2194 case CONNMAN_IPCONFIG_TYPE_IPV4:
2197 case CONNMAN_IPCONFIG_TYPE_IPV6:
2200 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2201 case CONNMAN_IPCONFIG_TYPE_ALL:
2206 if ((address && connman_inet_check_ipaddress(address)
2209 connman_inet_check_ipaddress(netmask)
2212 connman_inet_check_ipaddress(gateway)
2216 ipconfig->method = method;
2218 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2219 connman_ipaddress_set_ipv4(ipconfig->address,
2220 address, netmask, gateway);
2222 return connman_ipaddress_set_ipv6(
2223 ipconfig->address, address,
2224 prefix_length, gateway);
2228 case CONNMAN_IPCONFIG_METHOD_DHCP:
2229 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
2232 ipconfig->method = method;
2239 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2240 DBusMessageIter *iter)
2242 struct connman_ipdevice *ipdevice;
2243 const char *method = "auto";
2245 connman_dbus_dict_append_basic(iter, "Method",
2246 DBUS_TYPE_STRING, &method);
2248 ipdevice = g_hash_table_lookup(ipdevice_hash,
2249 GINT_TO_POINTER(ipconfig->index));
2253 if (ipconfig->index >= 0) {
2254 char *ifname = connman_inet_ifname(ipconfig->index);
2256 connman_dbus_dict_append_basic(iter, "Interface",
2257 DBUS_TYPE_STRING, &ifname);
2262 if (ipdevice->address)
2263 connman_dbus_dict_append_basic(iter, "Address",
2264 DBUS_TYPE_STRING, &ipdevice->address);
2266 if (ipdevice->mtu > 0)
2267 connman_dbus_dict_append_basic(iter, "MTU",
2268 DBUS_TYPE_UINT16, &ipdevice->mtu);
2271 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2272 GKeyFile *keyfile, const char *identifier, const char *prefix)
2278 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2280 key = g_strdup_printf("%smethod", prefix);
2281 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2283 switch (ipconfig->type) {
2284 case CONNMAN_IPCONFIG_TYPE_IPV4:
2285 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2287 case CONNMAN_IPCONFIG_TYPE_IPV6:
2288 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2290 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2291 case CONNMAN_IPCONFIG_TYPE_ALL:
2292 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2296 ipconfig->method = __connman_ipconfig_string2method(method);
2298 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2299 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2301 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2305 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2306 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2309 pprefix = g_strdup_printf("%sprivacy", prefix);
2310 privacy = g_key_file_get_string(keyfile, identifier,
2312 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2317 pprefix = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2318 ipconfig->last_dhcpv6_prefixes =
2319 g_key_file_get_string_list(keyfile, identifier, pprefix,
2321 if (ipconfig->last_dhcpv6_prefixes && length == 0) {
2322 g_free(ipconfig->last_dhcpv6_prefixes);
2323 ipconfig->last_dhcpv6_prefixes = NULL;
2331 switch (ipconfig->method) {
2332 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2333 case CONNMAN_IPCONFIG_METHOD_OFF:
2336 case CONNMAN_IPCONFIG_METHOD_FIXED:
2337 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2339 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2340 ipconfig->address->prefixlen = g_key_file_get_integer(
2341 keyfile, identifier, key, NULL);
2344 key = g_strdup_printf("%slocal_address", prefix);
2345 g_free(ipconfig->address->local);
2346 ipconfig->address->local = g_key_file_get_string(
2347 keyfile, identifier, key, NULL);
2350 key = g_strdup_printf("%speer_address", prefix);
2351 g_free(ipconfig->address->peer);
2352 ipconfig->address->peer = g_key_file_get_string(
2353 keyfile, identifier, key, NULL);
2356 key = g_strdup_printf("%sbroadcast_address", prefix);
2357 g_free(ipconfig->address->broadcast);
2358 ipconfig->address->broadcast = g_key_file_get_string(
2359 keyfile, identifier, key, NULL);
2362 key = g_strdup_printf("%sgateway", prefix);
2363 g_free(ipconfig->address->gateway);
2364 ipconfig->address->gateway = g_key_file_get_string(
2365 keyfile, identifier, key, NULL);
2369 case CONNMAN_IPCONFIG_METHOD_DHCP:
2371 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2372 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2374 g_free(ipconfig->last_dhcp_address);
2375 ipconfig->last_dhcp_address = str;
2381 case CONNMAN_IPCONFIG_METHOD_AUTO:
2388 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2389 GKeyFile *keyfile, const char *identifier, const char *prefix)
2394 method = __connman_ipconfig_method2string(ipconfig->method);
2396 DBG("ipconfig %p identifier %s method %s", ipconfig, identifier,
2399 key = g_strdup_printf("%smethod", prefix);
2400 g_key_file_set_string(keyfile, identifier, key, method);
2404 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2405 const char *privacy;
2406 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2407 key = g_strdup_printf("%sprivacy", prefix);
2408 g_key_file_set_string(keyfile, identifier, key, privacy);
2411 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2412 if (ipconfig->last_dhcp_address &&
2413 strlen(ipconfig->last_dhcp_address) > 0)
2414 g_key_file_set_string(keyfile, identifier, key,
2415 ipconfig->last_dhcp_address);
2417 g_key_file_remove_key(keyfile, identifier, key, NULL);
2420 key = g_strdup_printf("%sDHCP.LastPrefixes", prefix);
2421 if (ipconfig->last_dhcpv6_prefixes &&
2422 ipconfig->last_dhcpv6_prefixes[0]) {
2424 g_strv_length(ipconfig->last_dhcpv6_prefixes);
2426 g_key_file_set_string_list(keyfile, identifier, key,
2427 (const gchar **)ipconfig->last_dhcpv6_prefixes,
2430 g_key_file_remove_key(keyfile, identifier, key, NULL);
2434 switch (ipconfig->method) {
2435 case CONNMAN_IPCONFIG_METHOD_FIXED:
2436 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2438 case CONNMAN_IPCONFIG_METHOD_DHCP:
2439 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2440 if (ipconfig->last_dhcp_address &&
2441 strlen(ipconfig->last_dhcp_address) > 0)
2442 g_key_file_set_string(keyfile, identifier, key,
2443 ipconfig->last_dhcp_address);
2445 g_key_file_remove_key(keyfile, identifier, key, NULL);
2448 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2449 case CONNMAN_IPCONFIG_METHOD_OFF:
2450 case CONNMAN_IPCONFIG_METHOD_AUTO:
2454 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2455 if (ipconfig->address->prefixlen != 0)
2456 g_key_file_set_integer(keyfile, identifier,
2457 key, ipconfig->address->prefixlen);
2460 key = g_strdup_printf("%slocal_address", prefix);
2461 if (ipconfig->address->local)
2462 g_key_file_set_string(keyfile, identifier,
2463 key, ipconfig->address->local);
2466 key = g_strdup_printf("%speer_address", prefix);
2467 if (ipconfig->address->peer)
2468 g_key_file_set_string(keyfile, identifier,
2469 key, ipconfig->address->peer);
2472 key = g_strdup_printf("%sbroadcast_address", prefix);
2473 if (ipconfig->address->broadcast)
2474 g_key_file_set_string(keyfile, identifier,
2475 key, ipconfig->address->broadcast);
2478 key = g_strdup_printf("%sgateway", prefix);
2479 if (ipconfig->address->gateway)
2480 g_key_file_set_string(keyfile, identifier,
2481 key, ipconfig->address->gateway);
2487 int __connman_ipconfig_init(void)
2491 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2492 NULL, free_ipdevice);
2494 is_ipv6_supported = connman_inet_is_ipv6_supported();
2499 void __connman_ipconfig_cleanup(void)
2503 g_hash_table_destroy(ipdevice_hash);
2504 ipdevice_hash = NULL;