New port: net/mcjoin: Simple multicast testing application for UNIX
mcjoin is a very simple and easy-to-use tool to test IPv4 and IPv6 multicast. It features: * an optional multicast generator (server) * an end device that can act as a data sink (client) * supports joining one or more groups: * ASM (*,G) support * SSM (S,G) support * IPv4 * IPv6 WWW: https://github.com/troglobit/mcjoin PR: 243787 Submitted by: John W. O'Brien <john@saltant.com>
This commit is contained in:
parent
ca43454075
commit
53cf56ead2
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=527541
6 changed files with 202 additions and 0 deletions
|
@ -435,6 +435,7 @@
|
|||
SUBDIR += mailcommon
|
||||
SUBDIR += mailimporter
|
||||
SUBDIR += malo-firmware-kmod
|
||||
SUBDIR += mcjoin
|
||||
SUBDIR += mdns-repeater
|
||||
SUBDIR += measurement-kit
|
||||
SUBDIR += mediastreamer
|
||||
|
|
20
net/mcjoin/Makefile
Normal file
20
net/mcjoin/Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
# $FreeBSD$
|
||||
|
||||
PORTNAME= mcjoin
|
||||
DISTVERSIONPREFIX= v
|
||||
DISTVERSION= 2.4
|
||||
CATEGORIES= net
|
||||
|
||||
MAINTAINER= john@saltant.com
|
||||
COMMENT= Simple multicast testing application for UNIX
|
||||
|
||||
LICENSE= ISCL
|
||||
LICENSE_FILE= ${WRKSRC}/LICENSE
|
||||
|
||||
USES= autoreconf
|
||||
GNU_CONFIGURE= yes
|
||||
|
||||
USE_GITHUB= yes
|
||||
GH_ACCOUNT= troglobit
|
||||
|
||||
.include <bsd.port.mk>
|
3
net/mcjoin/distinfo
Normal file
3
net/mcjoin/distinfo
Normal file
|
@ -0,0 +1,3 @@
|
|||
TIMESTAMP = 1580591567
|
||||
SHA256 (troglobit-mcjoin-v2.4_GH0.tar.gz) = 8374018bba71621f48e67ce37f25ba095ce7ff247d67e46ac6171a9e68b30cc7
|
||||
SIZE (troglobit-mcjoin-v2.4_GH0.tar.gz) = 16108
|
163
net/mcjoin/files/patch-27657e27db1704fd258139a57ad3312003a6cef9
Normal file
163
net/mcjoin/files/patch-27657e27db1704fd258139a57ad3312003a6cef9
Normal file
|
@ -0,0 +1,163 @@
|
|||
commit 27657e27db1704fd258139a57ad3312003a6cef9
|
||||
Author: Ryan Libby <rlibby@FreeBSD.org>
|
||||
Date: Sun Nov 24 21:33:49 2019 -0800
|
||||
|
||||
Build and run on FreeBSD
|
||||
|
||||
An assortment of small changes to build and run on FreeBSD. FreeBSD:
|
||||
- Doesn't have IP_PKTINFO, but does have IP_RECVDSTADDR.
|
||||
- Doesn't have IP_MULTICAST_ALL (and doesn't need to disable it).
|
||||
- Is sensitive about the claimed size of the sockaddr, and has
|
||||
sockaddrs with builtin len fields.
|
||||
- Doesn't export s6_addr32.
|
||||
|
||||
--- configure.ac.orig 2019-04-04 07:57:50 UTC
|
||||
+++ configure.ac
|
||||
@@ -10,4 +10,9 @@ AC_PROG_INSTALL
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
+AC_CHECK_MEMBERS([struct sockaddr_storage.ss_len], , ,
|
||||
+[
|
||||
+#include <sys/socket.h>
|
||||
+])
|
||||
+
|
||||
AC_OUTPUT
|
||||
--- mcjoin.c.orig 2019-04-04 07:57:50 UTC
|
||||
+++ mcjoin.c
|
||||
@@ -123,6 +123,18 @@ static const char *convert_address(inet_addr_t *ss, ch
|
||||
return inet_ntop(AF_INET, &sin->sin_addr, buf, len);
|
||||
}
|
||||
|
||||
+static socklen_t ss_get_len(const struct sockaddr_storage *ss)
|
||||
+{
|
||||
+
|
||||
+#ifdef AF_INET6
|
||||
+ if (ss->ss_family == AF_INET6)
|
||||
+ return sizeof(struct sockaddr_in6);
|
||||
+#endif
|
||||
+ if (ss->ss_family == AF_INET)
|
||||
+ return sizeof(struct sockaddr_in);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int alloc_socket(inet_addr_t group)
|
||||
{
|
||||
int sd, val, proto;
|
||||
@@ -148,15 +160,22 @@ static int alloc_socket(inet_addr_t group)
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)))
|
||||
ERROR("Failed enabling SO_REUSEADDR: %s", strerror(errno));
|
||||
|
||||
+#if defined(IP_PKTINFO) || !defined(IP_RECVDSTADDR)
|
||||
if (setsockopt(sd, SOL_IP, IP_PKTINFO, &val, sizeof(val)))
|
||||
ERROR("Failed enabling IP_PKTINFO: %s", strerror(errno));
|
||||
+#elif defined(IP_RECVDSTADDR)
|
||||
+ if (setsockopt(sd, IPPROTO_IP, IP_RECVDSTADDR, &val, sizeof(val)))
|
||||
+ ERROR("Failed enabling IP_RECVDSTADDR: %s", strerror(errno));
|
||||
+#endif
|
||||
|
||||
val = 0;
|
||||
+#ifdef IP_MULTICAST_ALL
|
||||
if (setsockopt(sd, proto, IP_MULTICAST_ALL, &val, sizeof(val)))
|
||||
ERROR("Failed disabling IP_MULTICAST_ALL: %s", strerror(errno));
|
||||
+#endif
|
||||
|
||||
- if (bind(sd, (struct sockaddr *)&group, sizeof(group))) {
|
||||
- ERROR("Faild binding to socket: %s", strerror(errno));
|
||||
+ if (bind(sd, (struct sockaddr *)&group, ss_get_len(&group))) {
|
||||
+ ERROR("Failed binding to socket: %s", strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
@@ -266,7 +285,7 @@ static void send_mcast(int signo)
|
||||
|
||||
for (i = 0; i < group_num; i++) {
|
||||
struct sockaddr *dest = (struct sockaddr *)&groups[i].grp;
|
||||
- socklen_t len = sizeof(groups[i].grp);
|
||||
+ socklen_t len = ss_get_len(&groups[i].grp);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%u, MC group %s ... count: %u", MAGIC_KEY, getpid(), groups[i].group, counter++);
|
||||
DEBUG("Sending packet on signal %d, msg: %s", signo, buf);
|
||||
@@ -275,15 +294,21 @@ static void send_mcast(int signo)
|
||||
}
|
||||
}
|
||||
|
||||
-struct in_pktinfo *find_pktinfo(struct msghdr *msgh)
|
||||
+struct in_addr *find_dstaddr(struct msghdr *msgh)
|
||||
{
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(msgh); cmsg; cmsg = CMSG_NXTHDR(msgh, cmsg)) {
|
||||
- if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_PKTINFO)
|
||||
- continue;
|
||||
-
|
||||
- return (struct in_pktinfo *)CMSG_DATA(cmsg);
|
||||
+#if defined(IP_PKTINFO) || !defined(IP_RECVDSTADDR)
|
||||
+ if (cmsg->cmsg_level == IPPROTO_IP &&
|
||||
+ cmsg->cmsg_type == IP_PKTINFO)
|
||||
+ return &((struct in_pktinfo *)CMSG_DATA(cmsg))->
|
||||
+ ipi_addr;
|
||||
+#elif defined(IP_RECVDSTADDR)
|
||||
+ if (cmsg->cmsg_level == IPPROTO_IP &&
|
||||
+ cmsg->cmsg_type == IP_RECVDSTADDR)
|
||||
+ return (struct in_addr *)CMSG_DATA(cmsg);
|
||||
+#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -314,7 +339,7 @@ static void progress(void)
|
||||
static ssize_t recv_mcast(int id)
|
||||
{
|
||||
struct sockaddr_storage src;
|
||||
- struct in_pktinfo *ipi;
|
||||
+ struct in_addr *dstaddr;
|
||||
struct msghdr msgh;
|
||||
struct iovec iov[1];
|
||||
ssize_t bytes;
|
||||
@@ -336,8 +361,8 @@ static ssize_t recv_mcast(int id)
|
||||
if (bytes < 0)
|
||||
return -1;
|
||||
|
||||
- ipi = find_pktinfo(&msgh);
|
||||
- if (ipi) {
|
||||
+ dstaddr = find_dstaddr(&msgh);
|
||||
+ if (dstaddr) {
|
||||
char *ptr;
|
||||
int pid = 0;
|
||||
|
||||
@@ -348,7 +373,7 @@ static ssize_t recv_mcast(int id)
|
||||
|
||||
DEBUG("Count %5zu, our PID %d, sender PID %d, group %s msg: %s", groups[id].count, getpid(), pid, groups[id].group, buf);
|
||||
if (pid != getpid()) {
|
||||
- char *dst = inet_ntoa(ipi->ipi_addr);
|
||||
+ char *dst = inet_ntoa(*dstaddr);
|
||||
|
||||
if (strcmp(dst, groups[id].group)) {
|
||||
ERROR("Packet for group %s received on wrong socket, expected group %s.", dst, groups[id].group);
|
||||
@@ -658,9 +683,11 @@ int main(int argc, char *argv[])
|
||||
/* Next group ... */
|
||||
#ifdef AF_INET6
|
||||
if (strchr(group, ':')) {
|
||||
- step = ntohl(sin6->sin6_addr.s6_addr32[3]);
|
||||
- step++;
|
||||
- sin6->sin6_addr.s6_addr32[3] = htonl(step);
|
||||
+ memcpy(&step, &sin6->sin6_addr.s6_addr[12],
|
||||
+ sizeof(step));
|
||||
+ step = htonl(ntohl(step) + 1);
|
||||
+ memcpy(&sin6->sin6_addr.s6_addr[12], &step,
|
||||
+ sizeof(step));
|
||||
len = sizeof(*sin6);
|
||||
} else
|
||||
#endif
|
||||
@@ -706,6 +733,11 @@ int main(int argc, char *argv[])
|
||||
src->sin_port = htons(port);
|
||||
}
|
||||
}
|
||||
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
|
||||
+ groups[i].grp.ss_len = ss_get_len(&groups[i].grp);
|
||||
+ if (groups[i].source)
|
||||
+ groups[i].src.ss_len = ss_get_len(&groups[i].src);
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
12
net/mcjoin/pkg-descr
Normal file
12
net/mcjoin/pkg-descr
Normal file
|
@ -0,0 +1,12 @@
|
|||
mcjoin is a very simple and easy-to-use tool to test IPv4 and IPv6
|
||||
multicast. It features:
|
||||
|
||||
* an optional multicast generator (server)
|
||||
* an end device that can act as a data sink (client)
|
||||
* supports joining one or more groups:
|
||||
* ASM (*,G) support
|
||||
* SSM (S,G) support
|
||||
* IPv4
|
||||
* IPv6
|
||||
|
||||
WWW: https://github.com/troglobit/mcjoin
|
3
net/mcjoin/pkg-plist
Normal file
3
net/mcjoin/pkg-plist
Normal file
|
@ -0,0 +1,3 @@
|
|||
bin/mcjoin
|
||||
%%DOCSDIR%%/README.md
|
||||
man/man1/mcjoin.1.gz
|
Loading…
Reference in a new issue