/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
ssize_t
setvar(char ***e, const char *prefix, const char *var, const char *value)
{
- size_t len = strlen(prefix) + strlen(var) + strlen(value) + 4;
+ size_t len = strlen(var) + strlen(value) + 3;
+ if (prefix)
+ len += strlen(prefix) + 1;
**e = xmalloc(len);
- snprintf(**e, len, "%s_%s=%s", prefix, var, value);
+ if (prefix)
+ snprintf(**e, len, "%s_%s=%s", prefix, var, value);
+ else
+ snprintf(**e, len, "%s=%s", var, value);
(*e)++;
return len;
}
}
static ssize_t
-make_env(const struct interface *iface, char ***argv)
+make_env(const struct interface *iface, const char *reason, char ***argv)
{
char **env, *p;
ssize_t e, elen, l;
const struct interface *ifp;
int dhcp, ra;
- dhcp = 0;
- ra = 0;
- if (strcmp(iface->state->reason, "ROUTERADVERT") == 0)
+ dhcp = ra = 0;
+ if (strcmp(reason, "ROUTERADVERT") == 0)
ra = 1;
else
dhcp = 1;
if (options & DHCPCD_DUMPLEASE)
elen = 2;
else
- elen = 8;
+ elen = 10;
/* Make our env */
env = xmalloc(sizeof(char *) * (elen + 1));
e = strlen("interface") + strlen(iface->name) + 2;
env[0] = xmalloc(e);
snprintf(env[0], e, "interface=%s", iface->name);
- e = strlen("reason") + strlen(iface->state->reason) + 2;
+ e = strlen("reason") + strlen(reason) + 2;
env[1] = xmalloc(e);
- snprintf(env[1], e, "reason=%s", iface->state->reason);
+ snprintf(env[1], e, "reason=%s", reason);
if (options & DHCPCD_DUMPLEASE)
goto dumplease;
e--;
}
*--p = '\0';
+ if (iface->state->new || iface->ras) {
+ env[8] = strdup("if_up=true");
+ env[9] = strdup("if_down=false");
+ } else {
+ env[8] = strdup("if_up=false");
+ env[9] = strdup("if_down=true");
+ }
if (*iface->state->profile) {
e = strlen("profile=") + strlen(iface->state->profile) + 2;
env[elen] = xmalloc(e);
e = ipv6rs_env(NULL, NULL, iface);
if (e > 0) {
env = xrealloc(env, sizeof(char *) * (elen + e + 1));
- elen += ipv6rs_env(env + elen, "new", iface);
+ elen += ipv6rs_env(env + elen, NULL, iface);
}
}
return elen;
}
-int
-send_interface(int fd, const struct interface *iface)
+static int
+send_interface1(int fd, const struct interface *iface, const char *reason)
{
char **env, **ep, *s;
ssize_t elen;
int retval;
retval = 0;
- make_env(iface, &env);
+ make_env(iface, reason, &env);
elen = arraytostr((const char *const *)env, &s);
iov[0].iov_base = &elen;
iov[0].iov_len = sizeof(ssize_t);
}
int
-run_script(const struct interface *iface)
+send_interface(int fd, const struct interface *iface)
+{
+ int retval = 0;
+ if (send_interface1(fd, iface, iface->state->reason) == -1)
+ retval = -1;
+ if (iface->ras) {
+ if (send_interface1(fd, iface, "ROUTERADVERT") == -1)
+ retval = -1;
+ }
+ return retval;
+}
+
+int
+run_script_reason(const struct interface *iface, const char *reason)
{
char *const argv[2] = { UNCONST(iface->state->options->script), NULL };
char **env = NULL, **ep;
strcmp(iface->state->options->script, "/dev/null") == 0)
return 0;
+ if (reason == NULL)
+ reason = iface->state->reason;
syslog(LOG_DEBUG, "%s: executing `%s', reason %s",
- iface->name, argv[0], iface->state->reason);
+ iface->name, argv[0], reason);
/* Make our env */
- elen = make_env(iface, &env);
+ elen = make_env(iface, reason, &env);
env = xrealloc(env, sizeof(char *) * (elen + 2));
/* Add path to it */
path = getenv("PATH");
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2009 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#include "net.h"
int send_interface(int, const struct interface *);
-int run_script(const struct interface *);
+int run_script_reason(const struct interface *, const char *);
void build_routes(void);
int configure(struct interface *);
int route_deleted(const struct rt *);
+
+#define run_script(ifp) run_script_reason(ifp, (ifp)->state->reason);
#endif
add_resolv_conf()
{
- local x= conf="$signature$NL" i=${new_ra_count:-0} ra=
+ local x= conf="$signature$NL" i=${ra_count:-0} ra=
while [ $i -ne 0 ]; do
- eval ra=\$new_ra${i}_rdnss
+ eval ra=\$ra${i}_rdnss
new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$ra"
- eval ra=\$new_ra${i}_dnssl
+ eval ra=\$ra${i}_dnssl
new_domain_search="$new_domain_search${new_domain_search:+ }$ra"
i=$(($i - 1))
done
signature_end="$signature_base_end $from $interface"
state_dir=/var/run/dhcpcd
-if_up=false
-if_down=false
-case "$reason" in
-BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC) if_up=true;;
-PREINIT|EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP) if_down=true;;
-esac
-
if [ "$reason" = ROUTERADVERT ]; then
if_suffix=":ra"
- [ "$new_ra_count" != 0 ] && if_up=true
else
if_suffix=
fi
if (iface->ras) {
ipv6rs_free(iface);
iface->ras = NULL;
- iface->state->reason = "ROUTERADVERT";
- run_script(iface);
+ run_script_reason(iface, "ROUTERADVERT");
}
if (strcmp(iface->state->reason, "RELEASE") != 0)
drop_dhcp(iface, "STOP");
if (iface->ras) {
ipv6rs_free(iface);
iface->ras = NULL;
- iface->state->reason = "ROUTERADVERT";
- run_script(iface);
+ run_script_reason(iface, "ROUTERADVERT");
}
drop_dhcp(iface, "NOCARRIER");
}
} else if (strcmp(*argv, "--getinterfaces") == 0) {
len = 0;
if (argc == 1) {
- for (ifp = ifaces; ifp; ifp = ifp->next)
+ for (ifp = ifaces; ifp; ifp = ifp->next) {
len++;
+ if (ifp->ras)
+ len++;
+ }
len = write(fd->fd, &len, sizeof(len));
if (len != sizeof(len))
return -1;
opt = 0;
while (argv[++opt] != NULL) {
for (ifp = ifaces; ifp; ifp = ifp->next)
- if (strcmp(argv[opt], ifp->name) == 0)
+ if (strcmp(argv[opt], ifp->name) == 0) {
len++;
+ if (ifp->ras)
+ len++;
+ }
}
len = write(fd->fd, &len, sizeof(len));
if (len != sizeof(len))
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
sill = (si->state->new->cookie == htonl(MAGIC_COOKIE));
till = (ti->state->new->cookie == htonl(MAGIC_COOKIE));
if (!sill && till)
- return -1;
- if (sill && !till)
return 1;
+ if (sill && !till)
+ return -1;
}
/* Then carrier status. */
if (si->carrier > ti->carrier)
rao->type = ndo->nd_opt_type;
rao->option = opt;
}
- if (lifetime == ~0U) {
- rao->expire.tv_sec = 0;
- rao->expire.tv_usec = 0;
- } else {
+ if (lifetime == ~0U)
+ timerclear(&rao->expire);
+ else {
expire.tv_sec = lifetime;
expire.tv_usec = 0;
timeradd(&rap->received, &expire, &rao->expire);
}
ipv6rs_sort(ifp);
-
- if (options & DHCPCD_TEST)
- ifp->state->reason = "TEST";
- else
- ifp->state->reason = "ROUTERADVERT";
- run_script(ifp);
+ run_script_reason(ifp, options & DHCPCD_TEST ? "TEST" : "ROUTERADVERT");
if (options & DHCPCD_TEST)
exit(EXIT_SUCCESS);
setvar(&env, prefix, buffer, rap->sfrom);
}
l++;
+
for (rao = rap->options; rao; rao = rao->next) {
- if (rao->expire.tv_sec != 0 &&
- rao->expire.tv_usec != 0 &&
- timercmp(&now, &rao->expire, >))
- {
- syslog(LOG_INFO, "%s: %s: expired option %d",
- ifp->name, rap->sfrom, rao->type);
- continue;
- }
if (rao->option == NULL)
continue;
if (env == NULL) {
{
struct interface *ifp;
struct ra *rap, *ran, *ral;
+ struct ra_opt *rao, *raol, *raon;
struct timeval now, lt, expire, next;
int expired;
uint32_t expire_secs;
lt.tv_usec = 0;
timeradd(&rap->received, <, &expire);
if (timercmp(&now, &expire, >)) {
+ syslog(LOG_INFO, "%s: %s: expired Router Advertisement",
+ ifp->name, rap->sfrom);
expired = 1;
if (ral)
ral->next = ran;
ifp->ras = ran;
ipv6rs_free_opts(rap);
free(rap);
- } else {
- timersub(&now, &expire, <);
+ continue;
+ }
+ timersub(&expire, &now, <);
+ if (!timerisset(&next) || timercmp(&next, <, >))
+ next = lt;
+
+ for (rao = rap->options;
+ rao && (raon = rao->next);
+ raol = rao, rao = raon)
+ {
+ if (!timerisset(&rao->expire))
+ continue;
+ if (timercmp(&now, &rao->expire, >)) {
+ syslog(LOG_INFO,
+ "%s: %s: expired option %d",
+ ifp->name, rap->sfrom, rao->type);
+ if (raol)
+ raol = raon;
+ else
+ rap->options = raon;
+ continue;
+ }
+ timersub(&rao->expire, &now, <);
if (!timerisset(&next) || timercmp(&next, <, >))
next = lt;
}
if (timerisset(&next))
add_timeout_tv(&next, ipv6rs_expire, ifp);
-
- if (expired) {
- ifp->state->reason = "ROUTERADVERT";
- run_script(ifp);
- }
-
+ if (expired)
+ run_script_reason(ifp, "ROUTERADVERT");
}
int