Create IP configuration based on the interface index
[platform/upstream/connman.git] / src / ipconfig.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <gdbus.h>
27
28 #include "connman.h"
29
30 struct connman_ipconfig {
31         gint refcount;
32         unsigned int index;
33         char *interface;
34         enum connman_ipconfig_method method;
35 };
36
37 /**
38  * connman_ipconfig_create:
39  *
40  * Allocate a new ipconfig structure.
41  *
42  * Returns: a newly-allocated #connman_ipconfig structure
43  */
44 struct connman_ipconfig *connman_ipconfig_create(unsigned int index)
45 {
46         struct connman_ipconfig *ipconfig;
47
48         DBG("");
49
50         ipconfig = g_try_new0(struct connman_ipconfig, 1);
51         if (ipconfig == NULL)
52                 return NULL;
53
54         ipconfig->index = index;
55         ipconfig->interface = connman_inet_ifname(index);
56
57         DBG("ipconfig %p", ipconfig);
58
59         __connman_rtnl_register_ipconfig(ipconfig);
60
61         return ipconfig;
62 }
63
64 /**
65  * connman_ipconfig_ref:
66  * @ipconfig: ipconfig structure
67  *
68  * Increase reference counter of ipconfig
69  */
70 struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
71 {
72         g_atomic_int_inc(&ipconfig->refcount);
73
74         return ipconfig;
75 }
76
77 /**
78  * connman_ipconfig_unref:
79  * @ipconfig: ipconfig structure
80  *
81  * Decrease reference counter of ipconfig
82  */
83 void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
84 {
85         if (g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
86                 __connman_rtnl_unregister_ipconfig(ipconfig);
87
88                 g_free(ipconfig->interface);
89                 g_free(ipconfig);
90         }
91 }
92
93 /**
94  * connman_ipconfig_set_method:
95  * @ipconfig: ipconfig structure
96  * @method: configuration method
97  *
98  * Set the configuration method
99  */
100 int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
101                                         enum connman_ipconfig_method method)
102 {
103         ipconfig->method = method;
104
105         return 0;
106 }
107
108 int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
109 {
110         return ipconfig->index;
111 }
112
113 void __connman_ipconfig_add_address(struct connman_ipconfig *ipconfig,
114                                 const char *label, unsigned int prefixlen,
115                                 const char *address, const char *broadcast)
116 {
117         connman_info("%s {add} address %s/%d label %s", ipconfig->interface,
118                                                 address, prefixlen, label);
119 }
120
121 void __connman_ipconfig_del_address(struct connman_ipconfig *ipconfig,
122                                 const char *label, unsigned int prefixlen,
123                                 const char *address, const char *broadcast)
124 {
125         connman_info("%s {del} address %s/%d label %s", ipconfig->interface,
126                                                 address, prefixlen, label);
127 }
128
129 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
130 {
131         switch (method) {
132         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
133                 break;
134         case CONNMAN_IPCONFIG_METHOD_OFF:
135                 return "off";
136         case CONNMAN_IPCONFIG_METHOD_STATIC:
137                 return "static";
138         case CONNMAN_IPCONFIG_METHOD_DHCP:
139                 return "dhcp";
140         }
141
142         return NULL;
143 }
144
145 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method)
146 {
147         if (g_strcmp0(method, "off") == 0)
148                 return CONNMAN_IPCONFIG_METHOD_OFF;
149         else if (g_strcmp0(method, "static") == 0)
150                 return CONNMAN_IPCONFIG_METHOD_STATIC;
151         else if (g_strcmp0(method, "dhcp") == 0)
152                 return CONNMAN_IPCONFIG_METHOD_DHCP;
153         else
154                 return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
155 }
156
157 static void append_variant(DBusMessageIter *iter, const char *prefix,
158                                         const char *key, int type, void *val)
159 {
160         char *str;
161
162         if (prefix == NULL) {
163                 connman_dbus_dict_append_variant(iter, key, type, val);
164                 return;
165         }
166
167         str = g_strdup_printf("%s%s", prefix, key);
168         if (str != NULL)
169                 connman_dbus_dict_append_variant(iter, str, type, val);
170
171         g_free(str);
172 }
173
174 void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
175                                 DBusMessageIter *iter, const char *prefix)
176 {
177         const char *str;
178
179         str = __connman_ipconfig_method2string(ipconfig->method);
180         if (str == NULL)
181                 return;
182
183         append_variant(iter, prefix, "Method", DBUS_TYPE_STRING, &str);
184 }
185
186 int __connman_ipconfig_set_ipv4(struct connman_ipconfig *ipconfig,
187                                 const char *key, DBusMessageIter *value)
188 {
189         int type = dbus_message_iter_get_arg_type(value);
190
191         DBG("ipconfig %p key %s type %d", ipconfig, key, type);
192
193         if (g_strcmp0(key, "Method") == 0) {
194                 const char *method;
195
196                 if (type != DBUS_TYPE_STRING)
197                         return -EINVAL;
198
199                 dbus_message_iter_get_basic(value, &method);
200
201                 ipconfig->method = __connman_ipconfig_string2method(method);
202         } else
203                 return -EINVAL;
204
205         return 0;
206 }
207
208 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
209                 GKeyFile *keyfile, const char *identifier, const char *prefix)
210 {
211         DBG("ipconfig %p identifier %s", ipconfig, identifier);
212
213         return 0;
214 }
215
216 int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
217                 GKeyFile *keyfile, const char *identifier, const char *prefix)
218 {
219         DBG("ipconfig %p identifier %s", ipconfig, identifier);
220
221         return 0;
222 }
223
224 static GSList *driver_list = NULL;
225
226 static gint compare_priority(gconstpointer a, gconstpointer b)
227 {
228         const struct connman_ipconfig_driver *driver1 = a;
229         const struct connman_ipconfig_driver *driver2 = b;
230
231         return driver2->priority - driver1->priority;
232 }
233
234 /**
235  * connman_ipconfig_driver_register:
236  * @driver: IP configuration driver
237  *
238  * Register a new IP configuration driver
239  *
240  * Returns: %0 on success
241  */
242 int connman_ipconfig_driver_register(struct connman_ipconfig_driver *driver)
243 {
244         DBG("driver %p name %s", driver, driver->name);
245
246         driver_list = g_slist_insert_sorted(driver_list, driver,
247                                                         compare_priority);
248
249         return 0;
250 }
251
252 /**
253  * connman_ipconfig_driver_unregister:
254  * @driver: IP configuration driver
255  *
256  * Remove a previously registered IP configuration driver.
257  */
258 void connman_ipconfig_driver_unregister(struct connman_ipconfig_driver *driver)
259 {
260         DBG("driver %p name %s", driver, driver->name);
261
262         driver_list = g_slist_remove(driver_list, driver);
263 }