summaryrefslogtreecommitdiffstats
path: root/dhcpcd/dev
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-01-30 13:29:46 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-01-30 16:23:03 +0100
commitf2ed769880271654297a4be420f26ab94d39666b (patch)
tree4cbfc23184993e8ef11bb1d60b307cbb3644a259 /dhcpcd/dev
parentarphole: New test (diff)
downloadrtems-libbsd-f2ed769880271654297a4be420f26ab94d39666b.tar.bz2
DHCPCD(8): Import
Import DHCPCD(8) from: http://roy.marples.name/projects/dhcpcd/ The upstream sources can be obtained via: fossil clone http://roy.marples.name/projects/dhcpcd The imported version is 2014-01-29 19:46:44 [6b209507bb].
Diffstat (limited to 'dhcpcd/dev')
-rw-r--r--dhcpcd/dev/Makefile42
-rw-r--r--dhcpcd/dev/udev.c179
2 files changed, 221 insertions, 0 deletions
diff --git a/dhcpcd/dev/Makefile b/dhcpcd/dev/Makefile
new file mode 100644
index 00000000..e6b3a2cf
--- /dev/null
+++ b/dhcpcd/dev/Makefile
@@ -0,0 +1,42 @@
+TOP?= ../
+include ${TOP}/Makefile.inc
+include ${TOP}/config.mk
+
+CFLAGS?= -O2
+CSTD?= c99
+CFLAGS+= -std=${CSTD}
+
+DEVDIR= ${LIBDIR}/dhcpcd/dev
+DSRC= ${DEV_PLUGINS:=.c}
+DOBJ= ${DSRC:.c=.o}
+DSOBJ= ${DOBJ:.o=.So}
+DPLUGS= ${DEV_PLUGINS:=.so}
+
+CLEANFILES+= ${DSOBJ} ${DPLUGS}
+
+.SUFFIXES: .So .so
+
+.c.So:
+ ${CC} ${PICFLAG} -DPIC ${CPPFLAGS} ${CFLAGS} -c $< -o $@
+
+.So.so: ${DSOBJ}
+ ${CC} ${LDFLAGS} -shared -Wl,-x -o $@ -Wl,-soname,$@ \
+ $< ${LIBS}
+
+all: ${DPLUGS}
+
+udev.So:
+CFLAGS+= ${LIBUDEV_CFLAGS}
+CPPFLAGS+= ${LIBUDEV_CPPFLAGS}
+
+udev.so:
+LIBS+= ${LIBUDEV_LIBS}
+
+proginstall: ${DPLUGS}
+ ${INSTALL} -d ${DESTDIR}${DEVDIR}
+ ${INSTALL} -m ${BINMODE} ${PROG} ${DPLUGS} ${DESTDIR}${DEVDIR}
+
+install: proginstall
+
+clean:
+ rm -f ${CLEANFILES}
diff --git a/dhcpcd/dev/udev.c b/dhcpcd/dev/udev.c
new file mode 100644
index 00000000..0b02ffb8
--- /dev/null
+++ b/dhcpcd/dev/udev.c
@@ -0,0 +1,179 @@
+/*
+ * dhcpcd - DHCP client daemon
+ * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef LIBUDEV_NOINIT
+# define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
+# warning This version of udev is too old does not support
+# warning per device initialization checks.
+# warning As such, dhcpcd will need to depend on the
+# warning udev-settle service or similar if starting
+# warning in master mode.
+#endif
+
+#include <libudev.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "../common.h"
+#include "../dev.h"
+
+static const char udev_name[]="udev";
+static struct udev *udev;
+static struct udev_monitor *monitor;
+
+static const struct dev_dhcpcd *dhcpcd;
+
+static int
+udev_listening(void)
+{
+
+ return monitor ? 1 : 0;
+}
+
+static int
+udev_initialized(const char *ifname)
+{
+ struct udev_device *device;
+ int r;
+
+ device = udev_device_new_from_subsystem_sysname(udev, "net", ifname);
+ if (device) {
+#ifndef LIBUDEV_NOINIT
+ r = udev_device_get_is_initialized(device);
+#else
+ r = 1;
+#endif
+ udev_device_unref(device);
+ } else
+ r = 0;
+ return r;
+}
+
+static int
+udev_handle_device(void)
+{
+ struct udev_device *device;
+ const char *subsystem, *ifname, *action;
+
+ device = udev_monitor_receive_device(monitor);
+ if (device == NULL) {
+ syslog(LOG_ERR, "libudev: received NULL device");
+ return -1;
+ }
+
+ subsystem = udev_device_get_subsystem(device);
+ ifname = udev_device_get_sysname(device);
+ action = udev_device_get_action(device);
+
+ /* udev filter documentation says "usually" so double check */
+ if (strcmp(subsystem, "net") == 0) {
+ syslog(LOG_DEBUG, "%s: libudev: %s", ifname, action);
+ if (strcmp(action, "add") == 0 || strcmp(action, "move") == 0)
+ dhcpcd->handle_interface(1, ifname);
+ else if (strcmp(action, "remove") == 0)
+ dhcpcd->handle_interface(-1, ifname);
+ }
+
+ udev_device_unref(device);
+ return 1;
+}
+
+static void
+udev_stop(void)
+{
+
+ if (monitor) {
+ udev_monitor_unref(monitor);
+ monitor = NULL;
+ }
+
+ if (udev) {
+ udev_unref(udev);
+ udev = NULL;
+ }
+}
+
+static int
+udev_start(void)
+{
+ int fd;
+
+ if (udev) {
+ syslog(LOG_ERR, "udev: already started");
+ return -1;
+ }
+
+ syslog(LOG_DEBUG, "udev: starting");
+ udev = udev_new();
+ if (udev == NULL) {
+ syslog(LOG_ERR, "udev_new: %m");
+ return -1;
+ }
+ monitor = udev_monitor_new_from_netlink(udev, "udev");
+ if (monitor == NULL) {
+ syslog(LOG_ERR, "udev_monitor_new_from_netlink: %m");
+ goto bad;
+ }
+#ifndef LIBUDEV_NOFILTER
+ if (udev_monitor_filter_add_match_subsystem_devtype(monitor,
+ "net", NULL) != 0)
+ {
+ syslog(LOG_ERR,
+ "udev_monitor_filter_add_match_subsystem_devtype: %m");
+ goto bad;
+ }
+#endif
+ if (udev_monitor_enable_receiving(monitor) != 0) {
+ syslog(LOG_ERR, "udev_monitor_enable_receiving: %m");
+ goto bad;
+ }
+ fd = udev_monitor_get_fd(monitor);
+ if (fd == -1) {
+ syslog(LOG_ERR, "udev_monitor_get_fd: %m");
+ goto bad;
+ }
+ return fd;
+
+bad:
+ udev_stop();
+ return -1;
+}
+
+int
+dev_init(struct dev *dev, const struct dev_dhcpcd *dev_dhcpcd)
+{
+
+ dev->name = udev_name;
+ dev->initialized = udev_initialized;
+ dev->listening = udev_listening;
+ dev->handle_device = udev_handle_device;
+ dev->stop = udev_stop;
+ dev->start = udev_start;
+
+ dhcpcd = dev_dhcpcd;
+
+ return 0;
+}