Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions net/net-mtools/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=net-mtools
PKG_VERSION:=2.3
PKG_RELEASE:=1

PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/troglobit/mtools
PKG_SOURCE_VERSION:=db665a4303c38cee908eba4dac50873c3f1d899c
PKG_MIRROR_HASH:=687e3743e46c8ddd23f03168b4021ed08b1a858b2a6743db3b62cb3d4c3592a0

include $(INCLUDE_DIR)/package.mk

define Package/net-mtools
SECTION:=net
CATEGORY:=Network
TITLE:=Debug multicast setups with mtools (msend and mreceive)
URL:=https://github.com/troglobit/mtools
endef

define Package/net-mtools/description
The tools msend and mreceive can be particulary useful
when debugging multicast setups.

msend continuously sends UDP packets to the multicast
group specified by the -g and -p options.

mreceive joins a multicast group specified by the -g and
-p options, then receives and displays the multicast
packets sent to this group:port combination by the msend
command.
endef

define Package/net-mtools/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_BUILD_DIR)/msend $(1)/usr/sbin/
$(CP) $(PKG_BUILD_DIR)/mreceive $(1)/usr/sbin/
endef

$(eval $(call BuildPackage,net-mtools))
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
From 0cfc04eac370ee33118e17a298d4739c94cacc73 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Tue, 19 Apr 2022 12:28:03 +0300
Subject: [PATCH 1/6] mreceive: refactor multicast joining to separate function

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
mreceive.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)

--- a/mreceive.c
+++ b/mreceive.c
@@ -61,12 +61,27 @@ Usage: mreceive [-g GROUP] [-p PORT] [-i
-h Print the command usage.\n\n", VERSION);
}

+static void igmp_join(int s, in_addr_t multiaddr, in_addr_t interface)
+{
+ struct ip_mreq mreq;
+ int ret;
+
+ mreq.imr_multiaddr.s_addr = multiaddr;
+ mreq.imr_interface.s_addr = interface;
+
+ ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq));
+ if (ret == SOCKET_ERROR) {
+ printf("setsockopt() IP_ADD_MEMBERSHIP failed.\n");
+ exit(1);
+ }
+}
+
int main(int argc, char *argv[])
{
struct sockaddr_in stLocal, stFrom;
unsigned char achIn[BUFSIZE];
int s, i;
- struct ip_mreq stMreq;
int iTmp, iRet;
int ipnum = 0;
int ii;
@@ -153,22 +168,10 @@ int main(int argc, char *argv[])

/* join the multicast group. */
if (!ipnum) { /* single interface */
- stMreq.imr_multiaddr.s_addr = inet_addr(TEST_ADDR);
- stMreq.imr_interface.s_addr = INADDR_ANY;
- iRet = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq));
- if (iRet == SOCKET_ERROR) {
- printf("setsockopt() IP_ADD_MEMBERSHIP failed.\n");
- exit(1);
- }
+ igmp_join(s, inet_addr(TEST_ADDR), INADDR_ANY);
} else {
for (i = 0; i < ipnum; i++) {
- stMreq.imr_multiaddr.s_addr = inet_addr(TEST_ADDR);
- stMreq.imr_interface.s_addr = IP[i];
- iRet = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq));
- if (iRet == SOCKET_ERROR) {
- printf("setsockopt() IP_ADD_MEMBERSHIP failed.\n");
- exit(1);
- }
+ igmp_join(s, inet_addr(TEST_ADDR), IP[i]);
}
}

113 changes: 113 additions & 0 deletions net/net-mtools/patches/002-mreceive-join-IGMP-group-by-interface.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
From 65af96e0907ba9367aab9c1534b11c7f674c1e6a Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Tue, 19 Apr 2022 13:29:07 +0300
Subject: [PATCH 2/6] mreceive: join IGMP group by interface

mreceive uses the old-style struct ip_mreq for IP_ADD_MEMBERSHIP, which
takes the source address of the interface wishing to join.

Since the IPV6_ADD_MEMBERSHIP variant only takes a struct ipv6_mreq
which contains the ifindex and not the source address, we need to add
support for that.

In preparation for IPv6 support, add logic to join an IGMP group either
by source address or by interface name, whichever is specified.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
mreceive.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 5 deletions(-)

--- a/mreceive.c
+++ b/mreceive.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
@@ -61,7 +62,7 @@ Usage: mreceive [-g GROUP] [-p PORT] [-i
-h Print the command usage.\n\n", VERSION);
}

-static void igmp_join(int s, in_addr_t multiaddr, in_addr_t interface)
+static void igmp_join_by_saddr(int s, in_addr_t multiaddr, in_addr_t interface)
{
struct ip_mreq mreq;
int ret;
@@ -77,10 +78,34 @@ static void igmp_join(int s, in_addr_t m
}
}

+static void igmp_join_by_if_name(int s, in_addr_t multicast,
+ const char *if_name)
+{
+ struct ip_mreqn mreq = {};
+ int if_index;
+ int ret;
+
+ if_index = if_nametoindex(if_name);
+ if (!if_index) {
+ perror("if_nametoindex");
+ exit(1);
+ }
+
+ mreq.imr_multiaddr.s_addr = multicast;
+ mreq.imr_ifindex = if_index;
+
+ ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (ret) {
+ perror("setsockopt() IP_ADD_MEMBERSHIP");
+ exit(1);
+ }
+}
+
int main(int argc, char *argv[])
{
struct sockaddr_in stLocal, stFrom;
unsigned char achIn[BUFSIZE];
+ const char *if_name;
int s, i;
int iTmp, iRet;
int ipnum = 0;
@@ -131,6 +156,17 @@ int main(int argc, char *argv[])
ii++;
ipnum++;
}
+ } else if (strcmp(argv[ii], "-I") == 0) {
+ ii++;
+ if (ii < argc) {
+ if (if_name) {
+ printf("Single interface expected\n");
+ exit(1);
+ }
+
+ if_name = argv[ii];
+ ii++;
+ }
} else if (strcmp(argv[ii], "-n") == 0) {
ii++;
NUM = 1;
@@ -167,11 +203,16 @@ int main(int argc, char *argv[])
}

/* join the multicast group. */
- if (!ipnum) { /* single interface */
- igmp_join(s, inet_addr(TEST_ADDR), INADDR_ANY);
+ if (if_name) {
+ igmp_join_by_if_name(s, inet_addr(TEST_ADDR), if_name);
} else {
- for (i = 0; i < ipnum; i++) {
- igmp_join(s, inet_addr(TEST_ADDR), IP[i]);
+ if (!ipnum) { /* single interface */
+ igmp_join_by_saddr(s, inet_addr(TEST_ADDR), INADDR_ANY);
+ } else {
+ for (i = 0; i < ipnum; i++) {
+ igmp_join_by_saddr(s, inet_addr(TEST_ADDR),
+ IP[i]);
+ }
}
}

Loading