5 * Copyright (C) 2007-2012 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 DBG("prefix_len %d address %s gateway %s",
173 prefix_length, address, gateway);
175 ipaddress->family = AF_INET6;
177 ipaddress->prefixlen = prefix_length;
179 g_free(ipaddress->local);
180 ipaddress->local = g_strdup(address);
182 g_free(ipaddress->gateway);
183 ipaddress->gateway = g_strdup(gateway);
188 int connman_ipaddress_set_ipv4(struct connman_ipaddress *ipaddress,
189 const char *address, const char *netmask, const char *gateway)
191 if (ipaddress == NULL)
194 ipaddress->family = AF_INET;
196 ipaddress->prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
198 g_free(ipaddress->local);
199 ipaddress->local = g_strdup(address);
201 g_free(ipaddress->gateway);
202 ipaddress->gateway = g_strdup(gateway);
207 void connman_ipaddress_set_peer(struct connman_ipaddress *ipaddress,
210 if (ipaddress == NULL)
213 g_free(ipaddress->peer);
214 ipaddress->peer = g_strdup(peer);
217 void connman_ipaddress_clear(struct connman_ipaddress *ipaddress)
219 if (ipaddress == NULL)
222 ipaddress->prefixlen = 0;
224 g_free(ipaddress->local);
225 ipaddress->local = NULL;
227 g_free(ipaddress->peer);
228 ipaddress->peer = NULL;
230 g_free(ipaddress->broadcast);
231 ipaddress->broadcast = NULL;
233 g_free(ipaddress->gateway);
234 ipaddress->gateway = NULL;
237 void connman_ipaddress_copy(struct connman_ipaddress *ipaddress,
238 struct connman_ipaddress *source)
240 if (ipaddress == NULL || source == NULL)
243 ipaddress->family = source->family;
244 ipaddress->prefixlen = source->prefixlen;
246 g_free(ipaddress->local);
247 ipaddress->local = g_strdup(source->local);
249 g_free(ipaddress->peer);
250 ipaddress->peer = g_strdup(source->peer);
252 g_free(ipaddress->broadcast);
253 ipaddress->broadcast = g_strdup(source->broadcast);
255 g_free(ipaddress->gateway);
256 ipaddress->gateway = g_strdup(source->gateway);
259 static void free_address_list(struct connman_ipdevice *ipdevice)
263 for (list = ipdevice->address_list; list; list = list->next) {
264 struct connman_ipaddress *ipaddress = list->data;
266 connman_ipaddress_free(ipaddress);
270 g_slist_free(ipdevice->address_list);
271 ipdevice->address_list = NULL;
274 static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
275 unsigned char prefixlen, const char *local)
279 for (list = ipdevice->address_list; list; list = list->next) {
280 struct connman_ipaddress *ipaddress = list->data;
282 if (g_strcmp0(ipaddress->local, local) == 0 &&
283 ipaddress->prefixlen == prefixlen)
290 const char *__connman_ipconfig_type2string(enum connman_ipconfig_type type)
293 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
295 case CONNMAN_IPCONFIG_TYPE_IPV4:
297 case CONNMAN_IPCONFIG_TYPE_IPV6:
304 static const char *type2str(unsigned short type)
309 case ARPHRD_LOOPBACK:
322 static const char *scope2str(unsigned char scope)
334 static gboolean get_ipv6_state(gchar *ifname)
339 gboolean enabled = FALSE;
342 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
344 path = g_strdup_printf(
345 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
350 f = fopen(path, "r");
355 if (fscanf(f, "%d", &disabled) > 0)
363 static void set_ipv6_state(gchar *ifname, gboolean enable)
369 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
371 path = g_strdup_printf(
372 "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
377 f = fopen(path, "r+");
392 static int get_ipv6_privacy(gchar *ifname)
401 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
407 f = fopen(path, "r");
414 if (fscanf(f, "%d", &value) <= 0)
422 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
423 * The privacy extension is described in RFC 3041 and RFC 4941
425 static void set_ipv6_privacy(gchar *ifname, int value)
433 path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
442 f = fopen(path, "r+");
449 fprintf(f, "%d", value);
453 static int get_rp_filter()
456 int value = -EINVAL, tmp;
458 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
461 if (fscanf(f, "%d", &tmp) == 1)
469 static void set_rp_filter(int value)
473 f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
478 fprintf(f, "%d", value);
483 int __connman_ipconfig_set_rp_filter()
487 value = get_rp_filter();
494 connman_info("rp_filter set to 2 (loose mode routing), "
495 "old value was %d", value);
500 void __connman_ipconfig_unset_rp_filter(int old_value)
502 set_rp_filter(old_value);
504 connman_info("rp_filter restored to %d", old_value);
507 gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
509 if (ipconfig == NULL)
512 return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
515 static void free_ipdevice(gpointer data)
517 struct connman_ipdevice *ipdevice = data;
519 connman_info("%s {remove} index %d", ipdevice->ifname,
522 if (ipdevice->config_ipv4 != NULL) {
523 __connman_ipconfig_unref(ipdevice->config_ipv4);
524 ipdevice->config_ipv4 = NULL;
527 if (ipdevice->config_ipv6 != NULL) {
528 __connman_ipconfig_unref(ipdevice->config_ipv6);
529 ipdevice->config_ipv6 = NULL;
532 free_address_list(ipdevice);
533 g_free(ipdevice->ipv4_gateway);
534 g_free(ipdevice->ipv6_gateway);
535 g_free(ipdevice->pac);
537 g_free(ipdevice->address);
539 set_ipv6_state(ipdevice->ifname, ipdevice->ipv6_enabled);
540 set_ipv6_privacy(ipdevice->ifname, ipdevice->ipv6_privacy);
542 g_free(ipdevice->ifname);
546 static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
548 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
549 ipdevice->config_ipv6);
551 if (ipdevice->config_ipv6 != NULL &&
552 ipdevice->config_ipv6->enabled == TRUE)
555 if (__connman_device_isfiltered(ipdevice->ifname) == FALSE) {
556 ipdevice->ipv6_enabled = get_ipv6_state(ipdevice->ifname);
557 set_ipv6_state(ipdevice->ifname, FALSE);
561 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
563 DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
564 ipdevice->config_ipv6);
566 if (ipdevice->config_ipv4)
567 connman_inet_clear_address(ipdevice->index,
568 ipdevice->config_ipv4->address);
570 if (ipdevice->config_ipv6)
571 connman_inet_clear_ipv6_address(ipdevice->index,
572 ipdevice->config_ipv6->address->local,
573 ipdevice->config_ipv6->address->prefixlen);
576 static void update_stats(struct connman_ipdevice *ipdevice,
577 struct rtnl_link_stats *stats)
579 struct connman_service *service;
581 if (stats->rx_packets == 0 && stats->tx_packets == 0)
584 connman_info("%s {RX} %u packets %u bytes", ipdevice->ifname,
585 stats->rx_packets, stats->rx_bytes);
586 connman_info("%s {TX} %u packets %u bytes", ipdevice->ifname,
587 stats->tx_packets, stats->tx_bytes);
589 if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
592 if (ipdevice->config_ipv4)
593 service = __connman_ipconfig_get_data(ipdevice->config_ipv4);
594 else if (ipdevice->config_ipv6)
595 service = __connman_ipconfig_get_data(ipdevice->config_ipv6);
602 ipdevice->rx_packets = stats->rx_packets;
603 ipdevice->tx_packets = stats->tx_packets;
604 ipdevice->rx_bytes = stats->rx_bytes;
605 ipdevice->tx_bytes = stats->tx_bytes;
606 ipdevice->rx_errors = stats->rx_errors;
607 ipdevice->tx_errors = stats->tx_errors;
608 ipdevice->rx_dropped = stats->rx_dropped;
609 ipdevice->tx_dropped = stats->tx_dropped;
611 __connman_service_notify(service,
612 ipdevice->rx_packets, ipdevice->tx_packets,
613 ipdevice->rx_bytes, ipdevice->tx_bytes,
614 ipdevice->rx_errors, ipdevice->tx_errors,
615 ipdevice->rx_dropped, ipdevice->tx_dropped);
618 void __connman_ipconfig_newlink(int index, unsigned short type,
619 unsigned int flags, const char *address,
621 struct rtnl_link_stats *stats)
623 struct connman_ipdevice *ipdevice;
626 gboolean up = FALSE, down = FALSE;
627 gboolean lower_up = FALSE, lower_down = FALSE;
629 DBG("index %d", index);
631 if (type == ARPHRD_LOOPBACK)
634 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
635 if (ipdevice != NULL)
638 ipdevice = g_try_new0(struct connman_ipdevice, 1);
639 if (ipdevice == NULL)
642 ipdevice->index = index;
643 ipdevice->ifname = connman_inet_ifname(index);
644 ipdevice->type = type;
646 ipdevice->ipv6_enabled = get_ipv6_state(ipdevice->ifname);
647 ipdevice->ipv6_privacy = get_ipv6_privacy(ipdevice->ifname);
649 ipdevice->address = g_strdup(address);
651 g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
653 connman_info("%s {create} index %d type %d <%s>", ipdevice->ifname,
654 index, type, type2str(type));
659 update_stats(ipdevice, stats);
661 if (flags == ipdevice->flags)
664 if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
671 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
672 (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
673 if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
674 (IFF_RUNNING | IFF_LOWER_UP))
676 else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
680 ipdevice->flags = flags;
682 str = g_string_new(NULL);
687 g_string_append(str, "UP");
689 g_string_append(str, "DOWN");
691 if (flags & IFF_RUNNING)
692 g_string_append(str, ",RUNNING");
694 if (flags & IFF_LOWER_UP)
695 g_string_append(str, ",LOWER_UP");
697 connman_info("%s {update} flags %u <%s>", ipdevice->ifname,
700 g_string_free(str, TRUE);
702 for (list = g_list_first(ipconfig_list); list;
703 list = g_list_next(list)) {
704 struct connman_ipconfig *ipconfig = list->data;
706 if (index != ipconfig->index)
709 if (ipconfig->ops == NULL)
712 if (up == TRUE && ipconfig->ops->up)
713 ipconfig->ops->up(ipconfig);
714 if (lower_up == TRUE && ipconfig->ops->lower_up)
715 ipconfig->ops->lower_up(ipconfig);
717 if (lower_down == TRUE && ipconfig->ops->lower_down)
718 ipconfig->ops->lower_down(ipconfig);
719 if (down == TRUE && ipconfig->ops->down)
720 ipconfig->ops->down(ipconfig);
724 __connman_ipconfig_lower_up(ipdevice);
726 __connman_ipconfig_lower_down(ipdevice);
729 void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats)
731 struct connman_ipdevice *ipdevice;
734 DBG("index %d", index);
736 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
737 if (ipdevice == NULL)
740 update_stats(ipdevice, stats);
742 for (list = g_list_first(ipconfig_list); list;
743 list = g_list_next(list)) {
744 struct connman_ipconfig *ipconfig = list->data;
746 if (index != ipconfig->index)
749 ipconfig->index = -1;
751 if (ipconfig->ops == NULL)
754 if (ipconfig->ops->lower_down)
755 ipconfig->ops->lower_down(ipconfig);
756 if (ipconfig->ops->down)
757 ipconfig->ops->down(ipconfig);
760 __connman_ipconfig_lower_down(ipdevice);
762 g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
765 static inline gint check_duplicate_address(gconstpointer a, gconstpointer b)
767 const struct connman_ipaddress *addr1 = a;
768 const struct connman_ipaddress *addr2 = b;
770 if (addr1->prefixlen != addr2->prefixlen)
771 return addr2->prefixlen - addr1->prefixlen;
773 return g_strcmp0(addr1->local, addr2->local);
776 void __connman_ipconfig_newaddr(int index, int family, const char *label,
777 unsigned char prefixlen, const char *address)
779 struct connman_ipdevice *ipdevice;
780 struct connman_ipaddress *ipaddress;
781 enum connman_ipconfig_type type;
784 DBG("index %d", index);
786 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
787 if (ipdevice == NULL)
790 ipaddress = connman_ipaddress_alloc(family);
791 if (ipaddress == NULL)
794 ipaddress->prefixlen = prefixlen;
795 ipaddress->local = g_strdup(address);
797 if (g_slist_find_custom(ipdevice->address_list, ipaddress,
798 check_duplicate_address)) {
799 connman_ipaddress_free(ipaddress);
803 if (family == AF_INET)
804 type = CONNMAN_IPCONFIG_TYPE_IPV4;
805 else if (family == AF_INET6)
806 type = CONNMAN_IPCONFIG_TYPE_IPV6;
810 ipdevice->address_list = g_slist_append(ipdevice->address_list,
813 connman_info("%s {add} address %s/%u label %s family %d",
814 ipdevice->ifname, address, prefixlen, label, family);
816 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
817 __connman_ippool_newaddr(index, address, prefixlen);
819 if (ipdevice->config_ipv4 != NULL && family == AF_INET)
820 connman_ipaddress_copy(ipdevice->config_ipv4->system,
823 else if (ipdevice->config_ipv6 != NULL && family == AF_INET6)
824 connman_ipaddress_copy(ipdevice->config_ipv6->system,
829 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
832 for (list = g_list_first(ipconfig_list); list;
833 list = g_list_next(list)) {
834 struct connman_ipconfig *ipconfig = list->data;
836 if (index != ipconfig->index)
839 if (type != ipconfig->type)
842 if (ipconfig->ops == NULL)
845 if (ipconfig->ops->ip_bound)
846 ipconfig->ops->ip_bound(ipconfig);
850 void __connman_ipconfig_deladdr(int index, int family, const char *label,
851 unsigned char prefixlen, const char *address)
853 struct connman_ipdevice *ipdevice;
854 struct connman_ipaddress *ipaddress;
855 enum connman_ipconfig_type type;
858 DBG("index %d", index);
860 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
861 if (ipdevice == NULL)
864 ipaddress = find_ipaddress(ipdevice, prefixlen, address);
865 if (ipaddress == NULL)
868 if (family == AF_INET)
869 type = CONNMAN_IPCONFIG_TYPE_IPV4;
870 else if (family == AF_INET6)
871 type = CONNMAN_IPCONFIG_TYPE_IPV6;
875 ipdevice->address_list = g_slist_remove(ipdevice->address_list,
878 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
879 __connman_ippool_deladdr(index, address, prefixlen);
881 connman_ipaddress_clear(ipaddress);
884 connman_info("%s {del} address %s/%u label %s", ipdevice->ifname,
885 address, prefixlen, label);
887 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP))
890 if (g_slist_length(ipdevice->address_list) > 0)
893 for (list = g_list_first(ipconfig_list); list;
894 list = g_list_next(list)) {
895 struct connman_ipconfig *ipconfig = list->data;
897 if (index != ipconfig->index)
900 if (type != ipconfig->type)
903 if (ipconfig->ops == NULL)
906 if (ipconfig->ops->ip_release)
907 ipconfig->ops->ip_release(ipconfig);
911 void __connman_ipconfig_newroute(int index, int family, unsigned char scope,
912 const char *dst, const char *gateway)
914 struct connman_ipdevice *ipdevice;
916 DBG("index %d", index);
918 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
919 if (ipdevice == NULL)
922 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
923 g_strcmp0(dst, "::") == 0)) {
925 enum connman_ipconfig_type type;
927 if (family == AF_INET6) {
928 type = CONNMAN_IPCONFIG_TYPE_IPV6;
929 g_free(ipdevice->ipv6_gateway);
930 ipdevice->ipv6_gateway = g_strdup(gateway);
932 if (ipdevice->config_ipv6 != NULL &&
933 ipdevice->config_ipv6->system != NULL) {
934 g_free(ipdevice->config_ipv6->system->gateway);
935 ipdevice->config_ipv6->system->gateway =
938 } else if (family == AF_INET) {
939 type = CONNMAN_IPCONFIG_TYPE_IPV4;
940 g_free(ipdevice->ipv4_gateway);
941 ipdevice->ipv4_gateway = g_strdup(gateway);
943 if (ipdevice->config_ipv4 != NULL &&
944 ipdevice->config_ipv4->system != NULL) {
945 g_free(ipdevice->config_ipv4->system->gateway);
946 ipdevice->config_ipv4->system->gateway =
952 for (config_list = g_list_first(ipconfig_list); config_list;
953 config_list = g_list_next(config_list)) {
954 struct connman_ipconfig *ipconfig = config_list->data;
956 if (index != ipconfig->index)
959 if (type != ipconfig->type)
962 if (ipconfig->ops == NULL)
965 if (ipconfig->ops->route_set)
966 ipconfig->ops->route_set(ipconfig);
970 connman_info("%s {add} route %s gw %s scope %u <%s>",
971 ipdevice->ifname, dst, gateway,
972 scope, scope2str(scope));
975 void __connman_ipconfig_delroute(int index, int family, unsigned char scope,
976 const char *dst, const char *gateway)
978 struct connman_ipdevice *ipdevice;
980 DBG("index %d", index);
982 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
983 if (ipdevice == NULL)
986 if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
987 g_strcmp0(dst, "::") == 0)) {
989 enum connman_ipconfig_type type;
991 if (family == AF_INET6) {
992 type = CONNMAN_IPCONFIG_TYPE_IPV6;
993 g_free(ipdevice->ipv6_gateway);
994 ipdevice->ipv6_gateway = NULL;
996 if (ipdevice->config_ipv6 != NULL &&
997 ipdevice->config_ipv6->system != NULL) {
998 g_free(ipdevice->config_ipv6->system->gateway);
999 ipdevice->config_ipv6->system->gateway = NULL;
1001 } else if (family == AF_INET) {
1002 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1003 g_free(ipdevice->ipv4_gateway);
1004 ipdevice->ipv4_gateway = NULL;
1006 if (ipdevice->config_ipv4 != NULL &&
1007 ipdevice->config_ipv4->system != NULL) {
1008 g_free(ipdevice->config_ipv4->system->gateway);
1009 ipdevice->config_ipv4->system->gateway = NULL;
1014 for (config_list = g_list_first(ipconfig_list); config_list;
1015 config_list = g_list_next(config_list)) {
1016 struct connman_ipconfig *ipconfig = config_list->data;
1018 if (index != ipconfig->index)
1021 if (type != ipconfig->type)
1024 if (ipconfig->ops == NULL)
1027 if (ipconfig->ops->route_unset)
1028 ipconfig->ops->route_unset(ipconfig);
1032 connman_info("%s {del} route %s gw %s scope %u <%s>",
1033 ipdevice->ifname, dst, gateway,
1034 scope, scope2str(scope));
1037 void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
1042 keys = g_hash_table_get_keys(ipdevice_hash);
1046 for (list = g_list_first(keys); list; list = g_list_next(list)) {
1047 int index = GPOINTER_TO_INT(list->data);
1049 function(index, user_data);
1055 enum connman_ipconfig_type __connman_ipconfig_get_config_type(
1056 struct connman_ipconfig *ipconfig)
1058 return ipconfig ? ipconfig->type : CONNMAN_IPCONFIG_TYPE_UNKNOWN;
1061 unsigned short __connman_ipconfig_get_type_from_index(int index)
1063 struct connman_ipdevice *ipdevice;
1065 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1066 if (ipdevice == NULL)
1069 return ipdevice->type;
1072 unsigned int __connman_ipconfig_get_flags_from_index(int index)
1074 struct connman_ipdevice *ipdevice;
1076 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1077 if (ipdevice == NULL)
1080 return ipdevice->flags;
1083 const char *__connman_ipconfig_get_gateway_from_index(int index,
1084 enum connman_ipconfig_type type)
1086 struct connman_ipdevice *ipdevice;
1088 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1089 if (ipdevice == NULL)
1092 if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
1093 if (ipdevice->ipv4_gateway != NULL)
1094 return ipdevice->ipv4_gateway;
1096 if (ipdevice->config_ipv4 != NULL &&
1097 ipdevice->config_ipv4->address != NULL)
1098 return ipdevice->config_ipv4->address->gateway;
1101 if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
1102 if (ipdevice->ipv6_gateway != NULL)
1103 return ipdevice->ipv6_gateway;
1105 if (ipdevice->config_ipv6 != NULL &&
1106 ipdevice->config_ipv6->address != NULL)
1107 return ipdevice->config_ipv6->address->gateway;
1113 void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index)
1115 ipconfig->index = index;
1118 const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig)
1120 if (ipconfig->address == NULL)
1123 return ipconfig->address->local;
1126 void __connman_ipconfig_set_local(struct connman_ipconfig *ipconfig, const char *address)
1128 if (ipconfig->address == NULL)
1131 g_free(ipconfig->address->local);
1132 ipconfig->address->local = g_strdup(address);
1135 const char *__connman_ipconfig_get_peer(struct connman_ipconfig *ipconfig)
1137 if (ipconfig->address == NULL)
1140 return ipconfig->address->peer;
1143 void __connman_ipconfig_set_peer(struct connman_ipconfig *ipconfig, const char *address)
1145 if (ipconfig->address == NULL)
1148 g_free(ipconfig->address->peer);
1149 ipconfig->address->peer = g_strdup(address);
1152 const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig)
1154 if (ipconfig->address == NULL)
1157 return ipconfig->address->broadcast;
1160 void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const char *broadcast)
1162 if (ipconfig->address == NULL)
1165 g_free(ipconfig->address->broadcast);
1166 ipconfig->address->broadcast = g_strdup(broadcast);
1169 const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
1171 if (ipconfig->address == NULL)
1174 return ipconfig->address->gateway;
1177 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway)
1181 if (ipconfig->address == NULL)
1183 g_free(ipconfig->address->gateway);
1184 ipconfig->address->gateway = g_strdup(gateway);
1187 int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
1189 struct connman_service *service;
1193 if (ipconfig->address == NULL)
1196 service = __connman_service_lookup_from_index(ipconfig->index);
1197 if (service == NULL)
1200 __connman_connection_gateway_remove(service, ipconfig->type);
1202 DBG("type %d gw %s peer %s", ipconfig->type,
1203 ipconfig->address->gateway, ipconfig->address->peer);
1205 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6 ||
1206 ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1207 return __connman_connection_gateway_add(service,
1208 ipconfig->address->gateway,
1210 ipconfig->address->peer);
1215 void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig)
1217 struct connman_service *service;
1221 service = __connman_service_lookup_from_index(ipconfig->index);
1222 if (service != NULL)
1223 __connman_connection_gateway_remove(service, ipconfig->type);
1226 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
1228 if (ipconfig->address == NULL)
1231 return ipconfig->address->prefixlen;
1234 void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigned char prefixlen)
1236 if (ipconfig->address == NULL)
1239 ipconfig->address->prefixlen = prefixlen;
1242 static struct connman_ipconfig *create_ipv6config(int index)
1244 struct connman_ipconfig *ipv6config;
1245 struct connman_ipdevice *ipdevice;
1247 DBG("index %d", index);
1249 ipv6config = g_try_new0(struct connman_ipconfig, 1);
1250 if (ipv6config == NULL)
1253 ipv6config->refcount = 1;
1255 ipv6config->index = index;
1256 ipv6config->enabled = FALSE;
1257 ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
1258 ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
1260 ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
1261 if (ipdevice != NULL)
1262 ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
1264 ipv6config->address = connman_ipaddress_alloc(AF_INET6);
1265 if (ipv6config->address == NULL) {
1270 ipv6config->system = connman_ipaddress_alloc(AF_INET6);
1272 DBG("ipconfig %p", ipv6config);
1278 * connman_ipconfig_create:
1280 * Allocate a new ipconfig structure.
1282 * Returns: a newly-allocated #connman_ipconfig structure
1284 struct connman_ipconfig *__connman_ipconfig_create(int index,
1285 enum connman_ipconfig_type type)
1287 struct connman_ipconfig *ipconfig;
1289 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1290 return create_ipv6config(index);
1292 DBG("index %d", index);
1294 ipconfig = g_try_new0(struct connman_ipconfig, 1);
1295 if (ipconfig == NULL)
1298 ipconfig->refcount = 1;
1300 ipconfig->index = index;
1301 ipconfig->enabled = FALSE;
1302 ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
1304 ipconfig->address = connman_ipaddress_alloc(AF_INET);
1305 if (ipconfig->address == NULL) {
1310 ipconfig->system = connman_ipaddress_alloc(AF_INET);
1312 DBG("ipconfig %p", ipconfig);
1319 * connman_ipconfig_ref:
1320 * @ipconfig: ipconfig structure
1322 * Increase reference counter of ipconfig
1324 struct connman_ipconfig *
1325 __connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
1326 const char *file, int line, const char *caller)
1328 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
1329 file, line, caller);
1331 __sync_fetch_and_add(&ipconfig->refcount, 1);
1337 * connman_ipconfig_unref:
1338 * @ipconfig: ipconfig structure
1340 * Decrease reference counter of ipconfig
1342 void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
1343 const char *file, int line, const char *caller)
1345 if (ipconfig == NULL)
1348 DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
1349 file, line, caller);
1351 if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
1354 if (__connman_ipconfig_disable(ipconfig) < 0)
1355 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1357 __connman_ipconfig_set_ops(ipconfig, NULL);
1359 if (ipconfig->origin != NULL && ipconfig->origin != ipconfig) {
1360 __connman_ipconfig_unref(ipconfig->origin);
1361 ipconfig->origin = NULL;
1364 connman_ipaddress_free(ipconfig->system);
1365 connman_ipaddress_free(ipconfig->address);
1366 g_free(ipconfig->last_dhcp_address);
1371 * connman_ipconfig_get_data:
1372 * @ipconfig: ipconfig structure
1374 * Get private data pointer
1376 void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
1378 if (ipconfig == NULL)
1381 return ipconfig->ops_data;
1385 * connman_ipconfig_set_data:
1386 * @ipconfig: ipconfig structure
1387 * @data: data pointer
1389 * Set private data pointer
1391 void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
1393 ipconfig->ops_data = data;
1397 * connman_ipconfig_get_index:
1398 * @ipconfig: ipconfig structure
1400 * Get interface index
1402 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
1404 if (ipconfig == NULL)
1407 if (ipconfig->origin != NULL)
1408 return ipconfig->origin->index;
1410 return ipconfig->index;
1414 * connman_ipconfig_get_ifname:
1415 * @ipconfig: ipconfig structure
1417 * Get interface name
1419 const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
1421 struct connman_ipdevice *ipdevice;
1423 if (ipconfig == NULL)
1426 if (ipconfig->index < 0)
1429 ipdevice = g_hash_table_lookup(ipdevice_hash,
1430 GINT_TO_POINTER(ipconfig->index));
1431 if (ipdevice == NULL)
1434 return ipdevice->ifname;
1438 * connman_ipconfig_set_ops:
1439 * @ipconfig: ipconfig structure
1440 * @ops: operation callbacks
1442 * Set the operation callbacks
1444 void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
1445 const struct connman_ipconfig_ops *ops)
1447 ipconfig->ops = ops;
1451 * connman_ipconfig_set_method:
1452 * @ipconfig: ipconfig structure
1453 * @method: configuration method
1455 * Set the configuration method
1457 int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
1458 enum connman_ipconfig_method method)
1460 ipconfig->method = method;
1465 enum connman_ipconfig_method __connman_ipconfig_get_method(struct connman_ipconfig *ipconfig)
1467 if (ipconfig == NULL)
1468 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1470 return ipconfig->method;
1473 int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
1477 switch (ipconfig->method) {
1478 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1479 case CONNMAN_IPCONFIG_METHOD_OFF:
1481 case CONNMAN_IPCONFIG_METHOD_AUTO:
1482 case CONNMAN_IPCONFIG_METHOD_FIXED:
1483 case CONNMAN_IPCONFIG_METHOD_DHCP:
1484 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1485 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1486 return connman_inet_set_address(ipconfig->index,
1488 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1489 return connman_inet_set_ipv6_address(
1490 ipconfig->index, ipconfig->address);
1496 int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig)
1502 if (ipconfig == NULL)
1505 DBG("method %d", ipconfig->method);
1507 switch (ipconfig->method) {
1508 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1509 case CONNMAN_IPCONFIG_METHOD_OFF:
1511 case CONNMAN_IPCONFIG_METHOD_AUTO:
1512 case CONNMAN_IPCONFIG_METHOD_FIXED:
1513 case CONNMAN_IPCONFIG_METHOD_DHCP:
1514 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1515 err = __connman_ipconfig_address_unset(ipconfig);
1516 connman_ipaddress_clear(ipconfig->address);
1524 int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
1530 if (ipconfig == NULL)
1533 DBG("method %d", ipconfig->method);
1535 switch (ipconfig->method) {
1536 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1537 case CONNMAN_IPCONFIG_METHOD_OFF:
1539 case CONNMAN_IPCONFIG_METHOD_AUTO:
1540 case CONNMAN_IPCONFIG_METHOD_FIXED:
1541 case CONNMAN_IPCONFIG_METHOD_DHCP:
1542 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1543 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
1544 err = connman_inet_clear_address(ipconfig->index,
1546 else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
1547 err = connman_inet_clear_ipv6_address(
1549 ipconfig->address->local,
1550 ipconfig->address->prefixlen);
1560 int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig,
1563 struct connman_ipdevice *ipdevice;
1565 DBG("ipconfig %p", ipconfig);
1567 if (ipconfig == NULL || ipconfig->index < 0)
1570 ipdevice = g_hash_table_lookup(ipdevice_hash,
1571 GINT_TO_POINTER(ipconfig->index));
1572 if (ipdevice == NULL)
1575 g_free(ipdevice->pac);
1576 ipdevice->pac = g_strdup(url);
1581 const char *__connman_ipconfig_get_proxy_autoconfig(struct connman_ipconfig *ipconfig)
1583 struct connman_ipdevice *ipdevice;
1585 DBG("ipconfig %p", ipconfig);
1587 if (ipconfig == NULL || ipconfig->index < 0)
1590 ipdevice = g_hash_table_lookup(ipdevice_hash,
1591 GINT_TO_POINTER(ipconfig->index));
1592 if (ipdevice == NULL)
1595 return ipdevice->pac;
1598 void __connman_ipconfig_set_dhcp_address(struct connman_ipconfig *ipconfig,
1599 const char *address)
1601 if (ipconfig == NULL)
1604 g_free(ipconfig->last_dhcp_address);
1605 ipconfig->last_dhcp_address = g_strdup(address);
1608 char *__connman_ipconfig_get_dhcp_address(struct connman_ipconfig *ipconfig)
1610 if (ipconfig == NULL)
1613 return ipconfig->last_dhcp_address;
1616 static void disable_ipv6(struct connman_ipconfig *ipconfig)
1618 struct connman_ipdevice *ipdevice;
1622 ipdevice = g_hash_table_lookup(ipdevice_hash,
1623 GINT_TO_POINTER(ipconfig->index));
1624 if (ipdevice == NULL)
1627 set_ipv6_state(ipdevice->ifname, FALSE);
1630 static void enable_ipv6(struct connman_ipconfig *ipconfig)
1632 struct connman_ipdevice *ipdevice;
1636 ipdevice = g_hash_table_lookup(ipdevice_hash,
1637 GINT_TO_POINTER(ipconfig->index));
1638 if (ipdevice == NULL)
1641 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
1642 set_ipv6_privacy(ipdevice->ifname,
1643 ipconfig->ipv6_privacy_config);
1645 set_ipv6_state(ipdevice->ifname, TRUE);
1648 void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig)
1650 if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1653 enable_ipv6(ipconfig);
1656 void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig)
1658 if (ipconfig == NULL || ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1661 disable_ipv6(ipconfig);
1664 connman_bool_t __connman_ipconfig_is_usable(struct connman_ipconfig *ipconfig)
1666 if (ipconfig == NULL)
1669 switch (ipconfig->method) {
1670 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1671 case CONNMAN_IPCONFIG_METHOD_OFF:
1673 case CONNMAN_IPCONFIG_METHOD_AUTO:
1674 case CONNMAN_IPCONFIG_METHOD_FIXED:
1675 case CONNMAN_IPCONFIG_METHOD_DHCP:
1676 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1683 int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
1685 struct connman_ipdevice *ipdevice;
1686 gboolean up = FALSE, down = FALSE;
1687 gboolean lower_up = FALSE, lower_down = FALSE;
1688 enum connman_ipconfig_type type;
1690 DBG("ipconfig %p", ipconfig);
1692 if (ipconfig == NULL || ipconfig->index < 0)
1695 ipdevice = g_hash_table_lookup(ipdevice_hash,
1696 GINT_TO_POINTER(ipconfig->index));
1697 if (ipdevice == NULL)
1700 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
1701 if (ipdevice->config_ipv4 == ipconfig)
1703 type = CONNMAN_IPCONFIG_TYPE_IPV4;
1704 } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
1705 if (ipdevice->config_ipv6 == ipconfig)
1707 type = CONNMAN_IPCONFIG_TYPE_IPV6;
1708 enable_ipv6(ipconfig);
1712 ipconfig->enabled = TRUE;
1714 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1715 ipdevice->config_ipv4 != NULL) {
1716 ipconfig_list = g_list_remove(ipconfig_list,
1717 ipdevice->config_ipv4);
1719 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1721 __connman_ipconfig_unref(ipdevice->config_ipv4);
1724 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1725 ipdevice->config_ipv6 != NULL) {
1726 ipconfig_list = g_list_remove(ipconfig_list,
1727 ipdevice->config_ipv6);
1729 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1731 __connman_ipconfig_unref(ipdevice->config_ipv6);
1734 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1735 ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
1736 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1737 ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
1739 ipconfig_list = g_list_append(ipconfig_list, ipconfig);
1741 if (ipdevice->flags & IFF_UP)
1746 if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1747 (IFF_RUNNING | IFF_LOWER_UP))
1749 else if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
1752 if (up == TRUE && ipconfig->ops->up)
1753 ipconfig->ops->up(ipconfig);
1754 if (lower_up == TRUE && ipconfig->ops->lower_up)
1755 ipconfig->ops->lower_up(ipconfig);
1757 if (lower_down == TRUE && ipconfig->ops->lower_down)
1758 ipconfig->ops->lower_down(ipconfig);
1759 if (down == TRUE && ipconfig->ops->down)
1760 ipconfig->ops->down(ipconfig);
1765 int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
1767 struct connman_ipdevice *ipdevice;
1769 DBG("ipconfig %p", ipconfig);
1771 if (ipconfig == NULL || ipconfig->index < 0)
1774 ipdevice = g_hash_table_lookup(ipdevice_hash,
1775 GINT_TO_POINTER(ipconfig->index));
1776 if (ipdevice == NULL)
1779 if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
1782 ipconfig->enabled = FALSE;
1784 if (ipdevice->config_ipv4 == ipconfig) {
1785 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1787 connman_ipaddress_clear(ipdevice->config_ipv4->system);
1788 __connman_ipconfig_unref(ipdevice->config_ipv4);
1789 ipdevice->config_ipv4 = NULL;
1793 if (ipdevice->config_ipv6 == ipconfig) {
1794 ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
1796 if (ipdevice->config_ipv6->method ==
1797 CONNMAN_IPCONFIG_METHOD_AUTO)
1798 disable_ipv6(ipdevice->config_ipv6);
1800 connman_ipaddress_clear(ipdevice->config_ipv6->system);
1801 __connman_ipconfig_unref(ipdevice->config_ipv6);
1802 ipdevice->config_ipv6 = NULL;
1809 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
1812 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1814 case CONNMAN_IPCONFIG_METHOD_OFF:
1816 case CONNMAN_IPCONFIG_METHOD_FIXED:
1818 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1820 case CONNMAN_IPCONFIG_METHOD_DHCP:
1822 case CONNMAN_IPCONFIG_METHOD_AUTO:
1829 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
1831 if (g_strcmp0(method, "off") == 0)
1832 return CONNMAN_IPCONFIG_METHOD_OFF;
1833 else if (g_strcmp0(method, "fixed") == 0)
1834 return CONNMAN_IPCONFIG_METHOD_FIXED;
1835 else if (g_strcmp0(method, "manual") == 0)
1836 return CONNMAN_IPCONFIG_METHOD_MANUAL;
1837 else if (g_strcmp0(method, "dhcp") == 0)
1838 return CONNMAN_IPCONFIG_METHOD_DHCP;
1839 else if (g_strcmp0(method, "auto") == 0)
1840 return CONNMAN_IPCONFIG_METHOD_AUTO;
1842 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
1845 static const char *privacy2string(int privacy)
1849 else if (privacy == 1)
1851 else if (privacy > 1)
1857 static int string2privacy(const char *privacy)
1859 if (g_strcmp0(privacy, "disabled") == 0)
1861 else if (g_strcmp0(privacy, "enabled") == 0)
1863 else if (g_strcmp0(privacy, "prefered") == 0)
1869 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
1870 DBusMessageIter *iter)
1872 struct connman_ipaddress *append_addr = NULL;
1877 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
1880 str = __connman_ipconfig_method2string(ipconfig->method);
1884 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1886 switch (ipconfig->method) {
1887 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1888 case CONNMAN_IPCONFIG_METHOD_OFF:
1889 case CONNMAN_IPCONFIG_METHOD_AUTO:
1892 case CONNMAN_IPCONFIG_METHOD_FIXED:
1893 append_addr = ipconfig->address;
1896 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1897 case CONNMAN_IPCONFIG_METHOD_DHCP:
1898 append_addr = ipconfig->system;
1902 if (append_addr == NULL)
1905 if (append_addr->local != NULL) {
1907 struct in_addr netmask;
1910 connman_dbus_dict_append_basic(iter, "Address",
1911 DBUS_TYPE_STRING, &append_addr->local);
1913 addr = 0xffffffff << (32 - append_addr->prefixlen);
1914 netmask.s_addr = htonl(addr);
1915 mask = inet_ntoa(netmask);
1916 connman_dbus_dict_append_basic(iter, "Netmask",
1917 DBUS_TYPE_STRING, &mask);
1920 if (append_addr->gateway != NULL)
1921 connman_dbus_dict_append_basic(iter, "Gateway",
1922 DBUS_TYPE_STRING, &append_addr->gateway);
1925 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
1926 DBusMessageIter *iter,
1927 struct connman_ipconfig *ipconfig_ipv4)
1929 struct connman_ipaddress *append_addr = NULL;
1930 const char *str, *privacy;
1934 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
1937 str = __connman_ipconfig_method2string(ipconfig->method);
1941 if (ipconfig_ipv4 != NULL &&
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;
1965 if (append_addr == NULL)
1968 if (append_addr->local != NULL) {
1969 connman_dbus_dict_append_basic(iter, "Address",
1970 DBUS_TYPE_STRING, &append_addr->local);
1971 connman_dbus_dict_append_basic(iter, "PrefixLength",
1973 &append_addr->prefixlen);
1976 if (append_addr->gateway != NULL)
1977 connman_dbus_dict_append_basic(iter, "Gateway",
1978 DBUS_TYPE_STRING, &append_addr->gateway);
1980 privacy = privacy2string(ipconfig->ipv6_privacy_config);
1981 connman_dbus_dict_append_basic(iter, "Privacy",
1982 DBUS_TYPE_STRING, &privacy);
1985 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
1986 DBusMessageIter *iter)
1988 const char *str, *privacy;
1992 str = __connman_ipconfig_method2string(ipconfig->method);
1996 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
1998 switch (ipconfig->method) {
1999 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2000 case CONNMAN_IPCONFIG_METHOD_OFF:
2001 case CONNMAN_IPCONFIG_METHOD_DHCP:
2003 case CONNMAN_IPCONFIG_METHOD_FIXED:
2004 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2005 case CONNMAN_IPCONFIG_METHOD_AUTO:
2009 if (ipconfig->address == NULL)
2012 if (ipconfig->address->local != NULL) {
2013 connman_dbus_dict_append_basic(iter, "Address",
2014 DBUS_TYPE_STRING, &ipconfig->address->local);
2015 connman_dbus_dict_append_basic(iter, "PrefixLength",
2017 &ipconfig->address->prefixlen);
2020 if (ipconfig->address->gateway != NULL)
2021 connman_dbus_dict_append_basic(iter, "Gateway",
2022 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2024 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2025 connman_dbus_dict_append_basic(iter, "Privacy",
2026 DBUS_TYPE_STRING, &privacy);
2029 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
2030 DBusMessageIter *iter)
2036 str = __connman_ipconfig_method2string(ipconfig->method);
2040 connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
2042 switch (ipconfig->method) {
2043 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2044 case CONNMAN_IPCONFIG_METHOD_OFF:
2045 case CONNMAN_IPCONFIG_METHOD_DHCP:
2046 case CONNMAN_IPCONFIG_METHOD_AUTO:
2048 case CONNMAN_IPCONFIG_METHOD_FIXED:
2049 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2053 if (ipconfig->address == NULL)
2056 if (ipconfig->address->local != NULL) {
2058 struct in_addr netmask;
2061 connman_dbus_dict_append_basic(iter, "Address",
2062 DBUS_TYPE_STRING, &ipconfig->address->local);
2064 addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
2065 netmask.s_addr = htonl(addr);
2066 mask = inet_ntoa(netmask);
2067 connman_dbus_dict_append_basic(iter, "Netmask",
2068 DBUS_TYPE_STRING, &mask);
2071 if (ipconfig->address->gateway != NULL)
2072 connman_dbus_dict_append_basic(iter, "Gateway",
2073 DBUS_TYPE_STRING, &ipconfig->address->gateway);
2076 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
2077 DBusMessageIter *array)
2079 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
2080 const char *address = NULL, *netmask = NULL, *gateway = NULL,
2081 *prefix_length_string = NULL, *privacy_string = NULL;
2082 int prefix_length = 0, privacy = 0;
2083 DBusMessageIter dict;
2085 DBG("ipconfig %p", ipconfig);
2087 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
2090 dbus_message_iter_recurse(array, &dict);
2092 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2093 DBusMessageIter entry, value;
2097 dbus_message_iter_recurse(&dict, &entry);
2099 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2102 dbus_message_iter_get_basic(&entry, &key);
2103 dbus_message_iter_next(&entry);
2105 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2108 dbus_message_iter_recurse(&entry, &value);
2110 type = dbus_message_iter_get_arg_type(&value);
2112 if (g_str_equal(key, "Method") == TRUE) {
2115 if (type != DBUS_TYPE_STRING)
2118 dbus_message_iter_get_basic(&value, &str);
2119 method = __connman_ipconfig_string2method(str);
2120 } else if (g_str_equal(key, "Address") == TRUE) {
2121 if (type != DBUS_TYPE_STRING)
2124 dbus_message_iter_get_basic(&value, &address);
2125 } else if (g_str_equal(key, "PrefixLength") == TRUE) {
2126 if (type != DBUS_TYPE_STRING)
2129 dbus_message_iter_get_basic(&value,
2130 &prefix_length_string);
2132 prefix_length = atoi(prefix_length_string);
2133 if (prefix_length < 0 || prefix_length > 128)
2135 } else if (g_str_equal(key, "Netmask") == TRUE) {
2136 if (type != DBUS_TYPE_STRING)
2139 dbus_message_iter_get_basic(&value, &netmask);
2140 } else if (g_str_equal(key, "Gateway") == TRUE) {
2141 if (type != DBUS_TYPE_STRING)
2144 dbus_message_iter_get_basic(&value, &gateway);
2145 } else if (g_str_equal(key, "Privacy") == TRUE) {
2146 if (type != DBUS_TYPE_STRING)
2149 dbus_message_iter_get_basic(&value, &privacy_string);
2150 privacy = string2privacy(privacy_string);
2153 dbus_message_iter_next(&dict);
2156 DBG("method %d address %s netmask %s gateway %s prefix_length %d "
2158 method, address, netmask, gateway, prefix_length,
2162 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2163 case CONNMAN_IPCONFIG_METHOD_FIXED:
2166 case CONNMAN_IPCONFIG_METHOD_OFF:
2167 ipconfig->method = method;
2168 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2169 disable_ipv6(ipconfig);
2172 case CONNMAN_IPCONFIG_METHOD_AUTO:
2173 if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
2176 ipconfig->method = method;
2177 if (privacy_string != NULL)
2178 ipconfig->ipv6_privacy_config = privacy;
2179 enable_ipv6(ipconfig);
2182 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2183 if (address == NULL)
2186 ipconfig->method = method;
2188 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
2189 connman_ipaddress_set_ipv4(ipconfig->address,
2190 address, netmask, gateway);
2192 return connman_ipaddress_set_ipv6(
2193 ipconfig->address, address,
2194 prefix_length, gateway);
2197 case CONNMAN_IPCONFIG_METHOD_DHCP:
2198 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
2201 ipconfig->method = method;
2208 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
2209 DBusMessageIter *iter)
2211 struct connman_ipdevice *ipdevice;
2212 const char *method = "auto";
2214 connman_dbus_dict_append_basic(iter, "Method",
2215 DBUS_TYPE_STRING, &method);
2217 ipdevice = g_hash_table_lookup(ipdevice_hash,
2218 GINT_TO_POINTER(ipconfig->index));
2219 if (ipdevice == NULL)
2222 if (ipdevice->ifname != NULL)
2223 connman_dbus_dict_append_basic(iter, "Interface",
2224 DBUS_TYPE_STRING, &ipdevice->ifname);
2226 if (ipdevice->address != NULL)
2227 connman_dbus_dict_append_basic(iter, "Address",
2228 DBUS_TYPE_STRING, &ipdevice->address);
2230 if (ipdevice->mtu > 0)
2231 connman_dbus_dict_append_basic(iter, "MTU",
2232 DBUS_TYPE_UINT16, &ipdevice->mtu);
2235 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
2236 GKeyFile *keyfile, const char *identifier, const char *prefix)
2242 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2244 key = g_strdup_printf("%smethod", prefix);
2245 method = g_key_file_get_string(keyfile, identifier, key, NULL);
2246 if (method == NULL) {
2247 switch (ipconfig->type) {
2248 case CONNMAN_IPCONFIG_TYPE_IPV4:
2249 ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
2251 case CONNMAN_IPCONFIG_TYPE_IPV6:
2252 ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
2254 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2255 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2259 ipconfig->method = __connman_ipconfig_string2method(method);
2261 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
2262 ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
2264 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2265 if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO ||
2266 ipconfig->method == CONNMAN_IPCONFIG_METHOD_MANUAL) {
2268 char *pprefix = g_strdup_printf("%sprivacy", prefix);
2269 privacy = g_key_file_get_string(keyfile, identifier,
2271 ipconfig->ipv6_privacy_config = string2privacy(privacy);
2280 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2281 ipconfig->address->prefixlen = g_key_file_get_integer(
2282 keyfile, identifier, key, NULL);
2285 key = g_strdup_printf("%slocal_address", prefix);
2286 ipconfig->address->local = g_key_file_get_string(
2287 keyfile, identifier, key, NULL);
2290 key = g_strdup_printf("%speer_address", prefix);
2291 ipconfig->address->peer = g_key_file_get_string(
2292 keyfile, identifier, key, NULL);
2295 key = g_strdup_printf("%sbroadcast_address", prefix);
2296 ipconfig->address->broadcast = g_key_file_get_string(
2297 keyfile, identifier, key, NULL);
2300 key = g_strdup_printf("%sgateway", prefix);
2301 ipconfig->address->gateway = g_key_file_get_string(
2302 keyfile, identifier, key, NULL);
2305 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2306 str = g_key_file_get_string(keyfile, identifier, key, NULL);
2308 g_free(ipconfig->last_dhcp_address);
2309 ipconfig->last_dhcp_address = str;
2316 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
2317 GKeyFile *keyfile, const char *identifier, const char *prefix)
2322 DBG("ipconfig %p identifier %s", ipconfig, identifier);
2324 method = __connman_ipconfig_method2string(ipconfig->method);
2326 key = g_strdup_printf("%smethod", prefix);
2327 g_key_file_set_string(keyfile, identifier, key, method);
2330 if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
2331 const char *privacy;
2332 privacy = privacy2string(ipconfig->ipv6_privacy_config);
2333 key = g_strdup_printf("%sprivacy", prefix);
2334 g_key_file_set_string(keyfile, identifier, key, privacy);
2338 switch (ipconfig->method) {
2339 case CONNMAN_IPCONFIG_METHOD_FIXED:
2340 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2342 case CONNMAN_IPCONFIG_METHOD_DHCP:
2343 key = g_strdup_printf("%sDHCP.LastAddress", prefix);
2344 if (ipconfig->last_dhcp_address != NULL &&
2345 strlen(ipconfig->last_dhcp_address) > 0)
2346 g_key_file_set_string(keyfile, identifier, key,
2347 ipconfig->last_dhcp_address);
2349 g_key_file_remove_key(keyfile, identifier, key, NULL);
2352 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2353 case CONNMAN_IPCONFIG_METHOD_OFF:
2354 case CONNMAN_IPCONFIG_METHOD_AUTO:
2358 key = g_strdup_printf("%snetmask_prefixlen", prefix);
2359 if (ipconfig->address->prefixlen != 0)
2360 g_key_file_set_integer(keyfile, identifier,
2361 key, ipconfig->address->prefixlen);
2364 key = g_strdup_printf("%slocal_address", prefix);
2365 if (ipconfig->address->local != NULL)
2366 g_key_file_set_string(keyfile, identifier,
2367 key, ipconfig->address->local);
2370 key = g_strdup_printf("%speer_address", prefix);
2371 if (ipconfig->address->peer != NULL)
2372 g_key_file_set_string(keyfile, identifier,
2373 key, ipconfig->address->peer);
2376 key = g_strdup_printf("%sbroadcast_address", prefix);
2377 if (ipconfig->address->broadcast != NULL)
2378 g_key_file_set_string(keyfile, identifier,
2379 key, ipconfig->address->broadcast);
2382 key = g_strdup_printf("%sgateway", prefix);
2383 if (ipconfig->address->gateway != NULL)
2384 g_key_file_set_string(keyfile, identifier,
2385 key, ipconfig->address->gateway);
2391 int __connman_ipconfig_init(void)
2395 ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2396 NULL, free_ipdevice);
2401 void __connman_ipconfig_cleanup(void)
2405 g_hash_table_destroy(ipdevice_hash);
2406 ipdevice_hash = NULL;