ntp: add support for IP_RECVDSTADDR and IP_SENDSRCADDR
FreeBSD doesn't support IP_PKTINFO. Instead it provides IP_RECVDSTADDR and IP_SENDSRCADDR, which can be used to get/set the destination/source address. In future IP_RECVIF and IP_SENDIF may be supported to get and set also the interface.
This commit is contained in:
parent
5fc7674e36
commit
0adc8e8f92
1 changed files with 27 additions and 6 deletions
33
ntp_io.c
33
ntp_io.c
|
@ -231,11 +231,11 @@ prepare_socket(int family, int port_number, int client_only)
|
||||||
|
|
||||||
if (family == AF_INET) {
|
if (family == AF_INET) {
|
||||||
#ifdef HAVE_IN_PKTINFO
|
#ifdef HAVE_IN_PKTINFO
|
||||||
/* We want the local IP info on server sockets */
|
if (setsockopt(sock_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0)
|
||||||
if (setsockopt(sock_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on_off, sizeof(on_off)) < 0) {
|
|
||||||
LOG(LOGS_ERR, "Could not set %s socket option", "IP_PKTINFO");
|
LOG(LOGS_ERR, "Could not set %s socket option", "IP_PKTINFO");
|
||||||
/* Don't quit - we might survive anyway */
|
#elif defined(IP_RECVDSTADDR)
|
||||||
}
|
if (setsockopt(sock_fd, IPPROTO_IP, IP_RECVDSTADDR, (char *)&on_off, sizeof(on_off)) < 0)
|
||||||
|
LOG(LOGS_ERR, "Could not set %s socket option", "IP_RECVDSTADDR");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef FEAT_IPV6
|
#ifdef FEAT_IPV6
|
||||||
|
@ -642,6 +642,14 @@ process_message(struct msghdr *hdr, int length, int sock_fd)
|
||||||
local_addr.ip_addr.family = IPADDR_INET4;
|
local_addr.ip_addr.family = IPADDR_INET4;
|
||||||
local_addr.if_index = ipi.ipi_ifindex;
|
local_addr.if_index = ipi.ipi_ifindex;
|
||||||
}
|
}
|
||||||
|
#elif defined(IP_RECVDSTADDR)
|
||||||
|
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
|
||||||
|
struct in_addr addr;
|
||||||
|
|
||||||
|
memcpy(&addr, CMSG_DATA(cmsg), sizeof (addr));
|
||||||
|
local_addr.ip_addr.addr.in4 = ntohl(addr.s_addr);
|
||||||
|
local_addr.ip_addr.family = IPADDR_INET4;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IN6_PKTINFO
|
#ifdef HAVE_IN6_PKTINFO
|
||||||
|
@ -813,8 +821,8 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
cmsglen = 0;
|
cmsglen = 0;
|
||||||
|
|
||||||
#ifdef HAVE_IN_PKTINFO
|
|
||||||
if (local_addr->ip_addr.family == IPADDR_INET4) {
|
if (local_addr->ip_addr.family == IPADDR_INET4) {
|
||||||
|
#ifdef HAVE_IN_PKTINFO
|
||||||
struct in_pktinfo *ipi;
|
struct in_pktinfo *ipi;
|
||||||
|
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
@ -829,8 +837,21 @@ NIO_SendPacket(NTP_Packet *packet, NTP_Remote_Address *remote_addr,
|
||||||
ipi->ipi_spec_dst.s_addr = htonl(local_addr->ip_addr.addr.in4);
|
ipi->ipi_spec_dst.s_addr = htonl(local_addr->ip_addr.addr.in4);
|
||||||
if (local_addr->if_index != INVALID_IF_INDEX)
|
if (local_addr->if_index != INVALID_IF_INDEX)
|
||||||
ipi->ipi_ifindex = local_addr->if_index;
|
ipi->ipi_ifindex = local_addr->if_index;
|
||||||
}
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
struct in_addr *addr;
|
||||||
|
|
||||||
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
memset(cmsg, 0, CMSG_SPACE(sizeof (struct in_addr)));
|
||||||
|
cmsglen += CMSG_SPACE(sizeof (struct in_addr));
|
||||||
|
|
||||||
|
cmsg->cmsg_level = IPPROTO_IP;
|
||||||
|
cmsg->cmsg_type = IP_SENDSRCADDR;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof (struct in_addr));
|
||||||
|
|
||||||
|
addr = (struct in_addr *)CMSG_DATA(cmsg);
|
||||||
|
addr->s_addr = htonl(local_addr->ip_addr.addr.in4);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IN6_PKTINFO
|
#ifdef HAVE_IN6_PKTINFO
|
||||||
if (local_addr->ip_addr.family == IPADDR_INET6) {
|
if (local_addr->ip_addr.family == IPADDR_INET6) {
|
||||||
|
|
Loading…
Reference in a new issue