Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/netinet/tcpconnect/tcpconnect.c
39500 views
1
/*-
2
* Copyright (c) 2004-2005 Robert N. M. Watson
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#include <sys/types.h>
28
#include <sys/socket.h>
29
30
#include <netinet/in.h>
31
#include <netinet/tcp.h>
32
33
#include <arpa/inet.h>
34
35
#include <err.h>
36
#include <errno.h>
37
#include <fcntl.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <unistd.h>
42
43
44
static void
45
usage(void)
46
{
47
48
fprintf(stderr, "tcpconnect server port\n");
49
fprintf(stderr, "tcpconnect client ip port count [nonblock] [tcpmd5]\n");
50
exit(-1);
51
}
52
53
static void
54
tcpconnect_server(int argc, char *argv[])
55
{
56
int listen_sock, accept_sock;
57
struct sockaddr_in sin;
58
char *dummy;
59
long port;
60
61
if (argc != 1)
62
usage();
63
64
bzero(&sin, sizeof(sin));
65
sin.sin_len = sizeof(sin);
66
sin.sin_family = AF_INET;
67
sin.sin_addr.s_addr = htonl(INADDR_ANY);
68
69
port = strtoul(argv[0], &dummy, 10);
70
if (port < 1 || port > 65535 || *dummy != '\0')
71
usage();
72
sin.sin_port = htons(port);
73
74
listen_sock = socket(PF_INET, SOCK_STREAM, 0);
75
if (listen_sock == -1)
76
err(-1, "socket");
77
78
if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
79
err(-1, "bind");
80
81
if (listen(listen_sock, -1) == -1)
82
err(-1, "listen");
83
84
while (1) {
85
accept_sock = accept(listen_sock, NULL, NULL);
86
close(accept_sock);
87
}
88
}
89
90
static void
91
tcpconnect_client(int argc, char *argv[])
92
{
93
struct sockaddr_in sin;
94
long count, i, port;
95
char *dummy;
96
int sock;
97
int nonblock = 0, md5enable = 0;
98
99
if (argc < 3 || argc > 5)
100
usage();
101
for (i=3; i < argc; i++) {
102
if (strcmp(argv[i], "nonblock") == 0)
103
nonblock = 1;
104
if (strcmp(argv[i], "tcpmd5") == 0)
105
md5enable = 1;
106
}
107
108
bzero(&sin, sizeof(sin));
109
sin.sin_len = sizeof(sin);
110
sin.sin_family = AF_INET;
111
if (inet_aton(argv[0], &sin.sin_addr) == 0)
112
err(-1, "listen");
113
114
port = strtoul(argv[1], &dummy, 10);
115
if (port < 1 || port > 65535 || *dummy != '\0')
116
usage();
117
sin.sin_port = htons(port);
118
119
count = strtoul(argv[2], &dummy, 10);
120
if (count < 1 || count > 100000 || *dummy != '\0')
121
usage();
122
123
for (i = 0; i < count; i++) {
124
sock = socket(PF_INET, SOCK_STREAM, 0);
125
if (sock == -1)
126
err(-1, "socket");
127
128
/* No warning in default case on ENOPROTOOPT. */
129
if (setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG,
130
&md5enable, sizeof(md5enable)) != 0) {
131
if (errno == ENOPROTOOPT && md5enable > 0)
132
err(-1, "setsockopt(TCP_MD5SIG)");
133
else if (errno != ENOPROTOOPT)
134
warn("setsockopt(TCP_MD5SIG)");
135
}
136
137
if (nonblock) {
138
if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0)
139
err(-1, "fcntl(F_SETFL)");
140
141
if (connect(sock, (struct sockaddr *)&sin,
142
sizeof(sin)) == -1 && errno != EINPROGRESS)
143
err(-1, "connect");
144
} else {
145
if (connect(sock, (struct sockaddr *)&sin,
146
sizeof(sin)) == -1)
147
err(-1, "connect");
148
}
149
150
close(sock);
151
}
152
}
153
154
int
155
main(int argc, char *argv[])
156
{
157
158
if (argc < 2)
159
usage();
160
161
if (strcmp(argv[1], "server") == 0)
162
tcpconnect_server(argc - 2, argv + 2);
163
else if (strcmp(argv[1], "client") == 0)
164
tcpconnect_client(argc - 2, argv + 2);
165
else
166
usage();
167
168
exit(0);
169
}
170
171