From: Roy Marples Date: Wed, 16 Apr 2008 09:51:20 +0000 (+0000) Subject: Remove the .info file and now set environment vars in the same vein as dhclient.... X-Git-Tag: v4.0.2~486 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcab79de5ef939f5af004048748fa3dae8cd00f4;p=thirdparty%2Fdhcpcd.git Remove the .info file and now set environment vars in the same vein as dhclient. This allows similar scripts to be used. --- diff --git a/Makefile b/Makefile index 092ef7ce..a919890a 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,13 @@ SRCS+= ${SRC_IF} ${SRC_SOCKET} SCRIPT= dhcpcd.sh MAN= dhcpcd.8 -VERSION= 3.3.0-alpha1 -CLEANFILES= dhcpcd.8 +VERSION= 4.0.0-alpha1 +CLEANFILES= dhcpcd.sh dhcpcd.8 BINDIR= ${PREFIX}/sbin SYSCONFDIR?= ${PREFIX}/etc -.SUFFIXES: .in +.SUFFIXES: .in .sh.in MK= mk include ${MK}/prog.mk @@ -27,3 +27,7 @@ LDADD+= ${LIBRT} .in: ${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g; s:@DBDIR@:${DBDIR}:g' $< > $@ + +.sh.in.sh: + ${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g' $< > $@ + diff --git a/client.c b/client.c index bab77fcf..66386185 100644 --- a/client.c +++ b/client.c @@ -95,6 +95,7 @@ struct if_state { int options; struct interface *interface; struct dhcp_message *dhcp; + struct dhcp_message *old_dhcp; struct dhcp_lease lease; time_t start; time_t last_sent; @@ -139,8 +140,8 @@ get_dhcp_op(uint8_t type) return NULL; } -static pid_t -daemonise(int *pidfd) +static int +daemonise(struct if_state *state, const struct options *options) { pid_t pid; sigset_t full; @@ -150,6 +151,10 @@ daemonise(int *pidfd) int i; #endif + if (state->options & DHCPCD_DAEMONISED || + !(options->options & DHCPCD_DAEMONISE)) + return 0; + sigfillset(&full); sigprocmask(SIG_SETMASK, &full, &old); @@ -202,13 +207,21 @@ daemonise(int *pidfd) /* Done with the fd now */ if (pid != 0) { - writepid(*pidfd, pid); - close(*pidfd); - *pidfd = -1; + writepid(*state->pidfd, pid); + close(*state->pidfd); + *state->pidfd = -1; } sigprocmask(SIG_SETMASK, &old, NULL); - return pid; + + state->state = STATE_BOUND; + if (pid == 0) { + state->options |= DHCPCD_DAEMONISED; + return 0; + } + + state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED; + return -1; } @@ -316,7 +329,7 @@ static void get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp) { lease->addr.s_addr = dhcp->yiaddr; - if (get_option_addr(&lease->net.s_addr, dhcp, DHCP_NETMASK) == -1) + if (get_option_addr(&lease->net.s_addr, dhcp, DHCP_SUBNETMASK) == -1) lease->net.s_addr = get_netmask(dhcp->yiaddr); if (get_option_uint32(&lease->leasetime, dhcp, DHCP_LEASETIME) != 0) lease->leasetime = DEFAULT_LEASETIME; @@ -372,7 +385,8 @@ get_old_lease(struct if_state *state, const struct options *options) /* Ok, lets use this */ if (IN_LINKLOCAL(dhcp->yiaddr)) { - free(state->dhcp); + free(state->old_dhcp); + state->old_dhcp = state->dhcp; state->dhcp = dhcp; return 0; } @@ -399,7 +413,8 @@ get_old_lease(struct if_state *state, const struct options *options) offset = 0; state->timeout = lease->renewaltime - offset; iface->start_uptime = uptime(); - free(state->dhcp); + free(state->old_dhcp); + state->old_dhcp = state->dhcp; state->dhcp = dhcp; return 0; } @@ -611,11 +626,14 @@ send_message(struct if_state *state, int type, const struct options *options) } static void -drop_config(struct if_state *state, const struct options *options) +drop_config(struct if_state *state, const char *reason, const struct options *options) { - if (!(state->options & DHCPCD_PERSISTENT)) - configure(state->interface, state->dhcp, - &state->lease, options, 0); + configure(state->interface, reason, NULL, state->dhcp, + &state->lease, options, 0); + free(state->old_dhcp); + state->old_dhcp = NULL; + free(state->dhcp); + state->dhcp = NULL; state->lease.addr.s_addr = 0; } @@ -715,9 +733,11 @@ handle_signal(int sig, struct if_state *state, const struct options *options) switch (sig) { case SIGINT: logger(LOG_INFO, "received SIGINT, stopping"); + drop_config(state, "STOP", options); return -1; case SIGTERM: logger(LOG_INFO, "received SIGTERM, stopping"); + drop_config(state, "STOP", options); return -1; case SIGALRM: @@ -750,13 +770,13 @@ handle_signal(int sig, struct if_state *state, const struct options *options) logger (LOG_INFO, "received SIGHUP, releasing lease"); if (!IN_LINKLOCAL(ntohl(lease->addr.s_addr))) { - do_socket(state, SOCKET_OPEN); - state->xid = (uint32_t)random(); - send_message(state, DHCP_RELEASE, options); - do_socket(state, SOCKET_CLOSED); - } - unlink(state->interface->infofile); - return -1; + do_socket(state, SOCKET_OPEN); + state->xid = (uint32_t)random(); + send_message(state, DHCP_RELEASE, options); + do_socket(state, SOCKET_CLOSED); + } + drop_config(state, "RELEASE", options); + return -1; default: logger (LOG_ERR, @@ -772,96 +792,80 @@ handle_timeout(struct if_state *state, const struct options *options) { struct dhcp_lease *lease = &state->lease; struct interface *iface = state->interface; + int gotlease = -1; + char *reason = NULL; /* No NAK, so reset the backoff */ state->nakoff = 1; if (state->state == STATE_INIT && state->xid != 0) { - if (iface->addr.s_addr != 0 && - !IN_LINKLOCAL(ntohl(iface->addr.s_addr)) && - !(state->options & DHCPCD_INFORM)) - { - logger(LOG_ERR, "lost lease"); - if (!(state->options & DHCPCD_PERSISTENT)) - drop_config(state, options); - } else if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr))) - logger(LOG_ERR, "timed out"); + if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr))) { + if (iface->addr.s_addr != 0 && + !(state->options & DHCPCD_INFORM)) + logger(LOG_ERR, "lost lease"); + else + logger(LOG_ERR, "timed out"); + } do_socket(state, SOCKET_CLOSED); if (options->options & DHCPCD_INFORM) return -1; - if (!(state->options & DHCPCD_TEST) && - (state->options & DHCPCD_IPV4LL || - state->options & DHCPCD_LASTLEASE)) + if (state->options & DHCPCD_IPV4LL || + state->options & DHCPCD_LASTLEASE) { errno = 0; - if (get_old_lease(state, options) != 0) { - if (errno == EINTR) - return 0; - if (state->options & DHCPCD_LASTLEASE) - return -1; + gotlease = get_old_lease(state, options); + if (gotlease == 0) { + if (!(state->options & DHCPCD_DAEMONISED)) + reason = "REBOOT"; } else if (errno == EINTR) return 0; } #ifdef ENABLE_IPV4LL - if (!(state->options & DHCPCD_TEST) && - state->options & DHCPCD_IPV4LL && - (!lease->addr.s_addr || - (!IN_LINKLOCAL(ntohl(lease->addr.s_addr)) && - !(state->options & DHCPCD_LASTLEASE)))) - { + if (state->options & DHCPCD_IPV4LL && gotlease != -1) { logger(LOG_INFO, "probing for an IPV4LL address"); - if (ipv4ll_get_address(iface, lease) == -1) { - if (!(state->options & DHCPCD_DAEMONISED)) - return -1; - - /* start over */ - state->xid = 0; - return 0; - } - state->timeout = lease->renewaltime; - if (!state->dhcp) + errno = 0; + gotlease = ipv4ll_get_address(iface, lease); + if (gotlease != 0) { + if (errno == EINTR) + return 0; + } else { + free(state->old_dhcp); + state->old_dhcp = state->dhcp; state->dhcp = xmalloc(sizeof(*state->dhcp)); - memset(state->dhcp, 0, sizeof(*state->dhcp)); - state->dhcp->yiaddr = lease->addr.s_addr; - state->dhcp->options[0] = DHCP_END; + memset(state->dhcp, 0, sizeof(*state->dhcp)); + state->dhcp->yiaddr = lease->addr.s_addr; + state->dhcp->options[0] = DHCP_END; + reason = "IPV4LL"; + } } #endif - if (lease->addr.s_addr) { - if (!(state->options & DHCPCD_DAEMONISED) && - IN_LINKLOCAL(ntohl(lease->addr.s_addr))) - logger(LOG_WARNING, "using IPV4LL address %s", - inet_ntoa(lease->addr)); - if (configure(iface, state->dhcp, lease, options, 1) != 0 && - !(state->options & DHCPCD_DAEMONISED)) - return -1; - - state->state = STATE_BOUND; - if (!(state->options & DHCPCD_DAEMONISED) && - options->options & DHCPCD_DAEMONISE) { - switch (daemonise(state->pidfd)) { - case -1: - return -1; - case 0: - state->options |= DHCPCD_DAEMONISED; - return 0; - default: - state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED; - return -1; - } - } - - state->timeout = lease->renewaltime; - state->xid = 0; - return 0; + if (gotlease != 0) { + if (state->dhcp && !IN_LINKLOCAL(state->dhcp->yiaddr)) + reason = "EXPIRE"; + if (!reason) + reason = "FAIL"; + drop_config(state, reason, options); + if (!(state->options & DHCPCD_DAEMONISED)) + return -1; } - - if (!(state->options & DHCPCD_DAEMONISED)) - return -1; + if (!(state->options & DHCPCD_DAEMONISED) && + IN_LINKLOCAL(ntohl(lease->addr.s_addr))) + logger(LOG_WARNING, "using IPV4LL address %s", + inet_ntoa(lease->addr)); + if (!reason) + reason = "TIMEOUT"; + if (configure(iface, reason, + state->dhcp, state->old_dhcp, + lease, options, 1) == 0) + daemonise(state, options); + state->timeout = lease->renewaltime; + state->xid = 0; + return 0; } switch (state->state) { @@ -942,6 +946,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op uint8_t type; struct timeval tv; int r; + const char *reason = NULL; if (get_option_uint8(&type, dhcp, DHCP_MESSAGETYPE) == -1) { logger(LOG_ERR, "no DHCP type in message"); @@ -991,9 +996,9 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op logger(LOG_INFO, "offered %s", addr); free(addr); - if (options->options & DHCPCD_TEST) { - write_info(iface, dhcp, lease, options, 0); - errno = 0; + if (state->options & DHCPCD_TEST) { + exec_script(options->script, iface->name, + "TEST", dhcp, NULL); return -1; } @@ -1061,11 +1066,11 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op } #endif - if (state->dhcp) - free(state->dhcp); + free(state->old_dhcp); + state->old_dhcp = state->dhcp; state->dhcp = dhcp; *dhcpp = NULL; - + if (options->options & DHCPCD_INFORM) { if (options->request_address.s_addr != 0) lease->addr.s_addr = options->request_address.s_addr; @@ -1078,6 +1083,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op if (state->timeout == 0) state->timeout = DEFAULT_LEASETIME; state->state = STATE_INIT; + reason = "INFORM"; } else { if (gettimeofday(&tv, NULL) == 0) lease->leasedfrom = tv.tv_sec; @@ -1135,25 +1141,21 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, const struct op } state->xid = 0; - if (configure(iface, dhcp, &state->lease, options, 1) != 0) + if (!reason) { + if (state->old_dhcp) { + if (state->old_dhcp->yiaddr == dhcp->yiaddr && + lease->server.s_addr) + reason = "RENEW"; + else + reason = "REBIND"; + } else + reason = "BOUND"; + } + r = configure(iface, reason, dhcp, state->old_dhcp, + &state->lease, options, 1); + if (r != 0) return -1; - - if (!(state->options & DHCPCD_DAEMONISED) && - state->options & DHCPCD_DAEMONISE) - { - switch (daemonise(state->pidfd)) { - case 0: - state->options |= DHCPCD_DAEMONISED; - return 0; - case -1: - return -1; - default: - state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED; - return -1; - } - } - - return 0; + return daemonise(state, options); } static int @@ -1261,7 +1263,6 @@ dhcp_run(const struct options *options, int *pidfd) eexit: if (iface) { do_socket(state, SOCKET_CLOSED); - drop_config(state, options); free_routes(iface->routes); free(iface->clientid); free(iface); @@ -1274,6 +1275,7 @@ eexit: unlink(options->pidfile); free(state->buffer); free(state->dhcp); + free(state->old_dhcp); free(state); } diff --git a/config.h b/config.h index 20354106..f8bb018c 100644 --- a/config.h +++ b/config.h @@ -64,7 +64,6 @@ # define DBDIR "/var/db" #endif #define LEASEFILE DBDIR "/" PACKAGE "-%s.lease" -#define INFOFILE DBDIR "/" PACKAGE "-%s.info" #define DUIDFILE DBDIR "/" PACKAGE ".duid" #endif diff --git a/configure.c b/configure.c index 215ea2fe..abd11bbf 100644 --- a/configure.c +++ b/configure.c @@ -45,10 +45,11 @@ #include "net.h" #include "signal.h" -static int -exec_script(const char *cmd, const char *arg1, const char *arg2) +int +exec_script(const char *script, const char *iface, const char *reason, + const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo) { - char *const argv[4] = { (char *)cmd, (char *)arg1, (char *)arg2, NULL}; + char *const argv[2] = { (char *)script, NULL }; int ret = 0; pid_t pid; pid_t wpid; @@ -56,7 +57,7 @@ exec_script(const char *cmd, const char *arg1, const char *arg2) sigset_t full; sigset_t old; - logger(LOG_DEBUG, "exec `%s' `%s' `%s'", cmd, arg1, arg2); + logger(LOG_DEBUG, "exec `%s'", script); /* OK, we need to block signals */ sigfillset(&full); @@ -79,8 +80,14 @@ exec_script(const char *cmd, const char *arg1, const char *arg2) signal_reset(); #endif sigprocmask(SIG_SETMASK, &old, NULL); - execvp(cmd, argv); - logger(LOG_ERR, "%s: %s", cmd, strerror(errno)); + if (dhcpo) + configure_env("old", dhcpo); + if (dhcpn) + configure_env("new", dhcpn); + setenv("interface", iface, 1); + setenv("reason", reason, 1); + execvp(script, argv); + logger(LOG_ERR, "%s: %s", script, strerror(errno)); _exit(111); /* NOTREACHED */ } @@ -99,6 +106,8 @@ exec_script(const char *cmd, const char *arg1, const char *arg2) logger(LOG_ERR, "waitpid: %s", strerror(errno)); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + if (WIFSIGNALED(status)) + logger(LOG_ERR, "script signaled"); if (WIFEXITED(status)) ret = WEXITSTATUS(status); else @@ -336,116 +345,9 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, return retval; } -static void -print_clean(FILE *f, const char *name, const char *value) -{ - fprintf(f, "%s=", name); - if (value) - write_string(f, (const uint8_t*)value, strlen(value)); - fputc('\n', f); -} - -int -write_info(const struct interface *iface, const struct dhcp_message *dhcp, - const struct dhcp_lease *lease, const struct options *options, - int overwrite) -{ - FILE *f; - struct rt *rt, *ort; - struct stat sb; - struct in_addr addr; - int doneone; - - if (options->options & DHCPCD_TEST) - f = stdout; - else { - if (!overwrite && stat(iface->infofile, &sb) == 0) - return 0; - - if ((f = fopen(iface->infofile, "w")) == NULL) - return -1; - } - - if (dhcp->yiaddr) { - fprintf(f, "IPADDR=%s\n", inet_ntoa(iface->addr)); - fprintf(f, "NETMASK=%s\n", inet_ntoa(iface->net)); - addr.s_addr = dhcp->yiaddr & iface->net.s_addr; - fprintf(f, "NETWORK=%s\n", inet_ntoa(addr)); - if (get_option_addr(&addr.s_addr, dhcp, DHCP_BROADCAST) == -1) - addr.s_addr = dhcp->yiaddr | ~iface->net.s_addr; - fprintf(f, "BROADCAST=%s\n", inet_ntoa(addr)); - - ort = get_option_routes(dhcp); - doneone = 0; - fprintf(f, "ROUTES="); - for (rt = ort; rt; rt = rt->next) { - if (rt->dest.s_addr == 0) - continue; - if (doneone) - fprintf(f, "\\ "); - else - doneone = 1; - fprintf(f, "%s", inet_ntoa(rt->dest)); - fprintf(f, ",%s", inet_ntoa(rt->net)); - fprintf(f, ",%s", inet_ntoa(rt->gate)); - } - fputc('\n', f); - - doneone = 0; - fprintf(f, "GATEWAYS="); - for (rt = ort; rt; rt = rt->next) { - if (rt->dest.s_addr != 0) - continue; - if (doneone) - fprintf(f, "\\ "); - else - doneone = 1; - fprintf(f, "%s", inet_ntoa(rt->gate)); - } - fputc('\n', f); - free_routes(ort); - } - - write_options(f, dhcp); - -/* FIXME - if (dhcp->fqdn) { - fprintf(f, "FQDNFLAGS='%u'\n", dhcp->fqdn->flags); - fprintf(f, "FQDNRCODE1='%u'\n", dhcp->fqdn->r1); - fprintf(f, "FQDNRCODE2='%u'\n", dhcp->fqdn->r2); - print_clean(f, "FQDNHOSTNAME", dhcp->fqdn->name); - } -*/ - if (dhcp->siaddr) { - addr.s_addr = dhcp->siaddr; - fprintf(f, "DHCPSID=%s\n", inet_ntoa(addr)); - } - if (dhcp->servername[0]) - print_clean(f, "DHCPSNAME", (const char *)dhcp->servername); - - if (!(options->options & DHCPCD_INFORM) && dhcp->yiaddr) { - if (!(options->options & DHCPCD_TEST)) - fprintf(f, "LEASEDFROM=%u\n", lease->leasedfrom); - fprintf(f, "LEASETIME=%u\n", lease->leasetime); - fprintf(f, "RENEWALTIME=%u\n", lease->renewaltime); - fprintf(f, "REBINDTIME=%u\n", lease->rebindtime); - } - print_clean(f, "INTERFACE", iface->name); - print_clean(f, "CLASSID", options->classid); - if (iface->clientid_len > 0) { - fprintf(f, "CLIENTID=%s\n", - hwaddr_ntoa(iface->clientid, iface->clientid_len)); - } - fprintf(f, "DHCPCHADDR=%s\n", - hwaddr_ntoa(iface->hwaddr, iface->hwlen)); - - if (!(options->options & DHCPCD_TEST)) - fclose(f); - return 0; -} - int -configure(struct interface *iface, const struct dhcp_message *dhcp, +configure(struct interface *iface, const char *reason, + const struct dhcp_message *dhcp, const struct dhcp_message *old, const struct dhcp_lease *lease, const struct options *options, int up) { @@ -463,7 +365,7 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, else { addr.s_addr = dhcp->yiaddr; /* Ensure we have all the needed values */ - if (get_option_addr(&net.s_addr, dhcp, DHCP_NETMASK) == -1) + if (get_option_addr(&net.s_addr, dhcp, DHCP_SUBNETMASK) == -1) net.s_addr = get_netmask(addr.s_addr); if (get_option_addr(&brd.s_addr, dhcp, DHCP_BROADCAST) == -1) brd.s_addr = addr.s_addr | ~net.s_addr; @@ -471,13 +373,6 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, /* If we aren't up, then reset the interface as much as we can */ if (!up) { - /* If we haven't created an info file, do so now */ - if (!lease->frominfo) { - if (write_info(iface, dhcp, lease, options, 0) == -1) - logger(LOG_ERR, "write_info: %s", - strerror(errno)); - } - /* Only reset things if we had set them before */ if (iface->addr.s_addr != 0) { if (!(options->options & DHCPCD_KEEPADDRESS)) { @@ -495,7 +390,7 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, } } - exec_script(options->script, iface->infofile, "down"); + exec_script(options->script, iface->name, reason, NULL, old); return 0; } @@ -537,10 +432,9 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, iface->net.s_addr = net.s_addr; if (!lease->frominfo) - write_info(iface, dhcp, lease, options, 1); if (write_lease(iface, dhcp) == -1) logger(LOG_ERR, "write_lease: %s", strerror(errno)); - exec_script(options->script, iface->infofile, up ? "new" : "up"); + exec_script(options->script, iface->name, reason, dhcp, old); return 0; } diff --git a/configure.h b/configure.h index 61a89431..d5d30d45 100644 --- a/configure.h +++ b/configure.h @@ -32,9 +32,10 @@ #include "dhcp.h" #include "net.h" -int write_info(const struct interface *, const struct dhcp_message *, - const struct dhcp_lease *, const struct options *, int); -int configure(struct interface *, const struct dhcp_message *, - const struct dhcp_lease *, const struct options *, int); +int exec_script(const char *, const char *, const char *, + const struct dhcp_message *, const struct dhcp_message *); +int configure(struct interface *, const char *, + const struct dhcp_message *, const struct dhcp_message *, + const struct dhcp_lease *, const struct options *, int); #endif diff --git a/dhcp.c b/dhcp.c index 9655f090..25ecb55f 100644 --- a/dhcp.c +++ b/dhcp.c @@ -39,12 +39,16 @@ #define REQUEST (1 << 0) #define UINT8 (1 << 1) #define UINT16 (1 << 2) -#define UINT32 (1 << 3) -#define IPV4 (1 << 4) -#define STRING (1 << 5) -#define ARRAY (1 << 6) -#define RFC3361 (1 << 7) -#define RFC3397 (1 << 8) +#define SINT16 (1 << 3) +#define UINT32 (1 << 4) +#define SINT32 (1 << 5) +#define IPV4 (1 << 6) +#define STRING (1 << 7) +#define PAIR (1 << 8) +#define ARRAY (1 << 9) +#define RFC3361 (1 << 10) +#define RFC3397 (1 << 11) +#define RFC3442 (1 << 12) #define IPV4R IPV4 | REQUEST @@ -55,80 +59,93 @@ struct dhcp_option { }; const struct dhcp_option dhcp_options[] = { - { DHCP_NETMASK, IPV4R, NULL }, - { DHCP_TIMEOFFSET, UINT32, "TIMEOFFSET" }, - { DHCP_ROUTER, IPV4R, NULL }, - { DHCP_TIMESERVER, IPV4, "TIMESERVER" }, - { DHCP_NAMESERVER, IPV4, "NAMESERVER" }, - { DHCP_DNSSERVER, IPV4, "DNSSERVER" }, - { DHCP_LOGSERVER, IPV4, "LOGSERVER" }, - { DHCP_COOKIESERVER, IPV4, "COOKIESERVER" }, - { DHCP_LPRSERVER, IPV4, "LPRSERVER" }, - { DHCP_IMPRESSSERVER, IPV4, "IMPRESSSERVER" }, - { DHCP_RESOURCELOCATIONSERVER, IPV4, "RESOURCELOCATIONSERVER" }, - { DHCP_HOSTNAME, STRING, "HOSTNAME" }, - { DHCP_BOOTFILESIZE, UINT16, "BOOTFILESIZE" }, - { DHCP_MERITDUMPFILE, STRING, "MERITDUMPFILE" }, - { DHCP_DNSDOMAIN, STRING, "DNSDOMAIN" }, - { DHCP_SWAPSERVER, IPV4, "SWAPSERVER" }, - { DHCP_ROOTPATH, STRING, "ROOTPATH" }, - { DHCP_EXTENSIONSPATH, STRING, "EXTENSIONSPATH" }, - - { DHCP_IPFORWARDING, UINT8, "IPFORWARDING" }, - { DHCP_NONLOCALSOURCEROUTING, UINT8, "NONLOCALSOURCEROUTING" }, - { DHCP_POLICYFILTER, IPV4, "POLICYFILTER" }, - { DHCP_MAXDGRAMSIZE, UINT16, "MAXDGRAMSIZE" }, - { DHCP_DEFAULTIPTTL, UINT16, "DEFAULTIPTTL" }, - { DHCP_PATHMTUAGINGTIMEOUT, UINT32, "PATHMTUAGINGTIMEOUT" }, - { DHCP_PATHMTUPLATEAUTABLE, UINT16 | ARRAY, "PATHMTUPLATEAUTABLE" }, - - { DHCP_MTU, UINT16, "MTU" }, - { DHCP_ALLSUBNETSLOCAL, UINT8, "ALLSUBNETSLOCAL" }, - { DHCP_BROADCAST, IPV4R, NULL }, - { DHCP_MASKDISCOVERY, UINT8, "MASKDISCOVERY" }, - { DHCP_MASKSUPPLIER, UINT8, "MASKSUPPLIER" }, - { DHCP_ROUTERDISCOVERY, UINT8, "ROUTERDISCOVERY" }, - { DHCP_ROUTERSOLICITATIONADDR, UINT8, "ROUTERSOLICITATIONADDR" }, - { DHCP_STATICROUTE, IPV4R, NULL }, - - { DHCP_TRAILERENCAPSULATION, UINT8, "TRAILERENCAPSULATION" }, - { DHCP_ARPCACHETIMEOUT, UINT32, "ARPCACHETIMEOUT" }, - { DHCP_ETHERNETENCAPSULATION, UINT8, "ETHERNETENCAPSULATION" }, - - { DHCP_TCPDEFAULTTTL, UINT8, "TCPDEFAULTTTL" }, - { DHCP_TCPKEEPALIVEINTERVAL, UINT32, "TCPKEEPALIVEINTERVAL" }, - { DHCP_TCPKEEPALIVEGARBAGE, UINT8, "TCPKEEPALIVEGARBAGE" }, - - { DHCP_NISDOMAIN, IPV4, "NISDOMAIN" }, - { DHCP_NISSERVER, IPV4, "NISSERVER" }, - { DHCP_NTPSERVER, IPV4, "NTPSERVER" }, - { DHCP_VENDORSPECIFICINFO, STRING, "VENDORSPECIFICINFO" }, - { DHCP_NETBIOSNAMESERVER, IPV4, "NETBIOSNAMESERVER" }, - { DHCP_NETBIOSDGRAMSERVER, IPV4, "NETBIOSDGRAMSERVER" }, - { DHCP_NETBIOSNODETYPE, UINT8, "NETBIOSNODETYPE" }, - { DHCP_NETBIOSSCOPE, STRING, "NETBIOSSCOPE" }, - { DHCP_XFONTSERVER, IPV4, "XFONTSERVER" }, - { DHCP_XDISPLAYMANAGER, IPV4, "XDISPLAYMANAGER" }, - { DHCP_NISPLUSDOMAIN, IPV4, "NISPLUSDOMAIN" }, - { DHCP_NISPLUSSERVER, IPV4, "NISPLUSSERVER" }, - { DHCP_MOBILEIPHOMEAGENT, IPV4, "MOBILEIPHOMEAGENT" }, - { DHCP_SMTPSERVER, IPV4, "SMTPSERVER" }, - { DHCP_POP3SERVER, IPV4, "POP3SERVER" }, - { DHCP_NNTPSERVER, IPV4, "NNTPSERVER" }, - { DHCP_WWWSERVER, IPV4, "WWWSERVER" }, - { DHCP_FINGERSERVER, IPV4, "FINGERSERVER" }, - { DHCP_IRCSERVER, IPV4, "IRCSERVER" }, - { DHCP_STREETTALKSERVER, IPV4, "STREETTALKSERVER" }, - { DHCP_STREETTALKDASERVER, IPV4, "STREETTALKDASERVER" }, - - { DHCP_LEASETIME, UINT32, NULL }, - { DHCP_SERVERID, IPV4, "SERVERID" }, - { DHCP_RENEWALTIME, UINT32 | REQUEST, NULL }, - { DHCP_REBINDTIME, UINT32 | REQUEST, NULL }, - - { DHCP_MESSAGE, STRING, NULL}, - { DHCP_DNSSEARCH, STRING | RFC3397, "DNSSEARCH" }, - { DHCP_SIPSERVER, STRING | RFC3361, "SIPSERVER" }, + { 1, IPV4 | REQUEST, "subnet_mask" }, + { 2, UINT32, "time_offset" }, + { 3, IPV4 | ARRAY | REQUEST, "routers" }, + { 4, IPV4 | ARRAY, "time_servers" }, + { 5, IPV4 | ARRAY, "ien116_name_servers" }, + { 6, IPV4 | ARRAY, "domain_name_servers" }, + { 7, IPV4 | ARRAY, "log_servers" }, + { 8, IPV4 | ARRAY, "cookie_servers" }, + { 9, IPV4 | ARRAY, "lpr_servers" }, + { 10, IPV4 | ARRAY, "impress_servers" }, + { 11, IPV4 | ARRAY, "resource_location_servers" }, + { 12, STRING, "host_name" }, + { 13, UINT16, "boot_size" }, + { 14, STRING, "merit_dump" }, + { 15, STRING, "domain_name" }, + { 16, IPV4, "swap_server" }, + { 17, STRING, "root_path" }, + { 18, STRING, "extensions_path" }, + { 19, UINT8, "ip_forwarding" }, + { 20, UINT8, "non_local_source_routing" }, + { 21, IPV4 | ARRAY, "policy_filter" }, + { 22, SINT16, "max_dgram_reassembly" }, + { 23, UINT16, "default_ip_ttl" }, + { 24, UINT32, "path_mtu_aging_timeout" }, + { 25, UINT16 | ARRAY, "path_mtu_plateau_table" }, + { 26, UINT16, "interface_mtu" }, + { 27, UINT8, "all_subnets_local" }, + { 28, IPV4 | REQUEST, "broadcast_address" }, + { 29, UINT8, "perform_mask_discovery" }, + { 30, UINT8, "mask_supplier" }, + { 31, UINT8, "router_discovery" }, + { 32, IPV4, "router_solicitation_address" }, + { 33, IPV4 | ARRAY | REQUEST, "static_routes" }, + { 34, UINT8, "trailer_encapsulation" }, + { 35, UINT32, "arp_cache_timeout" }, + { 36, UINT16, "ieee802_3_encapsulation" }, + { 37, UINT8, "default_tcp_ttl" }, + { 38, UINT32, "tcp_keepalive_interval" }, + { 39, UINT8, "tcp_keepalive_garbage" }, + { 30, STRING, "nis_domain" }, + { 31, IPV4 | ARRAY, "nis_servers" }, + { 32, IPV4 | ARRAY, "ntp_servers" }, + { 43, STRING, "vendor_encapsulated_options" }, + { 44, IPV4 | ARRAY, "netbios_name_servers" }, + { 45, IPV4, "netbios_dd_server" }, + { 46, UINT8, "netbios_node_type" }, + { 47, STRING, "netbios_scope" }, + { 48, IPV4 | ARRAY, "font_servers" }, + { 49, IPV4 | ARRAY, "x_display_manager" }, + { 50, IPV4, "dhcp_requested_address" }, + { 51, UINT32 | REQUEST, "dhcp_lease_time" }, + { 52, UINT8, "dhcp_option_overload" }, + { 53, UINT8, "dhcp_message_type" }, + { 54, IPV4, "dhcp_server_identifier" }, + { 55, UINT8 | ARRAY, "dhcp_parameter_request_list" }, + { 56, STRING, "dhcp_message" }, + { 57, UINT16, "dhcp_max_message_size" }, + { 58, UINT32 | REQUEST, "dhcp_renewal_time" }, + { 59, UINT32 | REQUEST, "dhcp_rebinding_time" }, + { 64, STRING, "nisplus_domain" }, + { 65, IPV4 | ARRAY, "nisplus_servers" }, + { 66, STRING, "tftp_server_name" }, + { 67, STRING, "bootfile_name" }, + { 68, IPV4 | ARRAY, "mobile_ip_home_agent" }, + { 69, IPV4 | ARRAY, "smtp_server" }, + { 70, IPV4 | ARRAY, "pop_server" }, + { 71, IPV4 | ARRAY, "nntp_server" }, + { 72, IPV4 | ARRAY, "www_server" }, + { 73, IPV4 | ARRAY, "finger_server" }, + { 74, IPV4 | ARRAY, "irc_server" }, + { 75, IPV4 | ARRAY, "streettalk_server" }, + { 76, IPV4 | ARRAY, "streettalk_directory_assistance_server" }, + { 77, STRING, "user_class" }, + { 85, IPV4 | ARRAY, "nds_servers" }, + { 86, STRING, "nds_tree_name" }, + { 87, STRING, "nds_context" }, + { 88, STRING | RFC3397, "bcms_controller_names" }, + { 89, IPV4 | ARRAY, "bcms_controller_address" }, + { 91, UINT32, "client_last_transaction_time" }, + { 92, IPV4 | ARRAY, "associated_ip" }, + { 98, STRING, "uap_servers" }, + { 112, IPV4 | ARRAY, "netinfo_server_address" }, + { 113, STRING, "netinfo_server_tag" }, + { 114, STRING, "default_url" }, + { 118, IPV4, "subnet_selection" }, + { 119, STRING | RFC3397, "domain_search" }, + { 121, RFC3442, "classless_static_routes" }, { 0, 0, NULL } }; @@ -693,7 +710,7 @@ make_message(struct dhcp_message **message, lease->addr.s_addr != iface->addr.s_addr && !IN_LINKLOCAL(ntohl(lease->addr.s_addr))) { - PUTADDR(DHCP_ADDRESS, lease->addr); + PUTADDR(DHCP_IPADDRESS, lease->addr); if (lease->server.s_addr) PUTADDR(DHCP_SERVERID, lease->server); } @@ -832,19 +849,29 @@ read_lease(const struct interface *iface) } ssize_t -write_string(FILE *f, const uint8_t *data, ssize_t len) +print_string(char *s, const uint8_t *data, ssize_t len) { uint8_t c; const uint8_t *e; ssize_t bytes = 0; + ssize_t r; - if (!len) - len = *data++; - e = data + len; + c = *data++; + e = data + c; while (data < e) { c = *data++; if (!isascii(c) || !isprint(c)) { - bytes += fprintf(f, "\\%03o", c); + if (s) { + if (len < 5) { + errno = ENOBUFS; + return -1; + } + r = snprintf(s, len, "\\%03o", c); + len -= r; + bytes += r; + s += r; + } else + bytes += 4; continue; } switch (c) { @@ -853,88 +880,184 @@ write_string(FILE *f, const uint8_t *data, ssize_t len) case '$': /* FALLTHROUGH */ case '`': /* FALLTHROUGH */ case '\\': /* FALLTHROUGH */ - case ' ': /* FALLTHROUGH */ - if (fputc('\\', f)) - bytes++; + if (s) { + if (len < 3) { + errno = ENOBUFS; + return -1; + } + *s++ = '\\'; + len--; + } + bytes++; + break; + } + if (s) { + *s++ = c; + len--; + } + bytes++; + } + + /* NULL */ + if (s) + *s = '\0'; + bytes++; + return bytes; +} + +static ssize_t +print_option(char *s, int type, const uint8_t *data, ssize_t len) +{ + const uint8_t *e, *t; + uint8_t u8; + uint16_t u16; + int16_t s16; + uint32_t u32; + int32_t s32; + struct in_addr addr; + ssize_t bytes = 0; + ssize_t l; + + if (!type || type & STRING) + return print_string(s, data, len); + + if (!s) { + if (type & UINT8) + l = 3; + else if (type & UINT16) + l = 5; + else if (type & SINT16) + l = 6; + else if (type & UINT32) + l = 10; + else if (type & SINT32) + l = 11; + else if (type & IPV4) + l = 16; + else { + errno = EINVAL; + return -1; } - if (fputc(c, f)) + return (l + 1) * *data; + } + + l = *data++; + t = data; + e = data + l; + while (data < e) { + if (data != t) { + *s++ = ' '; bytes++; + len--; + } + if (type & UINT8) { + l = snprintf(s, len, "%d", *data); + data++; + } else if (type & UINT16) { + memcpy(&u16, data, sizeof(u16)); + u16 = ntohs(u16); + l = snprintf(s, len, "%d", u16); + data += sizeof(u16); + } else if (type & SINT16) { + memcpy(&s16, data, sizeof(s16)); + s16 = ntohs(s16); + l = snprintf(s, len, "%d", s16); + data += sizeof(s16); + } else if (type & UINT32) { + memcpy(&u32, data, sizeof(u32)); + u32 = ntohl(u32); + l = snprintf(s, len, "%d", u32); + data += sizeof(u32); + } else if (type & SINT32) { + memcpy(&s32, data, sizeof(s32)); + s32 = ntohl(s32); + l = snprintf(s, len, "%d", s32); + data += sizeof(s32); + } else if (type & IPV4) { + memcpy(&addr.s_addr, data, sizeof(addr.s_addr)); + l = snprintf(s, len, "%s", inet_ntoa(addr)); + data += sizeof(addr.s_addr); + } + len -= l; + bytes += l; + s += l; } + return bytes; } -ssize_t -write_options(FILE *f, const struct dhcp_message *dhcp) +static int +_setenv(const char *prefix, const char *var, const char *value) { - uint8_t i; + size_t len = strlen(prefix) + strlen(var) + 3; + char *name = xmalloc(len); + int r; + + snprintf(name, len, "%s_%s", prefix, var); + if (value) + r = setenv(name, value, 1); + else + r = unsetenv(name); + free(name); + return r; +} + +int +configure_env(const char *prefix, const struct dhcp_message *dhcp) +{ + int i; const uint8_t *p, *e, *t; uint32_t u32; uint16_t u16; uint8_t u8; struct in_addr addr; - ssize_t retval = 0; - - for (i = 0; i < sizeof(dhcp_options) / sizeof(dhcp_options[0]); i++) { - if (!dhcp_options[i].var) - continue; - - retval += fprintf(f, "%s=", dhcp_options[i].var); - - /* Unknown type, so just print escape codes */ - if (dhcp_options[i].type == STRING) { - p = get_option(dhcp, dhcp_options[i].option); - if (p) - retval += write_string(f, p, 0); + struct in_addr net; + struct in_addr brd; + char *val; + const struct dhcp_option *opt; + ssize_t len; + char cidr[4]; + + if (dhcp->yiaddr) { + /* Set some useful variables that we drive from the DHCP + * message but are not necessarily in the options */ + addr.s_addr = dhcp->yiaddr; + _setenv(prefix, "ip_address", inet_ntoa(addr)); + if (get_option_addr(&net.s_addr, dhcp, DHCP_SUBNETMASK) == -1) { + net.s_addr = get_netmask(addr.s_addr); + _setenv(prefix, "subnet_mask", inet_ntoa(net)); } - - if ((dhcp_options[i].type & IPV4 || - dhcp_options[i].type & ARRAY) && - (p = get_option(dhcp, dhcp_options[i].option))) - { - u8 = *p++; - t = p; - e = p + u8; - while (p < e) { - if (p != t) - retval += fprintf(f, "\\ "); - if (dhcp_options[i].type & UINT8) { - retval += fprintf(f, "%d", *p); - p++; - } else if (dhcp_options[i].type & UINT16) { - memcpy(&u16, p, sizeof(u16)); - u16 = ntohs(u16); - retval += fprintf(f, "%d", *p); - p += sizeof(u16); - } else if (dhcp_options[i].type & UINT32) { - memcpy(&u32, p, sizeof(u32)); - u32 = ntohl(u32); - retval += fprintf(f, "%d", *p); - p += sizeof(u32); - } else if (dhcp_options[i].type & IPV4) { - memcpy(&addr.s_addr, p, - sizeof(addr.s_addr)); - retval += fprintf(f, "%s", - inet_ntoa(addr)); - p += sizeof(addr.s_addr); - } else - /* Sanity check */ - p = e; - } + i = inet_ntocidr(net); + snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net)); + _setenv(prefix, "subnet_cidr", cidr); + if (get_option_addr(&brd.s_addr, dhcp, DHCP_BROADCAST) == -1) { + brd.s_addr = addr.s_addr | ~net.s_addr; + _setenv(prefix, "broadcast_address", inet_ntoa(net)); } + addr.s_addr = dhcp->yiaddr & net.s_addr; + _setenv(prefix, "network_address", inet_ntoa(addr)); - if (dhcp_options[i].type & UINT32) { - if (get_option_uint32(&u32, dhcp, - dhcp_options[i].option) == 0) - retval += fprintf(f, "%d", u32); - } + } else { + _setenv(prefix, "ip_address", NULL); + _setenv(prefix, "subnet_cidr", NULL); + _setenv(prefix, "network_address", NULL); + } - if (dhcp_options[i].type & UINT16) { - if (get_option_uint16(&u16, dhcp, - dhcp_options[i].option) == 0) - retval += fprintf(f, "%d", u16); + for (i = 0; i < sizeof(dhcp_options) / sizeof(dhcp_options[0]); i++) { + opt = &dhcp_options[i]; + if (!opt->var) + continue; + val = NULL; + p = get_option(dhcp, opt->option); + if (p) { + len = print_option(NULL, opt->type, p, 0); + if (len < 0) + return -1; + val = xmalloc(len); + print_option(val, opt->type, p, len); } - - retval += fprintf(f, "\n"); + _setenv(prefix, opt->var, val); + free(val); } - return retval; + return 0; } diff --git a/dhcp.h b/dhcp.h index 879cff72..20e8ca17 100644 --- a/dhcp.h +++ b/dhcp.h @@ -65,56 +65,17 @@ enum DHCP_OPTIONS { DHCP_PAD = 0, - DHCP_NETMASK = 1, - DHCP_TIMEOFFSET = 2, + DHCP_SUBNETMASK = 1, DHCP_ROUTER = 3, - DHCP_TIMESERVER = 4, - DHCP_NAMESERVER = 5, DHCP_DNSSERVER = 6, - DHCP_LOGSERVER = 7, - DHCP_COOKIESERVER = 8, - DHCP_LPRSERVER = 9, - DHCP_IMPRESSSERVER = 10, - DHCP_RESOURCELOCATIONSERVER = 11, DHCP_HOSTNAME = 12, - DHCP_BOOTFILESIZE = 13, - DHCP_MERITDUMPFILE = 14, DHCP_DNSDOMAIN = 15, - DHCP_SWAPSERVER = 16, - DHCP_ROOTPATH = 17, - DHCP_EXTENSIONSPATH = 18, - DHCP_IPFORWARDING = 19, - DHCP_NONLOCALSOURCEROUTING = 20, - DHCP_POLICYFILTER = 21, - DHCP_MAXDGRAMSIZE = 22, - DHCP_DEFAULTIPTTL = 23, - DHCP_PATHMTUAGINGTIMEOUT = 24, - DHCP_PATHMTUPLATEAUTABLE = 25, - DHCP_MTU = 26, - DHCP_ALLSUBNETSLOCAL = 27, DHCP_BROADCAST = 28, - DHCP_MASKDISCOVERY = 29, - DHCP_MASKSUPPLIER = 30, - DHCP_ROUTERDISCOVERY = 31, - DHCP_ROUTERSOLICITATIONADDR = 32, DHCP_STATICROUTE = 33, - DHCP_TRAILERENCAPSULATION = 34, - DHCP_ARPCACHETIMEOUT = 35, - DHCP_ETHERNETENCAPSULATION = 36, - DHCP_TCPDEFAULTTTL = 37, - DHCP_TCPKEEPALIVEINTERVAL = 38, - DHCP_TCPKEEPALIVEGARBAGE = 39, DHCP_NISDOMAIN = 40, DHCP_NISSERVER = 41, DHCP_NTPSERVER = 42, - DHCP_VENDORSPECIFICINFO = 43, - DHCP_NETBIOSNAMESERVER = 44, - DHCP_NETBIOSDGRAMSERVER = 45, - DHCP_NETBIOSNODETYPE = 46, - DHCP_NETBIOSSCOPE = 47, - DHCP_XFONTSERVER = 48, - DHCP_XDISPLAYMANAGER = 49, - DHCP_ADDRESS = 50, + DHCP_IPADDRESS = 50, DHCP_LEASETIME = 51, DHCP_OPTIONSOVERLOADED = 52, DHCP_MESSAGETYPE = 53, @@ -126,21 +87,9 @@ enum DHCP_OPTIONS DHCP_REBINDTIME = 59, DHCP_CLASSID = 60, DHCP_CLIENTID = 61, - DHCP_NISPLUSDOMAIN = 64, - DHCP_NISPLUSSERVER = 65, - DHCP_MOBILEIPHOMEAGENT = 68, - DHCP_SMTPSERVER = 69, - DHCP_POP3SERVER = 70, - DHCP_NNTPSERVER = 71, - DHCP_WWWSERVER = 72, - DHCP_FINGERSERVER = 73, - DHCP_IRCSERVER = 74, - DHCP_STREETTALKSERVER = 75, - DHCP_STREETTALKDASERVER = 76, DHCP_USERCLASS = 77, /* RFC 3004 */ DHCP_FQDN = 81, DHCP_DNSSEARCH = 119, /* RFC 3397 */ - DHCP_SIPSERVER = 120, /* RFC 3361 */ DHCP_CSR = 121, /* RFC 3442 */ DHCP_MSCSR = 249, /* MS code for RFC 3442 */ DHCP_END = 255 @@ -221,6 +170,8 @@ int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t); int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t); struct rt *get_option_routes(const struct dhcp_message *); struct rt *decode_rfc3442(const uint8_t *); +int configure_env(const char *, const struct dhcp_message *); + ssize_t make_message(struct dhcp_message **, const struct interface *, const struct dhcp_lease *, uint32_t, uint8_t, const struct options *); @@ -228,7 +179,4 @@ int valid_dhcp_packet(unsigned char *); ssize_t write_lease(const struct interface *, const struct dhcp_message *); struct dhcp_message *read_lease(const struct interface *iface); - -ssize_t write_string(FILE *f, const uint8_t *, ssize_t); -ssize_t write_options(FILE *f, const struct dhcp_message *); #endif diff --git a/dhcpcd.8.in b/dhcpcd.8.in index f32e59ef..f8928b0b 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -284,13 +284,11 @@ Don't request any options beyond what is needed to configure the interface. .It Fl R , -nodns Don't send DNS information to resolvconf or touch .Pa /etc/resolv.conf . -.It Fl T , -test -On receipt of discover messages, simply print the contents of the DHCP -message to the console. -.Nm -will not configure the -.Ar interface , -touch any files or restart any services. +.It Fl T, -test +On receipt of discover messages we just call @SYSCONFDIR@/dhcpcd.sh with the +reason of TEST which echo's the DHCP variables found in the message to the +console. The interface configuration isn't touched and neither are any +configuration files. .It Fl Y , -nonis Don't touch .Pa /etc/yp.conf @@ -331,10 +329,6 @@ Linux Socket Filter, or LPF device on Linux based systems. Bourne shell script that is run when we configure or deconfigure an interface. .It Pa @DBDIR@/dhcpcd.duid Text file that holds the DUID used to identify the host. -.It Pa @DBDIR@/dhcpcd- Ns Ar interface Ns .info -Bourne shell file that holds the DHCP values used in configuring the interface. -This path is passed as the first argument to -.Pa @SYSCONFDIR@/dhcpcd.sh . .It Pa @DBDIR@/dhcpcd- Ns Ar interface Ns .lease The actual DHCP message send by the server. We use this when reading the last lease and use the files mtime as when it was issued. diff --git a/dhcpcd.sh b/dhcpcd.sh deleted file mode 100755 index 2828a16b..00000000 --- a/dhcpcd.sh +++ /dev/null @@ -1,271 +0,0 @@ -#!/bin/sh -# dhcpcd - DHCP client daemon -# Copyright 2006-2008 Roy Marples -# All rights reserved -# -# 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. - -info="$1" -state="$2" - -[ -e "${info}" ] && . "${info}" - -do_hooks() -{ - local x= retval=0 - for x in /etc/dhcpcd/"$1"-hook /etc/dhcpcd/"$1"-hook.d/*; do - if [ -e "${x}" ]; then - . "${x}" - retval=$((${retval} + $?)) - fi - done - return ${retval} -} - -# Try and locate a service pidfile -service_pid() -{ - local service="$1" x= - for x in "${service}".pid \ - "${service}"/pid \ - "${service}"/"${service}".pid; - do - if [ -s "/var/run/${x}" ]; then - echo "/var/run/${x}" - return 0 - fi - done - return 1 -} - -# Try and detect how to handle services so we're pretty -# platform independant -do_service() -{ - local service="$1" action="$2" - shift; shift - - # If restarting check if service is running or not if we can - if [ "${action}" = "restart" ]; then - pidfile=$(service_pid "${service}") - [ -s "${pidfile}" ] || return 0 - kill -0 $(cat "${pidfile}") 2>/dev/null || return 0 - fi - - if type rc-service >/dev/null 2>/dev/null; then - rc-service "${service}" -- --nodeps "${action}" "$@" - elif [ -x /sbin/service ]; then - service "${service}" "${action}" "$@" - elif [ -x /etc/init.d/"${service}" -a -x /sbin/runscript ]; then - /etc/init.d/"${service}" --quiet --nodeps "${action}" "$@" - elif [ -x /etc/init.d/"${service}" ]; then - /etc/init.d/"${service}" "${action}" "$@" - elif [ -x /etc/rc.d/"${service}" ]; then - /etc/rc.d/"${service}" "${action}" "$@" - elif [ -x /etc/rc.d/rc."${service}" ]; then - /etc/rc.d/rc."${service}" "${action}" "$@" - else - echo "Don't know how to interact with services on this platform" >&2 - return 1 - fi -} - -yesno() -{ - [ -z "$1" ] && return 2 - - case "$1" in - [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;; - [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;; - esac - return 2 -} - -save_conf() -{ - if [ -e "$1" ]; then - rm -f "$1"-pre."${INTERFACE}" - mv -f "$1" "$1"-pre."${INTERFACE}" - fi -} - -restore_conf() -{ - [ -e "$1"-pre."${INTERFACE}" ] || return 1 - rm -f "$1" - mv -f "$1"-pre."${INTERFACE}" "$1" -} - -make_mtu() -{ - if [ -n "${MTU}" ]; then - ifconfig "${INTERFACE}" mtu "${MTU}" - fi -} - -make_nis_conf() { - [ -z "${NISDOMAIN}" -a -z "${NISSERVER}" ] && return 0 - local cf=/etc/yp.conf."${INTERFACE}" prefix= x= pidfile= - echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}" - if [ -n "${NISDOMAIN}" ]; then - domainname "${NISDOMAIN}" - if [ -n "${NISSERVER}" ]; then - prefix="domain ${NISDOMAIN} server " - else - echo "domain ${NISDOMAIN} broadcast" >> "${cf}" - fi - else - prefix="ypserver " - fi - for x in ${NISSERVER}; do - echo "${prefix}${x}" >> "${cf}" - done - save_conf /etc/yp.conf - mv -f "${cf}" /etc/yp.conf - pidfile="$(service_pidfile ypbind)" - if [ -s "${pidfile}" ]; then - kill -HUP "${pidfile}" - fi -} - -restore_nis_conf() -{ - restore_conf /etc/yp.conf || return 0 - pidfile="$(service_pidfile ypbind)" - if [ -s "${pidfile}" ]; then - kill -HUP "${pidfile}" - fi -} - -make_ntp_conf() -{ - [ -z "${NTPSERVER}" ] && return 0 - local cf=/etc/ntp.conf."${INTERFACE}" x= - echo "# Generated by dhcpcd for interface ${INTERFACE}" > "${cf}" - echo "restrict default noquery notrust nomodify" >> "${cf}" - echo "restrict 127.0.0.1" >> "${cf}" - for x in ${NTPSERVER}; do - echo "restrict ${x} nomodify notrap noquery" >> "${cf}" - echo "server ${x}" >> "${cf}" - done - if [ ! -e /etc/ntp.conf ]; then - true - elif type cmp >/dev/null 2>&1; then - cmp -s /etc/ntp.conf "${cf}" - elif type diff >/dev/null 2>&1; then - diff -q /etc/ntp.conf "${cf}" >/dev/null - else - false - fi - if [ $? = 0 ]; then - rm -f "${cf}" - else - save_conf /etc/ntp.conf - mv -f "${cf}" /etc/ntp.conf - do_service ntp restart - fi -} - -restore_ntp_conf() -{ - restore_conf /etc/ntp.conf || return 0 - do_service ntp restart -} - -make_resolv_conf() -{ - if [ -z "${DNSSERVER}" -a -z "${DNSDOMAIN}" -a -z "${DNSSEARCH}" ]; then - return 0 - fi - local x= conf="# Generated by dhcpcd for interface ${INTERFACE}\n" - if [ -n "${DNSSEARCH}" ]; then - conf="${conf}search ${DNSSEARCH}\n" - elif [ -n "${DNSDOMAIN}" ]; then - conf="${conf}search ${DNSDOMAIN}\n" - fi - for x in ${DNSSERVER}; do - conf="${conf}nameserver ${x}\n" - done - if type resolvconf >/dev/null 2>&1; then - printf "${conf}" | resolvconf -a "${INTERFACE}" - else - save_conf /etc/resolv.conf - printf "${conf}" > /etc/resolv.conf - do_service nscd restart - fi -} - -restore_resolv_conf() -{ - if type resolvconf >/dev/null 2>&1; then - resolvconf -d "${INTERFACE}" - else - restore_conf /etc/resolv.conf || return 0 - do_service nscd restart - fi -} - -need_hostname() -{ - case "$(hostname)" in - ""|"(none)"|localhost) return 0;; - esac - return 1 -} - -lookup_hostname() -{ - if type host >/dev/null 2>&1; then - host "${IPADDR}" | sed 's/.* domain name pointer \(.*\)./\1/' - elif type dig >/dev/null 2>&1; then - dig +short -x "${IPADDR}" | sed 's/\.$//' - else - return 1 - fi -} - -make_hostname() -{ - if need_hostname; then - local name="${HOSTNAME}" - [ -z "${name}" ] && name="$(lookup_hostname)" - [ -n "${name}" ] && hostname "${name}" - fi -} - -do_hooks enter - -# Don't do anything by default when we go down -if [ "${state}" = "down" ]; then - restore_resolv_conf - restore_nis_conf - restore_ntp_conf - exit $? -fi - -make_mtu -make_resolv_conf -make_hostname -make_nis_conf -make_ntp_conf - -do_hooks exit diff --git a/mk/prog.mk b/mk/prog.mk index fea7ca54..ae9a987f 100644 --- a/mk/prog.mk +++ b/mk/prog.mk @@ -15,9 +15,9 @@ SYSCONFDIR?= ${PREFIX}/etc INSTALL?= install SED?= sed -all: ${PROG} ${MAN} +all: ${PROG} ${SCRIPT} ${MAN} -${PROG}: ${SCRIPTS} ${OBJS} +${PROG}: ${OBJS} ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LDADD} # We could save about 600 bytes by building it like this diff --git a/net.c b/net.c index 3d225915..2c122856 100644 --- a/net.c +++ b/net.c @@ -358,7 +358,6 @@ read_interface(const char *ifname, _unused int metric) iface = xzalloc(sizeof(*iface)); strlcpy(iface->name, ifname, IF_NAMESIZE); snprintf(iface->leasefile, PATH_MAX, LEASEFILE, ifname); - snprintf(iface->infofile, PATH_MAX, INFOFILE, ifname); memcpy(&iface->hwaddr, hwaddr, hwlen); iface->hwlen = hwlen; diff --git a/net.h b/net.h index c60c672b..d767a9ee 100644 --- a/net.h +++ b/net.h @@ -112,7 +112,6 @@ struct interface #endif char leasefile[PATH_MAX]; - char infofile[PATH_MAX]; struct in_addr addr; struct in_addr net;