summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-06-26 13:30:27 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2014-06-26 13:30:27 +0200
commit8945f73d946a9323daf8dfc1bf5b3884cf6d7664 (patch)
tree8d1e073804f69d9fe7ca683c4a22dae7bc6be77a /sysdep
parent9d5960cfa5b4c15ddd48dbab599f864a6aa1e025 (diff)
Ensures that msg_controllen includes last padding.
Although RFC 3542 allows both cases, Theo de Raadt thinks he knows better, and msg_controllen without last padding fails on OpenBSD. Thanks to Job Snijders for the bugreport.
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/sysio.h4
-rw-r--r--sysdep/linux/sysio.h4
-rw-r--r--sysdep/unix/io.c4
3 files changed, 9 insertions, 3 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h
index fa3969bd..df5e0236 100644
--- a/sysdep/bsd/sysio.h
+++ b/sysdep/bsd/sysio.h
@@ -141,6 +141,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
#ifdef IP_SENDSRCADDR
struct cmsghdr *cm;
struct in_addr *sa;
+ int controllen = 0;
msg->msg_control = cbuf;
msg->msg_controllen = cbuflen;
@@ -149,11 +150,12 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
cm->cmsg_level = IPPROTO_IP;
cm->cmsg_type = IP_SENDSRCADDR;
cm->cmsg_len = CMSG_LEN(sizeof(*sa));
+ controllen += CMSG_SPACE(sizeof(*sa));
sa = (struct in_addr *) CMSG_DATA(cm);
*sa = ipa_to_in4(s->saddr);
- msg->msg_controllen = cm->cmsg_len;
+ msg->msg_controllen = controllen;
#endif
}
diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h
index 5fd75c90..c1561cbf 100644
--- a/sysdep/linux/sysio.h
+++ b/sysdep/linux/sysio.h
@@ -154,6 +154,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
{
struct cmsghdr *cm;
struct in_pktinfo *pi;
+ int controllen = 0;
msg->msg_control = cbuf;
msg->msg_controllen = cbuflen;
@@ -162,13 +163,14 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
cm->cmsg_level = SOL_IP;
cm->cmsg_type = IP_PKTINFO;
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
+ controllen += CMSG_SPACE(sizeof(*pi));
pi = (struct in_pktinfo *) CMSG_DATA(cm);
pi->ipi_ifindex = s->iface ? s->iface->index : 0;
pi->ipi_spec_dst = ipa_to_in4(s->saddr);
pi->ipi_addr = ipa_to_in4(IPA_NONE);
- msg->msg_controllen = cm->cmsg_len;
+ msg->msg_controllen = controllen;
}
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 5a0c07e5..a5477695 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -705,6 +705,7 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
{
struct cmsghdr *cm;
struct in6_pktinfo *pi;
+ int controllen = 0;
msg->msg_control = cbuf;
msg->msg_controllen = cbuflen;
@@ -713,12 +714,13 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
cm->cmsg_level = SOL_IPV6;
cm->cmsg_type = IPV6_PKTINFO;
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
+ controllen += CMSG_SPACE(sizeof(*pi));
pi = (struct in6_pktinfo *) CMSG_DATA(cm);
pi->ipi6_ifindex = s->iface ? s->iface->index : 0;
pi->ipi6_addr = ipa_to_in6(s->saddr);
- msg->msg_controllen = cm->cmsg_len;
+ msg->msg_controllen = controllen;
}