]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Remove the .info file and now set environment vars in the same vein as dhclient....
authorRoy Marples <roy@marples.name>
Wed, 16 Apr 2008 09:51:20 +0000 (09:51 +0000)
committerRoy Marples <roy@marples.name>
Wed, 16 Apr 2008 09:51:20 +0000 (09:51 +0000)
12 files changed:
Makefile
client.c
config.h
configure.c
configure.h
dhcp.c
dhcp.h
dhcpcd.8.in
dhcpcd.sh [deleted file]
mk/prog.mk
net.c
net.h

index 092ef7ce2f99631be64f216a08c210d0ece14f93..a919890aaa176a0e0028b29d2d2fc2d734915d7b 100644 (file)
--- 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' $< > $@
+
index bab77fcf6d6382ea08e2987daf9a2674abc95ba7..66386185b75f37ff8d41c64f1eaf03b8b64e3146 100644 (file)
--- 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);
        }
 
index 20354106ad252648b98d69fa02cdd24b1013e749..f8bb018ccf81c3f69b4ab55a5a1f3a16a98aafc3 100644 (file)
--- 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
index 215ea2feb56ed58020150ab3ca09fced0cd5f696..abd11bbf264bb238e6025831d60a5a9dbd1e679a 100644 (file)
 #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;
 }
index 61a894311b5d2b0c334761874d9c19a094e5abf8..d5d30d45006c8a0ac67e23aae81820a14becdbb4 100644 (file)
 #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 9655f0902f807400ba43794cd90d5d88fe8a77e3..25ecb55f06fec0f45e85652dee2eafebc48b1e38 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
 #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 879cff725d1e8eef1ab939df8f727bb50407fca3..20e8ca1750ab0c0658403af991df0ae33ff60e03 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
 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
index f32e59ef3c92c8fb3238434d9ce387cb40aed0c6..f8928b0b8bb9d4394e85fe50fbd49ccceeadba58 100644 (file)
@@ -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 (executable)
index 2828a16..0000000
--- a/dhcpcd.sh
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/bin/sh
-# dhcpcd - DHCP client daemon
-# Copyright 2006-2008 Roy Marples <roy@marples.name>
-# 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
index fea7ca54574246ba5d0910fb99c48818a66962f9..ae9a987f30f115cbfa7f8c1289b070f61c701db1 100644 (file)
@@ -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 3d225915edc7d4a395fd85b786bb6bc34c588d68..2c12285626d07cf78917eb784fd1ec639f1f7aa4 100644 (file)
--- 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 c60c672b89e36532ec9c7fd486697bd4ebdd54a2..d767a9ee7c21f6f4e82a90a50c47d06884dc15d2 100644 (file)
--- 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;