Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/blocklist/test/srvtest.c
105142 views
1
/* $NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $ */
2
3
/*-
4
* Copyright (c) 2015 The NetBSD Foundation, Inc.
5
* All rights reserved.
6
*
7
* This code is derived from software contributed to The NetBSD Foundation
8
* by Christos Zoulas.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
* POSSIBILITY OF SUCH DAMAGE.
30
*/
31
#ifdef HAVE_CONFIG_H
32
#include "config.h"
33
#endif
34
35
#ifdef HAVE_SYS_CDEFS_H
36
#include <sys/cdefs.h>
37
#endif
38
__RCSID("$NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $");
39
40
#include <sys/types.h>
41
#include <sys/socket.h>
42
#include <netinet/in.h>
43
44
#include <stdio.h>
45
#include <signal.h>
46
#include <string.h>
47
#include <syslog.h>
48
#include <unistd.h>
49
#include <stdlib.h>
50
#include <poll.h>
51
#include <err.h>
52
53
#include "blocklist.h"
54
#ifdef BLDEBUG
55
#include "bl.h"
56
static void *b;
57
#endif
58
59
#ifndef INFTIM
60
#define INFTIM -1
61
#endif
62
63
static void
64
process_tcp(int afd)
65
{
66
ssize_t n;
67
char buffer[256];
68
69
memset(buffer, 0, sizeof(buffer));
70
71
if ((n = read(afd, buffer, sizeof(buffer))) == -1)
72
err(1, "read");
73
buffer[sizeof(buffer) - 1] = '\0';
74
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
75
#ifdef BLDEBUG
76
blocklist_r(b, 1, afd, buffer);
77
#else
78
blocklist(1, afd, buffer);
79
#endif
80
exit(0);
81
}
82
83
static void
84
process_udp(int afd)
85
{
86
ssize_t n;
87
char buffer[256];
88
struct sockaddr_storage ss;
89
socklen_t slen;
90
91
memset(buffer, 0, sizeof(buffer));
92
93
slen = (socklen_t)sizeof(ss);
94
memset(&ss, 0, sizeof(ss));
95
if ((n = recvfrom(afd, buffer, sizeof(buffer), 0, (void *)&ss,
96
&slen)) == -1)
97
err(1, "recvfrom");
98
buffer[sizeof(buffer) - 1] = '\0';
99
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
100
blocklist_sa(1, afd, (void *)&ss, slen, buffer);
101
exit(0);
102
}
103
static int
104
cr(int af, int type, in_port_t p)
105
{
106
int sfd;
107
struct sockaddr_storage ss;
108
socklen_t slen;
109
sfd = socket(af == AF_INET ? PF_INET : PF_INET6, type, 0);
110
if (sfd == -1)
111
err(1, "socket");
112
113
p = htons(p);
114
memset(&ss, 0, sizeof(ss));
115
if (af == AF_INET) {
116
struct sockaddr_in *s = (void *)&ss;
117
s->sin_family = AF_INET;
118
slen = sizeof(*s);
119
s->sin_port = p;
120
} else {
121
struct sockaddr_in6 *s6 = (void *)&ss;
122
s6->sin6_family = AF_INET6;
123
slen = sizeof(*s6);
124
s6->sin6_port = p;
125
}
126
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
127
ss.ss_len = (uint8_t)slen;
128
#endif
129
130
if (bind(sfd, (const void *)&ss, slen) == -1)
131
err(1, "bind");
132
133
if (type != SOCK_DGRAM)
134
if (listen(sfd, 5) == -1)
135
err(1, "listen");
136
return sfd;
137
}
138
139
static void
140
handle(int type, int sfd)
141
{
142
struct sockaddr_storage ss;
143
socklen_t alen = sizeof(ss);
144
int afd;
145
146
if (type != SOCK_DGRAM) {
147
if ((afd = accept(sfd, (void *)&ss, &alen)) == -1)
148
err(1, "accept");
149
} else
150
afd = sfd;
151
152
/* Create child process */
153
switch (fork()) {
154
case -1:
155
err(1, "fork");
156
case 0:
157
if (type == SOCK_DGRAM)
158
process_udp(afd);
159
else
160
process_tcp(afd);
161
break;
162
default:
163
close(afd);
164
break;
165
}
166
}
167
168
static __dead void
169
usage(int c)
170
{
171
warnx("Unknown option `%c'", (char)c);
172
fprintf(stderr, "Usage: %s [-u] [-p <num>]"
173
#ifdef BLDEBUG
174
" [-s <sockpath>]"
175
#endif
176
"\n", getprogname());
177
exit(EXIT_FAILURE);
178
}
179
180
int
181
main(int argc, char *argv[])
182
{
183
#ifdef __linux__
184
#define NUMFD 1
185
#else
186
#define NUMFD 2
187
#endif
188
struct pollfd pfd[NUMFD];
189
int type = SOCK_STREAM, c;
190
in_port_t port = 6161;
191
#ifdef BLDEBUG
192
char *sockpath = "blsock";
193
const char *optstr = "up:s:";
194
#else
195
const char *optstr = "up:";
196
#endif
197
198
signal(SIGCHLD, SIG_IGN);
199
200
while ((c = getopt(argc, argv, optstr)) != -1)
201
switch (c) {
202
case 'u':
203
type = SOCK_DGRAM;
204
break;
205
case 'p':
206
port = (in_port_t)atoi(optarg);
207
break;
208
#ifdef BLDEBUG
209
case 's':
210
sockpath = (char *)optarg;
211
break;
212
#endif
213
default:
214
usage(c);
215
}
216
217
#ifdef BLDEBUG
218
b = bl_create(false, sockpath, vsyslog_r);
219
#endif
220
221
222
pfd[0].fd = cr(AF_INET, type, port);
223
pfd[0].events = POLLIN;
224
#if NUMFD > 1
225
pfd[1].fd = cr(AF_INET6, type, port);
226
pfd[1].events = POLLIN;
227
#endif
228
229
for (;;) {
230
if (poll(pfd, __arraycount(pfd), INFTIM) == -1)
231
err(1, "poll");
232
for (size_t i = 0; i < __arraycount(pfd); i++) {
233
if ((pfd[i].revents & POLLIN) == 0)
234
continue;
235
handle(type, pfd[i].fd);
236
}
237
}
238
}
239
240