static int
set_recvpktinfo(int s, int family)
{
-#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IP_PKTINFO)
+#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) || (defined(IP_RECVDSTADDR) && defined(IP_SENDSRCADDR)) || defined(IP_PKTINFO)
int on = 1;
#else
(void)s;
# endif /* defined IPV6_RECVPKTINFO */
} else if(family == AF_INET) {
-# ifdef IP_RECVDSTADDR
- if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
+# ifdef IP_PKTINFO
+ if(setsockopt(s, IPPROTO_IP, IP_PKTINFO,
(void*)&on, (socklen_t)sizeof(on)) < 0) {
- log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s",
+ log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s",
strerror(errno));
return 0;
}
-# elif defined(IP_PKTINFO)
- if(setsockopt(s, IPPROTO_IP, IP_PKTINFO,
+# elif defined(IP_RECVDSTADDR) && defined(IP_SENDSRCADDR)
+ if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
(void*)&on, (socklen_t)sizeof(on)) < 0) {
- log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s",
+ log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s",
strerror(errno));
return 0;
}
# else
- log_err("no IP_RECVDSTADDR or IP_PKTINFO option, please disable "
+ log_err("no IP_SENDSRCADDR or IP_PKTINFO option, please disable "
"interface-automatic in config");
return 0;
# endif /* IP_PKTINFO */
#ifndef S_SPLINT_S
cmsg = CMSG_FIRSTHDR(&msg);
if(r->srctype == 4) {
-#ifdef IP_RECVDSTADDR
- msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
- log_assert(msg.msg_controllen <= sizeof(control));
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_RECVDSTADDR;
- memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr,
- sizeof(struct in_addr));
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
-#elif defined(IP_PKTINFO)
+#ifdef IP_PKTINFO
msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
log_assert(msg.msg_controllen <= sizeof(control));
cmsg->cmsg_level = IPPROTO_IP;
memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info,
sizeof(struct in_pktinfo));
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+#elif defined(IP_SENDSRCADDR)
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
+ log_assert(msg.msg_controllen <= sizeof(control));
+ cmsg->cmsg_level = IPPROTO_IP;
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr,
+ sizeof(struct in_addr));
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+#else
+ verbose(VERB_ALGO, "no IP_PKTINFO or IP_SENDSRCADDR");
+ msg.msg_control = NULL;
#endif
} else if(r->srctype == 6) {
msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg),
sizeof(struct in6_pktinfo));
break;
-#ifdef IP_RECVDSTADDR
- } else if( cmsg->cmsg_level == IPPROTO_IP &&
- cmsg->cmsg_type == IP_RECVDSTADDR) {
- rep.srctype = 4;
- memmove(&rep.pktinfo.v4addr, CMSG_DATA(cmsg),
- sizeof(struct in_addr));
- break;
-#elif defined(IP_PKTINFO)
+#ifdef IP_PKTINFO
} else if( cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == IP_PKTINFO) {
rep.srctype = 4;
memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg),
sizeof(struct in_pktinfo));
break;
+#elif defined(IP_RECVDSTADDR)
+ } else if( cmsg->cmsg_level == IPPROTO_IP &&
+ cmsg->cmsg_type == IP_RECVDSTADDR) {
+ rep.srctype = 4;
+ memmove(&rep.pktinfo.v4addr, CMSG_DATA(cmsg),
+ sizeof(struct in_addr));
+ break;
#endif
}
}