summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/tools/mctest/Makefile4
-rw-r--r--tools/tools/mctest/mcgrab.178
-rw-r--r--tools/tools/mctest/mcgrab.cc189
3 files changed, 270 insertions, 1 deletions
diff --git a/tools/tools/mctest/Makefile b/tools/tools/mctest/Makefile
index 03bd022..4de93c3 100644
--- a/tools/tools/mctest/Makefile
+++ b/tools/tools/mctest/Makefile
@@ -3,7 +3,9 @@
#
# A Makefile that builds both the mctest program and its manual page.
-PROG_CXX= mctest
+PROG_CXX= mctest
+PROG_CXX= mcgrab
+
LDADD+= -lpthread
.include <bsd.prog.mk>
diff --git a/tools/tools/mctest/mcgrab.1 b/tools/tools/mctest/mcgrab.1
new file mode 100644
index 0000000..f2b8b34
--- /dev/null
+++ b/tools/tools/mctest/mcgrab.1
@@ -0,0 +1,78 @@
+.\" Copyright (c) 2008 George V. Neville-Neil
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 9, 2008
+.Dt mcgrab 1
+.Os
+.Sh NAME
+.Nm mcgrab
+.Nd "multicast filter overload test"
+.Sh SYNOPSIS
+.Nm
+.Op Fl i Ar interface
+.Op Fl g Ar group
+.Op Fl n Ar number
+.Sh DESCRIPTION
+The
+.Nm
+command implements a multicast test which grabs and holds
+N multicast addresses. The purpose of the test is to see what
+happens when a network interface is no longer able to filter
+multicasts in hardware and has to switch to promiscious or
+multicast promiscious mode. A successful test does not have any
+result, but an unsuccessful test will have deleterious side effects.
+Packet size in bytes.
+The options are as follows:
+.Bl -tag -width ".Fl d Ar argument"
+.It Fl i Ar interface
+Network interface, which can be found with ifconfig(1).
+.It Fl i Ar group
+Multicast group
+.It Fl n Ar number
+Number of groups to join.
+.Sh EXAMPLES
+The following is an example of a typical usage
+of the
+.Nm
+command:
+.Pp
+.Dl "mcgrab -i em0 -g 239.255.255.1 -n 1024"
+.Sh SEE ALSO
+.Xr mctest 1 ,
+.Xr ifconfig 8 ,
+.Xr netstat 1 ,
+.Xr nanosleep 2 .
+.Sh HISTORY
+The
+.Nm
+program first appeared in
+.Fx 7.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An George V. Neville-Neil Aq gnn@FreeBSD.org .
+.Sh BUGS
+Should be reported to the author or to net@freebsd.org.
diff --git a/tools/tools/mctest/mcgrab.cc b/tools/tools/mctest/mcgrab.cc
new file mode 100644
index 0000000..5522f30
--- /dev/null
+++ b/tools/tools/mctest/mcgrab.cc
@@ -0,0 +1,189 @@
+//
+// Copyright (c) 2008, Neville-Neil Consulting
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// This test simply grabs N multicast addresses starting
+// from a base address. The purpose is to make sure that switching a device
+// from using a multicast filtering table or function to promiscuous
+// multicast listening mode does not cause deleterious side effects.
+//
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+// C++ STL and other related includes
+#include <stdlib.h>
+#include <limits.h>
+#include <iostream>
+#include <string.h>
+#include <string>
+
+// Operating System and other C based includes
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+
+// Private include files
+#include "mctest.h"
+
+using namespace std;
+
+//
+// usage - just the program's usage line
+//
+//
+void usage()
+{
+ cout << "mcgrab -i interface -g multicast group -n number of groups\n";
+ exit(-1);
+}
+
+//
+// usage - print out the usage with a possible message and exit
+//
+// \param message optional string
+//
+//
+void usage(string message)
+{
+
+ cerr << message << endl;
+ usage();
+}
+
+
+//
+// grab a set of addresses
+//
+// @param interface ///< text name of the interface (em0 etc.)
+// @param group ///< multicast group
+// @param number ///< number of addresses to grab
+//
+// @return 0 for 0K, -1 for error, sets errno
+//
+void grab(char *interface, struct in_addr *group, int number) {
+
+
+ int sock;
+ struct ip_mreq mreq;
+ struct ifreq ifreq;
+ struct in_addr lgroup;
+
+ if (group == NULL) {
+ group = &lgroup;
+ if (inet_pton(AF_INET, DEFAULT_GROUP, group) < 1)
+ return;
+ }
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("failed to open datagram socket");
+ return;
+ }
+
+ for (int i = 0; i < number; i++) {
+ bzero((struct ip_mreq *)&mreq, sizeof(mreq));
+ bzero((struct ifreq *)&ifreq, sizeof(ifreq));
+
+ strncpy(ifreq.ifr_name, interface, IFNAMSIZ);
+ if (ioctl(sock, SIOCGIFADDR, &ifreq) < 0) {
+ perror("no such interface");
+ return;
+ }
+
+ memcpy(&mreq.imr_interface,
+ &((struct sockaddr_in*) &ifreq.ifr_addr)->sin_addr,
+ sizeof(struct in_addr));
+
+ mreq.imr_multiaddr.s_addr = group->s_addr;
+ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
+ sizeof(mreq)) < 0) {
+
+ perror("failed to add membership");
+ return;
+ }
+
+ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
+ &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
+ sizeof(struct in_addr)) < 0) {
+ perror("failed to bind interface");
+ return;
+ }
+
+ group->s_addr = htonl(ntohl(group->s_addr) + 1);
+ }
+ printf("Press Control-C to exit.\n");
+ sleep(INT_MAX);
+
+}
+
+
+//
+// main - the main program
+//
+// \param -g multicast group address which we will hold
+// \param -i interface on which we're holding the address
+//
+//
+int main(int argc, char**argv)
+{
+
+ char ch; ///< character from getopt()
+ extern char* optarg; ///< option argument
+
+ char* interface = 0; ///< Name of the interface
+ struct in_addr *group = NULL; ///< the multicast group address
+ int number = 0; ///< Number of addresses to grab
+
+ if (argc != 7)
+ usage();
+
+ while ((ch = getopt(argc, argv, "g:i:n:h")) != -1) {
+ switch (ch) {
+ case 'g':
+ group = new (struct in_addr );
+ if (inet_pton(AF_INET, optarg, group) < 1)
+ usage(argv[0] + string(" Error: invalid multicast group") +
+ optarg);
+ break;
+ case 'i':
+ interface = optarg;
+ break;
+ case 'n':
+ number = atoi(optarg);
+ break;
+ case 'h':
+ usage(string("Help\n"));
+ break;
+ }
+ }
+
+ grab(interface, group, number);
+
+}
OpenPOWER on IntegriCloud