Path: blob/main/tools/regression/netinet/tcpconnect/tcpconnect.c
39500 views
/*-1* Copyright (c) 2004-2005 Robert N. M. Watson2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/types.h>27#include <sys/socket.h>2829#include <netinet/in.h>30#include <netinet/tcp.h>3132#include <arpa/inet.h>3334#include <err.h>35#include <errno.h>36#include <fcntl.h>37#include <stdio.h>38#include <stdlib.h>39#include <string.h>40#include <unistd.h>414243static void44usage(void)45{4647fprintf(stderr, "tcpconnect server port\n");48fprintf(stderr, "tcpconnect client ip port count [nonblock] [tcpmd5]\n");49exit(-1);50}5152static void53tcpconnect_server(int argc, char *argv[])54{55int listen_sock, accept_sock;56struct sockaddr_in sin;57char *dummy;58long port;5960if (argc != 1)61usage();6263bzero(&sin, sizeof(sin));64sin.sin_len = sizeof(sin);65sin.sin_family = AF_INET;66sin.sin_addr.s_addr = htonl(INADDR_ANY);6768port = strtoul(argv[0], &dummy, 10);69if (port < 1 || port > 65535 || *dummy != '\0')70usage();71sin.sin_port = htons(port);7273listen_sock = socket(PF_INET, SOCK_STREAM, 0);74if (listen_sock == -1)75err(-1, "socket");7677if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)78err(-1, "bind");7980if (listen(listen_sock, -1) == -1)81err(-1, "listen");8283while (1) {84accept_sock = accept(listen_sock, NULL, NULL);85close(accept_sock);86}87}8889static void90tcpconnect_client(int argc, char *argv[])91{92struct sockaddr_in sin;93long count, i, port;94char *dummy;95int sock;96int nonblock = 0, md5enable = 0;9798if (argc < 3 || argc > 5)99usage();100for (i=3; i < argc; i++) {101if (strcmp(argv[i], "nonblock") == 0)102nonblock = 1;103if (strcmp(argv[i], "tcpmd5") == 0)104md5enable = 1;105}106107bzero(&sin, sizeof(sin));108sin.sin_len = sizeof(sin);109sin.sin_family = AF_INET;110if (inet_aton(argv[0], &sin.sin_addr) == 0)111err(-1, "listen");112113port = strtoul(argv[1], &dummy, 10);114if (port < 1 || port > 65535 || *dummy != '\0')115usage();116sin.sin_port = htons(port);117118count = strtoul(argv[2], &dummy, 10);119if (count < 1 || count > 100000 || *dummy != '\0')120usage();121122for (i = 0; i < count; i++) {123sock = socket(PF_INET, SOCK_STREAM, 0);124if (sock == -1)125err(-1, "socket");126127/* No warning in default case on ENOPROTOOPT. */128if (setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG,129&md5enable, sizeof(md5enable)) != 0) {130if (errno == ENOPROTOOPT && md5enable > 0)131err(-1, "setsockopt(TCP_MD5SIG)");132else if (errno != ENOPROTOOPT)133warn("setsockopt(TCP_MD5SIG)");134}135136if (nonblock) {137if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0)138err(-1, "fcntl(F_SETFL)");139140if (connect(sock, (struct sockaddr *)&sin,141sizeof(sin)) == -1 && errno != EINPROGRESS)142err(-1, "connect");143} else {144if (connect(sock, (struct sockaddr *)&sin,145sizeof(sin)) == -1)146err(-1, "connect");147}148149close(sock);150}151}152153int154main(int argc, char *argv[])155{156157if (argc < 2)158usage();159160if (strcmp(argv[1], "server") == 0)161tcpconnect_server(argc - 2, argv + 2);162else if (strcmp(argv[1], "client") == 0)163tcpconnect_client(argc - 2, argv + 2);164else165usage();166167exit(0);168}169170171