From 00028b6b41d90462e4e156813778155675e9628c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Feb 2007 16:42:22 +0000 Subject: FreeBSD portability (Patch from Bruce M Simpson) git-svn-id: file:///home/lennart/svn/public/nss-mdns/trunk@114 0ee8848e-81ea-0310-a63a-f631d1a40d77 --- src/query.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 15 deletions(-) (limited to 'src/query.c') diff --git a/src/query.c b/src/query.c index fe5d541..42549bd 100644 --- a/src/query.c +++ b/src/query.c @@ -87,13 +87,36 @@ int mdns_open_socket(void) { if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) goto fail; +#ifdef IP_PKTINFO yes = 1; - if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0) - goto fail; - if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0) goto fail; +#else + +#ifdef IP_RECVINTERFACE + yes = 1; + if (setsockopt (fd, IPPROTO_IP, IP_RECVINTERFACE, &yes, sizeof(yes)) < 0) + goto fail; +#elif defined(IP_RECVIF) + yes = 1; + if (setsockopt (fd, IPPROTO_IP, IP_RECVIF, &yes, sizeof(yes)) < 0) + goto fail; +#endif + +#ifdef IP_RECVDSTADDR + yes = 1; + if (setsockopt (fd, IPPROTO_IP, IP_RECVDSTADDR, &yes, sizeof(yes)) < 0) + goto fail; +#endif + +#endif /* IP_PKTINFO */ +#ifdef IP_RECVTTL + yes = 1; + if (setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0) + goto fail; +#endif + if (set_cloexec(fd) < 0) goto fail; @@ -113,9 +136,15 @@ static int send_dns_packet(int fd, struct dns_packet *p) { struct sockaddr_in sa; struct msghdr msg; struct iovec io; +#ifdef IP_PKTINFO struct cmsghdr *cmsg; + uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_pktinfo))]; struct in_pktinfo *pkti; - uint8_t cmsg_data[CMSG_LEN(sizeof(struct in_pktinfo))]; +#elif defined(IP_SENDSRCADDR) + struct cmsghdr *cmsg; + uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_addr))]; + struct in_addr *addr; +#endif int i, n; struct ifreq ifreq[32]; struct ifconf ifconf; @@ -131,24 +160,43 @@ static int send_dns_packet(int fd, struct dns_packet *p) { io.iov_base = p->data; io.iov_len = p->size; - memset(cmsg_data, 0, sizeof(cmsg_data)); - cmsg = (struct cmsghdr*) cmsg_data; - cmsg->cmsg_len = sizeof(cmsg_data); - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - - pkti = (struct in_pktinfo*) CMSG_DATA(cmsg); - pkti->ipi_ifindex = 0; - memset(&msg, 0, sizeof(msg)); msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &io; msg.msg_iovlen = 1; + msg.msg_flags = 0; + +#ifdef IP_PKTINFO + memset(cmsg_data, 0, sizeof(cmsg_data)); msg.msg_control = cmsg_data; msg.msg_controllen = sizeof(cmsg_data); - msg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + pkti = (struct in_pktinfo*) CMSG_DATA(cmsg); + + msg.msg_controllen = cmsg->cmsg_len; +#elif defined(IP_SENDSRCADDR) + memset(cmsg_data, 0, sizeof(cmsg_data)); + msg.msg_control = cmsg_data; + msg.msg_controllen = sizeof(cmsg_data); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + + addr = (struct in_addr *)CMSG_DATA(cmsg); + + msg.msg_controllen = cmsg->cmsg_len; +#elif defined(__GNUC__) +#warning "FIXME: We need some code to set the outgoing interface/local address here if IP_PKTINFO/IP_SENDSRCADDR is not available" +#endif + ifconf.ifc_req = ifreq; ifconf.ifc_len = sizeof(ifreq); @@ -183,6 +231,7 @@ static int send_dns_packet(int fd, struct dns_packet *p) { if (ioctl(fd, SIOCGIFINDEX, &ifreq[i]) < 0) continue; /* See above why we ignore this error */ +#ifdef IP_PKTINFO /* Only send the the packet once per interface. We assume that * multiple addresses assigned to the same interface follow * immediately one after the other.*/ @@ -190,6 +239,11 @@ static int send_dns_packet(int fd, struct dns_packet *p) { continue; last_index = pkti->ipi_ifindex = ifreq[i].ifr_ifindex; +#elif defined(IP_SENDSRCADDR) + addr->s_addr = ifsa->sin_addr.s_addr; +#elif defined(__GNUC__) +#warning "FIXME: We need some code to set the outgoing interface/local address here if IP_PKTINFO/IP_SENDSRCADDR is not available" +#endif for (;;) { @@ -241,7 +295,12 @@ static int recv_dns_packet(int fd, struct dns_packet **ret_packet, uint8_t *ret_ *ret_ttl = 0; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) { - if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) { +#ifdef SOL_IP + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) +#else + if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) +#endif + { *ret_ttl = (uint8_t) (*(uint32_t*) CMSG_DATA(cmsg)); break; } -- cgit