2 #include <sys/socket.h>
3 #include <sys/sysctl.h>
6 #include <netinet/in.h>
15 #define RCVBUF_SIZE (256 * 1024)
18 static void mainloop(struct sockaddr_in *, int, int, int);
21 usage(const char *cmd)
23 fprintf(stderr, "%s -4 addr4 -p port [-i ninst] [-r rcvbuf] [-N]\n",
29 main(int argc, char *argv[])
31 struct sockaddr_in in;
32 int opt, ninst, i, s, rcvbuf, noreply;
35 prm_len = sizeof(ninst);
36 if (sysctlbyname("hw.ncpu", &ninst, &prm_len, NULL, 0) != 0)
37 err(2, "sysctl hw.ncpu failed");
39 memset(&in, 0, sizeof(in));
40 in.sin_family = AF_INET;
45 while ((opt = getopt(argc, argv, "4:p:i:r:N")) != -1) {
48 if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0)
49 errx(1, "invalid -4 %s\n", optarg);
53 in.sin_port = strtoul(optarg, NULL, 10);
54 in.sin_port = htons(in.sin_port);
58 ninst = strtoul(optarg, NULL, 10);
62 rcvbuf = strtoul(optarg, NULL, 10);
75 if (in.sin_port == 0 || in.sin_addr.s_addr == INADDR_ANY)
80 for (i = 0; i < ninst - 1; ++i) {
85 mainloop(&in, s, rcvbuf, noreply);
87 err(1, "fork %d failed", i);
90 mainloop(&in, s, rcvbuf, noreply);
95 mainloop(struct sockaddr_in *in, int s, int rcvbuf, int noreply)
101 s = socket(AF_INET, SOCK_DGRAM, 0);
103 err(1, "socket(INET, DGRAM) failed");
106 buf = malloc(BUFLEN);
108 err(1, "malloc buf failed");
111 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
112 err(1, "setsockopt(SOCK, REUSEPORT) failed");
114 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0)
115 err(1, "setsockopt(SOCK, RCVBUF) failed");
117 if (bind(s, (const struct sockaddr *)in, sizeof(*in)) < 0)
118 err(1, "bind failed");
121 struct sockaddr_in cli;
125 cli_len = sizeof(cli);
126 n = recvfrom(s, buf, BUFLEN, 0,
127 (struct sockaddr *)&cli, &cli_len);
128 if (n > 0 && !noreply) {
130 (const struct sockaddr *)&cli, cli_len);