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
31 #define CONNMAN_API_SUBJECT_TO_CHANGE
32 #include <connman/plugin.h>
33 #include <connman/dhcp.h>
34 #include <connman/utsname.h>
35 #include <connman/log.h>
37 #include <gdhcp/gdhcp.h>
39 static void dhcp_debug(const char *str, void *data)
41 connman_info("%s: %s\n", (const char *) data, str);
44 static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data)
46 struct connman_dhcp *dhcp = user_data;
48 DBG("No lease available");
50 connman_dhcp_fail(dhcp);
53 static void lease_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
58 static void ipv4ll_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
60 struct connman_dhcp *dhcp = user_data;
64 connman_dhcp_release(dhcp);
67 static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
69 struct connman_dhcp *dhcp = user_data;
70 GList *list, *option = NULL;
71 char *address, *nameservers;
74 DBG("Lease available");
76 address = g_dhcp_client_get_address(dhcp_client);
78 connman_dhcp_set_value(dhcp, "Address", address);
80 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
82 connman_dhcp_set_value(dhcp, "Netmask", option->data);
84 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_DNS_SERVER);
85 for (list = option; list; list = list->next)
86 ns_strlen += strlen((char *) list->data) + 2;
87 nameservers = g_try_malloc0(ns_strlen);
89 char *ns_index = nameservers;
91 for (list = option; list; list = list->next) {
92 sprintf(ns_index, "%s ", (char *) list->data);
93 ns_index += strlen((char *) list->data) + 1;
96 connman_dhcp_set_value(dhcp, "Nameserver", nameservers);
100 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_DOMAIN_NAME);
102 connman_dhcp_set_value(dhcp, "Domainname", option->data);
104 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_ROUTER);
106 connman_dhcp_set_value(dhcp, "Gateway", option->data);
108 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_HOST_NAME);
110 connman_dhcp_set_value(dhcp, "Hostname", option->data);
112 option = g_dhcp_client_get_option(dhcp_client, G_DHCP_NTP_SERVER);
114 connman_dhcp_set_value(dhcp, "Timeserver", option->data);
116 option = g_dhcp_client_get_option(dhcp_client, 252);
118 connman_dhcp_set_value(dhcp, "PAC", option->data);
120 connman_dhcp_bound(dhcp);
123 static void ipv4ll_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
125 struct connman_dhcp *dhcp = user_data;
126 char *address, *netmask;
128 DBG("IPV4LL available");
130 address = g_dhcp_client_get_address(dhcp_client);
132 connman_dhcp_set_value(dhcp, "Address", address);
134 netmask = g_dhcp_client_get_netmask(dhcp_client);
136 connman_dhcp_set_value(dhcp, "Netmask", netmask);
141 connman_dhcp_bound(dhcp);
144 static int dhcp_request(struct connman_dhcp *dhcp)
146 GDHCPClient *dhcp_client;
147 GDHCPClientError error;
148 const char *hostname;
151 DBG("dhcp %p", dhcp);
153 index = connman_dhcp_get_index(dhcp);
155 dhcp_client = g_dhcp_client_new(G_DHCP_IPV4, index, &error);
156 if (error != G_DHCP_CLIENT_ERROR_NONE)
159 if (getenv("CONNMAN_DHCP_DEBUG"))
160 g_dhcp_client_set_debug(dhcp_client, dhcp_debug, "DHCP");
162 hostname = connman_utsname_get_hostname();
163 if (hostname != NULL)
164 g_dhcp_client_set_send(dhcp_client, G_DHCP_HOST_NAME, hostname);
166 g_dhcp_client_set_request(dhcp_client, G_DHCP_HOST_NAME);
167 g_dhcp_client_set_request(dhcp_client, G_DHCP_SUBNET);
168 g_dhcp_client_set_request(dhcp_client, G_DHCP_DNS_SERVER);
169 g_dhcp_client_set_request(dhcp_client, G_DHCP_DOMAIN_NAME);
170 g_dhcp_client_set_request(dhcp_client, G_DHCP_NTP_SERVER);
171 g_dhcp_client_set_request(dhcp_client, G_DHCP_ROUTER);
172 g_dhcp_client_set_request(dhcp_client, 252);
174 g_dhcp_client_register_event(dhcp_client,
175 G_DHCP_CLIENT_EVENT_LEASE_AVAILABLE,
176 lease_available_cb, dhcp);
178 g_dhcp_client_register_event(dhcp_client,
179 G_DHCP_CLIENT_EVENT_IPV4LL_AVAILABLE,
180 ipv4ll_available_cb, dhcp);
182 g_dhcp_client_register_event(dhcp_client,
183 G_DHCP_CLIENT_EVENT_LEASE_LOST, lease_lost_cb, dhcp);
185 g_dhcp_client_register_event(dhcp_client,
186 G_DHCP_CLIENT_EVENT_IPV4LL_LOST, ipv4ll_lost_cb, dhcp);
188 g_dhcp_client_register_event(dhcp_client,
189 G_DHCP_CLIENT_EVENT_NO_LEASE, no_lease_cb, dhcp);
191 connman_dhcp_set_data(dhcp, dhcp_client);
193 g_dhcp_client_ref(dhcp_client);
195 return g_dhcp_client_start(dhcp_client);
198 static int dhcp_release(struct connman_dhcp *dhcp)
200 GDHCPClient *dhcp_client = connman_dhcp_get_data(dhcp);
202 DBG("dhcp %p", dhcp);
204 g_dhcp_client_stop(dhcp_client);
205 g_dhcp_client_unref(dhcp_client);
210 static struct connman_dhcp_driver dhcp_driver = {
212 .priority = CONNMAN_DHCP_PRIORITY_DEFAULT,
213 .request = dhcp_request,
214 .release = dhcp_release,
217 static int dhcp_init(void)
219 return connman_dhcp_driver_register(&dhcp_driver);
222 static void dhcp_exit(void)
224 connman_dhcp_driver_unregister(&dhcp_driver);
227 CONNMAN_PLUGIN_DEFINE(dhcp, "Generic DHCP plugin", VERSION,
228 CONNMAN_PLUGIN_PRIORITY_DEFAULT, dhcp_init, dhcp_exit)