1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00

Add a new program to the multicast test suite. The mcgrab program

is used to grab and hold some number of multicast addresses in order
to test what happens when an interface goes over the number of multicast
addresses it can filter in hardware.
This commit is contained in:
George V. Neville-Neil 2008-07-09 22:33:46 +00:00
parent 401989b00b
commit ebcc69dad3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=180394
3 changed files with 270 additions and 1 deletions

View File

@ -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>

View File

@ -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.

View File

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