state->bpf_flags &= ~BPF_READING;
}
+static void
+dhcp_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
+{
+ struct sockaddr_in *from = (struct sockaddr_in *)msg->msg_name;
+ struct iovec *iov = &msg->msg_iov[0];
+ struct interface *ifp;
+ const struct dhcp_state *state;
+
+ ifp = if_findifpfromcmsg(ctx, msg, NULL);
+ if (ifp == NULL) {
+ logerr(__func__);
+ return;
+ }
+ state = D_CSTATE(ifp);
+ if (state == NULL) {
+ logdebugx("%s: received BOOTP for inactive interface",
+ ifp->name);
+ return;
+ }
+
+ if (state->bpf_fd != -1) {
+ /* Avoid a duplicate read if BPF is open for the interface. */
+ return;
+ }
+
+ dhcp_handlebootp(ifp, (struct bootp *)iov->iov_base, iov->iov_len,
+ &from->sin_addr);
+}
+
static void
dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
{
return;
}
- if (ifp == NULL) {
- ifp = if_findifpfromcmsg(ctx, &msg, NULL);
- if (ifp == NULL) {
- logerr(__func__);
- return;
- }
- state = D_CSTATE(ifp);
- if (state == NULL) {
- logdebugx("%s: received BOOTP for inactive interface",
- ifp->name);
- return;
- }
- }
-
- if (state->bpf_fd != -1) {
- /* Avoid a duplicate read if BPF is open for the interface. */
- return;
- }
-
- dhcp_handlebootp(ifp, (struct bootp *)(void *)buf, (size_t)bytes,
- &from.sin_addr);
+ iov.iov_len = (size_t)bytes;
+ dhcp_recvmsg(ctx, &msg);
}
static void
}
static void
-dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
+dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
{
- struct sockaddr_in6 from;
- unsigned char buf[64 * 1024]; /* Maximum UDP message size */
- struct iovec iov = {
- .iov_base = buf,
- .iov_len = sizeof(buf),
- };
- unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo))] = { 0 };
- struct msghdr msg = {
- .msg_name = &from, .msg_namelen = sizeof(from),
- .msg_iov = &iov, .msg_iovlen = 1,
- .msg_control = ctl, .msg_controllen = sizeof(ctl),
- };
- int s;
- size_t len;
- ssize_t bytes;
+ struct sockaddr_in6 *from = msg->msg_name;
+ size_t len = msg->msg_iov[0].iov_len;
char sfrom[INET6_ADDRSTRLEN];
struct interface *ifp;
struct dhcp6_message *r;
uint8_t *o;
uint16_t ol;
- s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_fd;
- bytes = recvmsg(s, &msg, 0);
- if (bytes == -1) {
- logerr(__func__);
- return;
- }
- len = (size_t)bytes;
- inet_ntop(AF_INET6, &from.sin6_addr, sfrom, sizeof(sfrom));
+ inet_ntop(AF_INET6, &from->sin6_addr, sfrom, sizeof(sfrom));
if (len < sizeof(struct dhcp6_message)) {
logerrx("DHCPv6 packet too short from %s", sfrom);
return;
if (ia != NULL)
ifp = ia->iface;
else {
- ifp = if_findifpfromcmsg(ctx, &msg, NULL);
+ ifp = if_findifpfromcmsg(ctx, msg, NULL);
if (ifp == NULL) {
logerr(__func__);
return;
}
}
- r = (struct dhcp6_message *)buf;
+ r = (struct dhcp6_message *)msg->msg_iov[0].iov_base;
o = dhcp6_findmoption(r, len, D6_OPTION_CLIENTID, &ol);
if (o == NULL || ol != ctx->duid_len ||
memcmp(o, ctx->duid, ol) != 0)
dhcp6_recvif(ifp, sfrom, r, len);
}
+static void
+dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
+{
+ struct sockaddr_in6 from;
+ unsigned char buf[64 * 1024]; /* Maximum UDP message size */
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = sizeof(buf),
+ };
+ unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo))] = { 0 };
+ struct msghdr msg = {
+ .msg_name = &from, .msg_namelen = sizeof(from),
+ .msg_iov = &iov, .msg_iovlen = 1,
+ .msg_control = ctl, .msg_controllen = sizeof(ctl),
+ };
+ int s;
+ ssize_t bytes;
+
+ s = ia != NULL ? ia->dhcp6_fd : ctx->dhcp6_fd;
+ bytes = recvmsg(s, &msg, 0);
+ if (bytes == -1) {
+ logerr(__func__);
+ return;
+ }
+
+ iov.iov_len = (size_t)bytes;
+ dhcp6_recvmsg(ctx, &msg, ia);
+}
+
static void
dhcp6_recvaddr(void *arg)
{
}
}
+static void
+ipv6nd_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
+{
+ struct sockaddr_in6 *from = (struct sockaddr_in6 *)msg->msg_name;
+ char sfrom[INET6_ADDRSTRLEN];
+ int hoplimit = 0;
+ struct icmp6_hdr *icp;
+ struct interface *ifp;
+ size_t len = msg->msg_iov[0].iov_len;
+
+ inet_ntop(AF_INET6, &from->sin6_addr, sfrom, sizeof(sfrom));
+ if ((size_t)len < sizeof(struct icmp6_hdr)) {
+ logerrx("IPv6 ICMP packet too short from %s", sfrom);
+ return;
+ }
+
+#ifdef __sun
+ if_findifpfromcmsg(ctx, msg, &hoplimit);
+#else
+ ifp = if_findifpfromcmsg(ctx, msg, &hoplimit);
+ if (ifp == NULL) {
+ logerr(__func__);
+ return;
+ }
+#endif
+
+ /* Don't do anything if the user hasn't configured it. */
+ if (ifp->active != IF_ACTIVE_USER ||
+ !(ifp->options->options & DHCPCD_IPV6))
+ return;
+
+ icp = (struct icmp6_hdr *)msg->msg_iov[0].iov_base;
+ if (icp->icmp6_code == 0) {
+ switch(icp->icmp6_type) {
+ case ND_ROUTER_ADVERT:
+ ipv6nd_handlera(ctx, from, sfrom,
+ ifp, icp, (size_t)len, hoplimit);
+ return;
+ }
+ }
+
+ logerrx("invalid IPv6 type %d or code %d from %s",
+ icp->icmp6_type, icp->icmp6_code, sfrom);
+}
+
static void
ipv6nd_handledata(void *arg)
{
.msg_control = ctl, .msg_controllen = sizeof(ctl),
};
ssize_t len;
- char sfrom[INET6_ADDRSTRLEN];
- int hoplimit = 0;
- struct icmp6_hdr *icp;
- struct interface *ifp;
#ifdef __sun
struct rs_state *state;
logerr(__func__);
return;
}
- inet_ntop(AF_INET6, &from.sin6_addr, sfrom, sizeof(sfrom));
- if ((size_t)len < sizeof(struct icmp6_hdr)) {
- logerrx("IPv6 ICMP packet too short from %s", sfrom);
- return;
- }
-
-#ifdef __sun
- if_findifpfromcmsg(ctx, &msg, &hoplimit);
-#else
- ifp = if_findifpfromcmsg(ctx, &msg, &hoplimit);
- if (ifp == NULL) {
- logerr(__func__);
- return;
- }
-#endif
- /* Don't do anything if the user hasn't configured it. */
- if (ifp->active != IF_ACTIVE_USER ||
- !(ifp->options->options & DHCPCD_IPV6))
- return;
-
- icp = (struct icmp6_hdr *)buf;
- if (icp->icmp6_code == 0) {
- switch(icp->icmp6_type) {
- case ND_ROUTER_ADVERT:
- ipv6nd_handlera(ctx, &from, sfrom,
- ifp, icp, (size_t)len, hoplimit);
- return;
- }
- }
-
- logerrx("invalid IPv6 type %d or code %d from %s",
- icp->icmp6_type, icp->icmp6_code, sfrom);
+ iov.iov_len = (size_t)len;
+ ipv6nd_recvmsg(ctx, &msg);
}
static void