~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/nettest.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* nettest - used for functional tests of networking APIs
  3  *
  4  * Copyright (c) 2013-2019 David Ahern <dsahern@gmail.com>. All rights reserved.
  5  */
  6 
  7 #define _GNU_SOURCE
  8 #include <features.h>
  9 #include <sys/types.h>
 10 #include <sys/ioctl.h>
 11 #include <sys/socket.h>
 12 #include <sys/wait.h>
 13 #include <linux/tcp.h>
 14 #include <linux/udp.h>
 15 #include <arpa/inet.h>
 16 #include <net/if.h>
 17 #include <netinet/in.h>
 18 #include <netinet/ip.h>
 19 #include <netdb.h>
 20 #include <fcntl.h>
 21 #include <libgen.h>
 22 #include <limits.h>
 23 #include <sched.h>
 24 #include <stdarg.h>
 25 #include <stdio.h>
 26 #include <stdlib.h>
 27 #include <string.h>
 28 #include <unistd.h>
 29 #include <time.h>
 30 #include <errno.h>
 31 #include <getopt.h>
 32 
 33 #include <linux/xfrm.h>
 34 #include <linux/ipsec.h>
 35 #include <linux/pfkeyv2.h>
 36 
 37 #ifndef IPV6_UNICAST_IF
 38 #define IPV6_UNICAST_IF         76
 39 #endif
 40 #ifndef IPV6_MULTICAST_IF
 41 #define IPV6_MULTICAST_IF       17
 42 #endif
 43 
 44 #define DEFAULT_PORT 12345
 45 
 46 #define NS_PREFIX "/run/netns/"
 47 
 48 #ifndef MAX
 49 #define MAX(a, b)  ((a) > (b) ? (a) : (b))
 50 #endif
 51 #ifndef MIN
 52 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
 53 #endif
 54 
 55 struct sock_args {
 56         /* local address */
 57         const char *local_addr_str;
 58         const char *client_local_addr_str;
 59         union {
 60                 struct in_addr  in;
 61                 struct in6_addr in6;
 62         } local_addr;
 63 
 64         /* remote address */
 65         const char *remote_addr_str;
 66         union {
 67                 struct in_addr  in;
 68                 struct in6_addr in6;
 69         } remote_addr;
 70         int scope_id;  /* remote scope; v6 send only */
 71 
 72         struct in_addr grp;     /* multicast group */
 73 
 74         unsigned int has_local_ip:1,
 75                      has_remote_ip:1,
 76                      has_grp:1,
 77                      has_expected_laddr:1,
 78                      has_expected_raddr:1,
 79                      bind_test_only:1,
 80                      client_dontroute:1,
 81                      server_dontroute:1;
 82 
 83         unsigned short port;
 84 
 85         int type;      /* DGRAM, STREAM, RAW */
 86         int protocol;
 87         int version;   /* AF_INET/AF_INET6 */
 88 
 89         int use_setsockopt;
 90         int use_freebind;
 91         int use_cmsg;
 92         uint8_t dsfield;
 93         const char *dev;
 94         const char *server_dev;
 95         int ifindex;
 96 
 97         const char *clientns;
 98         const char *serverns;
 99 
100         const char *password;
101         const char *client_pw;
102         /* prefix for MD5 password */
103         const char *md5_prefix_str;
104         union {
105                 struct sockaddr_in v4;
106                 struct sockaddr_in6 v6;
107         } md5_prefix;
108         unsigned int prefix_len;
109         /* 0: default, -1: force off, +1: force on */
110         int bind_key_ifindex;
111 
112         /* expected addresses and device index for connection */
113         const char *expected_dev;
114         const char *expected_server_dev;
115         int expected_ifindex;
116 
117         /* local address */
118         const char *expected_laddr_str;
119         union {
120                 struct in_addr  in;
121                 struct in6_addr in6;
122         } expected_laddr;
123 
124         /* remote address */
125         const char *expected_raddr_str;
126         union {
127                 struct in_addr  in;
128                 struct in6_addr in6;
129         } expected_raddr;
130 
131         /* ESP in UDP encap test */
132         int use_xfrm;
133 
134         /* use send() and connect() instead of sendto */
135         int datagram_connect;
136 };
137 
138 static int server_mode;
139 static unsigned int prog_timeout = 5;
140 static unsigned int interactive;
141 static int iter = 1;
142 static char *msg = "Hello world!";
143 static int msglen;
144 static int quiet;
145 static int try_broadcast = 1;
146 
147 static char *timestamp(char *timebuf, int buflen)
148 {
149         time_t now;
150 
151         now = time(NULL);
152         if (strftime(timebuf, buflen, "%T", localtime(&now)) == 0) {
153                 memset(timebuf, 0, buflen);
154                 strncpy(timebuf, "00:00:00", buflen-1);
155         }
156 
157         return timebuf;
158 }
159 
160 static void log_msg(const char *format, ...)
161 {
162         char timebuf[64];
163         va_list args;
164 
165         if (quiet)
166                 return;
167 
168         fprintf(stdout, "%s %s:",
169                 timestamp(timebuf, sizeof(timebuf)),
170                 server_mode ? "server" : "client");
171         va_start(args, format);
172         vfprintf(stdout, format, args);
173         va_end(args);
174 
175         fflush(stdout);
176 }
177 
178 static void log_error(const char *format, ...)
179 {
180         char timebuf[64];
181         va_list args;
182 
183         if (quiet)
184                 return;
185 
186         fprintf(stderr, "%s %s:",
187                 timestamp(timebuf, sizeof(timebuf)),
188                 server_mode ? "server" : "client");
189         va_start(args, format);
190         vfprintf(stderr, format, args);
191         va_end(args);
192 
193         fflush(stderr);
194 }
195 
196 static void log_err_errno(const char *fmt, ...)
197 {
198         char timebuf[64];
199         va_list args;
200 
201         if (quiet)
202                 return;
203 
204         fprintf(stderr, "%s %s: ",
205                 timestamp(timebuf, sizeof(timebuf)),
206                 server_mode ? "server" : "client");
207         va_start(args, fmt);
208         vfprintf(stderr, fmt, args);
209         va_end(args);
210 
211         fprintf(stderr, ": %d: %s\n", errno, strerror(errno));
212         fflush(stderr);
213 }
214 
215 static void log_address(const char *desc, struct sockaddr *sa)
216 {
217         char addrstr[64];
218 
219         if (quiet)
220                 return;
221 
222         if (sa->sa_family == AF_INET) {
223                 struct sockaddr_in *s = (struct sockaddr_in *) sa;
224 
225                 log_msg("%s %s:%d\n",
226                         desc,
227                         inet_ntop(AF_INET, &s->sin_addr, addrstr,
228                                   sizeof(addrstr)),
229                         ntohs(s->sin_port));
230 
231         } else if (sa->sa_family == AF_INET6) {
232                 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
233 
234                 log_msg("%s [%s]:%d\n",
235                         desc,
236                         inet_ntop(AF_INET6, &s6->sin6_addr, addrstr,
237                                   sizeof(addrstr)),
238                         ntohs(s6->sin6_port));
239         }
240 
241         fflush(stdout);
242 }
243 
244 static int switch_ns(const char *ns)
245 {
246         char path[PATH_MAX];
247         int fd, ret;
248 
249         if (geteuid())
250                 log_error("warning: likely need root to set netns %s!\n", ns);
251 
252         snprintf(path, sizeof(path), "%s%s", NS_PREFIX, ns);
253         fd = open(path, 0);
254         if (fd < 0) {
255                 log_err_errno("Failed to open netns path; can not switch netns");
256                 return 1;
257         }
258 
259         ret = setns(fd, CLONE_NEWNET);
260         close(fd);
261 
262         return ret;
263 }
264 
265 static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args)
266 {
267         int keylen = strlen(args->password);
268         struct tcp_md5sig md5sig = {};
269         int opt = TCP_MD5SIG;
270         int rc;
271 
272         md5sig.tcpm_keylen = keylen;
273         memcpy(md5sig.tcpm_key, args->password, keylen);
274 
275         if (args->prefix_len) {
276                 opt = TCP_MD5SIG_EXT;
277                 md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_PREFIX;
278 
279                 md5sig.tcpm_prefixlen = args->prefix_len;
280                 addr = &args->md5_prefix;
281         }
282         memcpy(&md5sig.tcpm_addr, addr, alen);
283 
284         if ((args->ifindex && args->bind_key_ifindex >= 0) || args->bind_key_ifindex >= 1) {
285                 opt = TCP_MD5SIG_EXT;
286                 md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_IFINDEX;
287 
288                 md5sig.tcpm_ifindex = args->ifindex;
289                 log_msg("TCP_MD5SIG_FLAG_IFINDEX set tcpm_ifindex=%d\n", md5sig.tcpm_ifindex);
290         } else {
291                 log_msg("TCP_MD5SIG_FLAG_IFINDEX off\n", md5sig.tcpm_ifindex);
292         }
293 
294         rc = setsockopt(sd, IPPROTO_TCP, opt, &md5sig, sizeof(md5sig));
295         if (rc < 0) {
296                 /* ENOENT is harmless. Returned when a password is cleared */
297                 if (errno == ENOENT)
298                         rc = 0;
299                 else
300                         log_err_errno("setsockopt(TCP_MD5SIG)");
301         }
302 
303         return rc;
304 }
305 
306 static int tcp_md5_remote(int sd, struct sock_args *args)
307 {
308         struct sockaddr_in sin = {
309                 .sin_family = AF_INET,
310         };
311         struct sockaddr_in6 sin6 = {
312                 .sin6_family = AF_INET6,
313         };
314         void *addr;
315         int alen;
316 
317         switch (args->version) {
318         case AF_INET:
319                 sin.sin_port = htons(args->port);
320                 sin.sin_addr = args->md5_prefix.v4.sin_addr;
321                 addr = &sin;
322                 alen = sizeof(sin);
323                 break;
324         case AF_INET6:
325                 sin6.sin6_port = htons(args->port);
326                 sin6.sin6_addr = args->md5_prefix.v6.sin6_addr;
327                 addr = &sin6;
328                 alen = sizeof(sin6);
329                 break;
330         default:
331                 log_error("unknown address family\n");
332                 exit(1);
333         }
334 
335         if (tcp_md5sig(sd, addr, alen, args))
336                 return -1;
337 
338         return 0;
339 }
340 
341 static int get_ifidx(const char *ifname)
342 {
343         struct ifreq ifdata;
344         int sd, rc;
345 
346         if (!ifname || *ifname == '\0')
347                 return -1;
348 
349         memset(&ifdata, 0, sizeof(ifdata));
350 
351         strcpy(ifdata.ifr_name, ifname);
352 
353         sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
354         if (sd < 0) {
355                 log_err_errno("socket failed");
356                 return -1;
357         }
358 
359         rc = ioctl(sd, SIOCGIFINDEX, (char *)&ifdata);
360         close(sd);
361         if (rc != 0) {
362                 log_err_errno("ioctl(SIOCGIFINDEX) failed");
363                 return -1;
364         }
365 
366         return ifdata.ifr_ifindex;
367 }
368 
369 static int bind_to_device(int sd, const char *name)
370 {
371         int rc;
372 
373         rc = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
374         if (rc < 0)
375                 log_err_errno("setsockopt(SO_BINDTODEVICE)");
376 
377         return rc;
378 }
379 
380 static int get_bind_to_device(int sd, char *name, size_t len)
381 {
382         int rc;
383         socklen_t optlen = len;
384 
385         name[0] = '\0';
386         rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen);
387         if (rc < 0)
388                 log_err_errno("setsockopt(SO_BINDTODEVICE)");
389 
390         return rc;
391 }
392 
393 static int check_device(int sd, struct sock_args *args)
394 {
395         int ifindex = 0;
396         char name[32];
397 
398         if (get_bind_to_device(sd, name, sizeof(name)))
399                 *name = '\0';
400         else
401                 ifindex = get_ifidx(name);
402 
403         log_msg("    bound to device %s/%d\n",
404                 *name ? name : "<none>", ifindex);
405 
406         if (!args->expected_ifindex)
407                 return 0;
408 
409         if (args->expected_ifindex != ifindex) {
410                 log_error("Device index mismatch: expected %d have %d\n",
411                           args->expected_ifindex, ifindex);
412                 return 1;
413         }
414 
415         log_msg("Device index matches: expected %d have %d\n",
416                 args->expected_ifindex, ifindex);
417 
418         return 0;
419 }
420 
421 static int set_pktinfo_v4(int sd)
422 {
423         int one = 1;
424         int rc;
425 
426         rc = setsockopt(sd, SOL_IP, IP_PKTINFO, &one, sizeof(one));
427         if (rc < 0 && rc != -ENOTSUP)
428                 log_err_errno("setsockopt(IP_PKTINFO)");
429 
430         return rc;
431 }
432 
433 static int set_recvpktinfo_v6(int sd)
434 {
435         int one = 1;
436         int rc;
437 
438         rc = setsockopt(sd, SOL_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
439         if (rc < 0 && rc != -ENOTSUP)
440                 log_err_errno("setsockopt(IPV6_RECVPKTINFO)");
441 
442         return rc;
443 }
444 
445 static int set_recverr_v4(int sd)
446 {
447         int one = 1;
448         int rc;
449 
450         rc = setsockopt(sd, SOL_IP, IP_RECVERR, &one, sizeof(one));
451         if (rc < 0 && rc != -ENOTSUP)
452                 log_err_errno("setsockopt(IP_RECVERR)");
453 
454         return rc;
455 }
456 
457 static int set_recverr_v6(int sd)
458 {
459         int one = 1;
460         int rc;
461 
462         rc = setsockopt(sd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one));
463         if (rc < 0 && rc != -ENOTSUP)
464                 log_err_errno("setsockopt(IPV6_RECVERR)");
465 
466         return rc;
467 }
468 
469 static int set_unicast_if(int sd, int ifindex, int version)
470 {
471         int opt = IP_UNICAST_IF;
472         int level = SOL_IP;
473         int rc;
474 
475         ifindex = htonl(ifindex);
476 
477         if (version == AF_INET6) {
478                 opt = IPV6_UNICAST_IF;
479                 level = SOL_IPV6;
480         }
481         rc = setsockopt(sd, level, opt, &ifindex, sizeof(ifindex));
482         if (rc < 0)
483                 log_err_errno("setsockopt(IP_UNICAST_IF)");
484 
485         return rc;
486 }
487 
488 static int set_multicast_if(int sd, int ifindex)
489 {
490         struct ip_mreqn mreq = { .imr_ifindex = ifindex };
491         int rc;
492 
493         rc = setsockopt(sd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq));
494         if (rc < 0)
495                 log_err_errno("setsockopt(IP_MULTICAST_IF)");
496 
497         return rc;
498 }
499 
500 static int set_membership(int sd, uint32_t grp, uint32_t addr, int ifindex)
501 {
502         uint32_t if_addr = addr;
503         struct ip_mreqn mreq;
504         int rc;
505 
506         if (addr == htonl(INADDR_ANY) && !ifindex) {
507                 log_error("Either local address or device needs to be given for multicast membership\n");
508                 return -1;
509         }
510 
511         mreq.imr_multiaddr.s_addr = grp;
512         mreq.imr_address.s_addr = if_addr;
513         mreq.imr_ifindex = ifindex;
514 
515         rc = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
516         if (rc < 0) {
517                 log_err_errno("setsockopt(IP_ADD_MEMBERSHIP)");
518                 return -1;
519         }
520 
521         return 0;
522 }
523 
524 static int set_freebind(int sd, int version)
525 {
526         unsigned int one = 1;
527         int rc = 0;
528 
529         switch (version) {
530         case AF_INET:
531                 if (setsockopt(sd, SOL_IP, IP_FREEBIND, &one, sizeof(one))) {
532                         log_err_errno("setsockopt(IP_FREEBIND)");
533                         rc = -1;
534                 }
535                 break;
536         case AF_INET6:
537                 if (setsockopt(sd, SOL_IPV6, IPV6_FREEBIND, &one, sizeof(one))) {
538                         log_err_errno("setsockopt(IPV6_FREEBIND");
539                         rc = -1;
540                 }
541                 break;
542         }
543 
544         return rc;
545 }
546 
547 static int set_broadcast(int sd)
548 {
549         unsigned int one = 1;
550         int rc = 0;
551 
552         if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) != 0) {
553                 log_err_errno("setsockopt(SO_BROADCAST)");
554                 rc = -1;
555         }
556 
557         return rc;
558 }
559 
560 static int set_reuseport(int sd)
561 {
562         unsigned int one = 1;
563         int rc = 0;
564 
565         if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != 0) {
566                 log_err_errno("setsockopt(SO_REUSEPORT)");
567                 rc = -1;
568         }
569 
570         return rc;
571 }
572 
573 static int set_reuseaddr(int sd)
574 {
575         unsigned int one = 1;
576         int rc = 0;
577 
578         if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) {
579                 log_err_errno("setsockopt(SO_REUSEADDR)");
580                 rc = -1;
581         }
582 
583         return rc;
584 }
585 
586 static int set_dsfield(int sd, int version, int dsfield)
587 {
588         if (!dsfield)
589                 return 0;
590 
591         switch (version) {
592         case AF_INET:
593                 if (setsockopt(sd, SOL_IP, IP_TOS, &dsfield,
594                                sizeof(dsfield)) < 0) {
595                         log_err_errno("setsockopt(IP_TOS)");
596                         return -1;
597                 }
598                 break;
599 
600         case AF_INET6:
601                 if (setsockopt(sd, SOL_IPV6, IPV6_TCLASS, &dsfield,
602                                sizeof(dsfield)) < 0) {
603                         log_err_errno("setsockopt(IPV6_TCLASS)");
604                         return -1;
605                 }
606                 break;
607 
608         default:
609                 log_error("Invalid address family\n");
610                 return -1;
611         }
612 
613         return 0;
614 }
615 
616 static int set_dontroute(int sd)
617 {
618         unsigned int one = 1;
619 
620         if (setsockopt(sd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0) {
621                 log_err_errno("setsockopt(SO_DONTROUTE)");
622                 return -1;
623         }
624 
625         return 0;
626 }
627 
628 static int str_to_uint(const char *str, int min, int max, unsigned int *value)
629 {
630         int number;
631         char *end;
632 
633         errno = 0;
634         number = (unsigned int) strtoul(str, &end, 0);
635 
636         /* entire string should be consumed by conversion
637          * and value should be between min and max
638          */
639         if (((*end == '\0') || (*end == '\n')) && (end != str) &&
640             (errno != ERANGE) && (min <= number) && (number <= max)) {
641                 *value = number;
642                 return 0;
643         }
644 
645         return -1;
646 }
647 
648 static int resolve_devices(struct sock_args *args)
649 {
650         if (args->dev) {
651                 args->ifindex = get_ifidx(args->dev);
652                 if (args->ifindex < 0) {
653                         log_error("Invalid device name\n");
654                         return 1;
655                 }
656         }
657 
658         if (args->expected_dev) {
659                 unsigned int tmp;
660 
661                 if (str_to_uint(args->expected_dev, 0, INT_MAX, &tmp) == 0) {
662                         args->expected_ifindex = (int)tmp;
663                 } else {
664                         args->expected_ifindex = get_ifidx(args->expected_dev);
665                         if (args->expected_ifindex < 0) {
666                                 fprintf(stderr, "Invalid expected device\n");
667                                 return 1;
668                         }
669                 }
670         }
671 
672         return 0;
673 }
674 
675 static int expected_addr_match(struct sockaddr *sa, void *expected,
676                                const char *desc)
677 {
678         char addrstr[64];
679         int rc = 0;
680 
681         if (sa->sa_family == AF_INET) {
682                 struct sockaddr_in *s = (struct sockaddr_in *) sa;
683                 struct in_addr *exp_in = (struct in_addr *) expected;
684 
685                 if (s->sin_addr.s_addr != exp_in->s_addr) {
686                         log_error("%s address does not match expected %s\n",
687                                   desc,
688                                   inet_ntop(AF_INET, exp_in,
689                                             addrstr, sizeof(addrstr)));
690                         rc = 1;
691                 }
692         } else if (sa->sa_family == AF_INET6) {
693                 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
694                 struct in6_addr *exp_in = (struct in6_addr *) expected;
695 
696                 if (memcmp(&s6->sin6_addr, exp_in, sizeof(*exp_in))) {
697                         log_error("%s address does not match expected %s\n",
698                                   desc,
699                                   inet_ntop(AF_INET6, exp_in,
700                                             addrstr, sizeof(addrstr)));
701                         rc = 1;
702                 }
703         } else {
704                 log_error("%s address does not match expected - unknown family\n",
705                           desc);
706                 rc = 1;
707         }
708 
709         if (!rc)
710                 log_msg("%s address matches expected\n", desc);
711 
712         return rc;
713 }
714 
715 static int show_sockstat(int sd, struct sock_args *args)
716 {
717         struct sockaddr_in6 local_addr, remote_addr;
718         socklen_t alen = sizeof(local_addr);
719         struct sockaddr *sa;
720         const char *desc;
721         int rc = 0;
722 
723         desc = server_mode ? "server local:" : "client local:";
724         sa = (struct sockaddr *) &local_addr;
725         if (getsockname(sd, sa, &alen) == 0) {
726                 log_address(desc, sa);
727 
728                 if (args->has_expected_laddr) {
729                         rc = expected_addr_match(sa, &args->expected_laddr,
730                                                  "local");
731                 }
732         } else {
733                 log_err_errno("getsockname failed");
734         }
735 
736         sa = (struct sockaddr *) &remote_addr;
737         desc = server_mode ? "server peer:" : "client peer:";
738         if (getpeername(sd, sa, &alen) == 0) {
739                 log_address(desc, sa);
740 
741                 if (args->has_expected_raddr) {
742                         rc |= expected_addr_match(sa, &args->expected_raddr,
743                                                  "remote");
744                 }
745         } else {
746                 log_err_errno("getpeername failed");
747         }
748 
749         return rc;
750 }
751 
752 enum addr_type {
753         ADDR_TYPE_LOCAL,
754         ADDR_TYPE_REMOTE,
755         ADDR_TYPE_MCAST,
756         ADDR_TYPE_EXPECTED_LOCAL,
757         ADDR_TYPE_EXPECTED_REMOTE,
758         ADDR_TYPE_MD5_PREFIX,
759 };
760 
761 static int convert_addr(struct sock_args *args, const char *_str,
762                         enum addr_type atype)
763 {
764         int pfx_len_max = args->version == AF_INET6 ? 128 : 32;
765         int family = args->version;
766         char *str, *dev, *sep;
767         struct in6_addr *in6;
768         struct in_addr  *in;
769         const char *desc;
770         void *addr;
771         int rc = 0;
772 
773         str = strdup(_str);
774         if (!str)
775                 return -ENOMEM;
776 
777         switch (atype) {
778         case ADDR_TYPE_LOCAL:
779                 desc = "local";
780                 addr = &args->local_addr;
781                 break;
782         case ADDR_TYPE_REMOTE:
783                 desc = "remote";
784                 addr = &args->remote_addr;
785                 break;
786         case ADDR_TYPE_MCAST:
787                 desc = "mcast grp";
788                 addr = &args->grp;
789                 break;
790         case ADDR_TYPE_EXPECTED_LOCAL:
791                 desc = "expected local";
792                 addr = &args->expected_laddr;
793                 break;
794         case ADDR_TYPE_EXPECTED_REMOTE:
795                 desc = "expected remote";
796                 addr = &args->expected_raddr;
797                 break;
798         case ADDR_TYPE_MD5_PREFIX:
799                 desc = "md5 prefix";
800                 if (family == AF_INET) {
801                         args->md5_prefix.v4.sin_family = AF_INET;
802                         addr = &args->md5_prefix.v4.sin_addr;
803                 } else if (family == AF_INET6) {
804                         args->md5_prefix.v6.sin6_family = AF_INET6;
805                         addr = &args->md5_prefix.v6.sin6_addr;
806                 } else
807                         return 1;
808 
809                 sep = strchr(str, '/');
810                 if (sep) {
811                         *sep = '\0';
812                         sep++;
813                         if (str_to_uint(sep, 1, pfx_len_max,
814                                         &args->prefix_len) != 0) {
815                                 fprintf(stderr, "Invalid port\n");
816                                 return 1;
817                         }
818                 } else {
819                         args->prefix_len = 0;
820                 }
821                 break;
822         default:
823                 log_error("unknown address type\n");
824                 exit(1);
825         }
826 
827         switch (family) {
828         case AF_INET:
829                 in  = (struct in_addr *) addr;
830                 if (str) {
831                         if (inet_pton(AF_INET, str, in) == 0) {
832                                 log_error("Invalid %s IP address\n", desc);
833                                 rc = -1;
834                                 goto out;
835                         }
836                 } else {
837                         in->s_addr = htonl(INADDR_ANY);
838                 }
839                 break;
840 
841         case AF_INET6:
842                 dev = strchr(str, '%');
843                 if (dev) {
844                         *dev = '\0';
845                         dev++;
846                 }
847 
848                 in6 = (struct in6_addr *) addr;
849                 if (str) {
850                         if (inet_pton(AF_INET6, str, in6) == 0) {
851                                 log_error("Invalid %s IPv6 address\n", desc);
852                                 rc = -1;
853                                 goto out;
854                         }
855                 } else {
856                         *in6 = in6addr_any;
857                 }
858                 if (dev) {
859                         args->scope_id = get_ifidx(dev);
860                         if (args->scope_id < 0) {
861                                 log_error("Invalid scope on %s IPv6 address\n",
862                                           desc);
863                                 rc = -1;
864                                 goto out;
865                         }
866                 }
867                 break;
868 
869         default:
870                 log_error("Invalid address family\n");
871         }
872 
873 out:
874         free(str);
875         return rc;
876 }
877 
878 static int validate_addresses(struct sock_args *args)
879 {
880         if (args->local_addr_str &&
881             convert_addr(args, args->local_addr_str, ADDR_TYPE_LOCAL) < 0)
882                 return 1;
883 
884         if (args->remote_addr_str &&
885             convert_addr(args, args->remote_addr_str, ADDR_TYPE_REMOTE) < 0)
886                 return 1;
887 
888         if (args->md5_prefix_str &&
889             convert_addr(args, args->md5_prefix_str,
890                          ADDR_TYPE_MD5_PREFIX) < 0)
891                 return 1;
892 
893         if (args->expected_laddr_str &&
894             convert_addr(args, args->expected_laddr_str,
895                          ADDR_TYPE_EXPECTED_LOCAL))
896                 return 1;
897 
898         if (args->expected_raddr_str &&
899             convert_addr(args, args->expected_raddr_str,
900                          ADDR_TYPE_EXPECTED_REMOTE))
901                 return 1;
902 
903         return 0;
904 }
905 
906 static int get_index_from_cmsg(struct msghdr *m)
907 {
908         struct cmsghdr *cm;
909         int ifindex = 0;
910         char buf[64];
911 
912         for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(m);
913              m->msg_controllen != 0 && cm;
914              cm = (struct cmsghdr *)CMSG_NXTHDR(m, cm)) {
915 
916                 if (cm->cmsg_level == SOL_IP &&
917                     cm->cmsg_type == IP_PKTINFO) {
918                         struct in_pktinfo *pi;
919 
920                         pi = (struct in_pktinfo *)(CMSG_DATA(cm));
921                         inet_ntop(AF_INET, &pi->ipi_addr, buf, sizeof(buf));
922                         ifindex = pi->ipi_ifindex;
923                 } else if (cm->cmsg_level == SOL_IPV6 &&
924                            cm->cmsg_type == IPV6_PKTINFO) {
925                         struct in6_pktinfo *pi6;
926 
927                         pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
928                         inet_ntop(AF_INET6, &pi6->ipi6_addr, buf, sizeof(buf));
929                         ifindex = pi6->ipi6_ifindex;
930                 }
931         }
932 
933         if (ifindex) {
934                 log_msg("    pktinfo: ifindex %d dest addr %s\n",
935                         ifindex, buf);
936         }
937         return ifindex;
938 }
939 
940 static int send_msg_no_cmsg(int sd, void *addr, socklen_t alen)
941 {
942         int err;
943 
944 again:
945         err = sendto(sd, msg, msglen, 0, addr, alen);
946         if (err < 0) {
947                 if (errno == EACCES && try_broadcast) {
948                         try_broadcast = 0;
949                         if (!set_broadcast(sd))
950                                 goto again;
951                         errno = EACCES;
952                 }
953 
954                 log_err_errno("sendto failed");
955                 return 1;
956         }
957 
958         return 0;
959 }
960 
961 static int send_msg_cmsg(int sd, void *addr, socklen_t alen,
962                          int ifindex, int version)
963 {
964         unsigned char cmsgbuf[64];
965         struct iovec iov[2];
966         struct cmsghdr *cm;
967         struct msghdr m;
968         int err;
969 
970         iov[0].iov_base = msg;
971         iov[0].iov_len = msglen;
972         m.msg_iov = iov;
973         m.msg_iovlen = 1;
974         m.msg_name = (caddr_t)addr;
975         m.msg_namelen = alen;
976 
977         memset(cmsgbuf, 0, sizeof(cmsgbuf));
978         cm = (struct cmsghdr *)cmsgbuf;
979         m.msg_control = (caddr_t)cm;
980 
981         if (version == AF_INET) {
982                 struct in_pktinfo *pi;
983 
984                 cm->cmsg_level = SOL_IP;
985                 cm->cmsg_type = IP_PKTINFO;
986                 cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
987                 pi = (struct in_pktinfo *)(CMSG_DATA(cm));
988                 pi->ipi_ifindex = ifindex;
989 
990                 m.msg_controllen = cm->cmsg_len;
991 
992         } else if (version == AF_INET6) {
993                 struct in6_pktinfo *pi6;
994 
995                 cm->cmsg_level = SOL_IPV6;
996                 cm->cmsg_type = IPV6_PKTINFO;
997                 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
998 
999                 pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
1000                 pi6->ipi6_ifindex = ifindex;
1001 
1002                 m.msg_controllen = cm->cmsg_len;
1003         }
1004 
1005 again:
1006         err = sendmsg(sd, &m, 0);
1007         if (err < 0) {
1008                 if (errno == EACCES && try_broadcast) {
1009                         try_broadcast = 0;
1010                         if (!set_broadcast(sd))
1011                                 goto again;
1012                         errno = EACCES;
1013                 }
1014 
1015                 log_err_errno("sendmsg failed");
1016                 return 1;
1017         }
1018 
1019         return 0;
1020 }
1021 
1022 
1023 static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
1024 {
1025         if (args->type == SOCK_STREAM) {
1026                 if (write(sd, msg, msglen) < 0) {
1027                         log_err_errno("write failed sending msg to peer");
1028                         return 1;
1029                 }
1030         } else if (args->datagram_connect) {
1031                 if (send(sd, msg, msglen, 0) < 0) {
1032                         log_err_errno("send failed sending msg to peer");
1033                         return 1;
1034                 }
1035         } else if (args->ifindex && args->use_cmsg) {
1036                 if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
1037                         return 1;
1038         } else {
1039                 if (send_msg_no_cmsg(sd, addr, alen))
1040                         return 1;
1041         }
1042 
1043         log_msg("Sent message:\n");
1044         log_msg("    %.24s%s\n", msg, msglen > 24 ? " ..." : "");
1045 
1046         return 0;
1047 }
1048 
1049 static int socket_read_dgram(int sd, struct sock_args *args)
1050 {
1051         unsigned char addr[sizeof(struct sockaddr_in6)];
1052         struct sockaddr *sa = (struct sockaddr *) addr;
1053         socklen_t alen = sizeof(addr);
1054         struct iovec iov[2];
1055         struct msghdr m = {
1056                 .msg_name = (caddr_t)addr,
1057                 .msg_namelen = alen,
1058                 .msg_iov = iov,
1059                 .msg_iovlen = 1,
1060         };
1061         unsigned char cmsgbuf[256];
1062         struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
1063         char buf[16*1024];
1064         int ifindex;
1065         int len;
1066 
1067         iov[0].iov_base = (caddr_t)buf;
1068         iov[0].iov_len = sizeof(buf);
1069 
1070         memset(cmsgbuf, 0, sizeof(cmsgbuf));
1071         m.msg_control = (caddr_t)cm;
1072         m.msg_controllen = sizeof(cmsgbuf);
1073 
1074         len = recvmsg(sd, &m, 0);
1075         if (len == 0) {
1076                 log_msg("peer closed connection.\n");
1077                 return 0;
1078         } else if (len < 0) {
1079                 log_msg("failed to read message: %d: %s\n",
1080                         errno, strerror(errno));
1081                 return -1;
1082         }
1083 
1084         buf[len] = '\0';
1085 
1086         log_address("Message from:", sa);
1087         log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");
1088 
1089         ifindex = get_index_from_cmsg(&m);
1090         if (args->expected_ifindex) {
1091                 if (args->expected_ifindex != ifindex) {
1092                         log_error("Device index mismatch: expected %d have %d\n",
1093                                   args->expected_ifindex, ifindex);
1094                         return -1;
1095                 }
1096                 log_msg("Device index matches: expected %d have %d\n",
1097                         args->expected_ifindex, ifindex);
1098         }
1099 
1100         if (!interactive && server_mode) {
1101                 if (sa->sa_family == AF_INET6) {
1102                         struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
1103                         struct in6_addr *in6 = &s6->sin6_addr;
1104 
1105                         if (IN6_IS_ADDR_V4MAPPED(in6)) {
1106                                 const uint32_t *pa = (uint32_t *) &in6->s6_addr;
1107                                 struct in_addr in4;
1108                                 struct sockaddr_in *sin;
1109 
1110                                 sin = (struct sockaddr_in *) addr;
1111                                 pa += 3;
1112                                 in4.s_addr = *pa;
1113                                 sin->sin_addr = in4;
1114                                 sin->sin_family = AF_INET;
1115                                 if (send_msg_cmsg(sd, addr, alen,
1116                                                   ifindex, AF_INET) < 0)
1117                                         goto out_err;
1118                         }
1119                 }
1120 again:
1121                 iov[0].iov_len = len;
1122 
1123                 if (args->version == AF_INET6) {
1124                         struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
1125 
1126                         if (args->dev) {
1127                                 /* avoid PKTINFO conflicts with bindtodev */
1128                                 if (sendto(sd, buf, len, 0,
1129                                            (void *) addr, alen) < 0)
1130                                         goto out_err;
1131                         } else {
1132                                 /* kernel is allowing scope_id to be set to VRF
1133                                  * index for LLA. for sends to global address
1134                                  * reset scope id
1135                                  */
1136                                 s6->sin6_scope_id = ifindex;
1137                                 if (sendmsg(sd, &m, 0) < 0)
1138                                         goto out_err;
1139                         }
1140                 } else {
1141                         int err;
1142 
1143                         err = sendmsg(sd, &m, 0);
1144                         if (err < 0) {
1145                                 if (errno == EACCES && try_broadcast) {
1146                                         try_broadcast = 0;
1147                                         if (!set_broadcast(sd))
1148                                                 goto again;
1149                                         errno = EACCES;
1150                                 }
1151                                 goto out_err;
1152                         }
1153                 }
1154                 log_msg("Sent message:\n");
1155                 log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");
1156         }
1157 
1158         return 1;
1159 out_err:
1160         log_err_errno("failed to send msg to peer");
1161         return -1;
1162 }
1163 
1164 static int socket_read_stream(int sd)
1165 {
1166         char buf[1024];
1167         int len;
1168 
1169         len = read(sd, buf, sizeof(buf)-1);
1170         if (len == 0) {
1171                 log_msg("client closed connection.\n");
1172                 return 0;
1173         } else if (len < 0) {
1174                 log_msg("failed to read message\n");
1175                 return -1;
1176         }
1177 
1178         buf[len] = '\0';
1179         log_msg("Incoming message:\n");
1180         log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");
1181 
1182         if (!interactive && server_mode) {
1183                 if (write(sd, buf, len) < 0) {
1184                         log_err_errno("failed to send buf");
1185                         return -1;
1186                 }
1187                 log_msg("Sent message:\n");
1188                 log_msg("     %.24s%s\n", buf, len > 24 ? " ..." : "");
1189         }
1190 
1191         return 1;
1192 }
1193 
1194 static int socket_read(int sd, struct sock_args *args)
1195 {
1196         if (args->type == SOCK_STREAM)
1197                 return socket_read_stream(sd);
1198 
1199         return socket_read_dgram(sd, args);
1200 }
1201 
1202 static int stdin_to_socket(int sd, int type, void *addr, socklen_t alen)
1203 {
1204         char buf[1024];
1205         int len;
1206 
1207         if (fgets(buf, sizeof(buf), stdin) == NULL)
1208                 return 0;
1209 
1210         len = strlen(buf);
1211         if (type == SOCK_STREAM) {
1212                 if (write(sd, buf, len) < 0) {
1213                         log_err_errno("failed to send buf");
1214                         return -1;
1215                 }
1216         } else {
1217                 int err;
1218 
1219 again:
1220                 err = sendto(sd, buf, len, 0, addr, alen);
1221                 if (err < 0) {
1222                         if (errno == EACCES && try_broadcast) {
1223                                 try_broadcast = 0;
1224                                 if (!set_broadcast(sd))
1225                                         goto again;
1226                                 errno = EACCES;
1227                         }
1228                         log_err_errno("failed to send msg to peer");
1229                         return -1;
1230                 }
1231         }
1232         log_msg("Sent message:\n");
1233         log_msg("    %.24s%s\n", buf, len > 24 ? " ..." : "");
1234 
1235         return 1;
1236 }
1237 
1238 static void set_recv_attr(int sd, int version)
1239 {
1240         if (version == AF_INET6) {
1241                 set_recvpktinfo_v6(sd);
1242                 set_recverr_v6(sd);
1243         } else {
1244                 set_pktinfo_v4(sd);
1245                 set_recverr_v4(sd);
1246         }
1247 }
1248 
1249 static int msg_loop(int client, int sd, void *addr, socklen_t alen,
1250                     struct sock_args *args)
1251 {
1252         struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
1253         fd_set rfds;
1254         int nfds;
1255         int rc;
1256 
1257         if (args->type != SOCK_STREAM)
1258                 set_recv_attr(sd, args->version);
1259 
1260         if (msg) {
1261                 msglen = strlen(msg);
1262 
1263                 /* client sends first message */
1264                 if (client) {
1265                         if (send_msg(sd, addr, alen, args))
1266                                 return 1;
1267                 }
1268                 if (!interactive) {
1269                         ptval = &timeout;
1270                         if (!prog_timeout)
1271                                 timeout.tv_sec = 5;
1272                 }
1273         }
1274 
1275         nfds = interactive ? MAX(fileno(stdin), sd)  + 1 : sd + 1;
1276         while (1) {
1277                 FD_ZERO(&rfds);
1278                 FD_SET(sd, &rfds);
1279                 if (interactive)
1280                         FD_SET(fileno(stdin), &rfds);
1281 
1282                 rc = select(nfds, &rfds, NULL, NULL, ptval);
1283                 if (rc < 0) {
1284                         if (errno == EINTR)
1285                                 continue;
1286 
1287                         rc = 1;
1288                         log_err_errno("select failed");
1289                         break;
1290                 } else if (rc == 0) {
1291                         log_error("Timed out waiting for response\n");
1292                         rc = 2;
1293                         break;
1294                 }
1295 
1296                 if (FD_ISSET(sd, &rfds)) {
1297                         rc = socket_read(sd, args);
1298                         if (rc < 0) {
1299                                 rc = 1;
1300                                 break;
1301                         }
1302                         if (rc == 0)
1303                                 break;
1304                 }
1305 
1306                 rc = 0;
1307 
1308                 if (FD_ISSET(fileno(stdin), &rfds)) {
1309                         if (stdin_to_socket(sd, args->type, addr, alen) <= 0)
1310                                 break;
1311                 }
1312 
1313                 if (interactive)
1314                         continue;
1315 
1316                 if (iter != -1) {
1317                         --iter;
1318                         if (iter == 0)
1319                                 break;
1320                 }
1321 
1322                 log_msg("Going into quiet mode\n");
1323                 quiet = 1;
1324 
1325                 if (client) {
1326                         if (send_msg(sd, addr, alen, args)) {
1327                                 rc = 1;
1328                                 break;
1329                         }
1330                 }
1331         }
1332 
1333         return rc;
1334 }
1335 
1336 static int msock_init(struct sock_args *args, int server)
1337 {
1338         uint32_t if_addr = htonl(INADDR_ANY);
1339         struct sockaddr_in laddr = {
1340                 .sin_family = AF_INET,
1341                 .sin_port = htons(args->port),
1342         };
1343         int one = 1;
1344         int sd;
1345 
1346         if (!server && args->has_local_ip)
1347                 if_addr = args->local_addr.in.s_addr;
1348 
1349         sd = socket(PF_INET, SOCK_DGRAM, 0);
1350         if (sd < 0) {
1351                 log_err_errno("socket");
1352                 return -1;
1353         }
1354 
1355         if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
1356                        (char *)&one, sizeof(one)) < 0) {
1357                 log_err_errno("Setting SO_REUSEADDR error");
1358                 goto out_err;
1359         }
1360 
1361         if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST,
1362                        (char *)&one, sizeof(one)) < 0)
1363                 log_err_errno("Setting SO_BROADCAST error");
1364 
1365         if (set_dsfield(sd, AF_INET, args->dsfield) != 0)
1366                 goto out_err;
1367 
1368         if (server) {
1369                 if (args->server_dontroute && set_dontroute(sd) != 0)
1370                         goto out_err;
1371         } else {
1372                 if (args->client_dontroute && set_dontroute(sd) != 0)
1373                         goto out_err;
1374         }
1375 
1376         if (args->dev && bind_to_device(sd, args->dev) != 0)
1377                 goto out_err;
1378         else if (args->use_setsockopt &&
1379                  set_multicast_if(sd, args->ifindex))
1380                 goto out_err;
1381 
1382         laddr.sin_addr.s_addr = if_addr;
1383 
1384         if (bind(sd, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
1385                 log_err_errno("bind failed");
1386                 goto out_err;
1387         }
1388 
1389         if (server &&
1390             set_membership(sd, args->grp.s_addr,
1391                            args->local_addr.in.s_addr, args->ifindex))
1392                 goto out_err;
1393 
1394         return sd;
1395 out_err:
1396         close(sd);
1397         return -1;
1398 }
1399 
1400 static int msock_server(struct sock_args *args)
1401 {
1402         return msock_init(args, 1);
1403 }
1404 
1405 static int msock_client(struct sock_args *args)
1406 {
1407         return msock_init(args, 0);
1408 }
1409 
1410 static int bind_socket(int sd, struct sock_args *args)
1411 {
1412         struct sockaddr_in serv_addr = {
1413                 .sin_family = AF_INET,
1414         };
1415         struct sockaddr_in6 serv6_addr = {
1416                 .sin6_family = AF_INET6,
1417         };
1418         void *addr;
1419         socklen_t alen;
1420 
1421         if (!args->has_local_ip && args->type == SOCK_RAW)
1422                 return 0;
1423 
1424         switch (args->version) {
1425         case AF_INET:
1426                 serv_addr.sin_port = htons(args->port);
1427                 serv_addr.sin_addr = args->local_addr.in;
1428                 addr = &serv_addr;
1429                 alen = sizeof(serv_addr);
1430                 break;
1431 
1432         case AF_INET6:
1433                 serv6_addr.sin6_port = htons(args->port);
1434                 serv6_addr.sin6_addr = args->local_addr.in6;
1435                 addr = &serv6_addr;
1436                 alen = sizeof(serv6_addr);
1437                 break;
1438 
1439         default:
1440                 log_error("Invalid address family\n");
1441                 return -1;
1442         }
1443 
1444         if (bind(sd, addr, alen) < 0) {
1445                 log_err_errno("error binding socket");
1446                 return -1;
1447         }
1448 
1449         return 0;
1450 }
1451 
1452 static int config_xfrm_policy(int sd, struct sock_args *args)
1453 {
1454         struct xfrm_userpolicy_info policy = {};
1455         int type = UDP_ENCAP_ESPINUDP;
1456         int xfrm_af = IP_XFRM_POLICY;
1457         int level = SOL_IP;
1458 
1459         if (args->type != SOCK_DGRAM) {
1460                 log_error("Invalid socket type. Only DGRAM could be used for XFRM\n");
1461                 return 1;
1462         }
1463 
1464         policy.action = XFRM_POLICY_ALLOW;
1465         policy.sel.family = args->version;
1466         if (args->version == AF_INET6) {
1467                 xfrm_af = IPV6_XFRM_POLICY;
1468                 level = SOL_IPV6;
1469         }
1470 
1471         policy.dir = XFRM_POLICY_OUT;
1472         if (setsockopt(sd, level, xfrm_af, &policy, sizeof(policy)) < 0)
1473                 return 1;
1474 
1475         policy.dir = XFRM_POLICY_IN;
1476         if (setsockopt(sd, level, xfrm_af, &policy, sizeof(policy)) < 0)
1477                 return 1;
1478 
1479         if (setsockopt(sd, IPPROTO_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) {
1480                 log_err_errno("Failed to set xfrm encap");
1481                 return 1;
1482         }
1483 
1484         return 0;
1485 }
1486 
1487 static int lsock_init(struct sock_args *args)
1488 {
1489         long flags;
1490         int sd;
1491 
1492         sd = socket(args->version, args->type, args->protocol);
1493         if (sd < 0) {
1494                 log_err_errno("Error opening socket");
1495                 return  -1;
1496         }
1497 
1498         if (set_reuseaddr(sd) != 0)
1499                 goto err;
1500 
1501         if (set_reuseport(sd) != 0)
1502                 goto err;
1503 
1504         if (set_dsfield(sd, args->version, args->dsfield) != 0)
1505                 goto err;
1506 
1507         if (args->server_dontroute && set_dontroute(sd) != 0)
1508                 goto err;
1509 
1510         if (args->dev && bind_to_device(sd, args->dev) != 0)
1511                 goto err;
1512         else if (args->use_setsockopt &&
1513                  set_unicast_if(sd, args->ifindex, args->version))
1514                 goto err;
1515 
1516         if (args->use_freebind && set_freebind(sd, args->version))
1517                 goto err;
1518 
1519         if (bind_socket(sd, args))
1520                 goto err;
1521 
1522         if (args->bind_test_only)
1523                 goto out;
1524 
1525         if (args->type == SOCK_STREAM && listen(sd, 1) < 0) {
1526                 log_err_errno("listen failed");
1527                 goto err;
1528         }
1529 
1530         flags = fcntl(sd, F_GETFL);
1531         if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
1532                 log_err_errno("Failed to set non-blocking option");
1533                 goto err;
1534         }
1535 
1536         if (fcntl(sd, F_SETFD, FD_CLOEXEC) < 0)
1537                 log_err_errno("Failed to set close-on-exec flag");
1538 
1539         if (args->use_xfrm && config_xfrm_policy(sd, args)) {
1540                 log_err_errno("Failed to set xfrm policy");
1541                 goto err;
1542         }
1543 
1544 out:
1545         return sd;
1546 
1547 err:
1548         close(sd);
1549         return -1;
1550 }
1551 
1552 static void ipc_write(int fd, int message)
1553 {
1554         /* Not in both_mode, so there's no process to signal */
1555         if (fd < 0)
1556                 return;
1557 
1558         if (write(fd, &message, sizeof(message)) < 0)
1559                 log_err_errno("Failed to send client status");
1560 }
1561 
1562 static int do_server(struct sock_args *args, int ipc_fd)
1563 {
1564         /* ipc_fd = -1 if no parent process to signal */
1565         struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
1566         unsigned char addr[sizeof(struct sockaddr_in6)] = {};
1567         socklen_t alen = sizeof(addr);
1568         int lsd, csd = -1;
1569 
1570         fd_set rfds;
1571         int rc;
1572 
1573         if (args->serverns) {
1574                 if (switch_ns(args->serverns)) {
1575                         log_error("Could not set server netns to %s\n",
1576                                   args->serverns);
1577                         goto err_exit;
1578                 }
1579                 log_msg("Switched server netns\n");
1580         }
1581 
1582         args->dev = args->server_dev;
1583         args->expected_dev = args->expected_server_dev;
1584         if (resolve_devices(args) || validate_addresses(args))
1585                 goto err_exit;
1586 
1587         if (prog_timeout)
1588                 ptval = &timeout;
1589 
1590         if (args->has_grp)
1591                 lsd = msock_server(args);
1592         else
1593                 lsd = lsock_init(args);
1594 
1595         if (lsd < 0)
1596                 goto err_exit;
1597 
1598         if (args->bind_test_only) {
1599                 close(lsd);
1600                 ipc_write(ipc_fd, 1);
1601                 return 0;
1602         }
1603 
1604         if (args->type != SOCK_STREAM) {
1605                 ipc_write(ipc_fd, 1);
1606                 rc = msg_loop(0, lsd, (void *) addr, alen, args);
1607                 close(lsd);
1608                 return rc;
1609         }
1610 
1611         if (args->password && tcp_md5_remote(lsd, args)) {
1612                 close(lsd);
1613                 goto err_exit;
1614         }
1615 
1616         ipc_write(ipc_fd, 1);
1617         while (1) {
1618                 log_msg("waiting for client connection.\n");
1619                 FD_ZERO(&rfds);
1620                 FD_SET(lsd, &rfds);
1621 
1622                 rc = select(lsd+1, &rfds, NULL, NULL, ptval);
1623                 if (rc == 0) {
1624                         rc = 2;
1625                         break;
1626                 }
1627 
1628                 if (rc < 0) {
1629                         if (errno == EINTR)
1630                                 continue;
1631 
1632                         log_err_errno("select failed");
1633                         break;
1634                 }
1635 
1636                 if (FD_ISSET(lsd, &rfds)) {
1637 
1638                         csd = accept(lsd, (void *) addr, &alen);
1639                         if (csd < 0) {
1640                                 log_err_errno("accept failed");
1641                                 break;
1642                         }
1643 
1644                         rc = show_sockstat(csd, args);
1645                         if (rc)
1646                                 break;
1647 
1648                         rc = check_device(csd, args);
1649                         if (rc)
1650                                 break;
1651                 }
1652 
1653                 rc = msg_loop(0, csd, (void *) addr, alen, args);
1654                 close(csd);
1655 
1656                 if (!interactive)
1657                         break;
1658         }
1659 
1660         close(lsd);
1661 
1662         return rc;
1663 err_exit:
1664         ipc_write(ipc_fd, 0);
1665         return 1;
1666 }
1667 
1668 static int wait_for_connect(int sd)
1669 {
1670         struct timeval _tv = { .tv_sec = prog_timeout }, *tv = NULL;
1671         fd_set wfd;
1672         int val = 0, sz = sizeof(val);
1673         int rc;
1674 
1675         FD_ZERO(&wfd);
1676         FD_SET(sd, &wfd);
1677 
1678         if (prog_timeout)
1679                 tv = &_tv;
1680 
1681         rc = select(FD_SETSIZE, NULL, &wfd, NULL, tv);
1682         if (rc == 0) {
1683                 log_error("connect timed out\n");
1684                 return -2;
1685         } else if (rc < 0) {
1686                 log_err_errno("select failed");
1687                 return -3;
1688         }
1689 
1690         if (getsockopt(sd, SOL_SOCKET, SO_ERROR, &val, (socklen_t *)&sz) < 0) {
1691                 log_err_errno("getsockopt(SO_ERROR) failed");
1692                 return -4;
1693         }
1694 
1695         if (val != 0) {
1696                 log_error("connect failed: %d: %s\n", val, strerror(val));
1697                 return -1;
1698         }
1699 
1700         return 0;
1701 }
1702 
1703 static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
1704 {
1705         int sd, rc = -1;
1706         long flags;
1707 
1708         sd = socket(args->version, args->type, args->protocol);
1709         if (sd < 0) {
1710                 log_err_errno("Failed to create socket");
1711                 return -1;
1712         }
1713 
1714         flags = fcntl(sd, F_GETFL);
1715         if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
1716                 log_err_errno("Failed to set non-blocking option");
1717                 goto err;
1718         }
1719 
1720         if (set_reuseport(sd) != 0)
1721                 goto err;
1722 
1723         if (set_dsfield(sd, args->version, args->dsfield) != 0)
1724                 goto err;
1725 
1726         if (args->client_dontroute && set_dontroute(sd) != 0)
1727                 goto err;
1728 
1729         if (args->dev && bind_to_device(sd, args->dev) != 0)
1730                 goto err;
1731         else if (args->use_setsockopt &&
1732                  set_unicast_if(sd, args->ifindex, args->version))
1733                 goto err;
1734 
1735         if (args->has_local_ip && bind_socket(sd, args))
1736                 goto err;
1737 
1738         if (args->type != SOCK_STREAM && !args->datagram_connect)
1739                 goto out;
1740 
1741         if (args->password && tcp_md5sig(sd, addr, alen, args))
1742                 goto err;
1743 
1744         if (args->bind_test_only)
1745                 goto out;
1746 
1747         if (connect(sd, addr, alen) < 0) {
1748                 if (errno != EINPROGRESS) {
1749                         log_err_errno("Failed to connect to remote host");
1750                         rc = -1;
1751                         goto err;
1752                 }
1753                 rc = wait_for_connect(sd);
1754                 if (rc < 0)
1755                         goto err;
1756         }
1757 out:
1758         return sd;
1759 
1760 err:
1761         close(sd);
1762         return rc;
1763 }
1764 
1765 static int do_client(struct sock_args *args)
1766 {
1767         struct sockaddr_in sin = {
1768                 .sin_family = AF_INET,
1769         };
1770         struct sockaddr_in6 sin6 = {
1771                 .sin6_family = AF_INET6,
1772         };
1773         void *addr;
1774         int alen;
1775         int rc = 0;
1776         int sd;
1777 
1778         if (!args->has_remote_ip && !args->has_grp) {
1779                 fprintf(stderr, "remote IP or multicast group not given\n");
1780                 return 1;
1781         }
1782 
1783         if (args->clientns) {
1784                 if (switch_ns(args->clientns)) {
1785                         log_error("Could not set client netns to %s\n",
1786                                   args->clientns);
1787                         return 1;
1788                 }
1789                 log_msg("Switched client netns\n");
1790         }
1791 
1792         args->local_addr_str = args->client_local_addr_str;
1793         if (resolve_devices(args) || validate_addresses(args))
1794                 return 1;
1795 
1796         if ((args->use_setsockopt || args->use_cmsg) && !args->ifindex) {
1797                 fprintf(stderr, "Device binding not specified\n");
1798                 return 1;
1799         }
1800         if (args->use_setsockopt || args->use_cmsg)
1801                 args->dev = NULL;
1802 
1803         switch (args->version) {
1804         case AF_INET:
1805                 sin.sin_port = htons(args->port);
1806                 if (args->has_grp)
1807                         sin.sin_addr = args->grp;
1808                 else
1809                         sin.sin_addr = args->remote_addr.in;
1810                 addr = &sin;
1811                 alen = sizeof(sin);
1812                 break;
1813         case AF_INET6:
1814                 sin6.sin6_port = htons(args->port);
1815                 sin6.sin6_addr = args->remote_addr.in6;
1816                 sin6.sin6_scope_id = args->scope_id;
1817                 addr = &sin6;
1818                 alen = sizeof(sin6);
1819                 break;
1820         }
1821 
1822         args->password = args->client_pw;
1823 
1824         if (args->has_grp)
1825                 sd = msock_client(args);
1826         else
1827                 sd = connectsock(addr, alen, args);
1828 
1829         if (sd < 0)
1830                 return -sd;
1831 
1832         if (args->bind_test_only)
1833                 goto out;
1834 
1835         if (args->type == SOCK_STREAM) {
1836                 rc = show_sockstat(sd, args);
1837                 if (rc != 0)
1838                         goto out;
1839         }
1840 
1841         rc = msg_loop(1, sd, addr, alen, args);
1842 
1843 out:
1844         close(sd);
1845 
1846         return rc;
1847 }
1848 
1849 static char *random_msg(int len)
1850 {
1851         int i, n = 0, olen = len + 1;
1852         char *m;
1853 
1854         if (len <= 0)
1855                 return NULL;
1856 
1857         m = malloc(olen);
1858         if (!m)
1859                 return NULL;
1860 
1861         while (len > 26) {
1862                 i = snprintf(m + n, olen - n, "%.26s",
1863                              "abcdefghijklmnopqrstuvwxyz");
1864                 n += i;
1865                 len -= i;
1866         }
1867 
1868         snprintf(m + n, olen - n, "%.*s", len,
1869              "abcdefghijklmnopqrstuvwxyz");
1870         return m;
1871 }
1872 
1873 static int ipc_child(int fd, struct sock_args *args)
1874 {
1875         char *outbuf, *errbuf;
1876         int rc = 1;
1877 
1878         outbuf = malloc(4096);
1879         errbuf = malloc(4096);
1880         if (!outbuf || !errbuf) {
1881                 fprintf(stderr, "server: Failed to allocate buffers for stdout and stderr\n");
1882                 goto out;
1883         }
1884 
1885         setbuffer(stdout, outbuf, 4096);
1886         setbuffer(stderr, errbuf, 4096);
1887 
1888         server_mode = 1; /* to tell log_msg in case we are in both_mode */
1889 
1890         /* when running in both mode, address validation applies
1891          * solely to client side
1892          */
1893         args->has_expected_laddr = 0;
1894         args->has_expected_raddr = 0;
1895 
1896         rc = do_server(args, fd);
1897 
1898 out:
1899         free(outbuf);
1900         free(errbuf);
1901 
1902         return rc;
1903 }
1904 
1905 static int ipc_parent(int cpid, int fd, struct sock_args *args)
1906 {
1907         int client_status;
1908         int status;
1909         int buf;
1910 
1911         /* do the client-side function here in the parent process,
1912          * waiting to be told when to continue
1913          */
1914         if (read(fd, &buf, sizeof(buf)) <= 0) {
1915                 log_err_errno("Failed to read IPC status from status");
1916                 return 1;
1917         }
1918         if (!buf) {
1919                 log_error("Server failed; can not continue\n");
1920                 return 1;
1921         }
1922         log_msg("Server is ready\n");
1923 
1924         client_status = do_client(args);
1925         log_msg("parent is done!\n");
1926 
1927         if (kill(cpid, 0) == 0)
1928                 kill(cpid, SIGKILL);
1929 
1930         wait(&status);
1931         return client_status;
1932 }
1933 
1934 #define GETOPT_STR  "sr:l:c:Q:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"
1935 #define OPT_FORCE_BIND_KEY_IFINDEX 1001
1936 #define OPT_NO_BIND_KEY_IFINDEX 1002
1937 #define OPT_CLIENT_DONTROUTE 1003
1938 #define OPT_SERVER_DONTROUTE 1004
1939 
1940 static struct option long_opts[] = {
1941         {"force-bind-key-ifindex", 0, 0, OPT_FORCE_BIND_KEY_IFINDEX},
1942         {"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX},
1943         {"client-dontroute", 0, 0, OPT_CLIENT_DONTROUTE},
1944         {"server-dontroute", 0, 0, OPT_SERVER_DONTROUTE},
1945         {0, 0, 0, 0}
1946 };
1947 
1948 static void print_usage(char *prog)
1949 {
1950         printf(
1951         "usage: %s OPTS\n"
1952         "Required:\n"
1953         "    -r addr       remote address to connect to (client mode only)\n"
1954         "    -p port       port to connect to (client mode)/listen on (server mode)\n"
1955         "                  (default: %d)\n"
1956         "    -s            server mode (default: client mode)\n"
1957         "    -t            timeout seconds (default: none)\n"
1958         "\n"
1959         "Optional:\n"
1960         "    -B            do both client and server via fork and IPC\n"
1961         "    -N ns         set client to network namespace ns (requires root)\n"
1962         "    -O ns         set server to network namespace ns (requires root)\n"
1963         "    -F            Restart server loop\n"
1964         "    -6            IPv6 (default is IPv4)\n"
1965         "    -P proto      protocol for socket: icmp, ospf (default: none)\n"
1966         "    -D|R          datagram (D) / raw (R) socket (default stream)\n"
1967         "    -l addr       local address to bind to in server mode\n"
1968         "    -c addr       local address to bind to in client mode\n"
1969         "    -Q dsfield    DS Field value of the socket (the IP_TOS or\n"
1970         "                  IPV6_TCLASS socket option)\n"
1971         "    -x            configure XFRM policy on socket\n"
1972         "\n"
1973         "    -d dev        bind socket to given device name\n"
1974         "    -I dev        bind socket to given device name - server mode\n"
1975         "    -S            use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
1976         "                  to set device binding\n"
1977         "    -U            Use connect() and send() for datagram sockets\n"
1978         "    -f            bind socket with the IP[V6]_FREEBIND option\n"
1979         "    -C            use cmsg and IP_PKTINFO to specify device binding\n"
1980         "\n"
1981         "    -L len        send random message of given length\n"
1982         "    -n num        number of times to send message\n"
1983         "\n"
1984         "    -M password   use MD5 sum protection\n"
1985         "    -X password   MD5 password for client mode\n"
1986         "    -m prefix/len prefix and length to use for MD5 key\n"
1987         "    --no-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX off\n"
1988         "    --force-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX on\n"
1989         "        (default: only if -I is passed)\n"
1990         "    --client-dontroute: don't use gateways for client socket: send\n"
1991         "                        packets only if destination is on link (see\n"
1992         "                        SO_DONTROUTE in socket(7))\n"
1993         "    --server-dontroute: don't use gateways for server socket: send\n"
1994         "                        packets only if destination is on link (see\n"
1995         "                        SO_DONTROUTE in socket(7))\n"
1996         "\n"
1997         "    -g grp        multicast group (e.g., 239.1.1.1)\n"
1998         "    -i            interactive mode (default is echo and terminate)\n"
1999         "\n"
2000         "    -0 addr       Expected local address\n"
2001         "    -1 addr       Expected remote address\n"
2002         "    -2 dev        Expected device name (or index) to receive packet\n"
2003         "    -3 dev        Expected device name (or index) to receive packets - server mode\n"
2004         "\n"
2005         "    -b            Bind test only.\n"
2006         "    -q            Be quiet. Run test without printing anything.\n"
2007         , prog, DEFAULT_PORT);
2008 }
2009 
2010 int main(int argc, char *argv[])
2011 {
2012         struct sock_args args = {
2013                 .version = AF_INET,
2014                 .type    = SOCK_STREAM,
2015                 .port    = DEFAULT_PORT,
2016         };
2017         struct protoent *pe;
2018         int both_mode = 0;
2019         unsigned int tmp;
2020         int forever = 0;
2021         int fd[2];
2022         int cpid;
2023 
2024         /* process inputs */
2025         extern char *optarg;
2026         int rc = 0;
2027 
2028         /*
2029          * process input args
2030          */
2031 
2032         while ((rc = getopt_long(argc, argv, GETOPT_STR, long_opts, NULL)) != -1) {
2033                 switch (rc) {
2034                 case 'B':
2035                         both_mode = 1;
2036                         break;
2037                 case 's':
2038                         server_mode = 1;
2039                         break;
2040                 case 'F':
2041                         forever = 1;
2042                         break;
2043                 case 'l':
2044                         args.has_local_ip = 1;
2045                         args.local_addr_str = optarg;
2046                         break;
2047                 case 'r':
2048                         args.has_remote_ip = 1;
2049                         args.remote_addr_str = optarg;
2050                         break;
2051                 case 'c':
2052                         args.has_local_ip = 1;
2053                         args.client_local_addr_str = optarg;
2054                         break;
2055                 case 'Q':
2056                         if (str_to_uint(optarg, 0, 255, &tmp) != 0) {
2057                                 fprintf(stderr, "Invalid DS Field\n");
2058                                 return 1;
2059                         }
2060                         args.dsfield = tmp;
2061                         break;
2062                 case 'p':
2063                         if (str_to_uint(optarg, 1, 65535, &tmp) != 0) {
2064                                 fprintf(stderr, "Invalid port\n");
2065                                 return 1;
2066                         }
2067                         args.port = (unsigned short) tmp;
2068                         break;
2069                 case 't':
2070                         if (str_to_uint(optarg, 0, INT_MAX,
2071                                         &prog_timeout) != 0) {
2072                                 fprintf(stderr, "Invalid timeout\n");
2073                                 return 1;
2074                         }
2075                         break;
2076                 case 'D':
2077                         args.type = SOCK_DGRAM;
2078                         break;
2079                 case 'R':
2080                         args.type = SOCK_RAW;
2081                         args.port = 0;
2082                         if (!args.protocol)
2083                                 args.protocol = IPPROTO_RAW;
2084                         break;
2085                 case 'P':
2086                         pe = getprotobyname(optarg);
2087                         if (pe) {
2088                                 args.protocol = pe->p_proto;
2089                         } else {
2090                                 if (str_to_uint(optarg, 0, 0xffff, &tmp) != 0) {
2091                                         fprintf(stderr, "Invalid protocol\n");
2092                                         return 1;
2093                                 }
2094                                 args.protocol = tmp;
2095                         }
2096                         break;
2097                 case 'n':
2098                         iter = atoi(optarg);
2099                         break;
2100                 case 'N':
2101                         args.clientns = optarg;
2102                         break;
2103                 case 'O':
2104                         args.serverns = optarg;
2105                         break;
2106                 case 'L':
2107                         msg = random_msg(atoi(optarg));
2108                         break;
2109                 case 'M':
2110                         args.password = optarg;
2111                         break;
2112                 case OPT_FORCE_BIND_KEY_IFINDEX:
2113                         args.bind_key_ifindex = 1;
2114                         break;
2115                 case OPT_NO_BIND_KEY_IFINDEX:
2116                         args.bind_key_ifindex = -1;
2117                         break;
2118                 case OPT_CLIENT_DONTROUTE:
2119                         args.client_dontroute = 1;
2120                         break;
2121                 case OPT_SERVER_DONTROUTE:
2122                         args.server_dontroute = 1;
2123                         break;
2124                 case 'X':
2125                         args.client_pw = optarg;
2126                         break;
2127                 case 'm':
2128                         args.md5_prefix_str = optarg;
2129                         break;
2130                 case 'S':
2131                         args.use_setsockopt = 1;
2132                         break;
2133                 case 'f':
2134                         args.use_freebind = 1;
2135                         break;
2136                 case 'C':
2137                         args.use_cmsg = 1;
2138                         break;
2139                 case 'd':
2140                         args.dev = optarg;
2141                         break;
2142                 case 'I':
2143                         args.server_dev = optarg;
2144                         break;
2145                 case 'i':
2146                         interactive = 1;
2147                         break;
2148                 case 'g':
2149                         args.has_grp = 1;
2150                         if (convert_addr(&args, optarg, ADDR_TYPE_MCAST) < 0)
2151                                 return 1;
2152                         args.type = SOCK_DGRAM;
2153                         break;
2154                 case '6':
2155                         args.version = AF_INET6;
2156                         break;
2157                 case 'b':
2158                         args.bind_test_only = 1;
2159                         break;
2160                 case '':
2161                         args.has_expected_laddr = 1;
2162                         args.expected_laddr_str = optarg;
2163                         break;
2164                 case '1':
2165                         args.has_expected_raddr = 1;
2166                         args.expected_raddr_str = optarg;
2167                         break;
2168                 case '2':
2169                         args.expected_dev = optarg;
2170                         break;
2171                 case '3':
2172                         args.expected_server_dev = optarg;
2173                         break;
2174                 case 'q':
2175                         quiet = 1;
2176                         break;
2177                 case 'x':
2178                         args.use_xfrm = 1;
2179                         break;
2180                 case 'U':
2181                         args.datagram_connect = 1;
2182                         break;
2183                 default:
2184                         print_usage(argv[0]);
2185                         return 1;
2186                 }
2187         }
2188 
2189         if (args.password &&
2190             ((!args.has_remote_ip && !args.md5_prefix_str) ||
2191               args.type != SOCK_STREAM)) {
2192                 log_error("MD5 passwords apply to TCP only and require a remote ip for the password\n");
2193                 return 1;
2194         }
2195 
2196         if (args.md5_prefix_str && !args.password) {
2197                 log_error("Prefix range for MD5 protection specified without a password\n");
2198                 return 1;
2199         }
2200 
2201         if (iter == 0) {
2202                 fprintf(stderr, "Invalid number of messages to send\n");
2203                 return 1;
2204         }
2205 
2206         if (args.type == SOCK_STREAM && !args.protocol)
2207                 args.protocol = IPPROTO_TCP;
2208         if (args.type == SOCK_DGRAM && !args.protocol)
2209                 args.protocol = IPPROTO_UDP;
2210 
2211         if ((args.type == SOCK_STREAM || args.type == SOCK_DGRAM) &&
2212              args.port == 0) {
2213                 fprintf(stderr, "Invalid port number\n");
2214                 return 1;
2215         }
2216 
2217         if ((both_mode || !server_mode) && !args.has_grp &&
2218             !args.has_remote_ip && !args.has_local_ip) {
2219                 fprintf(stderr,
2220                         "Local (server mode) or remote IP (client IP) required\n");
2221                 return 1;
2222         }
2223 
2224         if (interactive) {
2225                 prog_timeout = 0;
2226                 msg = NULL;
2227         }
2228 
2229         if (both_mode) {
2230                 if (pipe(fd) < 0) {
2231                         perror("pipe");
2232                         exit(1);
2233                 }
2234 
2235                 cpid = fork();
2236                 if (cpid < 0) {
2237                         perror("fork");
2238                         exit(1);
2239                 }
2240                 if (cpid)
2241                         return ipc_parent(cpid, fd[0], &args);
2242 
2243                 return ipc_child(fd[1], &args);
2244         }
2245 
2246         if (server_mode) {
2247                 do {
2248                         rc = do_server(&args, -1);
2249                 } while (forever);
2250 
2251                 return rc;
2252         }
2253         return do_client(&args);
2254 }
2255 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php