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