Skip to content

Commit 3d4b153

Browse files
committed
Add IPv6 support to the plain UDP and TCP servers
1 parent 5daa522 commit 3d4b153

File tree

2 files changed

+84
-26
lines changed

2 files changed

+84
-26
lines changed

server/tcp_server.c

+29-9
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ run_tcp_server(fko_srv_options_t *opts, int family)
6060
int reuse_addr = 1, rv=1;
6161
fd_set sfd_set;
6262
struct sockaddr_in saddr, caddr;
63+
struct sockaddr_in6 saddr6, caddr6;
6364
struct timeval tv;
64-
char sipbuf[MAX_IPV4_STR_LEN] = {0};
65+
char sipbuf[MAX_IPV46_STR_LEN] = {0};
6566

6667
log_msg(LOG_INFO, "Kicking off TCP server to listen on port %i.",
6768
opts->tcpserv_port);
@@ -135,13 +136,29 @@ run_tcp_server(fko_srv_options_t *opts, int family)
135136
#endif
136137

137138
/* Construct local address structure */
138-
memset(&saddr, 0, sizeof(saddr));
139-
saddr.sin_family = family; /* Internet address family */
140-
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
141-
saddr.sin_port = htons(opts->tcpserv_port); /* Local port */
139+
if(family == AF_INET)
140+
{
141+
memset(&saddr, 0, sizeof(saddr));
142+
saddr.sin_family = family; /* Internet address family */
143+
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
144+
saddr.sin_port = htons(opts->tcpserv_port); /* Local port */
145+
} else if(family == AF_INET6) {
146+
memset(&saddr6, 0, sizeof(saddr6));
147+
saddr6.sin6_family = family; /* Internet address family */
148+
saddr6.sin6_addr = in6addr_any; /* Any incoming interface */
149+
saddr6.sin6_port = htons(opts->tcpserv_port); /* Local port */
150+
}
151+
else
152+
{
153+
log_msg(LOG_ERR, "run_tcp_server: unsupported protocol family (%d)",
154+
family);
155+
close(s_sock);
156+
return -1;
157+
}
142158

