Skip to content

Commit

Permalink
Merge branch 'master' into route-expiry
Browse files Browse the repository at this point in the history
  • Loading branch information
ColinMcInnes authored Jan 24, 2025
2 parents d2789d8 + 58498b2 commit 9ba1271
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 132 deletions.
10 changes: 9 additions & 1 deletion src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,21 @@ is_root_local(void)
}

uint32_t
lifetime_left(uint32_t lifetime, const struct timespec *acquired, const struct timespec *now)
lifetime_left(uint32_t lifetime, const struct timespec *acquired, struct timespec *now)
{
uint32_t elapsed;
struct timespec n;

if (lifetime == INFINITE_LIFETIME)
return lifetime;

if (now == NULL) {
timespecclear(&n);
now = &n;
}
if (!timespecisset(now))
clock_gettime(CLOCK_MONOTONIC, now);

elapsed = (uint32_t)eloop_timespec_diff(now, acquired, NULL);
if (elapsed > lifetime)
return 0;
Expand Down
2 changes: 1 addition & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,5 @@ ssize_t writefile(const char *, mode_t, const void *, size_t);
int filemtime(const char *, time_t *);
char *get_line(char ** __restrict, ssize_t * __restrict);
int is_root_local(void);
uint32_t lifetime_left(uint32_t, const struct timespec *, const struct timespec *);
uint32_t lifetime_left(uint32_t, const struct timespec *, struct timespec *);
#endif
47 changes: 23 additions & 24 deletions src/dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,6 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
const struct dhcp_lease *lease = &state->lease;
char hbuf[HOSTNAME_MAX_LEN + 1];
const char *hostname;
const struct vivco *vivco;
int mtu;
#ifdef AUTH
uint8_t *auth, auth_len;
Expand Down Expand Up @@ -1138,35 +1137,35 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
p += ifo->mudurl[0] + 1;
}

