2 #include <sys/socket.h>
5 #include <netinet/in.h>
15 usage(const char *cmd)
17 fprintf(stderr, "%s -m addr -p port -i addr "
18 "-r remote_ip4 -P remote_port\n", cmd);
23 create_sock(const struct sockaddr_in *in, const struct in_addr *iface)
28 s = socket(AF_INET, SOCK_DGRAM, 0);
30 err(2, "socket failed");
33 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
34 err(2, "setsockopt SO_REUSEPORT failed");
36 if (bind(s, (const struct sockaddr *)in, sizeof(*in)) < 0)
37 err(2, "bind failed");
39 memset(&mreq, 0, sizeof(mreq));
40 mreq.imr_multiaddr = in->sin_addr;
41 mreq.imr_interface = *iface;
42 if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
43 &mreq, sizeof(mreq)) < 0)
44 err(2, "setsockopt IP_ADD_MEMBERSHIP failed");
50 main(int argc, char *argv[])
52 struct sockaddr_in in, remote_in;
57 memset(&in, 0, sizeof(in));
58 in.sin_family = AF_INET;
60 memset(&remote_in, 0, sizeof(remote_in));
61 remote_in.sin_family = AF_INET;
63 memset(&iface, 0, sizeof(iface));
65 while ((opt = getopt(argc, argv, "P:i:m:p:r:")) != -1) {
68 remote_in.sin_port = strtol(optarg, NULL, 10);
69 remote_in.sin_port = htons(remote_in.sin_port);
73 if (inet_pton(AF_INET, optarg, &iface) <= 0)
78 if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0)
83 in.sin_port = strtol(optarg, NULL, 10);
84 in.sin_port = htons(in.sin_port);
88 if (inet_pton(AF_INET, optarg,
89 &remote_in.sin_addr) <= 0)
98 if (in.sin_addr.s_addr == INADDR_ANY || in.sin_port == 0 ||
99 iface.s_addr == INADDR_ANY ||
100 remote_in.sin_addr.s_addr == INADDR_ANY ||
101 remote_in.sin_port == 0)
104 s1 = create_sock(&in, &iface);
105 s2 = create_sock(&in, &iface);
107 if (connect(s2, (const struct sockaddr *)&remote_in,
108 sizeof(remote_in)) < 0)
109 err(2, "connect failed");
111 n = read(s1, buf, sizeof(buf));
113 err(2, "read 1 failed");
114 fprintf(stderr, "read 1 got %d\n", n);
116 n = read(s2, buf, sizeof(buf));
118 err(2, "read 2 failed");
119 fprintf(stderr, "read 2 got %d\n", n);