APPEND(&tip, sizeof(tip));
state = ARP_CSTATE(ifp);
- return bpf_send(ifp, state->fd, ETHERTYPE_ARP, arp_buffer, len);
+ return bpf_send(ifp, state->bpf_fd, ETHERTYPE_ARP, arp_buffer, len);
eexit:
errno = ENOBUFS;
{
struct iarp_state *state;
- if ((state = ARP_STATE(ifp)) != NULL && state->fd != -1) {
- eloop_event_delete(ifp->ctx->eloop, state->fd);
- bpf_close(ifp, state->fd);
- state->fd = -1;
+ if ((state = ARP_STATE(ifp)) != NULL && state->bpf_fd != -1) {
+ eloop_event_delete(ifp->ctx->eloop, state->bpf_fd);
+ bpf_close(ifp, state->bpf_fd);
+ state->bpf_fd = -1;
+ state->bpf_flags |= BPF_EOF;
}
}
arp_read(void *arg)
{
struct interface *ifp = arg;
- const struct iarp_state *state;
+ struct iarp_state *state;
uint8_t buf[ARP_LEN];
- int flags;
ssize_t bytes;
/* 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. */
- state = ARP_CSTATE(ifp);
- flags = 0;
- while (!(flags & BPF_EOF)) {
- bytes = bpf_read(ifp, state->fd, buf, sizeof(buf), &flags);
+ state = ARP_STATE(ifp);
+ state->bpf_flags &= ~BPF_EOF;
+ while (!(state->bpf_flags & BPF_EOF)) {
+ bytes = bpf_read(ifp, state->bpf_fd, buf, sizeof(buf),
+ &state->bpf_flags);
if (bytes == -1) {
logerr("%s: %s", __func__, ifp->name);
arp_close(ifp);
}
arp_packet(ifp, buf, (size_t)bytes);
/* Check we still have a state after processing. */
- if ((state = ARP_CSTATE(ifp)) == NULL || state->fd == -1)
+ if ((state = ARP_STATE(ifp)))
break;
}
}
struct iarp_state *state;
state = ARP_STATE(ifp);
- if (state->fd == -1) {
- state->fd = bpf_open(ifp, bpf_arp);
- if (state->fd == -1) {
+ if (state->bpf_fd == -1) {
+ state->bpf_fd = bpf_open(ifp, bpf_arp);
+ if (state->bpf_fd == -1) {
logerr("%s: %s", __func__, ifp->name);
return -1;
}
- eloop_event_add(ifp->ctx->eloop, state->fd, arp_read, ifp);
+ eloop_event_add(ifp->ctx->eloop, state->bpf_fd, arp_read, ifp);
}
- return state->fd;
+ return state->bpf_fd;
}
static void
} else {
const struct iarp_state *state = ARP_CSTATE(astate->iface);
- if (bpf_arp(astate->iface, state->fd) == -1)
+ if (bpf_arp(astate->iface, state->bpf_fd) == -1)
logerr(__func__);
}
astate->probes = 0;
logerr(__func__);
return NULL;
}
- state->fd = -1;
+ state->bpf_fd = -1;
+ state->bpf_flags = 0;
TAILQ_INIT(&state->arp_states);
} else {
if (addr && (astate = arp_find(ifp, addr)))
state = ARP_STATE(ifp);
TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
- if (bpf_arp(ifp, state->fd) == -1)
+ if (bpf_arp(ifp, state->bpf_fd) == -1)
logerr(__func__); /* try and continue */
return astate;
free(state);
ifp->if_data[IF_DATA_ARP] = NULL;
} else
- if (bpf_arp(ifp, state->fd) == -1)
+ if (bpf_arp(ifp, state->bpf_fd) == -1)
logerr(__func__);
}
TAILQ_HEAD(arp_statehead, arp_state);
struct iarp_state {
- int fd;
+ int bpf_fd;
+ unsigned int bpf_flags;
struct arp_statehead arp_states;
};
/* 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;
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);
#ifndef BPF_HEADER
#define BPF_HEADER
-#define BPF_EOF 1 << 0
-#define BPF_PARTIALCSUM 2 << 0
+#define BPF_EOF (1U << 0)
+#define BPF_PARTIALCSUM (2U << 0)
#include "dhcpcd.h"
int bpf_close(struct interface *, int);
int bpf_attach(int, void *, unsigned int);
ssize_t bpf_send(const struct interface *, int, uint16_t, const void *, size_t);
-ssize_t bpf_read(struct interface *, int, void *, size_t, int *);
+ssize_t bpf_read(struct interface *, int, void *, size_t, unsigned int *);
int bpf_arp(struct interface *, int);
int bpf_bootp(struct interface *, int);
#endif
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;
}
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)
{
if (errno == EINVAL)
logerrx("%s: UDP checksum failure from %s",
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;
+ 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);
}
return;
}
- 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;
}
}
int socket;
int bpf_fd;
+ unsigned int bpf_flags;
struct ipv4_addr *addr;
uint8_t added;
/* 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 s, void *data, size_t len, int *flags)
+bpf_read(struct interface *ifp, int s, void *data, size_t len,
+ unsigned int *flags)
{
ssize_t bytes;
struct ipv4_state *state = IPV4_STATE(ifp);
bytes = recvmsg(s, &msg, 0);
if (bytes == -1)
return -1;
- *flags = BPF_EOF; /* We only ever read one packet. */
+ *flags |= BPF_EOF; /* We only ever read one packet. */
+ *flags &= ~BPF_PARTIALCSUM;
if (bytes) {
ssize_t fl = (ssize_t)bpf_frame_header_len(ifp);