diff options
author | Andreas Schneider <asn@samba.org> | 2014-05-26 11:07:45 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2014-05-26 16:45:16 +0200 |
commit | 3c55e35cad90ef3c1126b390cf53b860c99fdd6e (patch) | |
tree | f6d7837e6d715879ea261e49550d656b305a3090 /tests/echo_srv.c | |
parent | 29f24e5cc059ed37117126838045f85b494fc288 (diff) | |
download | socket_wrapper-3c55e35cad90ef3c1126b390cf53b860c99fdd6e.tar.gz socket_wrapper-3c55e35cad90ef3c1126b390cf53b860c99fdd6e.tar.xz socket_wrapper-3c55e35cad90ef3c1126b390cf53b860c99fdd6e.zip |
echo_srv: Implement support for IP_RECVDSTADDR on BSD.
Pair-Programmed-With: Michael Adam <obnox@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'tests/echo_srv.c')
-rw-r--r-- | tests/echo_srv.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/tests/echo_srv.c b/tests/echo_srv.c index 72dd411..3d53994 100644 --- a/tests/echo_srv.c +++ b/tests/echo_srv.c @@ -56,16 +56,23 @@ struct echo_srv_opts { }; #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL + +#if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO) union pktinfo { #ifdef HAVE_STRUCT_IN6_PKTINFO struct in6_pktinfo pkt6; #endif #ifdef HAVE_STRUCT_IN_PKTINFO struct in_pktinfo pkt4; +#elif defined(IP_RECVDSTADDR) + struct in_addr pkt4; #endif char c; }; +#define HAVE_UNION_PKTINFO 1 +#endif /* IP_PKTINFO || IP_RECVDSTADDR || IPV6_PKTINFO */ + static const char *echo_server_address(int family) { switch (family) { @@ -219,19 +226,25 @@ static void set_sock_pktinfo(int sock, int family) switch(family) { case AF_INET: -#ifdef IP_PKTINFO proto = IPPROTO_IP; +#ifdef IP_PKTINFO option = IP_PKTINFO; +#elif IP_RECVDSTADDR + option = IP_RECVDSTADDR; +#else + return; #endif /* IP_PKTINFO */ break; #ifdef HAVE_IPV6 - case AF_INET6: #ifdef IPV6_RECVPKTINFO + case AF_INET6: proto = IPPROTO_IPV6; option = IPV6_RECVPKTINFO; -#endif break; +#endif /* IPV6_RECVPKTINFO */ #endif /* HAVE_IPV6 */ + default: + return; } rc = setsockopt(sock, proto, option, &sockopt, sizeof(sockopt)); @@ -553,7 +566,7 @@ static ssize_t echo_udp_recv_from_to(int sock, struct iovec riov; ssize_t ret; -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO) size_t cmlen = CMSG_LEN(sizeof(union pktinfo)); char cmsg[cmlen]; #else @@ -572,7 +585,7 @@ static ssize_t echo_udp_recv_from_to(int sock, rmsg.msg_iov = &riov; rmsg.msg_iovlen = 1; -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO) memset(cmsg, 0, cmlen); rmsg.msg_control = cmsg; @@ -585,7 +598,7 @@ static ssize_t echo_udp_recv_from_to(int sock, } *fromlen = rmsg.msg_namelen; -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO) if (rmsg.msg_controllen > 0) { struct cmsghdr *cmsgptr; @@ -593,12 +606,12 @@ static ssize_t echo_udp_recv_from_to(int sock, while (cmsgptr != NULL) { const char *p; -#ifdef IP_PKTINFO +#if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO) if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) { char ip[INET_ADDRSTRLEN] = { 0 }; - struct in_pktinfo *pkt; struct sockaddr_in *sinp = (struct sockaddr_in *)to; + struct in_pktinfo *pkt; pkt = (struct in_pktinfo *)CMSG_DATA(cmsgptr); @@ -618,7 +631,32 @@ static ssize_t echo_udp_recv_from_to(int sock, } } #endif /* IP_PKTINFO */ -#ifdef IPV6_PKTINFO +#ifdef IP_RECVDSTADDR + if (cmsgptr->cmsg_level == IPPROTO_IP && + cmsgptr->cmsg_type == IP_RECVDSTADDR) { + char ip[INET_ADDRSTRLEN] = { 0 }; + struct sockaddr_in *sinp = (struct sockaddr_in *)to; + struct in_addr *addr; + + addr = (struct in_addr *)CMSG_DATA(cmsgptr); + + sinp->sin_family = AF_INET; + sinp->sin_addr = *addr; + *tolen = sizeof(struct sockaddr_in); + + p = inet_ntop(AF_INET, &sinp->sin_addr, ip, sizeof(ip)); + if (p == 0) { + fprintf(stderr, "Failed to convert IP address"); + abort(); + } + + if (strcmp(ip, echo_server_address(AF_INET)) != 0) { + fprintf(stderr, "Wrong IP received"); + abort(); + } + } +#endif /* IP_RECVDSTADDR */ +#if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO) if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO) { char ip[INET6_ADDRSTRLEN] = { 0 }; @@ -648,7 +686,7 @@ static ssize_t echo_udp_recv_from_to(int sock, fprintf(stderr, "Failed to receive pktinfo"); abort(); } -#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ +#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL && HAVE_UNION_PKTINFO */ return ret; } @@ -662,14 +700,14 @@ static ssize_t echo_udp_send_to_from(int sock, struct iovec iov; ssize_t ret; -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO) size_t clen = CMSG_SPACE(sizeof(union pktinfo)); char cbuf[clen]; struct cmsghdr *cmsgptr; #else (void)from; /* unused */ (void)fromlen; /* unused */ -#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */ +#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL && HAVE_UNION_PKTINFO */ iov.iov_base = buf; iov.iov_len = buflen; @@ -682,7 +720,7 @@ static ssize_t echo_udp_send_to_from(int sock, msg.msg_iov = &iov; msg.msg_iovlen = 1; -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO) memset(cbuf, 0, clen); msg.msg_control = cbuf; @@ -735,7 +773,7 @@ static ssize_t echo_udp_send_to_from(int sock, default: break; } -#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ +#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL && HAVE_UNION_PKTINFO */ ret = sendmsg(sock, &msg, flags); |