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.
This commit is contained in:
parent
9d5960cfa5
commit
8945f73d94
3 changed files with 9 additions and 3 deletions
|
@ -141,6 +141,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
#ifdef IP_SENDSRCADDR
|
#ifdef IP_SENDSRCADDR
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
struct in_addr *sa;
|
struct in_addr *sa;
|
||||||
|
int controllen = 0;
|
||||||
|
|
||||||
msg->msg_control = cbuf;
|
msg->msg_control = cbuf;
|
||||||
msg->msg_controllen = cbuflen;
|
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_level = IPPROTO_IP;
|
||||||
cm->cmsg_type = IP_SENDSRCADDR;
|
cm->cmsg_type = IP_SENDSRCADDR;
|
||||||
cm->cmsg_len = CMSG_LEN(sizeof(*sa));
|
cm->cmsg_len = CMSG_LEN(sizeof(*sa));
|
||||||
|
controllen += CMSG_SPACE(sizeof(*sa));
|
||||||
|
|
||||||
sa = (struct in_addr *) CMSG_DATA(cm);
|
sa = (struct in_addr *) CMSG_DATA(cm);
|
||||||
*sa = ipa_to_in4(s->saddr);
|
*sa = ipa_to_in4(s->saddr);
|
||||||
|
|
||||||
msg->msg_controllen = cm->cmsg_len;
|
msg->msg_controllen = controllen;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
{
|
{
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
struct in_pktinfo *pi;
|
struct in_pktinfo *pi;
|
||||||
|
int controllen = 0;
|
||||||
|
|
||||||
msg->msg_control = cbuf;
|
msg->msg_control = cbuf;
|
||||||
msg->msg_controllen = cbuflen;
|
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_level = SOL_IP;
|
||||||
cm->cmsg_type = IP_PKTINFO;
|
cm->cmsg_type = IP_PKTINFO;
|
||||||
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
|
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
|
||||||
|
controllen += CMSG_SPACE(sizeof(*pi));
|
||||||
|
|
||||||
pi = (struct in_pktinfo *) CMSG_DATA(cm);
|
pi = (struct in_pktinfo *) CMSG_DATA(cm);
|
||||||
pi->ipi_ifindex = s->iface ? s->iface->index : 0;
|
pi->ipi_ifindex = s->iface ? s->iface->index : 0;
|
||||||
pi->ipi_spec_dst = ipa_to_in4(s->saddr);
|
pi->ipi_spec_dst = ipa_to_in4(s->saddr);
|
||||||
pi->ipi_addr = ipa_to_in4(IPA_NONE);
|
pi->ipi_addr = ipa_to_in4(IPA_NONE);
|
||||||
|
|
||||||
msg->msg_controllen = cm->cmsg_len;
|
msg->msg_controllen = controllen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -705,6 +705,7 @@ sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
{
|
{
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
struct in6_pktinfo *pi;
|
struct in6_pktinfo *pi;
|
||||||
|
int controllen = 0;
|
||||||
|
|
||||||
msg->msg_control = cbuf;
|
msg->msg_control = cbuf;
|
||||||
msg->msg_controllen = cbuflen;
|
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_level = SOL_IPV6;
|
||||||
cm->cmsg_type = IPV6_PKTINFO;
|
cm->cmsg_type = IPV6_PKTINFO;
|
||||||
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
|
cm->cmsg_len = CMSG_LEN(sizeof(*pi));
|
||||||
|
controllen += CMSG_SPACE(sizeof(*pi));
|
||||||
|
|
||||||
pi = (struct in6_pktinfo *) CMSG_DATA(cm);
|
pi = (struct in6_pktinfo *) CMSG_DATA(cm);
|
||||||
pi->ipi6_ifindex = s->iface ? s->iface->index : 0;
|
pi->ipi6_ifindex = s->iface ? s->iface->index : 0;
|
||||||
pi->ipi6_addr = ipa_to_in6(s->saddr);
|
pi->ipi6_addr = ipa_to_in6(s->saddr);
|
||||||
|
|
||||||
msg->msg_controllen = cm->cmsg_len;
|
msg->msg_controllen = controllen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue