summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in1
-rw-r--r--plugins/Makefile.am5
-rw-r--r--plugins/dhclient.c82
-rw-r--r--scripts/dhclient-script.c23
4 files changed, 83 insertions, 28 deletions
diff --git a/configure.in b/configure.in
index 9918d72f..68301053 100644
--- a/configure.in
+++ b/configure.in
@@ -41,6 +41,7 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
fi
])
+AC_PATH_PROG(DHCLIENT, [dhclient])
AC_PATH_PROG(WPASUPPLICANT, [wpa_supplicant])
PKG_CHECK_MODULES(GMODULE, gmodule-2.0, dummy=yes,
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 87464b04..3ecb1aef 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -10,6 +10,8 @@ libconnman_80211_la_SOURCES = 80211.c supplicant.h supplicant.c
libconnman_dhclient_la_SOURCES = dhclient.c
libconnman_dhclient_la_LIBADD = @GDBUS_LIBS@
+libconnman_dhclient_la_CFLAGS = @GDBUS_CFLAGS@ -DDHCLIENT=\"@DHCLIENT@\" \
+ -DSTATEDIR=\""$(statedir)"\" -DSCRIPTDIR=\""$(scriptdir)"\"
libconnman_resolvconf_la_SOURCES = resolvconf.c
@@ -23,8 +25,7 @@ else
scriptdir = $(libdir)/connman/scripts
endif
-AM_CFLAGS = @GDBUS_CFLAGS@ \
- -DSTATEDIR=\""$(statedir)"\" -DSCRIPTDIR=\""$(scriptdir)"\"
+AM_CFLAGS = @GDBUS_CFLAGS@
INCLUDES = -I$(top_builddir)/include
diff --git a/plugins/dhclient.c b/plugins/dhclient.c
index 211b84ef..8847a1de 100644
--- a/plugins/dhclient.c
+++ b/plugins/dhclient.c
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <signal.h>
#include <string.h>
+#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -40,6 +41,9 @@
#include <connman/plugin.h>
#include <connman/dhcp.h>
+#define DHCLIENT_INTF "org.isc.dhclient"
+#define DHCLIENT_PATH "/org/isc/dhclient"
+
static const char *busname;
struct dhclient_task {
@@ -83,7 +87,8 @@ static void kill_task(struct dhclient_task *task)
{
char pathname[PATH_MAX];
- kill(task->pid, SIGTERM);
+ if (task->pid > 0)
+ kill(task->pid, SIGTERM);
snprintf(pathname, sizeof(pathname) - 1,
"%s/dhclient.%s.pid", STATEDIR, task->ifname);
@@ -98,11 +103,37 @@ static void kill_task(struct dhclient_task *task)
g_free(task);
}
+static void task_died(GPid pid, gint status, gpointer data)
+{
+ struct dhclient_task *task = data;
+
+ if (WIFEXITED(status))
+ printf("[DHCP] exit status %d for %s\n",
+ WEXITSTATUS(status), task->ifname);
+ else
+ printf("[DHCP] signal %d killed %s\n",
+ WTERMSIG(status), task->ifname);
+
+ g_spawn_close_pid(pid);
+ task->pid = 0;
+
+ tasks = g_slist_remove(tasks, task);
+
+ kill_task(task);
+}
+
+static void task_setup(gpointer data)
+{
+ struct dhclient_task *task = data;
+
+ printf("[DHCP] setup %s\n", task->ifname);
+}
+
static int dhclient_request(struct connman_iface *iface)
{
struct ifreq ifr;
struct dhclient_task *task;
- char *argv[16], address[128], pidfile[PATH_MAX];
+ char *argv[16], *envp[1], address[128], pidfile[PATH_MAX];
char leases[PATH_MAX], config[PATH_MAX], script[PATH_MAX];
int sk, err;
@@ -143,7 +174,7 @@ static int dhclient_request(struct connman_iface *iface)
snprintf(config, sizeof(config) - 1, "%s/dhclient.conf", SCRIPTDIR);
snprintf(script, sizeof(script) - 1, "%s/dhclient-script", SCRIPTDIR);
- argv[0] = "/sbin/dhclient";
+ argv[0] = DHCLIENT;
argv[1] = "-d";
argv[2] = "-q";
argv[3] = "-n";
@@ -160,15 +191,19 @@ static int dhclient_request(struct connman_iface *iface)
argv[14] = task->ifname;
argv[15] = NULL;
- if (g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &task->pid, NULL) == FALSE) {
+ envp[0] = NULL;
+
+ if (g_spawn_async(NULL, argv, envp, G_SPAWN_DO_NOT_REAP_CHILD,
+ task_setup, task, &task->pid, NULL) == FALSE) {
printf("Failed to spawn dhclient\n");
return -1;
}
tasks = g_slist_append(tasks, task);
- printf("[DHCP] executed with pid %d\n", task->pid);
+ g_child_watch_add(task->pid, task_died, task);
+
+ printf("[DHCP] executed %s with pid %d\n", DHCLIENT, task->pid);
return 0;
}
@@ -196,8 +231,8 @@ static struct connman_dhcp_driver dhclient_driver = {
.release = dhclient_release,
};
-static DBusMessage *notify_method(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static DBusHandlerResult dhclient_filter(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
DBusMessageIter iter, dict;
dbus_uint32_t pid;
@@ -205,6 +240,9 @@ static DBusMessage *notify_method(DBusConnection *conn,
struct connman_ipv4 ipv4;
const char *text, *key, *value;
+ if (dbus_message_is_method_call(msg, DHCLIENT_INTF, "notify") == FALSE)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
memset(&ipv4, 0, sizeof(ipv4));
dbus_message_iter_init(msg, &iter);
@@ -219,7 +257,7 @@ static DBusMessage *notify_method(DBusConnection *conn,
task = find_task_by_pid(pid);
if (task == NULL)
- return NULL;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_iter_recurse(&iter, &dict);
@@ -267,27 +305,29 @@ static DBusMessage *notify_method(DBusConnection *conn,
connman_dhcp_update(task->iface,
CONNMAN_DHCP_STATE_FAILED, NULL);
- return NULL;
+ return DBUS_HANDLER_RESULT_HANDLED;
}
-static GDBusMethodTable dhclient_methods[] = {
- { "notify", "usa{ss}", "", notify_method, G_DBUS_METHOD_FLAG_NOREPLY },
- { },
-};
-
static DBusConnection *connection;
static int plugin_init(void)
{
- connection = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+ gchar *filter;
+
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
busname = dbus_bus_get_unique_name(connection);
- g_dbus_register_object(connection, "/org/isc/dhclient", NULL, NULL);
+ busname = "org.freedesktop.connman";
+
+ dbus_connection_add_filter(connection, dhclient_filter, NULL, NULL);
+
+ filter = g_strdup_printf("interface=%s,path=%s",
+ DHCLIENT_INTF, DHCLIENT_PATH);
+
+ dbus_bus_add_match(connection, filter, NULL);
- g_dbus_register_interface(connection, "/org/isc/dhclient",
- "org.isc.dhclient",
- dhclient_methods, NULL, NULL);
+ g_free(filter);
connman_dhcp_register(&dhclient_driver);
@@ -310,7 +350,7 @@ static void plugin_exit(void)
connman_dhcp_unregister(&dhclient_driver);
- g_dbus_cleanup_connection(connection);
+ dbus_connection_unref(connection);
}
CONNMAN_PLUGIN_DEFINE("dhclient", "ISC DHCP client plugin", VERSION,
diff --git a/scripts/dhclient-script.c b/scripts/dhclient-script.c
index 39b235c7..f4a8431f 100644
--- a/scripts/dhclient-script.c
+++ b/scripts/dhclient-script.c
@@ -56,6 +56,7 @@ static void append(DBusMessageIter *dict, const char *pattern)
int main(int argc, char *argv[])
{
DBusConnection *conn;
+ DBusError error;
DBusMessage *msg;
DBusMessageIter iter, dict;
dbus_uint32_t pid;
@@ -67,17 +68,28 @@ int main(int argc, char *argv[])
reason = getenv("reason");
interface = getenv("interface");
- conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
- if (conn == NULL)
- exit(1);
+ dbus_error_init(&error);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (conn == NULL) {
+ if (dbus_error_is_set(&error) == TRUE) {
+ fprintf(stderr, "%s\n", error.message);
+ dbus_error_free(&error);
+ } else
+ fprintf(stderr, "Failed to get on system bus\n");
+ return 0;
+ }
msg = dbus_message_new_method_call(busname, "/org/isc/dhclient",
"org.isc.dhclient", "notify");
if (msg == NULL) {
dbus_connection_unref(conn);
- exit(1);
+ fprintf(stderr, "Failed to allocate method call\n");
+ return 0;
}
+ dbus_message_set_no_reply(msg, TRUE);
+
dbus_message_append_args(msg, DBUS_TYPE_UINT32, &pid,
DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID);
@@ -100,7 +112,8 @@ int main(int argc, char *argv[])
dbus_message_iter_close_container(&iter, &dict);
- dbus_connection_send(conn, msg, NULL);
+ if (dbus_connection_send(conn, msg, NULL) == FALSE)
+ fprintf(stderr, "Failed to send message\n");
dbus_message_unref(msg);