This source file includes following definitions.
- timestamp
- log_msg
- log_error
- log_err_errno
- log_address
- tcp_md5sig
- tcp_md5_remote
- get_ifidx
- bind_to_device
- get_bind_to_device
- check_device
- set_pktinfo_v4
- set_recvpktinfo_v6
- set_recverr_v4
- set_recverr_v6
- set_unicast_if
- set_multicast_if
- set_membership
- set_broadcast
- set_reuseport
- set_reuseaddr
- str_to_uint
- expected_addr_match
- show_sockstat
- get_index_from_cmsg
- send_msg_no_cmsg
- send_msg_cmsg
- send_msg
- socket_read_dgram
- socket_read_stream
- socket_read
- stdin_to_socket
- set_recv_attr
- msg_loop
- msock_init
- msock_server
- msock_client
- bind_socket
- lsock_init
- do_server
- wait_for_connect
- connectsock
- do_client
- convert_addr
- random_msg
- print_usage
- main
1
2
3
4
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 <linux/tcp.h>
13 #include <arpa/inet.h>
14 #include <net/if.h>
15 #include <netinet/in.h>
16 #include <netdb.h>
17 #include <fcntl.h>
18 #include <libgen.h>
19 #include <limits.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <errno.h>
27
28 #ifndef IPV6_UNICAST_IF
29 #define IPV6_UNICAST_IF 76
30 #endif
31 #ifndef IPV6_MULTICAST_IF
32 #define IPV6_MULTICAST_IF 17
33 #endif
34
35 #define DEFAULT_PORT 12345
36
37 #ifndef MAX
38 #define MAX(a, b) ((a) > (b) ? (a) : (b))
39 #endif
40 #ifndef MIN
41 #define MIN(a, b) ((a) < (b) ? (a) : (b))
42 #endif
43
44 struct sock_args {
45
46 union {
47 struct in_addr in;
48 struct in6_addr in6;
49 } local_addr;
50
51
52 union {
53 struct in_addr in;
54 struct in6_addr in6;
55 } remote_addr;
56 int scope_id;
57
58 struct in_addr grp;
59
60 unsigned int has_local_ip:1,
61 has_remote_ip:1,
62 has_grp:1,
63 has_expected_laddr:1,
64 has_expected_raddr:1,
65 bind_test_only:1;
66
67 unsigned short port;
68
69 int type;
70 int protocol;
71 int version;
72
73 int use_setsockopt;
74 int use_cmsg;
75 const char *dev;
76 int ifindex;
77 const char *password;
78
79
80 int expected_ifindex;
81
82
83 union {
84 struct in_addr in;
85 struct in6_addr in6;
86 } expected_laddr;
87
88
89 union {
90 struct in_addr in;
91 struct in6_addr in6;
92 } expected_raddr;
93 };
94
95 static int server_mode;
96 static unsigned int prog_timeout = 5;
97 static unsigned int interactive;
98 static int iter = 1;
99 static char *msg = "Hello world!";
100 static int msglen;
101 static int quiet;
102 static int try_broadcast = 1;
103
104 static char *timestamp(char *timebuf, int buflen)
105 {
106 time_t now;
107
108 now = time(NULL);
109 if (strftime(timebuf, buflen, "%T", localtime(&now)) == 0) {
110 memset(timebuf, 0, buflen);
111 strncpy(timebuf, "00:00:00", buflen-1);
112 }
113
114 return timebuf;
115 }
116
117 static void log_msg(const char *format, ...)
118 {
119 char timebuf[64];
120 va_list args;
121
122 if (quiet)
123 return;
124
125 fprintf(stdout, "%s %s:",
126 timestamp(timebuf, sizeof(timebuf)),
127 server_mode ? "server" : "client");
128 va_start(args, format);
129 vfprintf(stdout, format, args);
130 va_end(args);
131
132 fflush(stdout);
133 }
134
135 static void log_error(const char *format, ...)
136 {
137 char timebuf[64];
138 va_list args;
139
140 if (quiet)
141 return;
142
143 fprintf(stderr, "%s %s:",
144 timestamp(timebuf, sizeof(timebuf)),
145 server_mode ? "server" : "client");
146 va_start(args, format);
147 vfprintf(stderr, format, args);
148 va_end(args);
149
150 fflush(stderr);
151 }
152
153 static void log_err_errno(const char *fmt, ...)
154 {
155 char timebuf[64];
156 va_list args;
157
158 if (quiet)
159 return;
160
161 fprintf(stderr, "%s %s: ",
162 timestamp(timebuf, sizeof(timebuf)),
163 server_mode ? "server" : "client");
164 va_start(args, fmt);
165 vfprintf(stderr, fmt, args);
166 va_end(args);
167
168 fprintf(stderr, ": %d: %s\n", errno, strerror(errno));
169 fflush(stderr);
170 }
171
172 static void log_address(const char *desc, struct sockaddr *sa)
173 {
174 char addrstr[64];
175
176 if (quiet)
177 return;
178
179 if (sa->sa_family == AF_INET) {
180 struct sockaddr_in *s = (struct sockaddr_in *) sa;
181
182 log_msg("%s %s:%d",
183 desc,
184 inet_ntop(AF_INET, &s->sin_addr, addrstr,
185 sizeof(addrstr)),
186 ntohs(s->sin_port));
187
188 } else if (sa->sa_family == AF_INET6) {
189 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
190
191 log_msg("%s [%s]:%d",
192 desc,
193 inet_ntop(AF_INET6, &s6->sin6_addr, addrstr,
194 sizeof(addrstr)),
195 ntohs(s6->sin6_port));
196 }
197
198 printf("\n");
199
200 fflush(stdout);
201 }
202
203 static int tcp_md5sig(int sd, void *addr, socklen_t alen, const char *password)
204 {
205 struct tcp_md5sig md5sig;
206 int keylen = password ? strlen(password) : 0;
207 int rc;
208
209 memset(&md5sig, 0, sizeof(md5sig));
210 memcpy(&md5sig.tcpm_addr, addr, alen);
211 md5sig.tcpm_keylen = keylen;
212
213 if (keylen)
214 memcpy(md5sig.tcpm_key, password, keylen);
215
216 rc = setsockopt(sd, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof(md5sig));
217 if (rc < 0) {
218
219 if (errno == ENOENT)
220 rc = 0;
221 else
222 log_err_errno("setsockopt(TCP_MD5SIG)");
223 }
224
225 return rc;
226 }
227
228 static int tcp_md5_remote(int sd, struct sock_args *args)
229 {
230 struct sockaddr_in sin = {
231 .sin_family = AF_INET,
232 };
233 struct sockaddr_in6 sin6 = {
234 .sin6_family = AF_INET6,
235 };
236 void *addr;
237 int alen;
238
239 switch (args->version) {
240 case AF_INET:
241 sin.sin_port = htons(args->port);
242 sin.sin_addr = args->remote_addr.in;
243 addr = &sin;
244 alen = sizeof(sin);
245 break;
246 case AF_INET6:
247 sin6.sin6_port = htons(args->port);
248 sin6.sin6_addr = args->remote_addr.in6;
249 addr = &sin6;
250 alen = sizeof(sin6);
251 break;
252 default:
253 log_error("unknown address family\n");
254 exit(1);
255 }
256
257 if (tcp_md5sig(sd, addr, alen, args->password))
258 return -1;
259
260 return 0;
261 }
262
263 static int get_ifidx(const char *ifname)
264 {
265 struct ifreq ifdata;
266 int sd, rc;
267
268 if (!ifname || *ifname == '\0')
269 return -1;
270
271 memset(&ifdata, 0, sizeof(ifdata));
272
273 strcpy(ifdata.ifr_name, ifname);
274
275 sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
276 if (sd < 0) {
277 log_err_errno("socket failed");
278 return -1;
279 }
280
281 rc = ioctl(sd, SIOCGIFINDEX, (char *)&ifdata);
282 close(sd);
283 if (rc != 0) {
284 log_err_errno("ioctl(SIOCGIFINDEX) failed");
285 return -1;
286 }
287
288 return ifdata.ifr_ifindex;
289 }
290
291 static int bind_to_device(int sd, const char *name)
292 {
293 int rc;
294
295 rc = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
296 if (rc < 0)
297 log_err_errno("setsockopt(SO_BINDTODEVICE)");
298
299 return rc;
300 }
301
302 static int get_bind_to_device(int sd, char *name, size_t len)
303 {
304 int rc;
305 socklen_t optlen = len;
306
307 name[0] = '\0';
308 rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen);
309 if (rc < 0)
310 log_err_errno("setsockopt(SO_BINDTODEVICE)");
311
312 return rc;
313 }
314
315 static int check_device(int sd, struct sock_args *args)
316 {
317 int ifindex = 0;
318 char name[32];
319
320 if (get_bind_to_device(sd, name, sizeof(name)))
321 *name = '\0';
322 else
323 ifindex = get_ifidx(name);
324
325 log_msg(" bound to device %s/%d\n",
326 *name ? name : "<none>", ifindex);
327
328 if (!args->expected_ifindex)
329 return 0;
330
331 if (args->expected_ifindex != ifindex) {
332 log_error("Device index mismatch: expected %d have %d\n",
333 args->expected_ifindex, ifindex);
334 return 1;
335 }
336
337 log_msg("Device index matches: expected %d have %d\n",
338 args->expected_ifindex, ifindex);
339
340 return 0;
341 }
342
343 static int set_pktinfo_v4(int sd)
344 {
345 int one = 1;
346 int rc;
347
348 rc = setsockopt(sd, SOL_IP, IP_PKTINFO, &one, sizeof(one));
349 if (rc < 0 && rc != -ENOTSUP)
350 log_err_errno("setsockopt(IP_PKTINFO)");
351
352 return rc;
353 }
354
355 static int set_recvpktinfo_v6(int sd)
356 {
357 int one = 1;
358 int rc;
359
360 rc = setsockopt(sd, SOL_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
361 if (rc < 0 && rc != -ENOTSUP)
362 log_err_errno("setsockopt(IPV6_RECVPKTINFO)");
363
364 return rc;
365 }
366
367 static int set_recverr_v4(int sd)
368 {
369 int one = 1;
370 int rc;
371
372 rc = setsockopt(sd, SOL_IP, IP_RECVERR, &one, sizeof(one));
373 if (rc < 0 && rc != -ENOTSUP)
374 log_err_errno("setsockopt(IP_RECVERR)");
375
376 return rc;
377 }
378
379 static int set_recverr_v6(int sd)
380 {
381 int one = 1;
382 int rc;
383
384 rc = setsockopt(sd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one));
385 if (rc < 0 && rc != -ENOTSUP)
386 log_err_errno("setsockopt(IPV6_RECVERR)");
387
388 return rc;
389 }
390
391 static int set_unicast_if(int sd, int ifindex, int version)
392 {
393 int opt = IP_UNICAST_IF;
394 int level = SOL_IP;
395 int rc;
396
397 ifindex = htonl(ifindex);
398
399 if (version == AF_INET6) {
400 opt = IPV6_UNICAST_IF;
401 level = SOL_IPV6;
402 }
403 rc = setsockopt(sd, level, opt, &ifindex, sizeof(ifindex));
404 if (rc < 0)
405 log_err_errno("setsockopt(IP_UNICAST_IF)");
406
407 return rc;
408 }
409
410 static int set_multicast_if(int sd, int ifindex)
411 {
412 struct ip_mreqn mreq = { .imr_ifindex = ifindex };
413 int rc;
414
415 rc = setsockopt(sd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq));
416 if (rc < 0)
417 log_err_errno("setsockopt(IP_MULTICAST_IF)");
418
419 return rc;
420 }
421
422 static int set_membership(int sd, uint32_t grp, uint32_t addr, int ifindex)
423 {
424 uint32_t if_addr = addr;
425 struct ip_mreqn mreq;
426 int rc;
427
428 if (addr == htonl(INADDR_ANY) && !ifindex) {
429 log_error("Either local address or device needs to be given for multicast membership\n");
430 return -1;
431 }
432
433 mreq.imr_multiaddr.s_addr = grp;
434 mreq.imr_address.s_addr = if_addr;
435 mreq.imr_ifindex = ifindex;
436
437 rc = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
438 if (rc < 0) {
439 log_err_errno("setsockopt(IP_ADD_MEMBERSHIP)");
440 return -1;
441 }
442
443 return 0;
444 }
445
446 static int set_broadcast(int sd)
447 {
448 unsigned int one = 1;
449 int rc = 0;
450
451 if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) != 0) {
452 log_err_errno("setsockopt(SO_BROADCAST)");
453 rc = -1;
454 }
455
456 return rc;
457 }
458
459 static int set_reuseport(int sd)
460 {
461 unsigned int one = 1;
462 int rc = 0;
463
464 if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != 0) {
465 log_err_errno("setsockopt(SO_REUSEPORT)");
466 rc = -1;
467 }
468
469 return rc;
470 }
471
472 static int set_reuseaddr(int sd)
473 {
474 unsigned int one = 1;
475 int rc = 0;
476
477 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) {
478 log_err_errno("setsockopt(SO_REUSEADDR)");
479 rc = -1;
480 }
481
482 return rc;
483 }
484
485 static int str_to_uint(const char *str, int min, int max, unsigned int *value)
486 {
487 int number;
488 char *end;
489
490 errno = 0;
491 number = (unsigned int) strtoul(str, &end, 0);
492
493
494
495
496 if (((*end == '\0') || (*end == '\n')) && (end != str) &&
497 (errno != ERANGE) && (min <= number) && (number <= max)) {
498 *value = number;
499 return 0;
500 }
501
502 return -1;
503 }
504
505 static int expected_addr_match(struct sockaddr *sa, void *expected,
506 const char *desc)
507 {
508 char addrstr[64];
509 int rc = 0;
510
511 if (sa->sa_family == AF_INET) {
512 struct sockaddr_in *s = (struct sockaddr_in *) sa;
513 struct in_addr *exp_in = (struct in_addr *) expected;
514
515 if (s->sin_addr.s_addr != exp_in->s_addr) {
516 log_error("%s address does not match expected %s",
517 desc,
518 inet_ntop(AF_INET, exp_in,
519 addrstr, sizeof(addrstr)));
520 rc = 1;
521 }
522 } else if (sa->sa_family == AF_INET6) {
523 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
524 struct in6_addr *exp_in = (struct in6_addr *) expected;
525
526 if (memcmp(&s6->sin6_addr, exp_in, sizeof(*exp_in))) {
527 log_error("%s address does not match expected %s",
528 desc,
529 inet_ntop(AF_INET6, exp_in,
530 addrstr, sizeof(addrstr)));
531 rc = 1;
532 }
533 } else {
534 log_error("%s address does not match expected - unknown family",
535 desc);
536 rc = 1;
537 }
538
539 if (!rc)
540 log_msg("%s address matches expected\n", desc);
541
542 return rc;
543 }
544
545 static int show_sockstat(int sd, struct sock_args *args)
546 {
547 struct sockaddr_in6 local_addr, remote_addr;
548 socklen_t alen = sizeof(local_addr);
549 struct sockaddr *sa;
550 const char *desc;
551 int rc = 0;
552
553 desc = server_mode ? "server local:" : "client local:";
554 sa = (struct sockaddr *) &local_addr;
555 if (getsockname(sd, sa, &alen) == 0) {
556 log_address(desc, sa);
557
558 if (args->has_expected_laddr) {
559 rc = expected_addr_match(sa, &args->expected_laddr,
560 "local");
561 }
562 } else {
563 log_err_errno("getsockname failed");
564 }
565
566 sa = (struct sockaddr *) &remote_addr;
567 desc = server_mode ? "server peer:" : "client peer:";
568 if (getpeername(sd, sa, &alen) == 0) {
569 log_address(desc, sa);
570
571 if (args->has_expected_raddr) {
572 rc |= expected_addr_match(sa, &args->expected_raddr,
573 "remote");
574 }
575 } else {
576 log_err_errno("getpeername failed");
577 }
578
579 return rc;
580 }
581
582 static int get_index_from_cmsg(struct msghdr *m)
583 {
584 struct cmsghdr *cm;
585 int ifindex = 0;
586 char buf[64];
587
588 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(m);
589 m->msg_controllen != 0 && cm;
590 cm = (struct cmsghdr *)CMSG_NXTHDR(m, cm)) {
591
592 if (cm->cmsg_level == SOL_IP &&
593 cm->cmsg_type == IP_PKTINFO) {
594 struct in_pktinfo *pi;
595
596 pi = (struct in_pktinfo *)(CMSG_DATA(cm));
597 inet_ntop(AF_INET, &pi->ipi_addr, buf, sizeof(buf));
598 ifindex = pi->ipi_ifindex;
599 } else if (cm->cmsg_level == SOL_IPV6 &&
600 cm->cmsg_type == IPV6_PKTINFO) {
601 struct in6_pktinfo *pi6;
602
603 pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
604 inet_ntop(AF_INET6, &pi6->ipi6_addr, buf, sizeof(buf));
605 ifindex = pi6->ipi6_ifindex;
606 }
607 }
608
609 if (ifindex) {
610 log_msg(" pktinfo: ifindex %d dest addr %s\n",
611 ifindex, buf);
612 }
613 return ifindex;
614 }
615
616 static int send_msg_no_cmsg(int sd, void *addr, socklen_t alen)
617 {
618 int err;
619
620 again:
621 err = sendto(sd, msg, msglen, 0, addr, alen);
622 if (err < 0) {
623 if (errno == EACCES && try_broadcast) {
624 try_broadcast = 0;
625 if (!set_broadcast(sd))
626 goto again;
627 errno = EACCES;
628 }
629
630 log_err_errno("sendto failed");
631 return 1;
632 }
633
634 return 0;
635 }
636
637 static int send_msg_cmsg(int sd, void *addr, socklen_t alen,
638 int ifindex, int version)
639 {
640 unsigned char cmsgbuf[64];
641 struct iovec iov[2];
642 struct cmsghdr *cm;
643 struct msghdr m;
644 int err;
645
646 iov[0].iov_base = msg;
647 iov[0].iov_len = msglen;
648 m.msg_iov = iov;
649 m.msg_iovlen = 1;
650 m.msg_name = (caddr_t)addr;
651 m.msg_namelen = alen;
652
653 memset(cmsgbuf, 0, sizeof(cmsgbuf));
654 cm = (struct cmsghdr *)cmsgbuf;
655 m.msg_control = (caddr_t)cm;
656
657 if (version == AF_INET) {
658 struct in_pktinfo *pi;
659
660 cm->cmsg_level = SOL_IP;
661 cm->cmsg_type = IP_PKTINFO;
662 cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
663 pi = (struct in_pktinfo *)(CMSG_DATA(cm));
664 pi->ipi_ifindex = ifindex;
665
666 m.msg_controllen = cm->cmsg_len;
667
668 } else if (version == AF_INET6) {
669 struct in6_pktinfo *pi6;
670
671 cm->cmsg_level = SOL_IPV6;
672 cm->cmsg_type = IPV6_PKTINFO;
673 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
674
675 pi6 = (struct in6_pktinfo *)(CMSG_DATA(cm));
676 pi6->ipi6_ifindex = ifindex;
677
678 m.msg_controllen = cm->cmsg_len;
679 }
680
681 again:
682 err = sendmsg(sd, &m, 0);
683 if (err < 0) {
684 if (errno == EACCES && try_broadcast) {
685 try_broadcast = 0;
686 if (!set_broadcast(sd))
687 goto again;
688 errno = EACCES;
689 }
690
691 log_err_errno("sendmsg failed");
692 return 1;
693 }
694
695 return 0;
696 }
697
698
699 static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
700 {
701 if (args->type == SOCK_STREAM) {
702 if (write(sd, msg, msglen) < 0) {
703 log_err_errno("write failed sending msg to peer");
704 return 1;
705 }
706 } else if (args->ifindex && args->use_cmsg) {
707 if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
708 return 1;
709 } else {
710 if (send_msg_no_cmsg(sd, addr, alen))
711 return 1;
712 }
713
714 log_msg("Sent message:\n");
715 log_msg(" %.24s%s\n", msg, msglen > 24 ? " ..." : "");
716
717 return 0;
718 }
719
720 static int socket_read_dgram(int sd, struct sock_args *args)
721 {
722 unsigned char addr[sizeof(struct sockaddr_in6)];
723 struct sockaddr *sa = (struct sockaddr *) addr;
724 socklen_t alen = sizeof(addr);
725 struct iovec iov[2];
726 struct msghdr m = {
727 .msg_name = (caddr_t)addr,
728 .msg_namelen = alen,
729 .msg_iov = iov,
730 .msg_iovlen = 1,
731 };
732 unsigned char cmsgbuf[256];
733 struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
734 char buf[16*1024];
735 int ifindex;
736 int len;
737
738 iov[0].iov_base = (caddr_t)buf;
739 iov[0].iov_len = sizeof(buf);
740
741 memset(cmsgbuf, 0, sizeof(cmsgbuf));
742 m.msg_control = (caddr_t)cm;
743 m.msg_controllen = sizeof(cmsgbuf);
744
745 len = recvmsg(sd, &m, 0);
746 if (len == 0) {
747 log_msg("peer closed connection.\n");
748 return 0;
749 } else if (len < 0) {
750 log_msg("failed to read message: %d: %s\n",
751 errno, strerror(errno));
752 return -1;
753 }
754
755 buf[len] = '\0';
756
757 log_address("Message from:", sa);
758 log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : "");
759
760 ifindex = get_index_from_cmsg(&m);
761 if (args->expected_ifindex) {
762 if (args->expected_ifindex != ifindex) {
763 log_error("Device index mismatch: expected %d have %d\n",
764 args->expected_ifindex, ifindex);
765 return -1;
766 }
767 log_msg("Device index matches: expected %d have %d\n",
768 args->expected_ifindex, ifindex);
769 }
770
771 if (!interactive && server_mode) {
772 if (sa->sa_family == AF_INET6) {
773 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
774 struct in6_addr *in6 = &s6->sin6_addr;
775
776 if (IN6_IS_ADDR_V4MAPPED(in6)) {
777 const uint32_t *pa = (uint32_t *) &in6->s6_addr;
778 struct in_addr in4;
779 struct sockaddr_in *sin;
780
781 sin = (struct sockaddr_in *) addr;
782 pa += 3;
783 in4.s_addr = *pa;
784 sin->sin_addr = in4;
785 sin->sin_family = AF_INET;
786 if (send_msg_cmsg(sd, addr, alen,
787 ifindex, AF_INET) < 0)
788 goto out_err;
789 }
790 }
791 again:
792 iov[0].iov_len = len;
793
794 if (args->version == AF_INET6) {
795 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) sa;
796
797 if (args->dev) {
798
799 if (sendto(sd, buf, len, 0,
800 (void *) addr, alen) < 0)
801 goto out_err;
802 } else {
803
804
805
806
807 s6->sin6_scope_id = ifindex;
808 if (sendmsg(sd, &m, 0) < 0)
809 goto out_err;
810 }
811 } else {
812 int err;
813
814 err = sendmsg(sd, &m, 0);
815 if (err < 0) {
816 if (errno == EACCES && try_broadcast) {
817 try_broadcast = 0;
818 if (!set_broadcast(sd))
819 goto again;
820 errno = EACCES;
821 }
822 goto out_err;
823 }
824 }
825 log_msg("Sent message:\n");
826 log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : "");
827 }
828
829 return 1;
830 out_err:
831 log_err_errno("failed to send msg to peer");
832 return -1;
833 }
834
835 static int socket_read_stream(int sd)
836 {
837 char buf[1024];
838 int len;
839
840 len = read(sd, buf, sizeof(buf)-1);
841 if (len == 0) {
842 log_msg("client closed connection.\n");
843 return 0;
844 } else if (len < 0) {
845 log_msg("failed to read message\n");
846 return -1;
847 }
848
849 buf[len] = '\0';
850 log_msg("Incoming message:\n");
851 log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : "");
852
853 if (!interactive && server_mode) {
854 if (write(sd, buf, len) < 0) {
855 log_err_errno("failed to send buf");
856 return -1;
857 }
858 log_msg("Sent message:\n");
859 log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : "");
860 }
861
862 return 1;
863 }
864
865 static int socket_read(int sd, struct sock_args *args)
866 {
867 if (args->type == SOCK_STREAM)
868 return socket_read_stream(sd);
869
870 return socket_read_dgram(sd, args);
871 }
872
873 static int stdin_to_socket(int sd, int type, void *addr, socklen_t alen)
874 {
875 char buf[1024];
876 int len;
877
878 if (fgets(buf, sizeof(buf), stdin) == NULL)
879 return 0;
880
881 len = strlen(buf);
882 if (type == SOCK_STREAM) {
883 if (write(sd, buf, len) < 0) {
884 log_err_errno("failed to send buf");
885 return -1;
886 }
887 } else {
888 int err;
889
890 again:
891 err = sendto(sd, buf, len, 0, addr, alen);
892 if (err < 0) {
893 if (errno == EACCES && try_broadcast) {
894 try_broadcast = 0;
895 if (!set_broadcast(sd))
896 goto again;
897 errno = EACCES;
898 }
899 log_err_errno("failed to send msg to peer");
900 return -1;
901 }
902 }
903 log_msg("Sent message:\n");
904 log_msg(" %.24s%s\n", buf, len > 24 ? " ..." : "");
905
906 return 1;
907 }
908
909 static void set_recv_attr(int sd, int version)
910 {
911 if (version == AF_INET6) {
912 set_recvpktinfo_v6(sd);
913 set_recverr_v6(sd);
914 } else {
915 set_pktinfo_v4(sd);
916 set_recverr_v4(sd);
917 }
918 }
919
920 static int msg_loop(int client, int sd, void *addr, socklen_t alen,
921 struct sock_args *args)
922 {
923 struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
924 fd_set rfds;
925 int nfds;
926 int rc;
927
928 if (args->type != SOCK_STREAM)
929 set_recv_attr(sd, args->version);
930
931 if (msg) {
932 msglen = strlen(msg);
933
934
935 if (client) {
936 if (send_msg(sd, addr, alen, args))
937 return 1;
938 }
939 if (!interactive) {
940 ptval = &timeout;
941 if (!prog_timeout)
942 timeout.tv_sec = 5;
943 }
944 }
945
946 nfds = interactive ? MAX(fileno(stdin), sd) + 1 : sd + 1;
947 while (1) {
948 FD_ZERO(&rfds);
949 FD_SET(sd, &rfds);
950 if (interactive)
951 FD_SET(fileno(stdin), &rfds);
952
953 rc = select(nfds, &rfds, NULL, NULL, ptval);
954 if (rc < 0) {
955 if (errno == EINTR)
956 continue;
957
958 rc = 1;
959 log_err_errno("select failed");
960 break;
961 } else if (rc == 0) {
962 log_error("Timed out waiting for response\n");
963 rc = 2;
964 break;
965 }
966
967 if (FD_ISSET(sd, &rfds)) {
968 rc = socket_read(sd, args);
969 if (rc < 0) {
970 rc = 1;
971 break;
972 }
973 if (rc == 0)
974 break;
975 }
976
977 rc = 0;
978
979 if (FD_ISSET(fileno(stdin), &rfds)) {
980 if (stdin_to_socket(sd, args->type, addr, alen) <= 0)
981 break;
982 }
983
984 if (interactive)
985 continue;
986
987 if (iter != -1) {
988 --iter;
989 if (iter == 0)
990 break;
991 }
992
993 log_msg("Going into quiet mode\n");
994 quiet = 1;
995
996 if (client) {
997 if (send_msg(sd, addr, alen, args)) {
998 rc = 1;
999 break;
1000 }
1001 }
1002 }
1003
1004 return rc;
1005 }
1006
1007 static int msock_init(struct sock_args *args, int server)
1008 {
1009 uint32_t if_addr = htonl(INADDR_ANY);
1010 struct sockaddr_in laddr = {
1011 .sin_family = AF_INET,
1012 .sin_port = htons(args->port),
1013 };
1014 int one = 1;
1015 int sd;
1016
1017 if (!server && args->has_local_ip)
1018 if_addr = args->local_addr.in.s_addr;
1019
1020 sd = socket(PF_INET, SOCK_DGRAM, 0);
1021 if (sd < 0) {
1022 log_err_errno("socket");
1023 return -1;
1024 }
1025
1026 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
1027 (char *)&one, sizeof(one)) < 0) {
1028 log_err_errno("Setting SO_REUSEADDR error");
1029 goto out_err;
1030 }
1031
1032 if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST,
1033 (char *)&one, sizeof(one)) < 0)
1034 log_err_errno("Setting SO_BROADCAST error");
1035
1036 if (args->dev && bind_to_device(sd, args->dev) != 0)
1037 goto out_err;
1038 else if (args->use_setsockopt &&
1039 set_multicast_if(sd, args->ifindex))
1040 goto out_err;
1041
1042 laddr.sin_addr.s_addr = if_addr;
1043
1044 if (bind(sd, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
1045 log_err_errno("bind failed");
1046 goto out_err;
1047 }
1048
1049 if (server &&
1050 set_membership(sd, args->grp.s_addr,
1051 args->local_addr.in.s_addr, args->ifindex))
1052 goto out_err;
1053
1054 return sd;
1055 out_err:
1056 close(sd);
1057 return -1;
1058 }
1059
1060 static int msock_server(struct sock_args *args)
1061 {
1062 return msock_init(args, 1);
1063 }
1064
1065 static int msock_client(struct sock_args *args)
1066 {
1067 return msock_init(args, 0);
1068 }
1069
1070 static int bind_socket(int sd, struct sock_args *args)
1071 {
1072 struct sockaddr_in serv_addr = {
1073 .sin_family = AF_INET,
1074 };
1075 struct sockaddr_in6 serv6_addr = {
1076 .sin6_family = AF_INET6,
1077 };
1078 void *addr;
1079 socklen_t alen;
1080
1081 if (!args->has_local_ip && args->type == SOCK_RAW)
1082 return 0;
1083
1084 switch (args->version) {
1085 case AF_INET:
1086 serv_addr.sin_port = htons(args->port);
1087 serv_addr.sin_addr = args->local_addr.in;
1088 addr = &serv_addr;
1089 alen = sizeof(serv_addr);
1090 break;
1091
1092 case AF_INET6:
1093 serv6_addr.sin6_port = htons(args->port);
1094 serv6_addr.sin6_addr = args->local_addr.in6;
1095 addr = &serv6_addr;
1096 alen = sizeof(serv6_addr);
1097 break;
1098
1099 default:
1100 log_error("Invalid address family\n");
1101 return -1;
1102 }
1103
1104 if (bind(sd, addr, alen) < 0) {
1105 log_err_errno("error binding socket");
1106 return -1;
1107 }
1108
1109 return 0;
1110 }
1111
1112 static int lsock_init(struct sock_args *args)
1113 {
1114 long flags;
1115 int sd;
1116
1117 sd = socket(args->version, args->type, args->protocol);
1118 if (sd < 0) {
1119 log_err_errno("Error opening socket");
1120 return -1;
1121 }
1122
1123 if (set_reuseaddr(sd) != 0)
1124 goto err;
1125
1126 if (set_reuseport(sd) != 0)
1127 goto err;
1128
1129 if (args->dev && bind_to_device(sd, args->dev) != 0)
1130 goto err;
1131 else if (args->use_setsockopt &&
1132 set_unicast_if(sd, args->ifindex, args->version))
1133 goto err;
1134
1135 if (bind_socket(sd, args))
1136 goto err;
1137
1138 if (args->bind_test_only)
1139 goto out;
1140
1141 if (args->type == SOCK_STREAM && listen(sd, 1) < 0) {
1142 log_err_errno("listen failed");
1143 goto err;
1144 }
1145
1146 flags = fcntl(sd, F_GETFL);
1147 if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
1148 log_err_errno("Failed to set non-blocking option");
1149 goto err;
1150 }
1151
1152 if (fcntl(sd, F_SETFD, FD_CLOEXEC) < 0)
1153 log_err_errno("Failed to set close-on-exec flag");
1154
1155 out:
1156 return sd;
1157
1158 err:
1159 close(sd);
1160 return -1;
1161 }
1162
1163 static int do_server(struct sock_args *args)
1164 {
1165 struct timeval timeout = { .tv_sec = prog_timeout }, *ptval = NULL;
1166 unsigned char addr[sizeof(struct sockaddr_in6)] = {};
1167 socklen_t alen = sizeof(addr);
1168 int lsd, csd = -1;
1169
1170 fd_set rfds;
1171 int rc;
1172
1173 if (prog_timeout)
1174 ptval = &timeout;
1175
1176 if (args->has_grp)
1177 lsd = msock_server(args);
1178 else
1179 lsd = lsock_init(args);
1180
1181 if (lsd < 0)
1182 return 1;
1183
1184 if (args->bind_test_only) {
1185 close(lsd);
1186 return 0;
1187 }
1188
1189 if (args->type != SOCK_STREAM) {
1190 rc = msg_loop(0, lsd, (void *) addr, alen, args);
1191 close(lsd);
1192 return rc;
1193 }
1194
1195 if (args->password && tcp_md5_remote(lsd, args)) {
1196 close(lsd);
1197 return -1;
1198 }
1199
1200 while (1) {
1201 log_msg("\n");
1202 log_msg("waiting for client connection.\n");
1203 FD_ZERO(&rfds);
1204 FD_SET(lsd, &rfds);
1205
1206 rc = select(lsd+1, &rfds, NULL, NULL, ptval);
1207 if (rc == 0) {
1208 rc = 2;
1209 break;
1210 }
1211
1212 if (rc < 0) {
1213 if (errno == EINTR)
1214 continue;
1215
1216 log_err_errno("select failed");
1217 break;
1218 }
1219
1220 if (FD_ISSET(lsd, &rfds)) {
1221
1222 csd = accept(lsd, (void *) addr, &alen);
1223 if (csd < 0) {
1224 log_err_errno("accept failed");
1225 break;
1226 }
1227
1228 rc = show_sockstat(csd, args);
1229 if (rc)
1230 break;
1231
1232 rc = check_device(csd, args);
1233 if (rc)
1234 break;
1235 }
1236
1237 rc = msg_loop(0, csd, (void *) addr, alen, args);
1238 close(csd);
1239
1240 if (!interactive)
1241 break;
1242 }
1243
1244 close(lsd);
1245
1246 return rc;
1247 }
1248
1249 static int wait_for_connect(int sd)
1250 {
1251 struct timeval _tv = { .tv_sec = prog_timeout }, *tv = NULL;
1252 fd_set wfd;
1253 int val = 0, sz = sizeof(val);
1254 int rc;
1255
1256 FD_ZERO(&wfd);
1257 FD_SET(sd, &wfd);
1258
1259 if (prog_timeout)
1260 tv = &_tv;
1261
1262 rc = select(FD_SETSIZE, NULL, &wfd, NULL, tv);
1263 if (rc == 0) {
1264 log_error("connect timed out\n");
1265 return -2;
1266 } else if (rc < 0) {
1267 log_err_errno("select failed");
1268 return -3;
1269 }
1270
1271 if (getsockopt(sd, SOL_SOCKET, SO_ERROR, &val, (socklen_t *)&sz) < 0) {
1272 log_err_errno("getsockopt(SO_ERROR) failed");
1273 return -4;
1274 }
1275
1276 if (val != 0) {
1277 log_error("connect failed: %d: %s\n", val, strerror(val));
1278 return -1;
1279 }
1280
1281 return 0;
1282 }
1283
1284 static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
1285 {
1286 int sd, rc = -1;
1287 long flags;
1288
1289 sd = socket(args->version, args->type, args->protocol);
1290 if (sd < 0) {
1291 log_err_errno("Failed to create socket");
1292 return -1;
1293 }
1294
1295 flags = fcntl(sd, F_GETFL);
1296 if ((flags < 0) || (fcntl(sd, F_SETFL, flags|O_NONBLOCK) < 0)) {
1297 log_err_errno("Failed to set non-blocking option");
1298 goto err;
1299 }
1300
1301 if (set_reuseport(sd) != 0)
1302 goto err;
1303
1304 if (args->dev && bind_to_device(sd, args->dev) != 0)
1305 goto err;
1306 else if (args->use_setsockopt &&
1307 set_unicast_if(sd, args->ifindex, args->version))
1308 goto err;
1309
1310 if (args->has_local_ip && bind_socket(sd, args))
1311 goto err;
1312
1313 if (args->type != SOCK_STREAM)
1314 goto out;
1315
1316 if (args->password && tcp_md5sig(sd, addr, alen, args->password))
1317 goto err;
1318
1319 if (args->bind_test_only)
1320 goto out;
1321
1322 if (connect(sd, addr, alen) < 0) {
1323 if (errno != EINPROGRESS) {
1324 log_err_errno("Failed to connect to remote host");
1325 rc = -1;
1326 goto err;
1327 }
1328 rc = wait_for_connect(sd);
1329 if (rc < 0)
1330 goto err;
1331 }
1332 out:
1333 return sd;
1334
1335 err:
1336 close(sd);
1337 return rc;
1338 }
1339
1340 static int do_client(struct sock_args *args)
1341 {
1342 struct sockaddr_in sin = {
1343 .sin_family = AF_INET,
1344 };
1345 struct sockaddr_in6 sin6 = {
1346 .sin6_family = AF_INET6,
1347 };
1348 void *addr;
1349 int alen;
1350 int rc = 0;
1351 int sd;
1352
1353 if (!args->has_remote_ip && !args->has_grp) {
1354 fprintf(stderr, "remote IP or multicast group not given\n");
1355 return 1;
1356 }
1357
1358 switch (args->version) {
1359 case AF_INET:
1360 sin.sin_port = htons(args->port);
1361 if (args->has_grp)
1362 sin.sin_addr = args->grp;
1363 else
1364 sin.sin_addr = args->remote_addr.in;
1365 addr = &sin;
1366 alen = sizeof(sin);
1367 break;
1368 case AF_INET6:
1369 sin6.sin6_port = htons(args->port);
1370 sin6.sin6_addr = args->remote_addr.in6;
1371 sin6.sin6_scope_id = args->scope_id;
1372 addr = &sin6;
1373 alen = sizeof(sin6);
1374 break;
1375 }
1376
1377 if (args->has_grp)
1378 sd = msock_client(args);
1379 else
1380 sd = connectsock(addr, alen, args);
1381
1382 if (sd < 0)
1383 return -sd;
1384
1385 if (args->bind_test_only)
1386 goto out;
1387
1388 if (args->type == SOCK_STREAM) {
1389 rc = show_sockstat(sd, args);
1390 if (rc != 0)
1391 goto out;
1392 }
1393
1394 rc = msg_loop(1, sd, addr, alen, args);
1395
1396 out:
1397 close(sd);
1398
1399 return rc;
1400 }
1401
1402 enum addr_type {
1403 ADDR_TYPE_LOCAL,
1404 ADDR_TYPE_REMOTE,
1405 ADDR_TYPE_MCAST,
1406 ADDR_TYPE_EXPECTED_LOCAL,
1407 ADDR_TYPE_EXPECTED_REMOTE,
1408 };
1409
1410 static int convert_addr(struct sock_args *args, const char *_str,
1411 enum addr_type atype)
1412 {
1413 int family = args->version;
1414 struct in6_addr *in6;
1415 struct in_addr *in;
1416 const char *desc;
1417 char *str, *dev;
1418 void *addr;
1419 int rc = 0;
1420
1421 str = strdup(_str);
1422 if (!str)
1423 return -ENOMEM;
1424
1425 switch (atype) {
1426 case ADDR_TYPE_LOCAL:
1427 desc = "local";
1428 addr = &args->local_addr;
1429 break;
1430 case ADDR_TYPE_REMOTE:
1431 desc = "remote";
1432 addr = &args->remote_addr;
1433 break;
1434 case ADDR_TYPE_MCAST:
1435 desc = "mcast grp";
1436 addr = &args->grp;
1437 break;
1438 case ADDR_TYPE_EXPECTED_LOCAL:
1439 desc = "expected local";
1440 addr = &args->expected_laddr;
1441 break;
1442 case ADDR_TYPE_EXPECTED_REMOTE:
1443 desc = "expected remote";
1444 addr = &args->expected_raddr;
1445 break;
1446 default:
1447 log_error("unknown address type");
1448 exit(1);
1449 }
1450
1451 switch (family) {
1452 case AF_INET:
1453 in = (struct in_addr *) addr;
1454 if (str) {
1455 if (inet_pton(AF_INET, str, in) == 0) {
1456 log_error("Invalid %s IP address\n", desc);
1457 rc = -1;
1458 goto out;
1459 }
1460 } else {
1461 in->s_addr = htonl(INADDR_ANY);
1462 }
1463 break;
1464
1465 case AF_INET6:
1466 dev = strchr(str, '%');
1467 if (dev) {
1468 *dev = '\0';
1469 dev++;
1470 }
1471
1472 in6 = (struct in6_addr *) addr;
1473 if (str) {
1474 if (inet_pton(AF_INET6, str, in6) == 0) {
1475 log_error("Invalid %s IPv6 address\n", desc);
1476 rc = -1;
1477 goto out;
1478 }
1479 } else {
1480 *in6 = in6addr_any;
1481 }
1482 if (dev) {
1483 args->scope_id = get_ifidx(dev);
1484 if (args->scope_id < 0) {
1485 log_error("Invalid scope on %s IPv6 address\n",
1486 desc);
1487 rc = -1;
1488 goto out;
1489 }
1490 }
1491 break;
1492
1493 default:
1494 log_error("Invalid address family\n");
1495 }
1496
1497 out:
1498 free(str);
1499 return rc;
1500 }
1501
1502 static char *random_msg(int len)
1503 {
1504 int i, n = 0, olen = len + 1;
1505 char *m;
1506
1507 if (len <= 0)
1508 return NULL;
1509
1510 m = malloc(olen);
1511 if (!m)
1512 return NULL;
1513
1514 while (len > 26) {
1515 i = snprintf(m + n, olen - n, "%.26s",
1516 "abcdefghijklmnopqrstuvwxyz");
1517 n += i;
1518 len -= i;
1519 }
1520 i = snprintf(m + n, olen - n, "%.*s", len,
1521 "abcdefghijklmnopqrstuvwxyz");
1522 return m;
1523 }
1524
1525 #define GETOPT_STR "sr:l:p:t:g:P:DRn:M:d:SCi6L:0:1:2:Fbq"
1526
1527 static void print_usage(char *prog)
1528 {
1529 printf(
1530 "usage: %s OPTS\n"
1531 "Required:\n"
1532 " -r addr remote address to connect to (client mode only)\n"
1533 " -p port port to connect to (client mode)/listen on (server mode)\n"
1534 " (default: %d)\n"
1535 " -s server mode (default: client mode)\n"
1536 " -t timeout seconds (default: none)\n"
1537 "\n"
1538 "Optional:\n"
1539 " -F Restart server loop\n"
1540 " -6 IPv6 (default is IPv4)\n"
1541 " -P proto protocol for socket: icmp, ospf (default: none)\n"
1542 " -D|R datagram (D) / raw (R) socket (default stream)\n"
1543 " -l addr local address to bind to\n"
1544 "\n"
1545 " -d dev bind socket to given device name\n"
1546 " -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
1547 " to set device binding\n"
1548 " -C use cmsg and IP_PKTINFO to specify device binding\n"
1549 "\n"
1550 " -L len send random message of given length\n"
1551 " -n num number of times to send message\n"
1552 "\n"
1553 " -M password use MD5 sum protection\n"
1554 " -g grp multicast group (e.g., 239.1.1.1)\n"
1555 " -i interactive mode (default is echo and terminate)\n"
1556 "\n"
1557 " -0 addr Expected local address\n"
1558 " -1 addr Expected remote address\n"
1559 " -2 dev Expected device name (or index) to receive packet\n"
1560 "\n"
1561 " -b Bind test only.\n"
1562 " -q Be quiet. Run test without printing anything.\n"
1563 , prog, DEFAULT_PORT);
1564 }
1565
1566 int main(int argc, char *argv[])
1567 {
1568 struct sock_args args = {
1569 .version = AF_INET,
1570 .type = SOCK_STREAM,
1571 .port = DEFAULT_PORT,
1572 };
1573 struct protoent *pe;
1574 unsigned int tmp;
1575 int forever = 0;
1576
1577
1578 extern char *optarg;
1579 int rc = 0;
1580
1581
1582
1583
1584
1585 while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) {
1586 switch (rc) {
1587 case 's':
1588 server_mode = 1;
1589 break;
1590 case 'F':
1591 forever = 1;
1592 break;
1593 case 'l':
1594 args.has_local_ip = 1;
1595 if (convert_addr(&args, optarg, ADDR_TYPE_LOCAL) < 0)
1596 return 1;
1597 break;
1598 case 'r':
1599 args.has_remote_ip = 1;
1600 if (convert_addr(&args, optarg, ADDR_TYPE_REMOTE) < 0)
1601 return 1;
1602 break;
1603 case 'p':
1604 if (str_to_uint(optarg, 1, 65535, &tmp) != 0) {
1605 fprintf(stderr, "Invalid port\n");
1606 return 1;
1607 }
1608 args.port = (unsigned short) tmp;
1609 break;
1610 case 't':
1611 if (str_to_uint(optarg, 0, INT_MAX,
1612 &prog_timeout) != 0) {
1613 fprintf(stderr, "Invalid timeout\n");
1614 return 1;
1615 }
1616 break;
1617 case 'D':
1618 args.type = SOCK_DGRAM;
1619 break;
1620 case 'R':
1621 args.type = SOCK_RAW;
1622 args.port = 0;
1623 break;
1624 case 'P':
1625 pe = getprotobyname(optarg);
1626 if (pe) {
1627 args.protocol = pe->p_proto;
1628 } else {
1629 if (str_to_uint(optarg, 0, 0xffff, &tmp) != 0) {
1630 fprintf(stderr, "Invalid protocol\n");
1631 return 1;
1632 }
1633 args.protocol = tmp;
1634 }
1635 break;
1636 case 'n':
1637 iter = atoi(optarg);
1638 break;
1639 case 'L':
1640 msg = random_msg(atoi(optarg));
1641 break;
1642 case 'M':
1643 args.password = optarg;
1644 break;
1645 case 'S':
1646 args.use_setsockopt = 1;
1647 break;
1648 case 'C':
1649 args.use_cmsg = 1;
1650 break;
1651 case 'd':
1652 args.dev = optarg;
1653 args.ifindex = get_ifidx(optarg);
1654 if (args.ifindex < 0) {
1655 fprintf(stderr, "Invalid device name\n");
1656 return 1;
1657 }
1658 break;
1659 case 'i':
1660 interactive = 1;
1661 break;
1662 case 'g':
1663 args.has_grp = 1;
1664 if (convert_addr(&args, optarg, ADDR_TYPE_MCAST) < 0)
1665 return 1;
1666 args.type = SOCK_DGRAM;
1667 break;
1668 case '6':
1669 args.version = AF_INET6;
1670 break;
1671 case 'b':
1672 args.bind_test_only = 1;
1673 break;
1674 case '0':
1675 args.has_expected_laddr = 1;
1676 if (convert_addr(&args, optarg,
1677 ADDR_TYPE_EXPECTED_LOCAL))
1678 return 1;
1679 break;
1680 case '1':
1681 args.has_expected_raddr = 1;
1682 if (convert_addr(&args, optarg,
1683 ADDR_TYPE_EXPECTED_REMOTE))
1684 return 1;
1685
1686 break;
1687 case '2':
1688 if (str_to_uint(optarg, 0, INT_MAX, &tmp) == 0) {
1689 args.expected_ifindex = (int)tmp;
1690 } else {
1691 args.expected_ifindex = get_ifidx(optarg);
1692 if (args.expected_ifindex < 0) {
1693 fprintf(stderr,
1694 "Invalid expected device\n");
1695 return 1;
1696 }
1697 }
1698 break;
1699 case 'q':
1700 quiet = 1;
1701 break;
1702 default:
1703 print_usage(argv[0]);
1704 return 1;
1705 }
1706 }
1707
1708 if (args.password &&
1709 (!args.has_remote_ip || args.type != SOCK_STREAM)) {
1710 log_error("MD5 passwords apply to TCP only and require a remote ip for the password\n");
1711 return 1;
1712 }
1713
1714 if ((args.use_setsockopt || args.use_cmsg) && !args.ifindex) {
1715 fprintf(stderr, "Device binding not specified\n");
1716 return 1;
1717 }
1718 if (args.use_setsockopt || args.use_cmsg)
1719 args.dev = NULL;
1720
1721 if (iter == 0) {
1722 fprintf(stderr, "Invalid number of messages to send\n");
1723 return 1;
1724 }
1725
1726 if (args.type == SOCK_STREAM && !args.protocol)
1727 args.protocol = IPPROTO_TCP;
1728 if (args.type == SOCK_DGRAM && !args.protocol)
1729 args.protocol = IPPROTO_UDP;
1730
1731 if ((args.type == SOCK_STREAM || args.type == SOCK_DGRAM) &&
1732 args.port == 0) {
1733 fprintf(stderr, "Invalid port number\n");
1734 return 1;
1735 }
1736
1737 if (!server_mode && !args.has_grp &&
1738 !args.has_remote_ip && !args.has_local_ip) {
1739 fprintf(stderr,
1740 "Local (server mode) or remote IP (client IP) required\n");
1741 return 1;
1742 }
1743
1744 if (interactive) {
1745 prog_timeout = 0;
1746 msg = NULL;
1747 }
1748
1749 if (server_mode) {
1750 do {
1751 rc = do_server(&args);
1752 } while (forever);
1753
1754 return rc;
1755 }
1756 return do_client(&args);
1757 }