Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/dhcpcd/dist/src Sync
details: https://anonhg.NetBSD.org/src/rev/bb8c480c1343
branches: trunk
changeset: 828272:bb8c480c1343
user: roy <roy%NetBSD.org@localhost>
date: Wed Dec 06 10:35:05 2017 +0000
description:
Sync
diffstat:
external/bsd/dhcpcd/dist/src/bpf.c | 5 +-
external/bsd/dhcpcd/dist/src/dhcp.c | 213 +++++++++++++++++++++------------
external/bsd/dhcpcd/dist/src/dhcpcd.c | 68 ++++------
3 files changed, 164 insertions(+), 122 deletions(-)
diffs (truncated from 468 to 300 lines):
diff -r a92455ebcd6f -r bb8c480c1343 external/bsd/dhcpcd/dist/src/bpf.c
--- a/external/bsd/dhcpcd/dist/src/bpf.c Wed Dec 06 10:33:29 2017 +0000
+++ b/external/bsd/dhcpcd/dist/src/bpf.c Wed Dec 06 10:35:05 2017 +0000
@@ -194,7 +194,8 @@
/* BPF requires that we read the entire buffer.
* So we pass the buffer in the API so we can loop on >1 packet. */
ssize_t
-bpf_read(struct interface *ifp, int fd, void *data, size_t len, int *flags)
+bpf_read(struct interface *ifp, int fd, void *data, size_t len,
+ unsigned int *flags)
{
ssize_t fl = (ssize_t)bpf_frame_header_len(ifp);
ssize_t bytes;
@@ -203,7 +204,7 @@
struct bpf_hdr packet;
const char *payload;
- *flags = 0;
+ *flags &= ~BPF_EOF;
for (;;) {
if (state->buffer_len == 0) {
bytes = read(fd, state->buffer, state->buffer_size);
diff -r a92455ebcd6f -r bb8c480c1343 external/bsd/dhcpcd/dist/src/dhcp.c
--- a/external/bsd/dhcpcd/dist/src/dhcp.c Wed Dec 06 10:33:29 2017 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp.c Wed Dec 06 10:35:05 2017 +0000
@@ -428,7 +428,6 @@
if ((rt = rt_new(ifp)) == NULL)
return -1;
- TAILQ_INSERT_TAIL(routes, rt, rt_next);
/* If we have ocets then we have a destination and netmask */
dest.s_addr = 0;
@@ -461,6 +460,8 @@
/* If CIDR is 32 then it's a host route. */
if (cidr == 32)
rt->rt_flags = RTF_HOST;
+
+ TAILQ_INSERT_TAIL(routes, rt, rt_next);
n++;
}
return n;
@@ -1408,27 +1409,24 @@
continue;
if (dhcp_getoverride(ifo, opt->option))
continue;
- if ((p = get_option(ifp->ctx, bootp, bootp_len,
- opt->option, &pl)))
- {
- ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
- opt, dhcp_getoption, p, pl);
- if (opt->option == DHO_VIVSO &&
- pl > (int)sizeof(uint32_t))
- {
- memcpy(&en, p, sizeof(en));
- en = ntohl(en);
- vo = vivso_find(en, ifp);
- if (vo) {
- /* Skip over en + total size */
- p += sizeof(en) + 1;
- pl -= sizeof(en) + 1;
- ep += dhcp_envoption(ifp->ctx,
- ep, prefix, ifp->name,
- vo, dhcp_getoption, p, pl);
- }
- }
- }
+ p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl);
+ if (p == NULL)
+ continue;
+ ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
+ opt, dhcp_getoption, p, pl);
+
+ if (opt->option != DHO_VIVSO || pl <= (int)sizeof(uint32_t))
+ continue;
+ memcpy(&en, p, sizeof(en));
+ en = ntohl(en);
+ vo = vivso_find(en, ifp);
+ if (vo == NULL)
+ continue;
+ /* Skip over en + total size */
+ p += sizeof(en) + 1;
+ pl -= sizeof(en) + 1;
+ ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
+ vo, dhcp_getoption, p, pl);
}
for (i = 0, opt = ifo->dhcp_override;
@@ -1437,10 +1435,11 @@
{
if (has_option_mask(ifo->nomask, opt->option))
continue;
- if ((p = get_option(ifp->ctx, bootp, bootp_len,
- opt->option, &pl)))
- ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
- opt, dhcp_getoption, p, pl);
+ p = get_option(ifp->ctx, bootp, bootp_len, opt->option, &pl);
+ if (p == NULL)
+ continue;
+ ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
+ opt, dhcp_getoption, p, pl);
}
return ep - env;
@@ -1519,6 +1518,8 @@
dhcp_new_xid(struct interface *ifp)
{
struct dhcp_state *state;
+ const struct interface *ifp1;
+ const struct dhcp_state *state1;
state = D_STATE(ifp);
if (ifp->options->options & DHCPCD_XID_HWADDR &&
@@ -1527,8 +1528,30 @@
memcpy(&state->xid,
(ifp->hwaddr + ifp->hwlen) - sizeof(state->xid),
sizeof(state->xid));
- else
+ else {
+again:
state->xid = arc4random();
+ }
+
+ /* Ensure it's unique */
+ TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) {
+ if (ifp == ifp1)
+ continue;
+ if ((state1 = D_CSTATE(ifp1)) == NULL)
+ continue;
+ if (state1->xid == state->xid)
+ break;
+ }
+ if (ifp1 != NULL) {
+ if (ifp->options->options & DHCPCD_XID_HWADDR &&
+ ifp->hwlen >= sizeof(state->xid))
+ {
+ logerrx("%s: duplicate xid on %s",
+ ifp->name, ifp1->name);
+ return;
+ }
+ goto again;
+ }
/* We can't do this when sharing leases across interfaes */
#if 0
@@ -1552,6 +1575,7 @@
eloop_event_delete(ifp->ctx->eloop, state->bpf_fd);
bpf_close(ifp, state->bpf_fd);
state->bpf_fd = -1;
+ state->bpf_flags |= BPF_EOF;
}
state->interval = 0;
@@ -2464,11 +2488,43 @@
}
}
+#ifdef ARP
+static int
+dhcp_activeaddr(const struct interface *ifp, const struct in_addr *addr)
+{
+ const struct interface *ifp1;
+ const struct dhcp_state *state;
+
+ TAILQ_FOREACH(ifp1, ifp->ctx->ifaces, next) {
+ if (ifp1 == ifp)
+ continue;
+ if ((state = D_CSTATE(ifp1)) == NULL)
+ continue;
+ switch(state->state) {
+ case DHS_REBOOT:
+ case DHS_RENEW:
+ case DHS_REBIND:
+ case DHS_BOUND:
+ case DHS_INFORM:
+ break;
+ default:
+ continue;
+ }
+ if (state->lease.addr.s_addr == addr->s_addr)
+ return 1;
+ }
+ return 0;
+}
+#endif
+
static void
dhcp_reboot(struct interface *ifp)
{
struct if_options *ifo;
struct dhcp_state *state = D_STATE(ifp);
+#ifdef ARP
+ struct ipv4_addr *ia;
+#endif
if (state == NULL || state->state == DHS_NONE)
return;
@@ -2499,6 +2555,20 @@
loginfox("%s: rebinding lease of %s",
ifp->name, inet_ntoa(state->lease.addr));
+
+#ifdef ARP
+ /* If the address exists on the interface and no other interface
+ * is currently using it then announce it to ensure this
+ * interface gets the reply. */
+ ia = ipv4_iffindaddr(ifp, &state->lease.addr, NULL);
+ if (ia != NULL &&
+#ifdef IN_IFF_NOTUSEABLE
+ !(ia->addr_flags & IN_IFF_NOTUSEABLE) &&
+#endif
+ dhcp_activeaddr(ifp, &state->lease.addr) == 0)
+ arp_ifannounceaddr(ifp, &state->lease.addr);
+#endif
+
dhcp_new_xid(ifp);
state->lease.server.s_addr = 0;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
@@ -3147,7 +3217,7 @@
if (data_len < sizeof(p->ip) + sizeof(p->udp)) {
if (from)
from->s_addr = INADDR_ANY;
- errno = EINVAL;
+ errno = ERANGE;
return -1;
}
p = (struct bootp_pkt *)data;
@@ -3160,7 +3230,7 @@
bytes = ntohs(p->ip.ip_len);
if (bytes > data_len) {
- errno = EINVAL;
+ errno = ENOBUFS;
return -1;
}
@@ -3191,17 +3261,22 @@
}
static void
-dhcp_handlepacket(struct interface *ifp, uint8_t *data, size_t len, int flags)
+dhcp_handlepacket(struct interface *ifp, uint8_t *data, size_t len)
{
struct bootp *bootp;
struct in_addr from;
size_t udp_len;
const struct dhcp_state *state = D_CSTATE(ifp);
- if (valid_udp_packet(data, len, &from, flags & RAW_PARTIALCSUM) == -1)
+ if (valid_udp_packet(data, len, &from,
+ state->bpf_flags & RAW_PARTIALCSUM) == -1)
{
- logerrx("%s: invalid UDP packet from %s",
- ifp->name, inet_ntoa(from));
+ if (errno == EINVAL)
+ logerrx("%s: UDP checksum failure from %s",
+ ifp->name, inet_ntoa(from));
+ else
+ logerr("%s: invalid UDP packet from %s",
+ ifp->name, inet_ntoa(from));
return;
}
if (ifp->flags & IFF_POINTOPOINT &&
@@ -3243,27 +3318,30 @@
struct interface *ifp = arg;
uint8_t buf[MTU_MAX];
ssize_t bytes;
- int flags;
- const struct dhcp_state *state = D_CSTATE(ifp);
+ struct dhcp_state *state = D_STATE(ifp);
/* Some RAW mechanisms are generic file descriptors, not sockets.
* This means we have no kernel call to just get one packet,
* so we have to process the entire buffer. */
- flags = 0;
- while (!(flags & BPF_EOF)) {
- bytes = bpf_read(ifp, state->bpf_fd, buf, sizeof(buf), &flags);
+ state->bpf_flags &= ~BPF_EOF;
+ state->bpf_flags |= BPF_READING;
+ while (!(state->bpf_flags & BPF_EOF)) {
+ bytes = bpf_read(ifp, state->bpf_fd, buf, sizeof(buf),
+ &state->bpf_flags);
if (bytes == -1) {
if (state->state != DHS_NONE) {
logerr("%s: %s", __func__, ifp->name);
dhcp_close(ifp);
}
- return;
+ break;
}
- dhcp_handlepacket(ifp, buf, (size_t)bytes, flags);
+ dhcp_handlepacket(ifp, buf, (size_t)bytes);
/* Check we still have a state after processing. */
- if ((state = D_CSTATE(ifp)) == NULL || state->bpf_fd == -1)
+ if ((state = D_STATE(ifp)) == NULL)
break;
}
+ if (state != NULL)
+ state->bpf_flags &= ~BPF_READING;
}
Home |
Main Index |
Thread Index |
Old Index