linux/tools/testing/selftests/net/nettest.c
<<
>>
Prefs
   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 <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
  44struct sock_args {
  45        /* local address */
  46        union {
  47                struct in_addr  in;
  48                struct in6_addr in6;
  49        } local_addr;
  50
  51        /* remote address */
  52        union {
  53                struct in_addr  in;
  54                struct in6_addr in6;
  55        } remote_addr;
  56        int scope_id;  /* remote scope; v6 send only */
  57
  58        struct in_addr grp;     /* multicast group */
  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;      /* DGRAM, STREAM, RAW */
  70        int protocol;
  71        int version;   /* AF_INET/AF_INET6 */
  72
  73        int use_setsockopt;
  74        int use_cmsg;
  75        const char *dev;
  76        int ifindex;
  77        const char *password;
  78
  79        /* expected addresses and device index for connection */
  80        int expected_ifindex;
  81
  82        /* local address */
  83        union {
  84                struct in_addr  in;
  85                struct in6_addr in6;
  86        } expected_laddr;
  87
  88        /* remote address */
  89        union {
  90                struct in_addr  in;
  91                struct in6_addr in6;
  92        } expected_raddr;
  93};
  94
  95static int server_mode;
  96static unsigned int prog_timeout = 5;
  97static unsigned int interactive;
  98static int iter = 1;
  99static char *msg = "Hello world!";
 100static int msglen;
 101static int quiet;
 102static int try_broadcast = 1;
 103
 104static 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
 117static 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
 135static 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
 153static 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
 172static 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
 203static 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                /* ENOENT is harmless. Returned when a password is cleared */
 219                if (errno == ENOENT)
 220                        rc = 0;
 221                else
 222                        log_err_errno("setsockopt(TCP_MD5SIG)");
 223        }
 224
 225        return rc;
 226}
 227
 228static 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
 263static 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
 291static 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
 302static 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
 315static 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
 343static 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
 355static 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
 367static 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
 379static 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
 391static 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
 410static 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
 422static 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
 446static 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
 459static 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
 472static 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
 485static 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        /* entire string should be consumed by conversion
 494         * and value should be between min and max
 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
 505static 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
 545static 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
 582static 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
 616static int send_msg_no_cmsg(int sd, void *addr, socklen_t alen)
 617{
 618        int err;
 619
 620again:
 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
 637static 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
 681again:
 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
 699static 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
 720static 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                }
 791again:
 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                                /* avoid PKTINFO conflicts with bindtodev */
 799                                if (sendto(sd, buf, len, 0,
 800                                           (void *) addr, alen) < 0)
 801                                        goto out_err;
 802                        } else {
 803                                /* kernel is allowing scope_id to be set to VRF
 804                                 * index for LLA. for sends to global address
 805                                 * reset scope id
 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;
 830out_err:
 831        log_err_errno("failed to send msg to peer");
 832        return -1;
 833}
 834
 835static 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
 865static 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
 873static 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
 890again:
 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
 909static 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
 920static 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                /* client sends first message */
 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
1007static 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;
1055out_err:
1056        close(sd);
1057        return -1;
1058}
1059
1060static int msock_server(struct sock_args *args)
1061{
1062        return msock_init(args, 1);
1063}
1064
1065static int msock_client(struct sock_args *args)
1066{
1067        return msock_init(args, 0);
1068}
1069
1070static 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
1112static 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
1155out:
1156        return sd;
1157
1158err:
1159        close(sd);
1160        return -1;
1161}
1162
1163static 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
1249static 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
1284static 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        }
1332out:
1333        return sd;
1334
1335err:
1336        close(sd);
1337        return rc;
1338}
1339
1340static 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
1396out:
1397        close(sd);
1398
1399        return rc;
1400}
1401
1402enum 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
1410static 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
1497out:
1498        free(str);
1499        return rc;
1500}
1501
1502static 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
1527static 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
1566int 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        /* process inputs */
1578        extern char *optarg;
1579        int rc = 0;
1580
1581        /*
1582         * process input args
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}
1758