143159
/* Bind to the local address */
144-
if (bind(s_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
160+
if ((family == AF_INET && bind(s_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
161+
|| (family == AF_INET6 && bind(s_sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0))
145162
{
146163
log_msg(LOG_ERR, "run_tcp_server: bind() failed: %s",
147164
strerror(errno));
@@ -172,7 +189,7 @@ run_tcp_server(fko_srv_options_t *opts, int family)
172189
*/
173190
while(1)
174191
{
175-
clen = sizeof(caddr);
192+
clen = (family == AF_INET) ? sizeof(caddr) : sizeof(caddr6);
176193

177194
/* Initialize and setup the socket for select.
178195
*/
@@ -225,8 +242,11 @@ run_tcp_server(fko_srv_options_t *opts, int family)
225242

226243
if(opts->verbose)
227244
{
228-
memset(sipbuf, 0x0, sizeof(sipbuf));
229-
inet_ntop(family, &(caddr.sin_addr.s_addr), sipbuf, sizeof(sipbuf));
245+
memset(sipbuf, 0, sizeof(sipbuf));
246+
if(family == AF_INET)
247+
inet_ntop(family, &caddr.sin_addr.s_addr, sipbuf, sizeof(sipbuf));
248+
else if(family == AF_INET6)
249+
inet_ntop(family, &caddr6.sin6_addr, sipbuf, sizeof(sipbuf));
230250
log_msg(LOG_INFO, "tcp_server: Got TCP connection from %s.", sipbuf);
231251
}
232252

server/udp_server.c

+55-17
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ run_udp_server(fko_srv_options_t *opts, int family)
5656
int rv=1, chk_rm_all=0;
5757
fd_set sfd_set;
5858
struct sockaddr_in saddr, caddr;
59+
struct sockaddr_in6 saddr6, caddr6;
5960
struct timeval tv;
60-
char sipbuf[MAX_IPV4_STR_LEN] = {0};
61+
char sipbuf[MAX_IPV46_STR_LEN] = {0};
6162
char dgram_msg[MAX_SPA_PACKET_LEN+1] = {0};
6263
socklen_t clen;
6364

@@ -95,13 +96,29 @@ run_udp_server(fko_srv_options_t *opts, int family)
9596
}
9697

9798
/* Construct local address structure */
98-
memset(&saddr, 0x0, sizeof(saddr));
99-
saddr.sin_family = family; /* Internet address family */
100-
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
101-
saddr.sin_port = htons(opts->udpserv_port); /* Local port */
99+
if(family == AF_INET)
100+
{
101+
memset(&saddr, 0, sizeof(saddr));
102+
saddr.sin_family = family; /* Internet address family */
103+
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
104+
saddr.sin_port = htons(opts->udpserv_port); /* Local port */
105+
} else if(family == AF_INET6) {
106+
memset(&saddr6, 0, sizeof(saddr6));
107+
saddr6.sin6_family = family; /* Internet address family */
108+
saddr6.sin6_addr = in6addr_any; /* Any incoming interface */
109+
saddr6.sin6_port = htons(opts->udpserv_port); /* Local port */
110+
}
111+
else
112+
{
113+
log_msg(LOG_ERR, "run_udp_server: unsupported protocol family (%d)",
114+
family);
115+
close(s_sock);
116+
return -1;
117+
}
102118

103119
/* Bind to the local address */
104-
if (bind(s_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
120+
if ((family == AF_INET && bind(s_sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
121+
|| (family == AF_INET6 && bind(s_sock, (struct sockaddr *) &saddr6, sizeof(saddr6)) < 0))
105122
{
106123
log_msg(LOG_ERR, "run_udp_server: bind() failed: %s",
107124
strerror(errno));
@@ -184,17 +201,27 @@ run_udp_server(fko_srv_options_t *opts, int family)
184201

185202
/* If we make it here then there is a datagram to process
186203
*/
187-
clen = sizeof(caddr);
188-
189-
pkt_len = recvfrom(s_sock, dgram_msg, MAX_SPA_PACKET_LEN,
190-
0, (struct sockaddr *)&caddr, &clen);
204+
if(family == AF_INET) {
205+
clen = sizeof(caddr);
206+
pkt_len = recvfrom(s_sock, dgram_msg, MAX_SPA_PACKET_LEN,
207+
0, (struct sockaddr *)&caddr, &clen);
208+
}
209+
else if(family == AF_INET6)
210+
{
211+
clen = sizeof(caddr6);
212+
pkt_len = recvfrom(s_sock, dgram_msg, MAX_SPA_PACKET_LEN,
213+
0, (struct sockaddr *)&caddr6, &clen);
214+
}
191215

192216
dgram_msg[pkt_len] = 0x0;
193217

194218
if(opts->verbose)
195219
{
196-
memset(sipbuf, 0x0, sizeof(sipbuf));
197-
inet_ntop(family, &(caddr.sin_addr.s_addr), sipbuf, sizeof(sipbuf));
220+
memset(sipbuf, 0, sizeof(sipbuf));
221+
if(family == AF_INET)
222+
inet_ntop(family, &caddr.sin_addr.s_addr, sipbuf, sizeof(sipbuf));
223+
else if(family == AF_INET6)
224+
inet_ntop(family, &caddr6.sin6_addr, sipbuf, sizeof(sipbuf));
198225
log_msg(LOG_INFO, "udp_server: Got UDP datagram (%d bytes) from: %s",
199226
pkt_len, sipbuf);
200227
}
@@ -208,15 +235,26 @@ run_udp_server(fko_srv_options_t *opts, int family)
208235
strlcpy((char *)opts->spa_pkt.packet_data, dgram_msg, pkt_len+1);
209236
opts->spa_pkt.packet_data_len = pkt_len;
210237
opts->spa_pkt.packet_proto = IPPROTO_UDP;
211-
opts->spa_pkt.packet_src_ip = caddr.sin_addr.s_addr;
212-
opts->spa_pkt.packet_dst_ip = saddr.sin_addr.s_addr;
213-
opts->spa_pkt.packet_src_port = ntohs(caddr.sin_port);
214-
opts->spa_pkt.packet_dst_port = ntohs(saddr.sin_port);
238+
opts->spa_pkt.packet_family = family;
239+
if(family == AF_INET)
240+
{
241+
opts->spa_pkt.packet_src_ip = caddr.sin_addr.s_addr;
242+
opts->spa_pkt.packet_dst_ip = saddr.sin_addr.s_addr;
243+
opts->spa_pkt.packet_src_port = ntohs(caddr.sin_port);
244+
opts->spa_pkt.packet_dst_port = ntohs(saddr.sin_port);
245+
}
246+
else if(family == AF_INET6)
247+
{
248+
opts->spa_pkt.packet_addr.inet6.src_ip = caddr6.sin6_addr;
249+
opts->spa_pkt.packet_addr.inet6.dst_ip = saddr6.sin6_addr;
250+
opts->spa_pkt.packet_src_port = ntohs(caddr6.sin6_port);
251+
opts->spa_pkt.packet_dst_port = ntohs(saddr6.sin6_port);
252+
}
215253

216254
incoming_spa(opts);
217255
}
218256

219-
memset(dgram_msg, 0x0, sizeof(dgram_msg));
257+
memset(dgram_msg, 0, sizeof(dgram_msg));
220258

221259
opts->packet_ctr += 1;
222260
if(opts->foreground == 1 && opts->verbose > 2)

0 commit comments

Comments
 (0)