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
.in:
${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g; s:@DBDIR@:${DBDIR}:g' $< > $@
+
+.sh.in.sh:
+ ${SED} 's:@SYSCONFDIR@:${SYSCONFDIR}:g' $< > $@
+
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;
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;
int i;
#endif
+ if (state->options & DHCPCD_DAEMONISED ||
+ !(options->options & DHCPCD_DAEMONISE))
+ return 0;
+
sigfillset(&full);
sigprocmask(SIG_SETMASK, &full, &old);
/* 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;
}
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;
/* 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;
}
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;
}
}
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;
}
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:
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,
{
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) {
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");
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;
}
}
#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;
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;
}
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
eexit:
if (iface) {
do_socket(state, SOCKET_CLOSED);
- drop_config(state, options);
free_routes(iface->routes);
free(iface->clientid);
free(iface);
unlink(options->pidfile);
free(state->buffer);
free(state->dhcp);
+ free(state->old_dhcp);
free(state);
}
# define DBDIR "/var/db"
#endif
#define LEASEFILE DBDIR "/" PACKAGE "-%s.lease"
-#define INFOFILE DBDIR "/" PACKAGE "-%s.info"
#define DUIDFILE DBDIR "/" PACKAGE ".duid"
#endif
#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;
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);
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 */
}
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
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)
{
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;
/* 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)) {
}
}
- exec_script(options->script, iface->infofile, "down");
+ exec_script(options->script, iface->name, reason, NULL, old);
return 0;
}
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;
}
#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
#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
};
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 }
};
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);
}
}
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) {
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;
}
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,
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
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 *);
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
.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
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.
+++ /dev/null
-#!/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
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
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;
#endif
char leasefile[PATH_MAX];
- char infofile[PATH_MAX];
struct in_addr addr;
struct in_addr net;