summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dhcpcd/dhcpcd.c14
-rw-r--r--dhcpcd/namespace.h1
-rw-r--r--dhcpcd/script.c52
-rw-r--r--dhcpcd/script.h6
-rw-r--r--libbsd.py1
-rw-r--r--rtemsbsd/include/rtems/dhcpcd.h26
-rw-r--r--testsuite/dhcpcd01/test_main.c24
7 files changed, 118 insertions, 6 deletions
diff --git a/dhcpcd/dhcpcd.c b/dhcpcd/dhcpcd.c
index 59562d63..fd6356de 100644
--- a/dhcpcd/dhcpcd.c
+++ b/dhcpcd/dhcpcd.c
@@ -1599,3 +1599,17 @@ main(int argc, char **argv)
eloop_start(&dhcpcd_sigset);
exit(EXIT_SUCCESS);
}
+#ifdef __rtems__
+int
+dhcpcd_script_runreason_do_nothing(const struct interface *ifp,
+ const char *reason)
+{
+ return 0;
+}
+
+/*
+ * Do not pull in the script support if it is not used, e.g. no call to
+ * rtems_dhcpcd_add_hook() is present.
+ */
+__weak_reference(dhcpcd_script_runreason_do_nothing, dhcpcd_script_runreason);
+#endif /* __rtems__ */
diff --git a/dhcpcd/namespace.h b/dhcpcd/namespace.h
index efff909a..c9f5fb1f 100644
--- a/dhcpcd/namespace.h
+++ b/dhcpcd/namespace.h
@@ -156,6 +156,7 @@ extern rtems_recursive_mutex dhcpcd_mutex;
#define print_string dhcpcd_print_string
#define read_config dhcpcd_read_config
#define read_lease dhcpcd_read_lease
+#define script_runreason dhcpcd_script_runreason
#define select_profile dhcpcd_select_profile
#define set_cloexec dhcpcd_set_cloexec
#define set_nonblock dhcpcd_set_nonblock
diff --git a/dhcpcd/script.c b/dhcpcd/script.c
index 2de1e634..3de8715e 100644
--- a/dhcpcd/script.c
+++ b/dhcpcd/script.c
@@ -51,7 +51,30 @@
#include "ipv6nd.h"
#include "net.h"
#include "script.h"
+#ifdef __rtems__
+#include <rtems/dhcpcd.h>
+static SLIST_HEAD(, rtems_dhcpcd_hook) dhcpcd_hooks =
+ SLIST_HEAD_INITIALIZER(dhcpcd_hooks);
+
+void
+rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook)
+{
+ rtems_recursive_mutex_lock(&dhcpcd_mutex);
+ SLIST_INSERT_HEAD(&dhcpcd_hooks, hook, node);
+ rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+}
+
+void
+rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook)
+{
+ rtems_recursive_mutex_lock(&dhcpcd_mutex);
+ SLIST_REMOVE(&dhcpcd_hooks, hook, rtems_dhcpcd_hook, node);
+ rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+}
+#endif /* __rtems__ */
+
+#ifndef __rtems__
#define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
static const char * const if_params[] = {
@@ -104,6 +127,7 @@ exec_script(char *const *argv, char *const *env)
}
return pid;
}
+#endif /* __rtems__ */
#ifdef INET
static char *
@@ -168,6 +192,7 @@ append_config(char ***env, ssize_t *len,
}
#endif
+#ifndef __rtems__
static size_t
arraytostr(const char *const *argv, char **s)
{
@@ -191,6 +216,7 @@ arraytostr(const char *const *argv, char **s)
}
return len;
}
+#endif /* __rtems__ */
static ssize_t
make_env(const struct interface *ifp, const char *reason, char ***argv)
@@ -435,6 +461,7 @@ eexit:
return -1;
}
+#ifndef __rtems__
static int
send_interface1(int fd, const struct interface *iface, const char *reason)
{
@@ -507,29 +534,43 @@ send_interface(int fd, const struct interface *iface)
}
return retval;
}
+#endif /* __rtems__ */
int
script_runreason(const struct interface *ifp, const char *reason)
{
+#ifndef __rtems__
char *const argv[2] = { UNCONST(ifp->options->script), NULL };
+#endif /* __rtems__ */
char **env = NULL, **ep;
+#ifndef __rtems__
char *path, *bigenv;
ssize_t e, elen = 0;
pid_t pid;
+#else /* __rtems__ */
+ ssize_t elen;
+ rtems_dhcpcd_hook *hook;
+ rtems_dhcpcd_hook *hook2;
+#endif /* __rtems__ */
int status = 0;
+#ifndef __rtems__
const struct fd_list *fd;
struct iovec iov[2];
+#endif /* __rtems__ */
if (ifp->options->script == NULL ||
ifp->options->script[0] == '\0' ||
strcmp(ifp->options->script, "/dev/null") == 0)
return 0;
+#ifndef __rtems__
syslog(LOG_DEBUG, "%s: executing `%s' %s",
ifp->name, argv[0], reason);
+#endif /* __rtems__ */
/* Make our env */
elen = make_env(ifp, reason, &env);
+#ifndef __rtems__
ep = realloc(env, sizeof(char *) * (elen + 2));
if (ep == NULL) {
elen = -1;
@@ -596,6 +637,17 @@ script_runreason(const struct interface *ifp, const char *reason)
free(bigenv);
out:
+#else /* __rtems__ */
+ rtems_recursive_mutex_lock(&dhcpcd_mutex);
+
+ SLIST_FOREACH_SAFE(hook, &dhcpcd_hooks, node, hook2) {
+ syslog(LOG_DEBUG, "%s: executing `%s' %s", ifp->name,
+ hook->name, reason);
+ (*hook->handler)(hook, env);
+ }
+
+ rtems_recursive_mutex_unlock(&dhcpcd_mutex);
+#endif /* __rtems__ */
/* Cleanup */
ep = env;
while (*ep)
diff --git a/dhcpcd/script.h b/dhcpcd/script.h
index dfd4a172..9c5fd4d4 100644
--- a/dhcpcd/script.h
+++ b/dhcpcd/script.h
@@ -33,16 +33,12 @@
void if_printoptions(void);
#ifndef __rtems__
int send_interface(int, const struct interface *);
-int script_runreason(const struct interface *, const char *);
#else /* __rtems__ */
static inline int send_interface(int fd, const struct interface *iface)
{
return 0;
}
-static inline int script_runreason(const struct interface *ifp, const char *reason)
-{
- return 0;
-}
#endif /* __rtems__ */
+int script_runreason(const struct interface *, const char *);
#endif
diff --git a/libbsd.py b/libbsd.py
index dac1ece1..05e9dd51 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -4553,6 +4553,7 @@ class dhcpcd(builder.Module):
'dhcpcd/ipv6nd.c',
'dhcpcd/net.c',
'dhcpcd/platform-bsd.c',
+ 'dhcpcd/script.c',
'dhcpcd/compat/pselect.c',
'dhcpcd/crypt/hmac_md5.c',
],
diff --git a/rtemsbsd/include/rtems/dhcpcd.h b/rtemsbsd/include/rtems/dhcpcd.h
index 324c8a90..da4972d4 100644
--- a/rtemsbsd/include/rtems/dhcpcd.h
+++ b/rtemsbsd/include/rtems/dhcpcd.h
@@ -40,6 +40,9 @@
#ifndef _RTEMS_DHCPCD_H_
#define _RTEMS_DHCPCD_H_
+#include <sys/cdefs.h>
+#include <sys/queue.h>
+
#include <rtems.h>
#ifdef __cplusplus
@@ -75,6 +78,29 @@ typedef struct rtems_dhcpcd_config {
*/
rtems_status_code rtems_dhcpcd_start(const rtems_dhcpcd_config *config);
+typedef struct rtems_dhcpcd_hook {
+ SLIST_ENTRY(rtems_dhcpcd_hook) node;
+ const char *name;
+ void (*handler)(struct rtems_dhcpcd_hook *hook, char *const *env);
+} rtems_dhcpcd_hook;
+
+/**
+ * @brief Adds a DHCP client hook.
+ *
+ * The hook handler is invoked with an environment list (NULL terminated) of
+ * strings ('\0' terminated). Each string of the environment list has usually
+ * the format "key=value", e.g. "interface=eth0", "reason=BOUND".
+ *
+ * The hook handler are called by the DHCP client task. It is safe to
+ * add/remove hooks in the hook handler.
+ */
+void rtems_dhcpcd_add_hook(rtems_dhcpcd_hook *hook);
+
+/**
+ * @brief Removes a DHCP client hook.
+ */
+void rtems_dhcpcd_remove_hook(rtems_dhcpcd_hook *hook);
+
/** @} */
#ifdef __cplusplus
diff --git a/testsuite/dhcpcd01/test_main.c b/testsuite/dhcpcd01/test_main.c
index 181f92ae..358b4ac8 100644
--- a/testsuite/dhcpcd01/test_main.c
+++ b/testsuite/dhcpcd01/test_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013, 2018 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -30,14 +30,36 @@
*/
#include <assert.h>
+#include <stdio.h>
#include <rtems.h>
+#include <rtems/dhcpcd.h>
#define TEST_NAME "LIBBSD DHCPCD 1"
static void
+dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env)
+{
+
+ (void)hook;
+
+ while (*env != NULL) {
+ printf("%s\n", *env);
+ ++env;
+ }
+}
+
+static rtems_dhcpcd_hook dhcpcd_hook = {
+ .name = "test",
+ .handler = dhcpcd_hook_handler
+};
+
+static void
test_main(void)
{
+
+ rtems_dhcpcd_add_hook(&dhcpcd_hook);
+
rtems_task_delete(RTEMS_SELF);
assert(0);
}