5 * Copyright (C) 2007-2010 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
42 struct connman_ipconfig {
45 enum connman_ipconfig_type type;
47 struct connman_ipconfig *origin;
49 const struct connman_ipconfig_ops *ops;
52 connman_bool_t enabled;
53 enum connman_ipconfig_method method;
54 struct connman_ipaddress *address;
55 struct connman_ipaddress *system;
57 int ipv6_privacy_config;
58 char *last_dhcp_address;
61 struct connman_ipdevice {
83 struct connman_ipconfig *config_ipv4;
84 struct connman_ipconfig *config_ipv6;
86 gboolean ipv6_enabled;
90 static GHashTable *ipdevice_hash = NULL;
91 static GList *ipconfig_list = NULL;
93 struct connman_ipaddress *connman_ipaddress_alloc(int family)
95 struct connman_ipaddress *ipaddress;
97 ipaddress = g_try_new0(struct connman_ipaddress, 1);
98 if (ipaddress == NULL)
101 ipaddress->family = family;
102 ipaddress->prefixlen = 0;
103 ipaddress->local = NULL;
104 ipaddress->peer = NULL;
105 ipaddress->broadcast = NULL;
106 ipaddress->gateway = NULL;
111 void connman_ipaddress_free(struct connman_ipaddress *ipaddress)
113 if (ipaddress == NULL)
116 g_free(ipaddress->broadcast);
117 g_free(ipaddress->peer);
118 g_free(ipaddress->local);
119 g_free(ipaddress->gateway);
123 unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask)
132 mask = inet_network(netmask);
135 /* a valid netmask must be 2^n - 1 */
136 if ((host & (host + 1)) != 0)
140 for (; mask; mask <<= 1)
146 static gboolean check_ipv6_address(const char *address)
148 unsigned char buf[sizeof(struct in6_addr)];
154 err = inet_pton(AF_INET6, address, buf);
161 int connman_ipaddress_set_ipv6(struct connman_ipaddress *ipaddress,
163 unsigned char prefix_length,
166 if (ipaddress == NULL)
169 if (check_ipv6_address(address) == FALSE)
172 if (check_ipv6_address(gateway) == FALSE)
175 DBG("prefix_len %d address %s gateway %s",
176 prefix_length, address, gateway);
178 ipaddress->family = AF_INET6;
180 ipaddress->prefixlen = prefix_length;
182 g_free(ipaddress->local);
183 ipaddress->local = g_strdup(address);
185 g_free(ipaddress->gateway);
186 ipaddress->gateway = g_strdup(gateway);
191 int connman_ipaddress_set_ipv4(struct connman_ipaddress *ipaddress,
192 const char *address, const char *netmask, const char *gateway)
194 if (ipaddress == NULL)
197 ipaddress->family = AF_INET;
199 ipaddress->prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
201 g_free(ipaddress->local);
202 ipaddress->local = g_strdup(address);
204 g_free(ipaddress->gateway);
205 ipaddress->gateway = g_strdup(gateway);
210 void connman_ipaddress_set_peer(struct connman_ipaddress *ipaddress,
213 if (ipaddress == NULL)
216 g_free(ipaddress->peer);
217 ipaddress->peer = g_strdup(peer);
220 void connman_ipaddress_clear(struct connman_ipaddress *ipaddress)
222 if (ipaddress == NULL)
225 ipaddress->prefixlen = 0;
227 g_free(ipaddress->local);
228 ipaddress->local = NULL;
230 g_free(ipaddress->peer);
231 ipaddress->peer = NULL;
233 g_free(ipaddress->broadcast);
234 ipaddress->broadcast = NULL;
236 g_free(ipaddress->gateway);
237 ipaddress->gateway = NULL;
240 void connman_ipaddress_copy(struct connman_ipaddress *ipaddress,
241 struct connman_ipaddress *source)
243 if (ipaddress == NULL || source == NULL)
246 ipaddress->family = source->family;
247 ipaddress->prefixlen = source->prefixlen;
249 g_free(ipaddress->local);
250 ipaddress->local = g_strdup(source->local);
252 g_free(ipaddress->peer);
253 ipaddress->peer = g_strdup(source->peer);
255 g_free(ipaddress->broadcast);
256 ipaddress->broadcast = g_strdup(source->broadcast);
258 g_free(ipaddress->gateway);
259 ipaddress->gateway = g_strdup(source->gateway);
262 static void free_address_list(struct connman_ipdevice *ipdevice)
266 for (list = ipdevice->address_list; list; list = list->next) {
267 struct connman_ipaddress *ipaddress = list->data;
269 connman_ipaddress_free(ipaddress);
273 g_slist_free(ipdevice->address_list);
274 ipdevice->address_list = NULL;
277 static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
278 unsigned char prefixlen, const char *local)
282 for (list = ipdevice->address_list; list; list = list->next) {
283 struct connman_ipaddress *ipaddress = list->data;
285 if (g_strcmp0(ipaddress->local, local) == 0 &&
286 ipaddress->prefixlen == prefixlen)
293 const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type)
296 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
298 case CONNMAN_IPCONFIG_TYPE_IPV4:
300 case CONNMAN_IPCONFIG_TYPE_IPV6:
307 static const char *type2str(unsigned short type)
312 case ARPHRD_LOOPBACK:
325 static const char *scope2str(unsigned char scope)
337 static gboolean get_ipv6_state(gchar *ifname)
342 gboolean enabled = FALSE;
345 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
347 path = g_strdup_printf(
348 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
353 f = fopen(path, "r");
358 if (fscanf(f, "%d", &disabled) > 0)
366 static void set_ipv6_state(gchar *ifname, gboolean enable)
372 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
374 path = g_strdup_printf(
375 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
380 f = fopen(path, "r+");
395 static int get_ipv6_privacy(gchar *ifname)
404 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
410 f = fopen(path, "r");
417 if (fscanf(f, "%d", &value) <= 0)
425 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
426 * The privacy extension is described in RFC 3041 and RFC 4941
428 static void set_ipv6_privacy(gchar *ifname, int value)
436 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
445 f = fopen(path, "r+");
452 fprintf(f, "%d", value);
456 static int get_rp_filter()
459 int value = -EINVAL, tmp;
461 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
464 if (fscanf(f, "%d", &tmp) == 1)
472 static void set_rp_filter(int value)
476 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
481 fprintf(f, "%d", value);
486 int __connman_ipconfig_set_rp_filter()
490 value = get_rp_filter();
497 connman_info("rp_filter set to 2 (loose mode routing), "
498 "old value was %d", value);
503 void __connman_ipconfig_unset_rp_filter(int old_value)
505 set_rp_filter(old_value);
507 connman_info("rp_filter restored to %d", old_value);
510 gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
512 if (ipconfig == NULL)
515 return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
518 static void free_ipdevice(gpointer data)
520 struct connman_ipdevice *ipdevice = data;
522 connman_info("%s {remove} index %d", ipdevice->ifname,
525 if (ipdevice->config_ipv4 != NULL) {
526 __connman_ipconfig_unref(ipdevice->config_ipv4);
527 ipdevice->config_ipv4 = NULL;
530 if (ipdevice->config_ipv6 != NULL) {
531 __connman_ipconfig_unref(ipdevice->config_ipv6);
532 ipdevice->config_ipv6 = NULL;
535 free_address_list(ipdevice);
536 g_free(ipdevice->ipv4_gateway);
537 g_free(ipdevice->ipv6_gateway);
538 g_free(ipdevice->pac);
540 g_free(ipdevice->address);
542 set_ipv6_state(ipdevice->ifname, ipdevice->ipv6_enabled);
543 set_ipv6_privacy(ipdevice->ifname, ipdevice->ipv6_privacy);
545 g_free(ipdevice->ifname);
549 static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
551 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
552 ipdevice->config_ipv6);
554 if (ipdevice->config_ipv6 != NULL &&
555 ipdevice->config_ipv6->enabled == TRUE)
558 set_ipv6_state(ipdevice->ifname, FALSE);
559 ipdevice->ipv6_enabled = FALSE;
562 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
564 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
565 ipdevice->config_ipv6);
567 if (ipdevice->config_ipv4)
568 connman_inet_clear_address(ipdevice->index,
569 ipdevice->config_ipv4->address);
571 if (ipdevice->config_ipv6)
572 connman_inet_clear_ipv6_address(ipdevice->index,
573 ipdevice->config_ipv6->address->local,
574 ipdevice->config_ipv6->address->prefixlen);
577 static void update_stats(struct connman_ipdevice *ipdevice,
578 struct rtnl_link_stats *stats)
580 struct connman_service *service;
582 if (stats->rx_packets == 0 && stats->tx_packets == 0)
585 connman_info("%s {RX} %u packets %u bytes", ipdevice->ifname,
586 stats->rx_packets, stats->rx_bytes);
587 connman_info("%s {TX} %u packets %u bytes", ipdevice->ifname,
588 stats->tx_packets, stats->tx_bytes);
590 if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
593 if (ipdevice->config_ipv4)
594 service = __connman_ipconfig_get_data(ipdevice->config_ipv4);
595 else if (ipdevice->config_ipv6)
596 service = __connman_ipconfig_get_data(ipdevice->config_ipv6);
603 ipdevice->rx_packets = stats->rx_packets;
604 ipdevice->tx_packets = stats->tx_packets;
605 ipdevice->rx_bytes = stats->rx_bytes;
606 ipdevice->tx_bytes = stats->tx_bytes;
607 ipdevice->rx_errors = stats->rx_errors;
608 ipdevice->tx_errors = stats->tx_errors;
609 ipdevice->rx_dropped = stats->rx_dropped;
610 ipdevice->tx_dropped = stats->tx_dropped;
612 __connman_service_notify(service,
613 ipdevice->rx_packets, ipdevice->tx_packets,
614 ipdevice->rx_bytes, ipdevice->tx_bytes,
615 ipdevice->rx_errors, ipdevice->tx_errors,
616 ipdevice->rx_dropped, ipdevice->tx_dropped);
619 void __connman_ipconfig_newlink(int index, unsigned short type,
620 unsigned int flags, const char *address,
622 struct rtnl_link_stats *stats)
624 struct connman_ipdevice *ipdevice;
627 gboolean up = FALSE, down = FALSE;
628 gboolean lower_up = FALSE, lower_down = FALSE;
630 DBG("index %d", index);
632 if (type == ARPHRD_LOOPBACK)
635 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
636 if (ipdevice != NULL)
639 ipdevice = g_try_new0(struct connman_ipdevice, 1);
640 if (ipdevice == NULL)
643 ipdevice->index = index;
644 ipdevice->ifname = connman_inet_ifname(index);
645 ipdevice->type = type;
647 ipdevice->ipv6_enabled = get_ipv6_state(ipdevice->ifname);
648 ipdevice->ipv6_privacy = get_ipv6_privacy(ipdevice->ifname);
650 ipdevice->address = g_strdup(address);
652 g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
654 connman_info("%s {create} index %d type %d <%s>", ipdevice->ifname,
655 index, type, type2str(type));
660 update_stats(ipdevice, stats);
662 if (flags == ipdevice->flags)
665 if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
672 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
673 (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
674 if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
675 (IFF_RUNNING | IFF_LOWER_UP))
677 else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
681 ipdevice->flags = flags;
683 str = g_string_new(NULL);
688 g_string_append(str, "UP");
690 g_string_append(str, "DOWN");
692 if (flags & IFF_RUNNING)
693 g_string_append(str, ",RUNNING");
695 if (flags & IFF_LOWER_UP)
696 g_string_append(str, ",LOWER_UP");
698 connman_info("%s {update} flags %u <%s>", ipdevice->ifname,
701 g_string_free(str, TRUE);
703 for (list = g_list_first(ipconfig_list); list;
704 list = g_list_next(list)) {
705 struct connman_ipconfig *ipconfig = list->data;
707 if (index != ipconfig->index)
710 if (ipconfig->ops == NULL)
713 if (up == TRUE && ipconfig->ops->up)
714 ipconfig->ops->up(ipconfig);
715 if (lower_up == TRUE && ipconfig->ops->lower_up)
716 ipconfig->ops->lower_up(ipconfig);
718 if (lower_down == TRUE && ipconfig->ops->lower_down)
719 ipconfig->ops->lower_down(ipconfig);
720 if (down == TRUE && ipconfig->ops->down)
721 ipconfig->ops->down(ipconfig);
725 __connman_ipconfig_lower_up(ipdevice);
727 __connman_ipconfig_lower_down(ipdevice);
730 void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
732 struct connman_ipdevice *ipdevice;
735 DBG("index %d", index);
737 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
738 if (ipdevice == NULL)
741 update_stats(ipdevice, stats);
743 for (list = g_list_first(ipconfig_list); list;
744 list = g_list_next(list)) {
745 struct connman_ipconfig *ipconfig = list->data;
747 if (index != ipconfig->index)
750 ipconfig->index = -1;
752 if (ipconfig->ops == NULL)
755 if (ipconfig->ops->lower_down)
756 ipconfig->ops->lower_down(ipconfig);
757 if (ipconfig->ops->down)
758 ipconfig->ops->down(ipconfig);
761 __connman_ipconfig_lower_down(ipdevice);
763 g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
766 static inline gint check_duplicate_address(gconstpointer a, gconstpointer b)
768 const struct connman_ipaddress *addr1 = a;
769 const struct connman_ipaddress *addr2 = b;
771 if (addr1->prefixlen != addr2->prefixlen)
772 return addr2->prefixlen - addr1->prefixlen;
774 return g_strcmp0(addr1->local, addr2->local);
777 void __connman_ipconfig_newaddr(int index, int family, const char *label,
778 unsigned char prefixlen, const char *address)
780 struct connman_ipdevice *ipdevice;
781 struct connman_ipaddress *ipaddress;
782 enum connman_ipconfig_type type;
785 DBG("index %d", index);
787 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
788 if (ipdevice == NULL)
791 ipaddress = connman_ipaddress_alloc(family);
792 if (ipaddress == NULL)
795 ipaddress->prefixlen = prefixlen;
796 ipaddress->local = g_strdup(address);
798 if (g_slist_find_custom(ipdevice->address_list, ipaddress,
799 check_duplicate_address)) {
800 connman_ipaddress_free(ipaddress);
804 if (family == AF_INET)
805 type = CONNMAN_IPCONFIG_TYPE_IPV4;
806 else if (family == AF_INET6)
807 type = CONNMAN_IPCONFIG_TYPE_IPV6;
811 ipdevice->address_list = g_slist_append(ipdevice->address_list,
814 connman_info("%s {add} address %s/%u label %s family %d",
815 ipdevice->ifname, address, prefixlen, label, family);
817 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
818 __connman_ippool_newaddr(index, address, prefixlen);
820 if (ipdevice->config_ipv4 != NULL && family == AF_INET)
821 connman_ipaddress_copy(ipdevice->config_ipv4->system,
824 else if (ipdevice->config_ipv6 != NULL && family == AF_INET6)
825 connman_ipaddress_copy(ipdevice->config_ipv6->system,
830 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
833 for (list = g_list_first(ipconfig_list); list;
834 list = g_list_next(list)) {
835 struct connman_ipconfig *ipconfig = list->data;
837 if (index != ipconfig->index)
840 if (type != ipconfig->type)
843 if (ipconfig->ops == NULL)
846 if (ipconfig->ops->ip_bound)
847 ipconfig->ops->ip_bound(ipconfig);
851 void __connman_ipconfig_deladdr(int index, int family, const char *label,
852 unsigned char prefixlen, const char *address)
854 struct connman_ipdevice *ipdevice;
855 struct connman_ipaddress *ipaddress;
856 enum connman_ipconfig_type type;
859 DBG("index %d", index);
861 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
862 if (ipdevice == NULL)
865 ipaddress = find_ipaddress(ipdevice, prefixlen, address);
866 if (ipaddress == NULL)
869 if (family == AF_INET)
870 type = CONNMAN_IPCONFIG_TYPE_IPV4;
871 else if (family == AF_INET6)
872 type = CONNMAN_IPCONFIG_TYPE_IPV6;
876 ipdevice->address_list = g_slist_remove(ipdevice->address_list,
879 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
880 __connman_ippool_deladdr(index, address, prefixlen);
882 connman_ipaddress_clear(ipaddress);
885 connman_info("%s {del} address %s/%u label %s", ipdevice->ifname,
886 address, prefixlen, label);
888 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
891 if (g_slist_length(ipdevice->address_list) > 0)
894 for (list = g_list_first(ipconfig_list); list;
895 list = g_list_next(list)) {
896 struct connman_ipconfig *ipconfig = list->data;
898 if (index != ipconfig->index)
901 if (type != ipconfig->type)
904 if (ipconfig->ops == NULL)
907 if (ipconfig->ops->ip_release)
908 ipconfig->ops->ip_release(ipconfig);
912 void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
913 const char *dst, const char *gateway)
915 struct connman_ipdevice *ipdevice;
917 DBG("index %d", index);
919 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
920 if (ipdevice == NULL)
923 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
924 g_strcmp0(dst, "::") == 0)) {
926 enum connman_ipconfig_type type;
928 if (family == AF_INET6) {
929 type = CONNMAN_IPCONFIG_TYPE_IPV6;
930 g_free(ipdevice->ipv6_gateway);
931 ipdevice->ipv6_gateway = g_strdup(gateway);
933 if (ipdevice->config_ipv6 != NULL &&
934 ipdevice->config_ipv6->system != NULL) {
935 g_free(ipdevice->config_ipv6->system->gateway);
936 ipdevice->config_ipv6->system->gateway =
939 } else if (family == AF_INET) {
940 type = CONNMAN_IPCONFIG_TYPE_IPV4;
941 g_free(ipdevice->ipv4_gateway);
942 ipdevice->ipv4_gateway = g_strdup(gateway);
944 if (ipdevice->config_ipv4 != NULL &&
945 ipdevice->config_ipv4->system != NULL) {
946 g_free(ipdevice->config_ipv4->system->gateway);
947 ipdevice->config_ipv4->system->gateway =
953 for (config_list = g_list_first(ipconfig_list); config_list;
954 config_list = g_list_next(config_list)) {
955 struct connman_ipconfig *ipconfig = config_list->data;
957 if (index != ipconfig->index)
960 if (type != ipconfig->type)
963 if (ipconfig->ops == NULL)
966 if (ipconfig->ops->route_set)
967 ipconfig->ops->route_set(ipconfig);
971 connman_info("%s {add} route %s gw %s scope %u <%s>",
972 ipdevice->ifname, dst, gateway,
973 scope, scope2str(scope));
976 void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
977 const char *dst, const char *gateway)
979 struct connman_ipdevice *ipdevice;
981 DBG("index %d", index);
983 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
984 if (ipdevice == NULL)
987 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
988 g_strcmp0(dst, "::") == 0)) {
990 enum connman_ipconfig_type type;
992 if (family == AF_INET6) {
993 type = CONNMAN_IPCONFIG_TYPE_IPV6;
994 g_free(ipdevice->ipv6_gateway);
995 ipdevice->ipv6_gateway = NULL;
997 if (ipdevice->config_ipv6 != NULL &&
998 ipdevice->config_ipv6->system != NULL) {
999 g_free(ipdevice->config_ipv6->system->gateway);
1000 ipdevice->config_ipv6->system->gateway = NULL;
1002 } else if (family == AF_INET) {
1003 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1004 g_free(ipdevice->ipv4_gateway);
1005 ipdevice->ipv4_gateway = NULL;
1007 if (ipdevice->config_ipv4 != NULL &&
1008 ipdevice->config_ipv4->system != NULL) {
1009 g_free(ipdevice->config_ipv4->system->gateway);
1010 ipdevice->config_ipv4->system->gateway = NULL;
1015 for (config_list = g_list_first(ipconfig_list); config_list;
1016 config_list = g_list_next(config_list)) {
1017 struct connman_ipconfig *ipconfig = config_list->data;
1019 if (index != ipconfig->index)
1022 if (type != ipconfig->type)
1025 if (ipconfig->ops == NULL)
1028 if (ipconfig->ops->route_unset)
1029 ipconfig->ops->route_unset(ipconfig);
1033 connman_info("%s {del} route %s gw %s scope %u <%s>",
1034 ipdevice->ifname, dst, gateway,
1035 scope, scope2str(scope));
1038 void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
1043 keys = g_hash_table_get_keys(ipdevice_hash);
1047 for (list = g_list_first(keys); list; list = g_list_next(list)) {
1048 int index = GPOINTER_TO_INT(list->data);
1050 function(index, user_data);
1056 enum connman_ipconfig_type __connman_ipconfig_get_config_type(
1057 struct connman_ipconfig *ipconfig)
1059 return ipconfig ? ipconfig->type : CONNMAN_IPCONFIG_TYPE_UNKNOWN;
1062 unsigned short __connman_ipconfig_get_type_from_index(int index)
1064 struct connman_ipdevice *ipdevice;
1066 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1067 if (ipdevice == NULL)
1070 return ipdevice->type;
1073 unsigned int __connman_ipconfig_get_flags_from_index(int index)
1075 struct connman_ipdevice *ipdevice;
1077 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1078 if (ipdevice == NULL)
1081 return ipdevice->flags;
1084 const char *__connman_ipconfig_get_gateway_from_index(int index)
1086 struct connman_ipdevice *ipdevice;
1088 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1089 if (ipdevice == NULL)
1092 if (ipdevice->ipv4_gateway != NULL)
1093 return ipdevice->ipv4_gateway;
1095 if (ipdevice->config_ipv4 != NULL &&
1096 ipdevice->config_ipv4->address != NULL)
1097 return ipdevice->config_ipv4->address->gateway;
1099 if (ipdevice->ipv6_gateway != NULL)
1100 return ipdevice->ipv6_gateway;
1102 if (ipdevice->config_ipv6 != NULL &&
1103 ipdevice->config_ipv6->address != NULL)
1104 return ipdevice->config_ipv6->address->gateway;
1109 void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
1111 ipconfig->index = index;
1114 const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
1116 if (ipconfig->address == NULL)
1119 return ipconfig->address->local;
1122 void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig, const char *address)
1124 if (ipconfig->address == NULL)
1127 g_free(ipconfig->address->local);
1128 ipconfig->address->local = g_strdup(address);
1131 const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
1133 if (ipconfig->address == NULL)
1136 return ipconfig->address->peer;
1139 void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig, const char *address)
1141 if (ipconfig->address == NULL)
1144 g_free(ipconfig->address->peer);
1145 ipconfig->address->peer = g_strdup(address);
1148 const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
1150 if (ipconfig->address == NULL)
1153 return ipconfig->address->broadcast;
1156 void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const char *broadcast)
1158 if (ipconfig->address == NULL)
1161 g_free(ipconfig->address->broadcast);
1162 ipconfig->address->broadcast = g_strdup(broadcast);
1165 const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
1167 if (ipconfig->address == NULL)
1170 return ipconfig->address->gateway;
1173 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway)
1177 if (ipconfig->address == NULL)
1179 g_free(ipconfig->address->gateway);
1180 ipconfig->address->gateway = g_strdup(gateway);
1183 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
1185 struct connman_service *service;
1189 if (ipconfig->address == NULL)
1192 service = __connman_service_lookup_from_index(ipconfig->index);
1193 if (service == NULL)
1196 __connman_connection_gateway_remove(service, ipconfig->type);
1198 DBG("type %d gw %s peer %s", ipconfig->type,
1199 ipconfig->address->gateway, ipconfig->address->peer);
1201 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6 ||
1202 ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1203 return __connman_connection_gateway_add(service,
1204 ipconfig->address->gateway,
1206 ipconfig->address->peer);
1211 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
1213 struct connman_service *service;
1217 service = __connman_service_lookup_from_index(ipconfig->index);
1218 if (service != NULL)
1219 __connman_connection_gateway_remove(service, ipconfig->type);
1222 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
1224 if (ipconfig->address == NULL)
1227 return ipconfig->address->prefixlen;
1230 void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigned char prefixlen)
1232 if (ipconfig->address == NULL)
1235 ipconfig->address->prefixlen = prefixlen;
1238 static struct connman_ipconfig *create_ipv6config(int index)
1240 struct connman_ipconfig *ipv6config;
1242 DBG("index %d", index);
1244 ipv6config = g_try_new0(struct connman_ipconfig, 1);
1245 if (ipv6config == NULL)
1248 ipv6config->refcount = 1;
1250 ipv6config->index = index;
1251 ipv6config->enabled = FALSE;
1252 ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
1253 ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
1254 ipv6config->ipv6_privacy_config = 0;
1256 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1257 if (ipv6config->address == NULL) {
1262 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1264 DBG("ipconfig %p", ipv6config);
1270 * connman_ipconfig_create:
1272 * Allocate a new ipconfig structure.
1274 * Returns: a newly-allocated #connman_ipconfig structure
1276 struct connman_ipconfig *__connman_ipconfig_create(int index,
1277 enum connman_ipconfig_type type)
1279 struct connman_ipconfig *ipconfig;
1281 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1282 return create_ipv6config(index);
1284 DBG("index %d", index);
1286 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1287 if (ipconfig == NULL)
1290 ipconfig->refcount = 1;
1292 ipconfig->index = index;
1293 ipconfig->enabled = FALSE;
1294 ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
1296 ipconfig->address = connman_ipaddress_alloc(AF_INET);
1297 if (ipconfig->address == NULL) {
1302 ipconfig->system = connman_ipaddress_alloc(AF_INET);
1304 DBG("ipconfig %p", ipconfig);
1311 * connman_ipconfig_ref:
1312 * @ipconfig: ipconfig structure
1314 * Increase reference counter of ipconfig
1316 struct connman_ipconfig *
1317 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1318 const char *file, int line, const char *caller)
1320 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1321 file, line, caller);
1323 __sync_fetch_and_add(&ipconfig->refcount, 1);
1329 * connman_ipconfig_unref:
1330 * @ipconfig: ipconfig structure
1332 * Decrease reference counter of ipconfig
1334 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1335 const char *file, int line, const char *caller)
1337 if (ipconfig == NULL)
1340 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1341 file, line, caller);
1343 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1346 if (__connman_ipconfig_disable(ipconfig) < 0)
1347 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1349 __connman_ipconfig_set_ops(ipconfig, NULL);
1351 if (ipconfig->origin != NULL && ipconfig->origin != ipconfig) {
1352 __connman_ipconfig_unref(ipconfig->origin);
1353 ipconfig->origin = NULL;
1356 connman_ipaddress_free(ipconfig->system);
1357 connman_ipaddress_free(ipconfig->address);
1358 g_free(ipconfig->last_dhcp_address);
1363 * connman_ipconfig_get_data:
1364 * @ipconfig: ipconfig structure
1366 * Get private data pointer
1368 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1370 if (ipconfig == NULL)
1373 return ipconfig->ops_data;
1377 * connman_ipconfig_set_data:
1378 * @ipconfig: ipconfig structure
1379 * @data: data pointer
1381 * Set private data pointer
1383 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1385 ipconfig->ops_data = data;
1389 * connman_ipconfig_get_index:
1390 * @ipconfig: ipconfig structure
1392 * Get interface index
1394 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1396 if (ipconfig == NULL)
1399 if (ipconfig->origin != NULL)
1400 return ipconfig->origin->index;
1402 return ipconfig->index;
1406 * connman_ipconfig_get_ifname:
1407 * @ipconfig: ipconfig structure
1409 * Get interface name
1411 const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
1413 struct connman_ipdevice *ipdevice;
1415 if (ipconfig == NULL)
1418 if (ipconfig->index < 0)
1421 ipdevice = g_hash_table_lookup(ipdevice_hash,
1422 GINT_TO_POINTER(ipconfig->index));
1423 if (ipdevice == NULL)
1426 return ipdevice->ifname;
1430 * connman_ipconfig_set_ops:
1431 * @ipconfig: ipconfig structure
1432 * @ops: operation callbacks
1434 * Set the operation callbacks
1436 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1437 const struct connman_ipconfig_ops *ops)
1439 ipconfig->ops = ops;
1443 * connman_ipconfig_set_method:
1444 * @ipconfig: ipconfig structure
1445 * @method: configuration method
1447 * Set the configuration method
1449 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1450 enum connman_ipconfig_method method)
1452 ipconfig->method = method;
1457 enum connman_ipconfig_method __connman_ipconfig_get_method(struct connman_ipconfig *ipconfig)
1459 if (ipconfig == NULL)
1460 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1462 return ipconfig->method;
1465 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1469 switch (ipconfig->method) {
1470 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1471 case CONNMAN_IPCONFIG_METHOD_OFF:
1473 case CONNMAN_IPCONFIG_METHOD_AUTO:
1474 case CONNMAN_IPCONFIG_METHOD_FIXED:
1475 case CONNMAN_IPCONFIG_METHOD_DHCP:
1476 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1477 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1478 return connman_inet_set_address(ipconfig->index,
1480 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1481 return connman_inet_set_ipv6_address(
1482 ipconfig->index, ipconfig->address);
1488 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1494 if (ipconfig == NULL)
1497 DBG("method %d", ipconfig->method);
1499 switch (ipconfig->method) {
1500 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1501 case CONNMAN_IPCONFIG_METHOD_OFF:
1503 case CONNMAN_IPCONFIG_METHOD_AUTO:
1504 case CONNMAN_IPCONFIG_METHOD_FIXED:
1505 case CONNMAN_IPCONFIG_METHOD_DHCP:
1506 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1507 err = __connman_ipconfig_address_unset(ipconfig);
1508 connman_ipaddress_clear(ipconfig->address);
1516 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1522 if (ipconfig == NULL)
1525 DBG("method %d", ipconfig->method);
1527 switch (ipconfig->method) {
1528 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1529 case CONNMAN_IPCONFIG_METHOD_OFF:
1531 case CONNMAN_IPCONFIG_METHOD_AUTO:
1532 case CONNMAN_IPCONFIG_METHOD_FIXED:
1533 case CONNMAN_IPCONFIG_METHOD_DHCP:
1534 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1535 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1536 err = connman_inet_clear_address(ipconfig->index,
1538 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1539 err = connman_inet_clear_ipv6_address(
1541 ipconfig->address->local,
1542 ipconfig->address->prefixlen);
1552 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1555 struct connman_ipdevice *ipdevice;
1557 DBG("ipconfig %p", ipconfig);
1559 if (ipconfig == NULL || ipconfig->index < 0)
1562 ipdevice = g_hash_table_lookup(ipdevice_hash,
1563 GINT_TO_POINTER(ipconfig->index));
1564 if (ipdevice == NULL)
1567 g_free(ipdevice->pac);
1568 ipdevice->pac = g_strdup(url);
1573 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1575 struct connman_ipdevice *ipdevice;
1577 DBG("ipconfig %p", ipconfig);
1579 if (ipconfig == NULL || ipconfig->index < 0)
1582 ipdevice = g_hash_table_lookup(ipdevice_hash,
1583 GINT_TO_POINTER(ipconfig->index));
1584 if (ipdevice == NULL)
1587 return ipdevice->pac;
1590 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1591 const char *address)
1593 if (ipconfig == NULL)
1596 g_free(ipconfig->last_dhcp_address);
1597 ipconfig->last_dhcp_address = g_strdup(address);
1600 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1602 if (ipconfig == NULL)
1605 return ipconfig->last_dhcp_address;
1608 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1610 struct connman_ipdevice *ipdevice;
1614 ipdevice = g_hash_table_lookup(ipdevice_hash,
1615 GINT_TO_POINTER(ipconfig->index));
1616 if (ipdevice == NULL)
1619 set_ipv6_state(ipdevice->ifname, FALSE);
1622 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1624 struct connman_ipdevice *ipdevice;
1628 ipdevice = g_hash_table_lookup(ipdevice_hash,
1629 GINT_TO_POINTER(ipconfig->index));
1630 if (ipdevice == NULL)
1633 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1634 set_ipv6_privacy(ipdevice->ifname,
1635 ipconfig->ipv6_privacy_config);
1637 set_ipv6_state(ipdevice->ifname, TRUE);
1640 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1642 if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1645 enable_ipv6(ipconfig);
1648 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1650 if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1653 disable_ipv6(ipconfig);
1656 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1658 struct connman_ipdevice *ipdevice;
1659 gboolean up = FALSE, down = FALSE;
1660 gboolean lower_up = FALSE, lower_down = FALSE;
1661 enum connman_ipconfig_type type;
1663 DBG("ipconfig %p", ipconfig);
1665 if (ipconfig == NULL || ipconfig->index < 0)
1668 ipdevice = g_hash_table_lookup(ipdevice_hash,
1669 GINT_TO_POINTER(ipconfig->index));
1670 if (ipdevice == NULL)
1673 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1674 if (ipdevice->config_ipv4 == ipconfig)
1676 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1677 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1678 if (ipdevice->config_ipv6 == ipconfig)
1680 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1681 enable_ipv6(ipconfig);
1685 ipconfig->enabled = TRUE;
1687 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1688 ipdevice->config_ipv4 != NULL) {
1689 ipconfig_list = g_list_remove(ipconfig_list,
1690 ipdevice->config_ipv4);
1692 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1694 __connman_ipconfig_unref(ipdevice->config_ipv4);
1697 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1698 ipdevice->config_ipv6 != NULL) {
1699 ipconfig_list = g_list_remove(ipconfig_list,
1700 ipdevice->config_ipv6);
1702 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1704 __connman_ipconfig_unref(ipdevice->config_ipv6);
1707 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1708 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1709 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1710 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1712 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1714 if (ipdevice->flags & IFF_UP)
1719 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1720 (IFF_RUNNING | IFF_LOWER_UP))
1722 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1725 if (up == TRUE && ipconfig->ops->up)
1726 ipconfig->ops->up(ipconfig);
1727 if (lower_up == TRUE && ipconfig->ops->lower_up)
1728 ipconfig->ops->lower_up(ipconfig);
1730 if (lower_down == TRUE && ipconfig->ops->lower_down)
1731 ipconfig->ops->lower_down(ipconfig);
1732 if (down == TRUE && ipconfig->ops->down)
1733 ipconfig->ops->down(ipconfig);
1738 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1740 struct connman_ipdevice *ipdevice;
1742 DBG("ipconfig %p", ipconfig);
1744 if (ipconfig == NULL || ipconfig->index < 0)
1747 ipdevice = g_hash_table_lookup(ipdevice_hash,
1748 GINT_TO_POINTER(ipconfig->index));
1749 if (ipdevice == NULL)
1752 if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
1755 ipconfig->enabled = FALSE;
1757 if (ipdevice->config_ipv4 == ipconfig) {
1758 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1760 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1761 __connman_ipconfig_unref(ipdevice->config_ipv4);
1762 ipdevice->config_ipv4 = NULL;
1766 if (ipdevice->config_ipv6 == ipconfig) {
1767 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1769 if (ipdevice->config_ipv6->method ==
1770 CONNMAN_IPCONFIG_METHOD_AUTO)
1771 disable_ipv6(ipdevice->config_ipv6);
1773 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1774 __connman_ipconfig_unref(ipdevice->config_ipv6);
1775 ipdevice->config_ipv6 = NULL;
1782 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1785 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1787 case CONNMAN_IPCONFIG_METHOD_OFF:
1789 case CONNMAN_IPCONFIG_METHOD_FIXED:
1791 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1793 case CONNMAN_IPCONFIG_METHOD_DHCP:
1795 case CONNMAN_IPCONFIG_METHOD_AUTO:
1802 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1804 if (g_strcmp0(method, "off") == 0)
1805 return CONNMAN_IPCONFIG_METHOD_OFF;
1806 else if (g_strcmp0(method, "fixed") == 0)
1807 return CONNMAN_IPCONFIG_METHOD_FIXED;
1808 else if (g_strcmp0(method, "manual") == 0)
1809 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1810 else if (g_strcmp0(method, "dhcp") == 0)
1811 return CONNMAN_IPCONFIG_METHOD_DHCP;
1812 else if (g_strcmp0(method, "auto") == 0)
1813 return CONNMAN_IPCONFIG_METHOD_AUTO;
1815 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1818 static const char *privacy2string(int privacy)
1822 else if (privacy == 1)
1824 else if (privacy > 1)
1830 static int string2privacy(const char *privacy)
1832 if (g_strcmp0(privacy, "disabled") == 0)
1834 else if (g_strcmp0(privacy, "enabled") == 0)
1836 else if (g_strcmp0(privacy, "prefered") == 0)
1842 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1843 DBusMessageIter *iter)
1849 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1852 str = __connman_ipconfig_method2string(ipconfig->method);
1856 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1858 if (ipconfig->system == NULL)
1861 if (ipconfig->system->local != NULL) {
1863 struct in_addr netmask;
1866 connman_dbus_dict_append_basic(iter, "Address",
1867 DBUS_TYPE_STRING, &ipconfig->system->local);
1869 addr = 0xffffffff << (32 - ipconfig->system->prefixlen);
1870 netmask.s_addr = htonl(addr);
1871 mask = inet_ntoa(netmask);
1872 connman_dbus_dict_append_basic(iter, "Netmask",
1873 DBUS_TYPE_STRING, &mask);
1876 if (ipconfig->system->gateway != NULL)
1877 connman_dbus_dict_append_basic(iter, "Gateway",
1878 DBUS_TYPE_STRING, &ipconfig->system->gateway);
1881 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1882 DBusMessageIter *iter,
1883 struct connman_ipconfig *ipconfig_ipv4)
1885 const char *str, *privacy;
1889 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1892 str = __connman_ipconfig_method2string(ipconfig->method);
1896 if (ipconfig_ipv4 != NULL &&
1897 ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1898 if (__connman_6to4_check(ipconfig_ipv4) == 1)
1902 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1904 if (ipconfig->system == NULL)
1907 if (ipconfig->system->local != NULL) {
1908 connman_dbus_dict_append_basic(iter, "Address",
1909 DBUS_TYPE_STRING, &ipconfig->system->local);
1910 connman_dbus_dict_append_basic(iter, "PrefixLength",
1912 &ipconfig->system->prefixlen);
1915 if (ipconfig->system->gateway != NULL)
1916 connman_dbus_dict_append_basic(iter, "Gateway",
1917 DBUS_TYPE_STRING, &ipconfig->system->gateway);
1919 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1920 connman_dbus_dict_append_basic(iter, "Privacy",
1921 DBUS_TYPE_STRING, &privacy);
1924 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1925 DBusMessageIter *iter)
1927 const char *str, *privacy;
1931 str = __connman_ipconfig_method2string(ipconfig->method);
1935 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1937 switch (ipconfig->method) {
1938 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1939 case CONNMAN_IPCONFIG_METHOD_OFF:
1940 case CONNMAN_IPCONFIG_METHOD_DHCP:
1942 case CONNMAN_IPCONFIG_METHOD_FIXED:
1943 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1944 case CONNMAN_IPCONFIG_METHOD_AUTO:
1948 if (ipconfig->address == NULL)
1951 if (ipconfig->address->local != NULL) {
1952 connman_dbus_dict_append_basic(iter, "Address",
1953 DBUS_TYPE_STRING, &ipconfig->address->local);
1954 connman_dbus_dict_append_basic(iter, "PrefixLength",
1956 &ipconfig->address->prefixlen);
1959 if (ipconfig->address->gateway != NULL)
1960 connman_dbus_dict_append_basic(iter, "Gateway",
1961 DBUS_TYPE_STRING, &ipconfig->address->gateway);
1963 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1964 connman_dbus_dict_append_basic(iter, "Privacy",
1965 DBUS_TYPE_STRING, &privacy);
1968 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
1969 DBusMessageIter *iter)
1975 str = __connman_ipconfig_method2string(ipconfig->method);
1979 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1981 switch (ipconfig->method) {
1982 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1983 case CONNMAN_IPCONFIG_METHOD_OFF:
1984 case CONNMAN_IPCONFIG_METHOD_DHCP:
1985 case CONNMAN_IPCONFIG_METHOD_AUTO:
1987 case CONNMAN_IPCONFIG_METHOD_FIXED:
1988 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1992 if (ipconfig->address == NULL)
1995 if (ipconfig->address->local != NULL) {
1997 struct in_addr netmask;
2000 connman_dbus_dict_append_basic(iter, "Address",
2001 DBUS_TYPE_STRING, &ipconfig->address->local);
2003 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2004 netmask.s_addr = htonl(addr);
2005 mask = inet_ntoa(netmask);
2006 connman_dbus_dict_append_basic(iter, "Netmask",
2007 DBUS_TYPE_STRING, &mask);
2010 if (ipconfig->address->gateway != NULL)
2011 connman_dbus_dict_append_basic(iter, "Gateway",
2012 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2015 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2016 DBusMessageIter *array)
2018 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2019 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2020 *prefix_length_string = NULL, *privacy_string = NULL;
2021 int prefix_length = 0, privacy = 0;
2022 DBusMessageIter dict;
2024 DBG("ipconfig %p", ipconfig);
2026 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2029 dbus_message_iter_recurse(array, &dict);
2031 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2032 DBusMessageIter entry, value;
2036 dbus_message_iter_recurse(&dict, &entry);
2038 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2041 dbus_message_iter_get_basic(&entry, &key);
2042 dbus_message_iter_next(&entry);
2044 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2047 dbus_message_iter_recurse(&entry, &value);
2049 type = dbus_message_iter_get_arg_type(&value);
2051 if (g_str_equal(key, "Method") == TRUE) {
2054 if (type != DBUS_TYPE_STRING)
2057 dbus_message_iter_get_basic(&value, &str);
2058 method = __connman_ipconfig_string2method(str);
2059 } else if (g_str_equal(key, "Address") == TRUE) {
2060 if (type != DBUS_TYPE_STRING)
2063 dbus_message_iter_get_basic(&value, &address);
2064 } else if (g_str_equal(key, "PrefixLength") == TRUE) {
2065 if (type != DBUS_TYPE_STRING)
2068 dbus_message_iter_get_basic(&value,
2069 &prefix_length_string);
2071 prefix_length = atoi(prefix_length_string);
2072 if (prefix_length < 0 || prefix_length > 128)
2074 } else if (g_str_equal(key, "Netmask") == TRUE) {
2075 if (type != DBUS_TYPE_STRING)
2078 dbus_message_iter_get_basic(&value, &netmask);
2079 } else if (g_str_equal(key, "Gateway") == TRUE) {
2080 if (type != DBUS_TYPE_STRING)
2083 dbus_message_iter_get_basic(&value, &gateway);
2084 } else if (g_str_equal(key, "Privacy") == TRUE) {
2085 if (type != DBUS_TYPE_STRING)
2088 dbus_message_iter_get_basic(&value, &privacy_string);
2089 privacy = string2privacy(privacy_string);
2092 dbus_message_iter_next(&dict);
2095 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2097 method, address, netmask, gateway, prefix_length,
2101 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2102 case CONNMAN_IPCONFIG_METHOD_FIXED:
2105 case CONNMAN_IPCONFIG_METHOD_OFF:
2106 ipconfig->method = method;
2107 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2108 disable_ipv6(ipconfig);
2111 case CONNMAN_IPCONFIG_METHOD_AUTO:
2112 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2115 ipconfig->method = method;
2116 if (privacy_string != NULL)
2117 ipconfig->ipv6_privacy_config = privacy;
2118 enable_ipv6(ipconfig);
2121 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2122 if (address == NULL)
2125 ipconfig->method = method;
2127 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2128 connman_ipaddress_set_ipv4(ipconfig->address,
2129 address, netmask, gateway);
2131 return connman_ipaddress_set_ipv6(
2132 ipconfig->address, address,
2133 prefix_length, gateway);
2136 case CONNMAN_IPCONFIG_METHOD_DHCP:
2137 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2140 ipconfig->method = method;
2147 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2148 DBusMessageIter *iter)
2150 struct connman_ipdevice *ipdevice;
2151 const char *method = "auto";
2153 connman_dbus_dict_append_basic(iter, "Method",
2154 DBUS_TYPE_STRING, &method);
2156 ipdevice = g_hash_table_lookup(ipdevice_hash,
2157 GINT_TO_POINTER(ipconfig->index));
2158 if (ipdevice == NULL)
2161 if (ipdevice->ifname != NULL)
2162 connman_dbus_dict_append_basic(iter, "Interface",
2163 DBUS_TYPE_STRING, &ipdevice->ifname);
2165 if (ipdevice->address != NULL)
2166 connman_dbus_dict_append_basic(iter, "Address",
2167 DBUS_TYPE_STRING, &ipdevice->address);
2169 if (ipdevice->mtu > 0)
2170 connman_dbus_dict_append_basic(iter, "MTU",
2171 DBUS_TYPE_UINT16, &ipdevice->mtu);
2174 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2175 GKeyFile *keyfile, const char *identifier, const char *prefix)
2181 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2183 key = g_strdup_printf("%smethod", prefix);
2184 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2185 if (method == NULL) {
2186 switch (ipconfig->type) {
2187 case CONNMAN_IPCONFIG_TYPE_IPV4:
2188 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2190 case CONNMAN_IPCONFIG_TYPE_IPV6:
2191 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2193 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2194 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2198 ipconfig->method = __connman_ipconfig_string2method(method);
2200 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2201 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2203 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2204 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2205 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2207 char *pprefix = g_strdup_printf("%sprivacy", prefix);
2208 privacy = g_key_file_get_string(keyfile, identifier,
2210 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2219 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2220 ipconfig->address->prefixlen = g_key_file_get_integer(
2221 keyfile, identifier, key, NULL);
2224 key = g_strdup_printf("%slocal_address", prefix);
2225 ipconfig->address->local = g_key_file_get_string(
2226 keyfile, identifier, key, NULL);
2229 key = g_strdup_printf("%speer_address", prefix);
2230 ipconfig->address->peer = g_key_file_get_string(
2231 keyfile, identifier, key, NULL);
2234 key = g_strdup_printf("%sbroadcast_address", prefix);
2235 ipconfig->address->broadcast = g_key_file_get_string(
2236 keyfile, identifier, key, NULL);
2239 key = g_strdup_printf("%sgateway", prefix);
2240 ipconfig->address->gateway = g_key_file_get_string(
2241 keyfile, identifier, key, NULL);
2244 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2245 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2247 g_free(ipconfig->last_dhcp_address);
2248 ipconfig->last_dhcp_address = str;
2255 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2256 GKeyFile *keyfile, const char *identifier, const char *prefix)
2261 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2263 method = __connman_ipconfig_method2string(ipconfig->method);
2265 key = g_strdup_printf("%smethod", prefix);
2266 g_key_file_set_string(keyfile, identifier, key, method);
2269 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2270 const char *privacy;
2271 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2272 key = g_strdup_printf("%sprivacy", prefix);
2273 g_key_file_set_string(keyfile, identifier, key, privacy);
2277 switch (ipconfig->method) {
2278 case CONNMAN_IPCONFIG_METHOD_FIXED:
2279 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2281 case CONNMAN_IPCONFIG_METHOD_DHCP:
2282 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2283 if (ipconfig->last_dhcp_address != NULL &&
2284 strlen(ipconfig->last_dhcp_address) > 0)
2285 g_key_file_set_string(keyfile, identifier, key,
2286 ipconfig->last_dhcp_address);
2288 g_key_file_remove_key(keyfile, identifier, key, NULL);
2291 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2292 case CONNMAN_IPCONFIG_METHOD_OFF:
2293 case CONNMAN_IPCONFIG_METHOD_AUTO:
2297 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2298 g_key_file_set_integer(keyfile, identifier,
2299 key, ipconfig->address->prefixlen);
2302 key = g_strdup_printf("%slocal_address", prefix);
2303 if (ipconfig->address->local != NULL)
2304 g_key_file_set_string(keyfile, identifier,
2305 key, ipconfig->address->local);
2308 key = g_strdup_printf("%speer_address", prefix);
2309 if (ipconfig->address->peer != NULL)
2310 g_key_file_set_string(keyfile, identifier,
2311 key, ipconfig->address->peer);
2314 key = g_strdup_printf("%sbroadcast_address", prefix);
2315 if (ipconfig->address->broadcast != NULL)
2316 g_key_file_set_string(keyfile, identifier,
2317 key, ipconfig->address->broadcast);
2320 key = g_strdup_printf("%sgateway", prefix);
2321 if (ipconfig->address->gateway != NULL)
2322 g_key_file_set_string(keyfile, identifier,
2323 key, ipconfig->address->gateway);
2329 int __connman_ipconfig_init(void)
2333 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2334 NULL, free_ipdevice);
2339 void __connman_ipconfig_cleanup(void)
2343 g_hash_table_destroy(ipdevice_hash);
2344 ipdevice_hash = NULL;