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
);