#ifndef SMALL
if (ifo->vivco_len &&
!has_option_mask(ifo->nomask, DHO_VIVCO))
{
AREA_CHECK(sizeof(ul));
*p++ = DHO_VIVCO;
lp = p++;
*lp = sizeof(ul);
ul = htonl(ifo->vivco_en);
memcpy(p, &ul, sizeof(ul));
p += sizeof(ul);
for (i = 0, vivco = ifo->vivco;
i < ifo->vivco_len;
i++, vivco++)
{
AREA_FIT(vivco->len);
if (vivco->len + 2 + *lp > 255) {
logerrx("%s: VIVCO option too big",
ifp->name);
free(bootp);
return -1;
}
*p++ = (uint8_t)vivco->len;
memcpy(p, vivco->data, vivco->len);
p += vivco->len;
struct vivco *vivco = ifo->vivco;
size_t vlen = ifo->vivco_len;
struct rfc3396_ctx rctx = {
.code = DHO_VIVCO,
.buf = &p,
.buflen = AREA_LEFT,
};

for (; vlen > 0; vivco++, vlen--) {
ul = htonl(vivco->en);
if (rfc3396_write(&rctx, &ul, sizeof(ul)) == -1)
goto toobig;
lp = rfc3396_zero(&rctx);
if (lp == NULL)
goto toobig;
if (rfc3396_write_byte(&rctx,
(uint8_t)vivco->len) == -1)
goto toobig;
if (rfc3396_write(&rctx,
vivco->data, vivco->len) == -1)
goto toobig;
*lp = (uint8_t)(*lp + vivco->len + 1);
}
}

#ifndef SMALL

if (ifo->vsio_len &&
!has_option_mask(ifo->nomask, DHO_VIVSO))
{
Expand Down
52 changes: 28 additions & 24 deletions src/dhcp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,29 +276,28 @@ dhcp6_makeuser(void *data, const struct interface *ifp)
return sizeof(o) + olen;
}

#ifndef SMALL
/* DHCPv6 Option 16 (Vendor Class Option) */
static size_t
dhcp6_makevendor(void *data, const struct interface *ifp)
{
const struct if_options *ifo;
size_t len, vlen, i;
size_t len = 0, optlen, vlen, i;
uint8_t *p;
const struct vivco *vivco;
struct dhcp6_option o;

ifo = ifp->options;
len = sizeof(uint32_t); /* IANA PEN */
if (ifo->vivco_en) {
vlen = 0;
if (ifo->vivco_len > 0) {
for (i = 0, vivco = ifo->vivco;
i < ifo->vivco_len;
i++, vivco++)
vlen += sizeof(uint16_t) + vivco->len;
len += vlen;
len += sizeof(o) + sizeof(uint32_t) + sizeof(uint16_t) + vivco->len;
} else if (ifo->vendorclassid[0] != '\0') {
/* dhcpcd owns DHCPCD_IANA_PEN.
* If you need your own string, get your own IANA PEN. */
vlen = strlen(ifp->ctx->vendor);
len += sizeof(uint16_t) + vlen;
len += sizeof(o) + sizeof(uint32_t) + sizeof(uint16_t) + vlen;
} else
return 0;

Expand All @@ -312,37 +311,42 @@ dhcp6_makevendor(void *data, const struct interface *ifp)
uint16_t hvlen;

p = data;
o.code = htons(D6_OPTION_VENDOR_CLASS);
o.len = htons((uint16_t)len);
memcpy(p, &o, sizeof(o));
p += sizeof(o);
pen = htonl(ifo->vivco_en ? ifo->vivco_en : DHCPCD_IANA_PEN);
memcpy(p, &pen, sizeof(pen));
p += sizeof(pen);

if (ifo->vivco_en) {
if (ifo->vivco_len > 0) {
for (i = 0, vivco = ifo->vivco;
i < ifo->vivco_len;
i++, vivco++)
{
i++, vivco++) {
optlen = sizeof(uint32_t) + sizeof(uint16_t) + vivco->len;
o.code = htons(D6_OPTION_VENDOR_CLASS);
o.len = htons((uint16_t)optlen);
memcpy(p, &o, sizeof(o));
p += sizeof(o);
pen = htonl(vivco->en);
memcpy(p, &pen, sizeof(pen));
p += sizeof(pen);
hvlen = htons((uint16_t)vivco->len);
memcpy(p, &hvlen, sizeof(hvlen));
p += sizeof(hvlen);
memcpy(p, vivco->data, vivco->len);
p += vivco->len;
}
} else if (ifo->vendorclassid[0] != '\0') {
o.code = htons(D6_OPTION_VENDOR_CLASS);
o.len = htons((uint16_t)len);
memcpy(p, &o, sizeof(o));
p += sizeof(o);
pen = htonl(DHCPCD_IANA_PEN);
memcpy(p, &pen, sizeof(pen));
p += sizeof(pen);
hvlen = htons((uint16_t)vlen);
memcpy(p, &hvlen, sizeof(hvlen));
p += sizeof(hvlen);
memcpy(p, ifp->ctx->vendor, vlen);
}
}

return sizeof(o) + len;
return len;
}

#ifndef SMALL
/* DHCPv6 Option 17 (Vendor-Specific Information Option) */
static size_t
dhcp6_makevendoropts(void *data, const struct interface *ifp)
Expand Down Expand Up @@ -875,10 +879,10 @@ dhcp6_makemessage(struct interface *ifp)

if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
len += dhcp6_makeuser(NULL, ifp);
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
len += dhcp6_makevendor(NULL, ifp);

#ifndef SMALL
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
len += dhcp6_makevendor(NULL, ifp);
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_OPTS))
len += dhcp6_makevendoropts(NULL, ifp);
#endif
Expand Down Expand Up @@ -1199,10 +1203,10 @@ dhcp6_makemessage(struct interface *ifp)

if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
p += dhcp6_makeuser(p, ifp);
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
p += dhcp6_makevendor(p, ifp);

