5 * Copyright (C) 2007-2009 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/driver.h>
34 #include <connman/inet.h>
35 #include <connman/dbus.h>
36 #include <connman/log.h>
40 #define UDHCPC_INTF "net.busybox.udhcpc"
41 #define UDHCPC_PATH "/net/busybox/udhcpc"
43 static int udhcp_probe(struct connman_element *element)
45 struct task_data *task;
46 char *argv[9], *envp[2], *ifname;
47 char pidfile[PATH_MAX], script[PATH_MAX];
49 DBG("element %p name %s", element, element->name);
51 if (access(UDHCPC, X_OK) < 0)
54 ifname = connman_inet_ifname(element->index);
58 snprintf(pidfile, sizeof(pidfile) - 1,
59 "%s/udhcpc.%s.pid", STATEDIR, ifname);
60 snprintf(script, sizeof(script) - 1, "%s/udhcpc-script", SCRIPTDIR);
74 task = task_spawn(element->index, argv, envp, NULL, element);
85 static void udhcp_remove(struct connman_element *element)
87 struct task_data *task;
89 DBG("element %p name %s", element, element->name);
91 task = task_find_by_index(element->index);
98 static struct connman_driver udhcp_driver = {
100 .type = CONNMAN_ELEMENT_TYPE_DHCP,
101 .priority = CONNMAN_DRIVER_PRIORITY_HIGH,
102 .probe = udhcp_probe,
103 .remove = udhcp_remove,
106 static void udhcp_bound(DBusMessage *msg, gboolean renew)
108 struct task_data *task;
109 struct connman_element *element, *parent;
110 const char *interface, *address, *netmask, *broadcast, *gateway, *dns;
113 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface,
114 DBUS_TYPE_STRING, &address,
115 DBUS_TYPE_STRING, &netmask,
116 DBUS_TYPE_STRING, &broadcast,
117 DBUS_TYPE_STRING, &gateway,
118 DBUS_TYPE_STRING, &dns,
121 DBG("%s ==> address %s gateway %s", interface, address, gateway);
123 index = connman_inet_ifindex(interface);
127 task = task_find_by_index(index);
131 parent = task_get_data(task);
135 g_free(parent->ipv4.address);
136 parent->ipv4.address = g_strdup(address);
138 g_free(parent->ipv4.netmask);
139 parent->ipv4.netmask = g_strdup(netmask);
141 g_free(parent->ipv4.broadcast);
142 parent->ipv4.broadcast = g_strdup(broadcast);
144 g_free(parent->ipv4.gateway);
145 parent->ipv4.gateway = g_strdup(gateway);
147 g_free(parent->ipv4.nameserver);
148 parent->ipv4.nameserver = g_strdup(dns);
150 connman_element_update(parent);
155 element = connman_element_create(NULL);
159 element->type = CONNMAN_ELEMENT_TYPE_IPV4;
160 element->index = index;
162 if (connman_element_register(element, parent) < 0)
163 connman_element_unref(element);
166 static gboolean udhcp_filter(DBusConnection *conn,
167 DBusMessage *msg, void *data)
169 if (dbus_message_is_method_call(msg, UDHCPC_INTF, "bound") == TRUE) {
170 udhcp_bound(msg, FALSE);
174 if (dbus_message_is_method_call(msg, UDHCPC_INTF, "renew") == TRUE) {
175 udhcp_bound(msg, TRUE);
182 static DBusConnection *connection;
186 static int udhcp_init(void)
190 connection = connman_dbus_get_connection();
192 watch = g_dbus_add_signal_watch(connection, NULL, UDHCPC_PATH,
193 UDHCPC_INTF, NULL, udhcp_filter,
198 err = connman_driver_register(&udhcp_driver);
200 dbus_connection_unref(connection);
207 static void udhcp_exit(void)
209 connman_driver_unregister(&udhcp_driver);
211 g_dbus_remove_watch(connection, watch);
213 dbus_connection_unref(connection);
216 CONNMAN_PLUGIN_DEFINE(udhcp, "uDHCP client plugin", VERSION,
217 CONNMAN_PLUGIN_PRIORITY_DEFAULT, udhcp_init, udhcp_exit)