diff --git a/src/bsd.c b/src/bsd.c index b4abea5..b06b30d 100644 --- a/src/bsd.c +++ b/src/bsd.c @@ -144,13 +144,23 @@ int bsd_udp_packet_buffer_local_ip(void *msgvec, int index, char *ip) { #else struct msghdr *mh = &((struct mmsghdr *) msgvec)[index].msg_hdr; for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(mh); cmsg != NULL; cmsg = CMSG_NXTHDR(mh, cmsg)) { - // ipv6 or ipv4 + // Linux ipv4 + #ifdef IP_PKTINFO if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); memcpy(ip, &pi->ipi_addr, 4); return 4; } + // FreeBSD ipv4 + #elif IP_RECVDSTADDR + if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { + struct in_addr *addr = (struct in_addr *) CMSG_DATA(cmsg); + memcpy(ip, addr, 4); + return 4; + } + #endif + // Linux, FreeBSD ipv6 if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { struct in6_pktinfo *pi6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); memcpy(ip, &pi6->ipi6_addr, 16); @@ -630,9 +640,17 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_udp_socket(const char *host, int port) { int enabled = 1; if (setsockopt(listenFd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (void *) &enabled, sizeof(enabled)) == -1) { if (errno == 92) { + // Linux ipv4 + #ifdef IP_PKTINFO if (setsockopt(listenFd, IPPROTO_IP, IP_PKTINFO, (void *) &enabled, sizeof(enabled)) != 0) { printf("Error setting IPv4 pktinfo!\n"); } + // FreeBSD ipv4 + #elif IP_RECVDSTADDR + if (setsockopt(listenFd, IPPROTO_IP, IP_RECVDSTADDR, (void *) &enabled, sizeof(enabled)) != 0) { + printf("Error setting IPv4 pktinfo!\n"); + } + #endif } else { printf("Error setting IPv6 pktinfo!\n"); } diff --git a/src/quic.c b/src/quic.c index 5290746..94a37b9 100644 --- a/src/quic.c +++ b/src/quic.c @@ -229,7 +229,7 @@ void on_udp_socket_data(struct us_udp_socket_t *s, struct us_udp_packet_buffer_t #ifndef UIO_MAXIOV #define UIO_MAXIOV 1024 -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__FreeBSD__) struct mmsghdr { struct msghdr msg_hdr; /* Message header */ unsigned int msg_len; /* Number of bytes transmitted */