summaryrefslogtreecommitdiff
path: root/ipsvd/udp_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipsvd/udp_io.c')
-rw-r--r--ipsvd/udp_io.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/ipsvd/udp_io.c b/ipsvd/udp_io.c
index 68999d44d..2efc15913 100644
--- a/ipsvd/udp_io.c
+++ b/ipsvd/udp_io.c
@@ -18,12 +18,13 @@ socket_want_pktinfo(int fd)
18#ifdef IP_PKTINFO 18#ifdef IP_PKTINFO
19 setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); 19 setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int));
20#endif 20#endif
21#ifdef IPV6_PKTINFO 21#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
22 setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); 22 setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int));
23#endif 23#endif
24} 24}
25 25
26 26
27#ifdef UNUSED
27ssize_t 28ssize_t
28send_to_from(int fd, void *buf, size_t len, int flags, 29send_to_from(int fd, void *buf, size_t len, int flags,
29 const struct sockaddr *from, const struct sockaddr *to, 30 const struct sockaddr *from, const struct sockaddr *to,
@@ -34,8 +35,11 @@ send_to_from(int fd, void *buf, size_t len, int flags,
34#else 35#else
35 struct iovec iov[1]; 36 struct iovec iov[1];
36 struct msghdr msg; 37 struct msghdr msg;
37 char cbuf[LSA_SIZEOF_SA]; 38 char cbuf[sizeof(struct in_pktinfo)
38 /* actually, max(sizeof(in_pktinfo),sizeof(in6_pktinfo)) */ 39#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
40 | sizeof(struct in6_pktinfo) /* (a|b) is poor man's max(a,b) */
41#endif
42 ];
39 struct cmsghdr* cmsgptr; 43 struct cmsghdr* cmsgptr;
40 44
41 if (from->sa_family != AF_INET 45 if (from->sa_family != AF_INET
@@ -73,11 +77,11 @@ send_to_from(int fd, void *buf, size_t len, int flags,
73 /* pktptr->ipi_ifindex = 0; -- already done by memset(cbuf...) */ 77 /* pktptr->ipi_ifindex = 0; -- already done by memset(cbuf...) */
74 pktptr->ipi_spec_dst = ((struct sockaddr_in*)from)->sin_addr; 78 pktptr->ipi_spec_dst = ((struct sockaddr_in*)from)->sin_addr;
75 } 79 }
76#if ENABLE_FEATURE_IPV6 && defined(IP6_PKTINFO) 80#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
77 else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) { 81 else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) {
78 struct in6_pktinfo *pktptr; 82 struct in6_pktinfo *pktptr;
79 cmsgptr->cmsg_level = IPPROTO_IPV6; 83 cmsgptr->cmsg_level = IPPROTO_IPV6;
80 cmsgptr->cmsg_type = IP6_PKTINFO; 84 cmsgptr->cmsg_type = IPV6_PKTINFO;
81 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 85 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
82 pktptr = (struct in6_pktinfo *)(CMSG_DATA(cmsgptr)); 86 pktptr = (struct in6_pktinfo *)(CMSG_DATA(cmsgptr));
83 /* pktptr->ipi6_ifindex = 0; -- already done by memset(cbuf...) */ 87 /* pktptr->ipi6_ifindex = 0; -- already done by memset(cbuf...) */
@@ -87,8 +91,12 @@ send_to_from(int fd, void *buf, size_t len, int flags,
87 return sendmsg(fd, &msg, flags); 91 return sendmsg(fd, &msg, flags);
88#endif 92#endif
89} 93}
94#endif /* UNUSED */
90 95
91/* NB: this will never set port# in *to! */ 96/* NB: this will never set port# in 'to'!
97 * _Only_ IP/IPv6 address part of 'to' is _maybe_ modified.
98 * Typical usage is to preinit it with "default" value
99 * before calling recv_from_to(). */
92ssize_t 100ssize_t
93recv_from_to(int fd, void *buf, size_t len, int flags, 101recv_from_to(int fd, void *buf, size_t len, int flags,
94 struct sockaddr *from, struct sockaddr *to, 102 struct sockaddr *from, struct sockaddr *to,
@@ -123,7 +131,6 @@ recv_from_to(int fd, void *buf, size_t len, int flags,
123 return recv_length; 131 return recv_length;
124 132
125 /* Here we try to retrieve destination IP and memorize it */ 133 /* Here we try to retrieve destination IP and memorize it */
126 memset(to, 0, sa_size);
127 for (cmsgptr = CMSG_FIRSTHDR(&msg); 134 for (cmsgptr = CMSG_FIRSTHDR(&msg);
128 cmsgptr != NULL; 135 cmsgptr != NULL;
129 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr) 136 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)
@@ -138,9 +145,9 @@ recv_from_to(int fd, void *buf, size_t len, int flags,
138#undef pktinfo 145#undef pktinfo
139 break; 146 break;
140 } 147 }
141#if ENABLE_FEATURE_IPV6 && defined(IP6_PKTINFO) 148#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO)
142 if (cmsgptr->cmsg_level == IPPROTO_IPV6 149 if (cmsgptr->cmsg_level == IPPROTO_IPV6
143 && cmsgptr->cmsg_type == IP6_PKTINFO 150 && cmsgptr->cmsg_type == IPV6_PKTINFO
144 ) { 151 ) {
145#define pktinfo(cmsgptr) ( (struct in6_pktinfo*)(CMSG_DATA(cmsgptr)) ) 152#define pktinfo(cmsgptr) ( (struct in6_pktinfo*)(CMSG_DATA(cmsgptr)) )
146 to->sa_family = AF_INET6; 153 to->sa_family = AF_INET6;