#ifdef ENABLE_ARP
/* Check that no-one is using the address */
- if ((options->dolastlease ||
+ if ((options->options & DHCPCD_LASTLEASE ||
(IN_LINKLOCAL(ntohl (dhcp->address.s_addr)) &&
- (!options->doipv4ll ||
+ (!(options->options & DHCPCD_IPV4LL) ||
arp_claim(iface, dhcp->address)))))
{
memset(&dhcp->address, 0, sizeof(dhcp->address));
state->state = STATE_INIT;
state->last_type = DHCP_DISCOVER;
state->nakoff = 1;
- state->daemonised = options->daemonised;
- state->persistent = options->persistent;
+ state->daemonised = (options->options & DHCPCD_DAEMONISED);
+ state->persistent = (options->options & DHCPCD_PERSISTENT);
if (options->request_address.s_addr == 0 &&
- (options->doinform || options->dorequest || options->daemonised))
+ (options->options & DHCPCD_INFORM ||
+ options->options & DHCPCD_REQUEST ||
+ options->options & DHCPCD_DAEMONISED))
{
#ifdef ENABLE_INFO
if (!get_old_lease(state, options))
}
state->timeout = 0;
- if (!options->daemonised &&
+ if (!(options->options & DHCPCD_DAEMONISED) &&
IN_LINKLOCAL(ntohl(dhcp->address.s_addr)))
{
logger(LOG_ERR, "cannot request a link local address");
return false;
}
#ifdef THERE_IS_NO_FORK
- if (options->daemonised) {
+ if (options->options & DHCPCD_DAEMONISED) {
state->state = STATE_BOUND;
state->timeout = dhcp->renewaltime;
iface->previous_address = dhcp->address;
* After all, we ARE a DHCP client whose job it is to configure the
* interface. We only do this on start, so persistent addresses
* can be added afterwards by the user if needed. */
- if (!options->test && !options->daemonised) {
- if (!options->doinform) {
+ if (!(options->options & DHCPCD_TEST) &&
+ !(options->options & DHCPCD_DAEMONISED))
+ {
+ if (!(options->options & DHCPCD_INFORM)) {
flush_addresses (iface->name);
- } else {
+ } else if (has_address(iface->name, dhcp->address) < 1) {
/* The inform address HAS to be configured for it to
* work with most DHCP servers */
- if (options->doinform &&
- has_address(iface->name, dhcp->address) < 1)
- {
- /* add_address */
- iface->previous_address = dhcp->address;
- iface->previous_netmask = dhcp->netmask;
- }
+ /* add_address */
+ iface->previous_address = dhcp->address;
+ iface->previous_netmask = dhcp->netmask;
}
}
size_t duid_len = 0;
uint32_t ul;
- if (options->doduid) {
+ if (options->options & DHCPCD_DUID) {
duid = xmalloc(DUID_LEN);
duid_len = get_duid(duid, iface);
if (duid_len == 0)
}
static bool
-handle_signal (int sig, struct if_state *state, const struct options *options)
+handle_signal(int sig, struct if_state *state, const struct options *options)
{
switch (sig) {
case SIGINT:
}
static int
-handle_timeout (struct if_state *state, const struct options *options)
+handle_timeout(struct if_state *state, const struct options *options)
{
struct dhcp *dhcp = state->dhcp;
struct interface *iface = state->interface;
if (state->state == STATE_INIT && state->xid != 0) {
if (iface->previous_address.s_addr != 0 &&
!IN_LINKLOCAL(ntohl(iface->previous_address.s_addr)) &&
- !options->doinform)
+ !(options->options & DHCPCD_INFORM))
{
logger(LOG_ERR, "lost lease");
- if (!options->persistent)
+ if (!(options->options & DHCPCD_PERSISTENT))
drop_config(state, options);
} else if (!IN_LINKLOCAL(ntohl(iface->previous_address.s_addr)))
logger(LOG_ERR, "timed out");
memset(dhcp, 0, sizeof(*dhcp));
#ifdef ENABLE_INFO
- if (!options->test &&
- (options->doipv4ll || options->dolastlease))
+ if (!(options->options & DHCPCD_TEST) &&
+ (options->options & DHCPCD_IPV4LL ||
+ options->options & DHCPCD_LASTLEASE))
{
errno = 0;
- if (!get_old_lease (state, options))
+ if (!get_old_lease(state, options))
{
if (errno == EINTR)
return 0;
- if (options->dolastlease)
+ if (options->options & DHCPCD_LASTLEASE)
return -1;
free_dhcp(dhcp);
memset(dhcp, 0, sizeof(*dhcp));
#endif
#ifdef ENABLE_IPV4LL
- if (!options->test && options->doipv4ll &&
+ if (!(options->options & DHCPCD_TEST) &&
+ options->options & DHCPCD_IPV4LL &&
(!dhcp->address.s_addr ||
(!IN_LINKLOCAL(ntohl(dhcp->address.s_addr)) &&
- !options->dolastlease)))
+ !(options->options & DHCPCD_LASTLEASE))))
{
logger(LOG_INFO, "probing for an IPV4LL address");
free_dhcp(dhcp);
- memset(dhcp, 0, sizeof (*dhcp));
+ memset(dhcp, 0, sizeof(*dhcp));
if (ipv4ll_get_address(iface, dhcp) == -1) {
if (!state->daemonised)
return -1;
return -1;
state->state = STATE_BOUND;
- if (!state->daemonised && options->daemonise) {
- switch (daemonise (state->pidfd)) {
+ if (!state->daemonised && options->options & DHCPCD_DAEMONISE) {
+ switch (daemonise(state->pidfd)) {
case -1:
return -1;
case 0:
switch (state->state) {
case STATE_INIT:
state->xid = (uint32_t) random ();
- do_socket (state, SOCKET_OPEN);
+ do_socket(state, SOCKET_OPEN);
state->timeout = options->timeout;
iface->start_uptime = uptime ();
if (dhcp->address.s_addr == 0) {
if (!IN_LINKLOCAL(ntohl(iface->previous_address.s_addr)))
logger(LOG_INFO, "broadcasting for a lease");
_send_message (state, DHCP_DISCOVER, options);
- } else if (options->doinform) {
+ } else if (options->options & DHCPCD_INFORM) {
logger(LOG_INFO, "broadcasting inform for %s",
inet_ntoa(dhcp->address));
_send_message(state, DHCP_INFORM, options);
free(addr);
#ifdef ENABLE_INFO
- if (options->test) {
+ if (options->options & DHCPCD_TEST) {
write_info(iface, dhcp, options, false);
errno = 0;
return -1;
case STATE_REBINDING:
break;
default:
- logger (LOG_ERR, "wrong state %d", state->state);
+ logger(LOG_ERR, "wrong state %d", state->state);
}
do_socket(state, SOCKET_CLOSED);
#ifdef ENABLE_ARP
- if (options->doarp &&
+ if (options->options & DHCPCD_ARP &&
iface->previous_address.s_addr != dhcp->address.s_addr)
{
errno = 0;
}
#endif
- if (options->doinform) {
+ if (options->options & DHCPCD_INFORM) {
if (options->request_address.s_addr != 0)
dhcp->address = options->request_address;
else
!state->daemonised)
return -1;
- if (!state->daemonised && options->daemonise) {
+ if (!state->daemonised && options->options & DHCPCD_DAEMONISE) {
switch (daemonise(state->pidfd)) {
case 0:
state->daemonised = true;
}
int
-configure (const struct options *options, struct interface *iface,
- const struct dhcp *dhcp, bool up)
+configure(const struct options *options, struct interface *iface,
+ const struct dhcp *dhcp, bool up)
{
struct rt *route = NULL;
struct route_head *new_routes = NULL;
* Always do this as the interface may have >1 address not added by us
* so the routes we added may still exist. */
NSTAILQ_FOREACH(route, iface->previous_routes, entries)
- if ((route->destination.s_addr || options->dogateway) &&
+ if ((route->destination.s_addr ||
+ options->options & DHCPCD_GATEWAY) &&
(!up || !in_routes(dhcp->routes, route)))
del_route(iface->name, &route->destination,
&route->netmask, &route->gateway,
/* Only reset things if we had set them before */
if (iface->previous_address.s_addr != 0) {
- if (!options->keep_address) {
+ if (!(options->options & DHCPCD_KEEPADDRESS)) {
del_address(iface->name,
- iface->previous_address,
- iface->previous_netmask);
+ &iface->previous_address,
+ &iface->previous_netmask);
memset(&iface->previous_address,
0, sizeof (iface->previous_address));
memset(&iface->previous_netmask,
/* Set the MTU requested.
* If the DHCP server no longer sends one OR it's invalid then
* we restore the original MTU */
- if (options->domtu) {
+ if (options->options & DHCPCD_MTU) {
mtu = iface->mtu;
if (dhcp->mtu)
mtu = dhcp->mtu;
}
/* This also changes netmask */
- if (!options->doinform || !has_address (iface->name, dhcp->address))
+ if (!(options->options & DHCPCD_INFORM) ||
+ !has_address (iface->name, dhcp->address))
if (a_address(iface->name, &dhcp->address, &dhcp->netmask,
- &dhcp->broadcast) == -1 &&
+ &dhcp->broadcast) == -1 &&
errno != EEXIST)
return false;
/* Now delete the old address if different */
if (iface->previous_address.s_addr != dhcp->address.s_addr &&
iface->previous_address.s_addr != 0 &&
- ! options->keep_address)
+ !(options->options & DHCPCD_KEEPADDRESS))
d_address(iface->name,
- &iface->previous_address, &iface->previous_netmask);
+ &iface->previous_address, &iface->previous_netmask);
#ifdef __linux__
/* On linux, we need to change the subnet route to have our metric. */
/* Don't set default routes if not asked to */
if (route->destination.s_addr == 0 &&
route->netmask.s_addr == 0 &&
- ! options->dogateway)
+ !(options->options & DHCPCD_GATEWAY))
continue;
remember = a_route(iface->name, &route->destination,
remember = 1;
if (remember >= 0) {
- if (! new_routes) {
+ if (!new_routes) {
new_routes = xmalloc(sizeof(*new_routes));
STAILQ_INIT(new_routes);
}
#ifdef THERE_IS_NO_FORK
/* If we have daemonised yet we need to record which routes
* we failed to add so we can skip them */
- else if (!options->daemonised) {
+ else if (!(options->options & DAEMONISED)) {
/* We can never have more than 255 / 4 routes,
* so 3 chars is plently */
if (*skipp)
#ifdef ENABLE_IPV4LL
/* Ensure we always add the link local route if we got a private
* address and isn't link local itself */
- if (options->doipv4ll &&
+ if (options->options & DHCPCD_IPV4LL &&
!haslinklocal &&
IN_PRIVATE(ntohl(dhcp->address.s_addr)))
{
dest.s_addr = htonl(LINKLOCAL_ADDR);
mask.s_addr = htonl(LINKLOCAL_MASK);
gate.s_addr = 0;
- remember = d_route(iface->name, &dest, &mask, &gate,
+ remember = a_route(iface->name, &dest, &mask, &gate,
options->metric);
if (remember >= 0) {
- if (! new_routes) {
+ if (!new_routes) {
new_routes = xmalloc(sizeof(*new_routes));
STAILQ_INIT(new_routes);
}
free_route(iface->previous_routes);
iface->previous_routes = new_routes;
- if (options->dodns && dhcp->dnsservers)
+ if (options->options & DHCPCD_DNS && dhcp->dnsservers)
make_resolv(iface->name, dhcp);
else
logger(LOG_DEBUG, "no dns information to write");
#ifdef ENABLE_NTP
- if (options->dontp && dhcp->ntpservers)
+ if (options->options & DHCPCD_NTP && dhcp->ntpservers)
make_ntp(iface->name, dhcp);
#endif
#ifdef ENABLE_NIS
- if (options->donis && (dhcp->nisservers || dhcp->nisdomain))
+ if (options->options & DHCPCD_NIS &&
+ (dhcp->nisservers || dhcp->nisdomain))
make_nis(iface->name, dhcp);
#endif
snprintf(options->classid, CLASS_ID_MAX_LEN, "%s %s",
PACKAGE, VERSION);
- options->doarp = true;
- options->dodns = true;
- options->domtu = true;
- options->donis = true;
- options->dontp = true;
- options->dogateway = true;
- options->daemonise = true;
- options->doinform = false;
- options->doipv4ll = true;
- options->doduid = true;
+ options->options |= DHCPCD_ARP | DHCPCD_DNS | DHCPCD_MTU |
+ DHCPCD_NIS | DHCPCD_NTP | DHCPCD_GATEWAY |
+ DHCPCD_DAEMONISE | DHCPCD_IPV4LL | DHCPCD_DUID;
options->timeout = DEFAULT_TIMEOUT;
gethostname(options->hostname, sizeof(options->hostname));
if (strcmp(options->hostname, "(none)") == 0 ||
strcmp(options->hostname, "localhost") == 0)
- memset(options->hostname, 0, sizeof(options->hostname));
+ *options->hostname = '\0';
/* Don't set any optional arguments here so we retain POSIX
* compatibility with getopt */
setloglevel(LOG_DEBUG);
break;
case 2:
- options->daemonise = false;
+ options->options &= ~DHCPCD_DAEMONISE;
break;
}
break;
#ifdef THERE_IS_NO_FORK
case 'f':
- options->daemonised = true;
+ options->options |= DHCPCD_DAEMONISED;
close_fds();
break;
case 'g':
case 'i':
if (!optarg) {
*options->classid = '\0';
- } else if (strlen (optarg) > CLASS_ID_MAX_LEN) {
+ } else if (strlen(optarg) > CLASS_ID_MAX_LEN) {
logger(LOG_ERR,
"`%s' too long for ClassID string,"
" max is %d", optarg, CLASS_ID_MAX_LEN);
sig = SIGALRM;
break;
case 'p':
- options->persistent = true;
+ options->options |= DHCPCD_PERSISTENT;
break;
case 's':
- options->doinform = true;
- options->doarp = false;
+ options->options |= DHCPCD_INFORM;
+ options->options &= ~DHCPCD_ARP;
if (!optarg || strlen(optarg) == 0) {
options->request_address.s_addr = 0;
break;
}
/* FALLTHROUGH */
case 'r':
- if (!options->doinform)
- options->dorequest = true;
+ if (!(options->options & DHCPCD_INFORM))
+ options->options |= DHCPCD_REQUEST;
if (strlen(optarg) > 0 &&
- ! inet_aton(optarg, &options->request_address))
+ !inet_aton(optarg, &options->request_address))
{
logger(LOG_ERR,
"`%s' is not a valid IP address",
}
break;
case 't':
- options->timeout = atoint (optarg);
+ options->timeout = atoint(optarg);
if (options->timeout < 0) {
logger (LOG_ERR, "timeout must be a positive value");
goto abort;
goto abort;
}
userclasses++;
- memcpy (options->userclass + j + 1 ,
- optarg, strlen(optarg));
+ memcpy(options->userclass + j + 1 ,
+ optarg, strlen(optarg));
options->userclass[j] = strlen(optarg);
options->userclass_len += (strlen(optarg)) + 1;
break;
logger (LOG_ERR, "arp not compiled into dhcpcd");
goto abort;
#endif
- options->doarp = false;
+ options->options &= ~DHCPCD_ARP;
break;
case 'E':
#ifndef ENABLE_INFO
logger (LOG_ERR, "info not compiled into dhcpcd");
goto abort;
#endif
- options->dolastlease = true;
+ options->options |= DHCPCD_LASTLEASE;
break;
case 'F':
if (!optarg) {
}
break;
case 'G':
- options->dogateway = false;
+ options->options &= ~DHCPCD_GATEWAY;
break;
case 'H':
options->dohostname++;
if (strlcpy(options->clientid, optarg,
sizeof(options->clientid)) == 0)
/* empty string disabled duid */
- options->doduid = false;
+ options->options &= ~DHCPCD_DUID;
} else {
memset(options->clientid, 0,
sizeof(options->clientid));
- options->doduid = false;
+ options->options &= ~DHCPCD_DUID;
}
break;
case 'L':
- options->doipv4ll = false;
+ options->options &= ~DHCPCD_IPV4LL;
break;
case 'M':
- options->domtu = false;
+ options->options &= ~DHCPCD_MTU;
break;
case 'N':
- options->dontp = false;
+ options->options &= ~DHCPCD_NTP;
break;
case 'R':
- options->dodns = false;
+ options->options &= ~DHCPCD_DNS;
break;
case 'S':
options->domscsr++;
logger(LOG_ERR, "info support not compiled into dhcpcd");
goto abort;
#endif
- options->test = true;
- options->persistent = true;
+ options->options |= DHCPCD_TEST | DHCPCD_PERSISTENT;
break;
case 'Y':
- options->donis = false;
+ options->options &= ~DHCPCD_NIS;
break;
case '?':
usage();
} else
options->fqdn = FQDN_DISABLE;
- if (options->request_address.s_addr == 0 && options->doinform) {
+ if (options->request_address.s_addr == 0 &&
+ options->options & DHCPCD_INFORM)
+ {
if ((options->request_address.s_addr =
get_address(options->interface)) != 0)
- options->keep_address = true;
+ options->options |= DHCPCD_KEEPADDRESS;
}
if (IN_LINKLOCAL(ntohl (options->request_address.s_addr))) {
chdir("/");
umask(022);
- if (options->test) {
- if (options->dorequest || options->doinform) {
+ if (options->options & DHCPCD_TEST) {
+ if (options->options & DHCPCD_REQUEST ||
+ options->options & DHCPCD_INFORM) {
logger(LOG_ERR,
"cannot test with --inform or --request");
goto abort;
}
- if (options->dolastlease) {
+ if (options->options & DHCPCD_LASTLEASE) {
logger(LOG_ERR, "cannot test with --lastlease");
goto abort;
}
goto abort;
}
- if (!options->test && !options->daemonised) {
+ if (!(options->options & DHCPCD_TEST) &&
+ !(options->options & DHCPCD_DAEMONISED))
+ {
if ((pid = read_pid(options->pidfile)) > 0 &&
kill(pid, 0) == 0)
{
#include <netinet/in.h>
#include <limits.h>
-#include <stdbool.h>
#include "common.h"
-#define DEFAULT_TIMEOUT 20
-#define DEFAULT_LEASETIME 3600 /* 1 hour */
+#define DEFAULT_TIMEOUT 20
+#define DEFAULT_LEASETIME 3600 /* 1 hour */
-#define CLASS_ID_MAX_LEN 48
-#define CLIENT_ID_MAX_LEN 48
-#define USERCLASS_MAX_LEN 255
+#define CLASS_ID_MAX_LEN 48
+#define CLIENT_ID_MAX_LEN 48
+#define USERCLASS_MAX_LEN 255
#ifdef THERE_IS_NO_FORK
extern char dhcpcd[PATH_MAX];
extern char *dhcpcd_skiproutes;
#endif
+#define DHCPCD_ARP (1 << 0)
+#define DHCPCD_DNS (1 << 1)
+#define DHCPCD_DOMAIN (1 << 2)
+#define DHCPCD_GATEWAY (1 << 3)
+#define DHCPCD_MTU (1 << 4)
+#define DHCPCD_NIS (1 << 5)
+#define DHCPCD_NTP (1 << 6)
+#define DHCPCD_LASTLEASE (1 << 7)
+#define DHCPCD_INFORM (1 << 8)
+#define DHCPCD_REQUEST (1 << 9)
+#define DHCPCD_IPV4LL (1 << 10)
+#define DHCPCD_DUID (1 << 11)
+#define DHCPCD_PERSISTENT (1 << 12)
+#define DHCPCD_KEEPADDRESS (1 << 13)
+#define DHCPCD_DAEMONISE (1 << 14)
+#define DHCPCD_DAEMONISED (1 << 15)
+#define DHCPCD_TEST (1 << 16)
+
struct options {
char interface[IF_NAMESIZE];
char hostname[MAXHOSTNAMELEN];
uint32_t leasetime;
time_t timeout;
int metric;
+ int options;
- bool doarp;
- bool dodns;
- bool dodomainname;
- bool dogateway;
int dohostname;
- bool domtu;
- bool donis;
- bool dontp;
- bool dolastlease;
- bool doinform;
- bool dorequest;
- bool doipv4ll;
- bool doduid;
int domscsr;
struct in_addr request_address;
struct in_addr request_netmask;
- bool persistent;
- bool keep_address;
- bool daemonise;
- bool daemonised;
- bool test;
-
char *script;
char pidfile[PATH_MAX];
};
sizeof(netmask));
if (del_address(ifname,
- address.sin_addr,
- netmask.sin_addr) == -1)
+ &address.sin_addr,
+ &netmask.sin_addr) == -1)
retval = -1;
} else if (get) {
addr->s_addr = address.sin_addr.s_addr;
#define set_mtu(iface, mtu) do_mtu(iface, mtu)
#define add_address(ifname, addr, mask, brd) \
- if_address(ifname, &(addr), &(mask), brd, 1)
+ if_address(ifname, addr, mask, brd, 1)
#define del_address(ifname, addr, mask) \
- if_address(ifname, &(addr), &(mask), NULL, -1)
+ if_address(ifname, addr, mask, NULL, -1)
#define flush_addresses(ifname) \
do_interface(ifname, NULL, NULL, NULL, true, false)
in_addr_t get_address(const char *);
struct in_addr addr;
bool doneone;
- if (options->test)
+ if (options->options & DHCPCD_TEST)
f = stdout;
else {
if (!overwrite && stat(iface->infofile, &sb) == 0)
if (dhcp->servername[0])
print_clean(f, "DHCPSNAME", dhcp->servername);
- if (!options->doinform && dhcp->address.s_addr) {
- if (!options->test)
+ if (!(options->options & DHCPCD_INFORM) && dhcp->address.s_addr) {
+ if (!(options->options & DHCPCD_TEST))
fprintf(f, "LEASEDFROM='%u'\n", dhcp->leasedfrom);
fprintf(f, "LEASETIME='%u'\n", dhcp->leasetime);
fprintf(f, "RENEWALTIME='%u'\n", dhcp->renewaltime);
}
#endif
- if (!options->test)
+ if (!(options->options & DHCPCD_TEST))
fclose(f);
return true;
}