~shakaran/ubuntu/quantal/connman/bug-pattern-update

« back to all changes in this revision

Viewing changes to src/dhcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel
  • Date: 2010-02-12 10:08:03 UTC
  • mfrom: (1.1.8 upstream) (0.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100212100803-s8iaj8g1dmgwm2uz
Tags: 0.48+dfsg-2
* Ubuntu/Debian sync upload
* Re-add missing changes from 0.45+dfsg that made it only in Ubuntu:
  - ship development parts in a connman-dev package (Closes: 546616)
    - add debian/connman-dev.install
    - update debian/control
* Update long descriptions for connman and connman-dev
  - update debian/control
* Add missing Depends on libglib2.0-dev, libdbus-1-dev for connman-dev
  - update debian/control
* Don't run bootstrap twice during build.
  - update debian/rules
* Remove old configure option: enable-ppp, with-pppd, enable-novatel,
  enable-huawei and enable-modemmgr are no longer recognized.
  - update debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <glib.h>
 
27
 
 
28
#include "connman.h"
 
29
 
 
30
struct connman_dhcp {
 
31
        gint refcount;
 
32
        int index;
 
33
        enum connman_dhcp_state state;
 
34
 
 
35
        struct connman_element *element;
 
36
 
 
37
        struct connman_dhcp_driver *driver;
 
38
        void *driver_data;
 
39
};
 
40
 
 
41
/**
 
42
 * connman_dhcp_ref:
 
43
 * @dhcp: DHCP structure
 
44
 *
 
45
 * Increase reference counter of DHCP
 
46
 */
 
47
struct connman_dhcp *connman_dhcp_ref(struct connman_dhcp *dhcp)
 
48
{
 
49
        g_atomic_int_inc(&dhcp->refcount);
 
50
 
 
51
        return dhcp;
 
52
}
 
53
 
 
54
/**
 
55
 * connman_dhcp_unref:
 
56
 * @dhcp: DHCP structure
 
57
 *
 
58
 * Decrease reference counter of DHCP
 
59
 */
 
60
void connman_dhcp_unref(struct connman_dhcp *dhcp)
 
61
{
 
62
        if (g_atomic_int_dec_and_test(&dhcp->refcount) == TRUE)
 
63
                g_free(dhcp);
 
64
}
 
65
 
 
66
/**
 
67
 * connman_dhcp_get_index:
 
68
 * @dhcp: DHCP structure
 
69
 *
 
70
 * Get network index of DHCP
 
71
 */
 
72
int connman_dhcp_get_index(struct connman_dhcp *dhcp)
 
73
{
 
74
        return dhcp->index;
 
75
}
 
76
 
 
77
/**
 
78
 * connman_dhcp_get_interface:
 
79
 * @dhcp: DHCP structure
 
80
 *
 
81
 * Get network interface of DHCP
 
82
 */
 
83
char *connman_dhcp_get_interface(struct connman_dhcp *dhcp)
 
84
{
 
85
        return connman_inet_ifname(dhcp->index);
 
86
}
 
87
 
 
88
/**
 
89
 * connman_dhcp_set_value:
 
90
 * @dhcp: DHCP structure
 
91
 * @key: unique identifier
 
92
 * @value: string value
 
93
 *
 
94
 * Set string value for specific key
 
95
 */
 
96
void connman_dhcp_set_value(struct connman_dhcp *dhcp,
 
97
                                        const char *key, const char *value)
 
98
{
 
99
        if (g_strcmp0(key, "Address") == 0) {
 
100
                g_free(dhcp->element->ipv4.address);
 
101
                dhcp->element->ipv4.address = g_strdup(value);
 
102
        } else if (g_strcmp0(key, "Netmask") == 0) {
 
103
                g_free(dhcp->element->ipv4.netmask);
 
104
                dhcp->element->ipv4.netmask = g_strdup(value);
 
105
        } else if (g_strcmp0(key, "Gateway") == 0) {
 
106
                g_free(dhcp->element->ipv4.gateway);
 
107
                dhcp->element->ipv4.gateway = g_strdup(value);
 
108
        } else if (g_strcmp0(key, "Network") == 0) {
 
109
                g_free(dhcp->element->ipv4.network);
 
110
                dhcp->element->ipv4.network = g_strdup(value);
 
111
        } else if (g_strcmp0(key, "Broadcast") == 0) {
 
112
                g_free(dhcp->element->ipv4.broadcast);
 
113
                dhcp->element->ipv4.broadcast = g_strdup(value);
 
114
        } else if (g_strcmp0(key, "Nameserver") == 0) {
 
115
                g_free(dhcp->element->ipv4.nameserver);
 
116
                dhcp->element->ipv4.nameserver = g_strdup(value);
 
117
        } else if (g_strcmp0(key, "Domainname") == 0) {
 
118
                __connman_utsname_set_domainname(value);
 
119
        } else if (g_strcmp0(key, "Hostname") == 0) {
 
120
                __connman_utsname_set_hostname(value);
 
121
        } else if (g_strcmp0(key, "Timeserver") == 0) {
 
122
                g_free(dhcp->element->ipv4.timeserver);
 
123
                dhcp->element->ipv4.timeserver = g_strdup(value);
 
124
        } else if (g_strcmp0(key, "MTU") == 0) {
 
125
        }
 
126
}
 
127
 
 
128
/**
 
129
 * connman_dhcp_bound:
 
130
 * @dhcp: DHCP structure
 
131
 *
 
132
 * Report successful bound of the interface
 
133
 */
 
134
void connman_dhcp_bound(struct connman_dhcp *dhcp)
 
135
{
 
136
        struct connman_element *element;
 
137
 
 
138
        DBG("dhcp %p", dhcp);
 
139
 
 
140
        element = connman_element_create(NULL);
 
141
        if (element == NULL)
 
142
                return;
 
143
 
 
144
        element->type = CONNMAN_ELEMENT_TYPE_IPV4;
 
145
        element->index = dhcp->index;
 
146
 
 
147
        connman_element_update(dhcp->element);
 
148
 
 
149
        if (connman_element_register(element, dhcp->element) < 0)
 
150
                connman_element_unref(element);
 
151
}
 
152
 
 
153
/**
 
154
 * connman_dhcp_renew:
 
155
 * @dhcp: DHCP structure
 
156
 *
 
157
 * Report successful renew of the interface
 
158
 */
 
159
void connman_dhcp_renew(struct connman_dhcp *dhcp)
 
160
{
 
161
        DBG("dhcp %p", dhcp);
 
162
 
 
163
        connman_element_update(dhcp->element);
 
164
}
 
165
 
 
166
/**
 
167
 * connman_dhcp_fail:
 
168
 * @dhcp: DHCP structure
 
169
 *
 
170
 * Report DHCP failure of the interface
 
171
 */
 
172
void connman_dhcp_fail(struct connman_dhcp *dhcp)
 
173
{
 
174
        DBG("dhcp %p", dhcp);
 
175
 
 
176
        connman_element_set_error(dhcp->element,
 
177
                                        CONNMAN_ELEMENT_ERROR_FAILED);
 
178
}
 
179
 
 
180
/**
 
181
 * connman_dhcp_get_data:
 
182
 * @dhcp: DHCP structure
 
183
 *
 
184
 * Get private DHCP data pointer
 
185
 */
 
186
void *connman_dhcp_get_data(struct connman_dhcp *dhcp)
 
187
{
 
188
        return dhcp->driver_data;
 
189
}
 
190
 
 
191
/**
 
192
 * connman_dhcp_set_data:
 
193
 * @dhcp: DHCP structure
 
194
 * @data: data pointer
 
195
 *
 
196
 * Set private DHCP data pointer
 
197
 */
 
198
void connman_dhcp_set_data(struct connman_dhcp *dhcp, void *data)
 
199
{
 
200
        dhcp->driver_data = data;
 
201
}
 
202
 
 
203
static GSList *driver_list = NULL;
 
204
 
 
205
static gint compare_priority(gconstpointer a, gconstpointer b)
 
206
{
 
207
        const struct connman_dhcp_driver *driver1 = a;
 
208
        const struct connman_dhcp_driver *driver2 = b;
 
209
 
 
210
        return driver2->priority - driver1->priority;
 
211
}
 
212
 
 
213
/**
 
214
 * connman_dhcp_driver_register:
 
215
 * @driver: DHCP driver definition
 
216
 *
 
217
 * Register a new DHCP driver
 
218
 *
 
219
 * Returns: %0 on success
 
220
 */
 
221
int connman_dhcp_driver_register(struct connman_dhcp_driver *driver)
 
222
{
 
223
        DBG("driver %p name %s", driver, driver->name);
 
224
 
 
225
        driver_list = g_slist_insert_sorted(driver_list, driver,
 
226
                                                        compare_priority);
 
227
 
 
228
        return 0;
 
229
}
 
230
 
 
231
/**
 
232
 * connman_dhcp_driver_unregister:
 
233
 * @driver: DHCP driver definition
 
234
 *
 
235
 * Remove a previously registered DHCP driver
 
236
 */
 
237
void connman_dhcp_driver_unregister(struct connman_dhcp_driver *driver)
 
238
{
 
239
        DBG("driver %p name %s", driver, driver->name);
 
240
 
 
241
        driver_list = g_slist_remove(driver_list, driver);
 
242
}
 
243
 
 
244
static int dhcp_probe(struct connman_element *element)
 
245
{
 
246
        struct connman_dhcp *dhcp;
 
247
        GSList *list;
 
248
 
 
249
        DBG("element %p name %s", element, element->name);
 
250
 
 
251
        dhcp = g_try_new0(struct connman_dhcp, 1);
 
252
        if (dhcp == NULL)
 
253
                return -ENOMEM;
 
254
 
 
255
        dhcp->refcount = 1;
 
256
        dhcp->index = element->index;
 
257
        dhcp->state = CONNMAN_DHCP_STATE_IDLE;
 
258
 
 
259
        dhcp->element = element;
 
260
 
 
261
        connman_element_set_data(element, dhcp);
 
262
 
 
263
        for (list = driver_list; list; list = list->next) {
 
264
                struct connman_dhcp_driver *driver = list->data;
 
265
 
 
266
                DBG("driver %p name %s", driver, driver->name);
 
267
 
 
268
                if (driver->request(dhcp) == 0) {
 
269
                        dhcp->driver = driver;
 
270
                        break;
 
271
                }
 
272
        }
 
273
 
 
274
        if (dhcp->driver == NULL) {
 
275
                connman_dhcp_unref(dhcp);
 
276
                return -ENOENT;
 
277
        }
 
278
 
 
279
        return 0;
 
280
}
 
281
 
 
282
static void dhcp_remove(struct connman_element *element)
 
283
{
 
284
        struct connman_dhcp *dhcp = connman_element_get_data(element);
 
285
 
 
286
        DBG("element %p name %s", element, element->name);
 
287
 
 
288
        connman_element_set_data(element, NULL);
 
289
 
 
290
        if (dhcp->driver) {
 
291
                dhcp->driver->release(dhcp);
 
292
                dhcp->driver = NULL;
 
293
        }
 
294
 
 
295
        connman_dhcp_unref(dhcp);
 
296
}
 
297
 
 
298
static void dhcp_change(struct connman_element *element)
 
299
{
 
300
        DBG("element %p name %s", element, element->name);
 
301
 
 
302
        if (element->state == CONNMAN_ELEMENT_STATE_ERROR)
 
303
                connman_element_set_error(element->parent,
 
304
                                        CONNMAN_ELEMENT_ERROR_DHCP_FAILED);
 
305
}
 
306
 
 
307
static struct connman_driver dhcp_driver = {
 
308
        .name           = "dhcp",
 
309
        .type           = CONNMAN_ELEMENT_TYPE_DHCP,
 
310
        .priority       = CONNMAN_DRIVER_PRIORITY_LOW,
 
311
        .probe          = dhcp_probe,
 
312
        .remove         = dhcp_remove,
 
313
        .change         = dhcp_change,
 
314
};
 
315
 
 
316
int __connman_dhcp_init(void)
 
317
{
 
318
        return connman_driver_register(&dhcp_driver);
 
319
}
 
320
 
 
321
void __connman_dhcp_cleanup(void)
 
322
{
 
323
        connman_driver_unregister(&dhcp_driver);
 
324
}