summaryrefslogtreecommitdiffstats
path: root/dhcp.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-09-02 13:28:11 +0000
committerRoy Marples <roy@marples.name>2008-09-02 13:28:11 +0000
commitfd05b7dcfc61e1a8f1d4f0f7ecd27bb25a6cc7a8 (patch)
treeeefcda1304078e7ee7e7508103cb6e1775ff5513 /dhcp.c
parentca07508a27a3048ead0c0a411f2cecc84ac97935 (diff)
downloaddhcpcd-fd05b7dcfc61e1a8f1d4f0f7ecd27bb25a6cc7a8.tar.xz
Add an event loop.
Split client.c into smaller files and functions and recode around the event loop. Add multiple interface support using the new event loop. Document changes and outstanding bugs.
Diffstat (limited to 'dhcp.c')
-rw-r--r--dhcp.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/dhcp.c b/dhcp.c
index a9ef632c..0fb1f63f 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -35,6 +35,7 @@
#include "config.h"
#include "common.h"
#include "dhcp.h"
+#include "dhcpf.h"
#define REQUEST (1 << 0)
#define UINT8 (1 << 1)
@@ -166,12 +167,13 @@ print_options(void)
printf("%03d %s\n", opt->option, opt->var);
}
-int make_option_mask(uint8_t *mask, char **opts, int add)
+int make_option_mask(uint8_t *mask, const char *opts, int add)
{
- char *token, *p = *opts, *t;
+ char *token, *o, *p, *t;
const struct dhcp_opt *opt;
int match, n;
+ o = p = xstrdup(opts);
while ((token = strsep(&p, ", "))) {
if (*token == '\0')
continue;
@@ -199,11 +201,12 @@ int make_option_mask(uint8_t *mask, char **opts, int add)
}
}
if (!opt->option) {
- *opts = token;
+ free(o);
errno = ENOENT;
return -1;
}
}
+ free(o);
return 0;
}
@@ -745,8 +748,8 @@ encode_rfc1035(const char *src, uint8_t *dst, size_t len)
ssize_t
make_message(struct dhcp_message **message,
- const struct interface *iface, const struct dhcp_lease *lease,
- uint32_t xid, uint8_t type, const struct options *options)
+ const struct interface *iface,
+ uint8_t type)
{
struct dhcp_message *dhcp;
uint8_t *m, *lp, *p;
@@ -755,6 +758,8 @@ make_message(struct dhcp_message **message,
uint32_t ul;
uint16_t sz;
const struct dhcp_opt *opt;
+ const struct if_options *ifo = iface->state->options;
+ const struct dhcp_lease *lease = &iface->state->lease;
dhcp = xzalloc(sizeof (*dhcp));
m = (uint8_t *)dhcp;
@@ -795,7 +800,7 @@ make_message(struct dhcp_message **message,
dhcp->secs = htons((uint16_t)UINT16_MAX);
else
dhcp->secs = htons(up);
- dhcp->xid = xid;
+ dhcp->xid = iface->state->xid;
dhcp->cookie = htonl(MAGIC_COOKIE);
*p++ = DHO_MESSAGETYPE;
@@ -822,17 +827,17 @@ make_message(struct dhcp_message **message,
}
if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
- if (options->userclass[0]) {
+ if (ifo->userclass[0]) {
*p++ = DHO_USERCLASS;
- memcpy(p, options->userclass, options->userclass[0] + 1);
- p += options->userclass[0] + 1;
+ memcpy(p, ifo->userclass, ifo->userclass[0] + 1);
+ p += ifo->userclass[0] + 1;
}
- if (options->vendorclassid[0]) {
+ if (ifo->vendorclassid[0]) {
*p++ = DHO_VENDORCLASSID;
- memcpy(p, options->vendorclassid,
- options->vendorclassid[0] + 1);
- p += options->vendorclassid[0] + 1;
+ memcpy(p, ifo->vendorclassid,
+ ifo->vendorclassid[0] + 1);
+ p += ifo->vendorclassid[0] + 1;
}
}
@@ -854,10 +859,10 @@ make_message(struct dhcp_message **message,
}
#undef PUTADDR
- if (options->leasetime != 0) {
+ if (ifo->leasetime != 0) {
*p++ = DHO_LEASETIME;
*p++ = 4;
- ul = htonl(options->leasetime);
+ ul = htonl(ifo->leasetime);
memcpy(p, &ul, 4);
p += 4;
}
@@ -867,12 +872,12 @@ make_message(struct dhcp_message **message,
type == DHCP_INFORM ||
type == DHCP_REQUEST)
{
- if (options->hostname[0]) {
+ if (ifo->hostname[0]) {
*p++ = DHO_HOSTNAME;
- memcpy(p, options->hostname, options->hostname[0] + 1);
- p += options->hostname[0] + 1;
+ memcpy(p, ifo->hostname, ifo->hostname[0] + 1);
+ p += ifo->hostname[0] + 1;
}
- if (options->fqdn != FQDN_DISABLE) {
+ if (ifo->fqdn != FQDN_DISABLE) {
/* IETF DHC-FQDN option (81), RFC4702 */
*p++ = DHO_FQDN;
lp = p;
@@ -887,20 +892,20 @@ make_message(struct dhcp_message **message,
* N: 1 => Client requests Server to not
* update DNS
*/
- *p++ = (options->fqdn & 0x09) | 0x04;
+ *p++ = (ifo->fqdn & 0x09) | 0x04;
*p++ = 0; /* from server for PTR RR */
*p++ = 0; /* from server for A RR if S=1 */
- ul = encode_rfc1035(options->hostname + 1, p,
- options->hostname[0]);
+ ul = encode_rfc1035(ifo->hostname + 1, p,
+ ifo->hostname[0]);
*lp += ul;
p += ul;
}
/* vendor is already encoded correctly, so just add it */
- if (options->vendor[0]) {
+ if (ifo->vendor[0]) {
*p++ = DHO_VENDOR;
- memcpy(p, options->vendor, options->vendor[0] + 1);
- p += options->vendor[0] + 1;
+ memcpy(p, ifo->vendor, ifo->vendor[0] + 1);
+ p += ifo->vendor[0] + 1;
}
*p++ = DHO_PARAMETERREQUESTLIST;
@@ -908,7 +913,7 @@ make_message(struct dhcp_message **message,
*p++ = 0;
for (opt = dhcp_opts; opt->option; opt++) {
if (!(opt->type & REQUEST ||
- has_option_mask(options->requestmask, opt->option)))
+ has_option_mask(ifo->requestmask, opt->option)))
continue;
switch (opt->option) {
case DHO_RENEWALTIME: /* FALLTHROUGH */
@@ -1155,7 +1160,7 @@ setvar(char ***e, const char *prefix, const char *var, const char *value)
ssize_t
configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
- const struct options *options)
+ const struct if_options *ifo)
{
unsigned int i;
const uint8_t *p;
@@ -1176,7 +1181,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
for (opt = dhcp_opts; opt->option; opt++) {
if (!opt->var)
continue;
- if (has_option_mask(options->nomask, opt->option))
+ if (has_option_mask(ifo->nomask, opt->option))
continue;
if (get_option_raw(dhcp, opt->option))
e++;
@@ -1219,7 +1224,7 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
for (opt = dhcp_opts; opt->option; opt++) {
if (!opt->var)
continue;
- if (has_option_mask(options->nomask, opt->option))
+ if (has_option_mask(ifo->nomask, opt->option))
continue;
val = NULL;
p = get_option(dhcp, opt->option, &pl, NULL);
@@ -1242,3 +1247,25 @@ configure_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
return ep - env;
}
+
+void
+get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
+{
+ time_t t;
+
+ lease->frominfo = 0;
+ lease->addr.s_addr = dhcp->yiaddr;
+ if (get_option_addr(&lease->net.s_addr, dhcp, DHO_SUBNETMASK) == -1)
+ lease->net.s_addr = get_netmask(dhcp->yiaddr);
+ if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
+ /* Ensure that we can use the lease */
+ t = 0;
+ if (t + (time_t)lease->leasetime < t)
+ lease->leasetime = ~0U; /* Infinite lease */
+ } else
+ lease->leasetime = DEFAULT_LEASETIME;
+ if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
+ lease->renewaltime = 0;
+ if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
+ lease->rebindtime = 0;
+}