#ifndef SMALL
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
p += dhcp6_makevendor(p, ifp);
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_OPTS))
p += dhcp6_makevendoropts(p, ifp);
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/eloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ eloop_timespec_diff(const struct timespec *tsp, const struct timespec *usp,
unsigned long long tsecs, usecs, secs;
long nsecs;

if (tsp->tv_sec < 0) /* time wreapped */
if (tsp->tv_sec < 0) /* time wrapped */
tsecs = UTIME_MAX - (unsigned long long)(-tsp->tv_sec);
else
tsecs = (unsigned long long)tsp->tv_sec;
Expand Down
13 changes: 5 additions & 8 deletions src/if-bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,15 +742,12 @@ if_route(unsigned char cmd, const struct rt *rt)
{
rtm->rtm_index = (unsigned short)rt->rt_ifp->index;
/*
* OpenBSD rejects the message for on-link routes.
* FreeBSD-12 kernel apparently panics.
* I can't replicate the panic, but better safe than sorry!
* https://roy.marples.name/archives/dhcpcd-discuss/0002286.html
*
* Neither OS currently allows IPv6 address sharing anyway, so let's
* try to encourage someone to fix that by logging a waring during compile.
* OpenBSD rejects this for on-link routes when there is no default route
* OpenBSD does not allow the same IPv6 address on different
* interfaces on the same network, so let's try to encourage someone to
* fix that by logging a waring during compile.
*/
#if defined(__FreeBSD__) || defined(__OpenBSD__)
#ifdef __OpenBSD__
#warning kernel does not allow IPv6 address sharing
if (!gateway_unspec || rt->rt_dest.sa_family!=AF_INET6)
#endif
Expand Down
16 changes: 14 additions & 2 deletions src/if-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
struct dhcp_opt **dop, *ndop;
size_t *dop_len, dl, odl;
struct vivco *vivco;
const struct vivco *vivco_endp = ifo->vivco + ifo->vivco_len;
struct group *grp;
#ifdef AUTH
struct token *token;
Expand Down Expand Up @@ -2111,6 +2112,10 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
case O_VENDCLASS:
ARG_REQUIRED;
#ifdef SMALL
logwarnx("%s: vendor options not compiled in", ifname);
return -1;
#else
fp = strwhite(arg);
if (fp)
*fp++ = '\0';
Expand All @@ -2119,6 +2124,12 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
logerrx("invalid code: %s", arg);
return -1;
}
for (vivco = ifo->vivco; vivco != vivco_endp; vivco++) {
if (vivco->en == (uint32_t)u) {
logerrx("vendor class option for enterprise number %u already defined", vivco->en);
return -1;
}
}
fp = strskipwhite(fp);
if (fp) {
s = parse_string(NULL, 0, fp);
Expand Down Expand Up @@ -2149,11 +2160,12 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
return -1;
}
ifo->vivco = vivco;
ifo->vivco_en = (uint32_t)u;
vivco = &ifo->vivco[ifo->vivco_len++];
vivco->en = (uint32_t)u;
vivco->len = dl;
vivco->data = (uint8_t *)np;
break;
#endif
case O_AUTHPROTOCOL:
ARG_REQUIRED;
#ifdef AUTH
Expand Down Expand Up @@ -2994,12 +3006,12 @@ free_options(struct dhcpcd_ctx *ctx, struct if_options *ifo)
opt++, ifo->dhcp6_override_len--)
free_dhcp_opt_embenc(opt);
free(ifo->dhcp6_override);
#ifndef SMALL
for (vo = ifo->vivco;
ifo->vivco_len > 0;
vo++, ifo->vivco_len--)
free(vo->data);
free(ifo->vivco);
#ifndef SMALL
for (vsio = ifo->vsio;
ifo->vsio_len > 0;
vsio++, ifo->vsio_len--)
Expand Down
10 changes: 4 additions & 6 deletions src/if-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
#define USERCLASS_MAX_LEN 255
#define VENDOR_MAX_LEN 255
#define MUDURL_MAX_LEN 255
#define ENTERPRISE_NUMS_MAX_LEN 255

#define DHCPCD_ARP (1ULL << 0)
#define DHCPCD_RELEASE (1ULL << 1)
Expand Down Expand Up @@ -220,12 +219,12 @@ struct if_ia {
#endif
};

#ifndef SMALL
struct vivco {
uint32_t en;
size_t len;
uint8_t *data;
};

#ifndef SMALL
struct vsio_so {
uint16_t opt;
uint16_t len;
Expand Down Expand Up @@ -303,13 +302,12 @@ struct if_options {
size_t nd_override_len;
struct dhcp_opt *dhcp6_override;
size_t dhcp6_override_len;
uint32_t vivco_en;
struct vivco *vivco;
size_t vivco_len;
struct dhcp_opt *vivso_override;
size_t vivso_override_len;

#ifndef SMALL
size_t vivco_len;
struct vivco *vivco;
size_t vsio_len;
struct vsio *vsio;
size_t vsio6_len;
Expand Down
Loading

0 comments on commit 9ba1271

Please sign in to comment.