Commit 8a955c1c authored by Alessandro Rubini's avatar Alessandro Rubini

test/swflood: new dir, with code, cfg, results

parent eb4bb59d
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
CFLAGS = -Wall -O2 -ggdb
ALL = swflood multidump
all: $(ALL)
swflood: main.o parse.o commands.o
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
# build commands.o by various cmd-*.c using a linker script
CMD_C := $(wildcard cmd-*.c)
CMD_O := $(CMD_C:.c=.o)
commands.o: $(CMD_O)
$(LD) -r -T commands.lds $^ -o $@
clean:
rm -f $(ALL) *.o *~ core
repeat df r
repeat 1000 50
repeat 100 f
repeat 50 a
endr x
iface eth1 eth2 eth3 eth4
verbose 9 /dev/tty
send 0 20 00:00 +1 ff:ff:ff:ff:ff:ff
flush
send 1 20 00:00 +1 ff:ff:ff:ff:ff:ff
flush
send 2 20 00:00 +1 ff:ff:ff:ff:ff:ff
flush
send 3 20 00:00 +1 ff:ff:ff:ff:ff:ff
flush
repeat A 10
send 1 50 00:00 22:00:10:00:00:00
send 1 50 00:00 ff:ff:ff:ff:ff:ff
flush
endr A
#-*-shell-script-*-
flush
verbose 9 /dev/stdout
### I run this test with a 4-cable octopus
iface eth1 eth2 eth3 eth4
echo testing from 32 different senders plus another
send 0 32 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 32 32 32
send 1 32 00:00 22:00:10:00:00:00 +1
expect 32 0 0 0
echo testing from 64 different senders plus another
send 0 64 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 64 64 64
send 1 64 00:00 22:00:10:00:00:00 +1
expect 64 0 0 0
echo testing from 128 different senders plus another
send 0 128 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 128 128 128
send 1 128 00:00 22:00:10:00:00:00 +1
expect 128 0 0 0
echo testing from 256 different senders plus another
send 0 256 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 256 256 256
send 1 256 00:00 22:00:10:00:00:00 +1
expect 256 0 0 0
echo testing from 512 different senders plus another
send 0 512 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 512 512 512
send 1 512 00:00 22:00:10:00:00:00 +1
expect 512 0 0 0
echo testing from 1024 different senders plus another
send 0 1024 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 1024 1024 1024
send 1 1024 00:00 22:00:10:00:00:00 +1
expect 1024 0 0 0
echo testing from 2048 different senders plus another
send 0 2048 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 2048 2048 2048
send 1 2048 00:00 22:00:10:00:00:00 +1
expect 2048 0 0 0
echo testing from 4096 different senders plus another
send 0 4096 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 4096 4096 4096
send 1 4096 00:00 22:00:10:00:00:00 +1
expect 4096 0 0 0
echo testing from 8192 different senders plus another
send 0 8192 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 8192 8192 8192
send 1 8192 00:00 22:00:10:00:00:00 +1
expect 8192 0 0 0
echo testing from 16384 different senders plus another
send 0 16384 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 16384 16384 16384
send 1 16384 00:00 22:00:10:00:00:00 +1
expect 16384 0 0 0
iface br0 tap0 tap1 tap2 tap3
verbose 9 /dev/stdout
send 0 5 00:00 +1 ff:ff:ff:ff:ff:ff
flush
send 1 5 00:02 +0 ff:ff:ff:ff:ff:ff
flush
send 2 5 00:00 +0 ff:ff:ff:ff:ff:ff
flush
send 3 5 00:00 +0 ff:ff:ff:ff:ff:ff
flush
echo now repeating 10 times
repeat A 2
echo loop
send 1 5 00:00 22:00:10:00:00:00
flush
send 1 1 00:00 ff:ff:ff:ff:ff:ff
flush
send 2 5 00:20 22:00:11:00:00:00
flush
endr A
send 1 5 00:ff 22:00:12:00:00:20
flush
echo foreign
send 0 20 00:66 00:01:02:00:00:00 +1
flush
\ No newline at end of file
#-*-shell-script-*-
flush
verbose 9 /dev/stdout
### I run this test with a 4-cable octopus
iface tap1 tap2 tap3 tap4
echo testing from 32 different senders plus another
send 0 32 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 32 32 32
send 1 32 00:00 22:00:10:00:00:00 +1
expect 32 0 0 0
echo testing from 64 different senders plus another
send 0 64 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 64 64 64
send 1 64 00:00 22:00:10:00:00:00 +1
expect 64 0 0 0
echo testing from 128 different senders plus another
send 0 128 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 128 128 128
send 1 128 00:00 22:00:10:00:00:00 +1
expect 128 0 0 0
echo testing from 256 different senders plus another
send 0 256 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 256 256 256
send 1 256 00:00 22:00:10:00:00:00 +1
expect 256 0 0 0
echo testing from 512 different senders plus another
send 0 512 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 512 512 512
send 1 512 00:00 22:00:10:00:00:00 +1
expect 512 0 0 0
echo testing from 1024 different senders plus another
send 0 1024 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 1024 1024 1024
send 1 1024 00:00 22:00:10:00:00:00 +1
expect 1024 0 0 0
echo testing from 2048 different senders plus another
send 0 2048 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 2048 2048 2048
send 1 2048 00:00 22:00:10:00:00:00 +1
expect 2048 0 0 0
echo testing from 4096 different senders plus another
send 0 4096 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 4096 4096 4096
send 1 4096 00:00 22:00:10:00:00:00 +1
expect 4096 0 0 0
echo testing from 8192 different senders plus another
send 0 8192 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 8192 8192 8192
send 1 8192 00:00 22:00:10:00:00:00 +1
expect 8192 0 0 0
echo testing from 16384 different senders plus another
send 0 16384 00:00 +1 ff:ff:ff:ff:ff:ff
expect 0 16384 16384 16384
send 1 16384 00:00 22:00:10:00:00:00 +1
expect 16384 0 0 0
echo tsting repeat, expect 10 "loop" messages
repeat x 5
repeat y 2
repeat a 10000
endr a
echo loop
endr y
endr x
\ No newline at end of file
echo sleep 2s
sleep 2
echo sleep 2s
sleep 0 2000
repeat x 10
echo sleep .5s
sleep 0 500
endr x
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "swflood.h"
/*
* Loops are made of two commands: "repeat" and "endr"
*/
static int rep_verify(struct swf_line *line)
{
char *t;
int i, err = 0;
if (line->argc != 3) {
fprintf(stderr, "%s: wrong number of arguments\n",
line->argv[0]);
return -EINVAL;
}
if (strlen(line->argv[1]) != 1 || !isalpha(line->argv[1][0])) {
fprintf(stderr, "%s: not a letter \"%s\"\n",
line->argv[0], line->argv[1]);
err++;
}
i = strtol(line->argv[2], &t, 0);
if (t && *t) {
fprintf(stderr, "%s: not a number \"%s\"\n",
line->argv[0], line->argv[2]);
err++;
}
if (err)
return -EINVAL;
line->repcount = i;
return 0;
}
static struct swf_line *rep_execute(struct swf_line *line,
struct swf_status *status)
{
return line->next;
}
static struct swf_command cmd_repeat = {
.name = "repeat",
.verify = rep_verify,
.execute = rep_execute,
};
declare_command(cmd_repeat);
/* endr decrements and goes back or forward */
static int endr_verify(struct swf_line *line)
{
if (line->argc != 2) {
fprintf(stderr, "%s: wrong number of arguments\n",
line->argv[0]);
return -EINVAL;
}
if (strlen(line->argv[1]) != 1 || !isalpha(line->argv[1][0])) {
fprintf(stderr, "%s: not a letter \"%s\"\n",
line->argv[0], line->argv[1]);
return -EINVAL;
}
return 0;
}
static int endr_verify_late(struct swf_line *line)
{
/* Loop back looking for the letter */
struct swf_line *other;
int letter = line->argv[1][0];
for (other = line->prev; other; other = other->prev) {
if (other->cmd != &cmd_repeat)
continue;
if (other->argv[1][0] != letter)
continue;
line->data = other;
return 0;
}
fprintf(stderr, "%s: can't find matching '%c'\n",
line->argv[0], letter);
return -EINVAL;
}
static struct swf_line *endr_execute(struct swf_line *line,
struct swf_status *status)
{
struct swf_line *other = line->data;
/* The repcount field was 0 at allocate time */
if (!line->repcount) {
line->repcount = other->repcount;
}
line->repcount--;
if (line->repcount > 0)
return line->data;
return line->next;
}
static struct swf_command cmd_verbose = {
.name = "endr",
.verify = endr_verify,
.verify_late = endr_verify_late,
.execute = endr_execute,
};
declare_command(cmd_verbose);
This diff is collapsed.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "swflood.h"
/* echo is always verified and is trivial to execute */
static int echo_verify(struct swf_line *line)
{
return 0;
}
static int do_echo(FILE *f, int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
fprintf(f, "%s%c", argv[i], i+1 == argc ? '\n' : ' ');
if (argc == 1)
putc('\n', f);
return 0;
}
static struct swf_line *echo_execute(struct swf_line *line,
struct swf_status *status)
{
do_echo(stdout, line->argc, line->argv);
fprintf(status->logfile, "# ");
do_echo(status->logfile, line->argc, line->argv);
return line->next;
}
static struct swf_command cmd_echo = {
.name = "echo",
.verify = echo_verify,
.execute = echo_execute,
};
declare_command(cmd_echo);
/* verbose sets status variables by possibly opening a file */
static int verbose_verify(struct swf_line *line)
{
char *t;
int i;
if (line->argc < 2 || line->argc > 3) {
fprintf(stderr, "%s: wrong number of arguments\n",
line->argv[0]);
return -EINVAL;
}
i = strtol(line->argv[1], &t, 0);
if (t && *t) {
fprintf(stderr, "%s: not a number \"%s\"\n",
line->argv[0], line->argv[1]);
return -EINVAL;
}
/* check of the file name is left to exectute time */
return 0;
}
static struct swf_line *verbose_execute(struct swf_line *line,
struct swf_status *status)
{
FILE *f;
status->verbose = atoi(line->argv[1]);
if (line->argc != 3)
return line->next;
f = fopen(line->argv[2], "a");
if (!f) {
fprintf(stderr, "%s: open(): %s\n",
line->argv[2], strerror(errno));
fprintf(status->logfile, "Error: %s: open(): %s\n",
line->argv[2], strerror(errno));
return line->next;
}
fclose(status->logfile);
status->logfile = f;
return line->next;
}
static struct swf_command cmd_verbose = {
.name = "verbose",
.verify = verbose_verify,
.execute = verbose_execute,
};
declare_command(cmd_verbose);
/* sleep seconds and/or milliseconds */
static int sleep_verify(struct swf_line *line)
{
char *t;
int i, err = 0;
if (line->argc != 2 && line->argc != 3) {
fprintf(stderr, "%s: wrong number of arguments\n",
line->argv[0]);
return -EINVAL;
}
i = strtol(line->argv[1], &t, 0);
if (t && *t) {
fprintf(stderr, "%s: not a number \"%s\"\n",
line->argv[0], line->argv[1]);
err++;
t = NULL;
}
if (line->argc == 3)
i = strtol(line->argv[1], &t, 0);
if (t && *t) {
fprintf(stderr, "%s: not a number \"%s\"\n",
line->argv[0], line->argv[2]);
err++;
}
if (err)
return -EINVAL;
return 0;
}
static struct swf_line *sleep_execute(struct swf_line *line,
struct swf_status *status)
{
int i;
i = strtol(line->argv[1], NULL, 0);
sleep(i);
if (line->argc == 3) {
i = strtol(line->argv[2], NULL, 0);
usleep(1000 * i);
}
return line->next;
}
static struct swf_command cmd_sleep = {
.name = "sleep",
.verify = sleep_verify,
.execute = sleep_execute,
};
declare_command(cmd_sleep);
SECTIONS
{
.data : {
. = ALIGN(4);
__cmd_start = .;
*(.commands);
__cmd_end = .;
}
}
/* Alessandro Rubini for CERN and White Rabbit, 2011 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "swflood.h"
static void swf_dump(struct swf_line *line)
{
int i;
fprintf(stderr, "%s:%i: (%i) =", line->fname, line->lineno,
line->argc);
for (i = 0; i < line->argc; i++)
fprintf(stderr, " \"%s\"", line->argv[i]);
putc('\n', stderr);
}
int main(int argc, char **argv)
{
struct swf_status *status;
struct swf_line *line, *lastline = NULL;
FILE *f;
char s[256];
int i, ret, lineno, err = 0;
status = calloc(1, sizeof(*status));
if (!status) {
fprintf(stderr, "%s: %s\n", argv[0], strerror(errno));
exit(1);
}
status->logfile = fopen("/dev/null", "w");
if (argc == 1) {
fprintf(stderr, "%s: Use \"%s <cfg> [<cfg> ...]\n",
argv[0], argv[0]);
exit(1);
}
/* Do the parsing */
for (i = 1; i < argc; i++) {
lineno = 0;
f = fopen(argv[i], "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i],
strerror(errno));
err++;
continue;
}
while (fgets(s, sizeof(s), f)) {
lineno++;
line = calloc(1, sizeof(*line));
if (!line) {
fprintf(stderr, "%s: %s\n", argv[0],
strerror(errno));
exit(1);
}
line->fname = argv[i];
line->lineno = lineno;
ret = swf_parse(s, line);
if (ret == -ENODATA) {
free(line);
continue;
}
if (ret < 0) {
fprintf(stderr, "%s:%i: %s in \"%s\"\n",
argv[i], lineno,
strerror(-ret), s);
err++;
continue;
}
/* enqueue this line */
if (lastline) {
lastline->next = line;
line->prev = lastline;
} else {
status->line = line;
}
lastline = line;
if (line->cmd->verify_late
&& line->cmd->verify_late(line)) {
err++;
continue;
}
if (getenv("VERBOSE"))
swf_dump(line);
}
}
if (err) exit(1);
/* Now run the commands */
for (line = status->line; line;
line = line->cmd->execute(line, status)) {
if (getenv("VERBOSE") && atoi(getenv("VERBOSE")) > 10)
fprintf(stderr, "run %-10s (%s:%i -- %i)\n",
line->argv[0], line->fname, line->lineno,
line->repcount);
}
/* done, it was easy, wasn't it? */
return 0;
}
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/select.h>
#include <sys/time.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if_arp.h>
#include <netpacket/packet.h>
static int dumpone(char *name, struct timeval *tv,
unsigned char *packet, int plen)
{
int i;
static char sep[]="::::: ::::: . " "... ... ... ...\n";
char *s = sep;
printf("%-8s %li.%06li ", name, tv->tv_sec, tv->tv_usec);
for (i = 0; i < plen && *s; i++)
printf("%02x%c", packet[i], *(s++));
return 0;
}
int main(int argc, char **argv)
{
int i, len;
int sock = -1, *socks;
fd_set fullset, set;
struct ifreq ifr;
struct packet_mreq req;
struct sockaddr_ll addr;
unsigned char packet[128];
if (argc == 1) {
fprintf(stderr, "%s: pass a list of eth addresses\n",
argv[0]);
exit(1);
}
socks = malloc(sizeof(socks[0]) * (argc-1));
FD_ZERO(&fullset);
for (i = 0; i < argc-1; i++) {
/* one socket per interface */
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock < 0) {
fprintf(stderr, "%s: socket(): %s\n",
argv[0], strerror(errno));
exit(1);
}
/* one ifindex per inteface */
memset (&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, argv[i+1], IF_NAMESIZE);
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
fprintf(stderr, "%s: getindex(%s): %s\n",
argv[0], argv[i+1], strerror(errno));
exit(1);
}
/* one promiscuous per inteface */
memset(&req, 0, sizeof(req));
req.mr_ifindex = ifr.ifr_ifindex;
req.mr_type = PACKET_MR_PROMISC;
if (setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&req, sizeof(req)) < 0) {
fprintf(stderr, "%s: set_promiscuous(%s): %s\n",
argv[0], argv[i+1], strerror(errno));
exit(1);
}
/* one bind per inteface */
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = ifr.ifr_ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
fprintf(stderr, "%s: bind(%s): %s\n",
argv[0], argv[i+1], strerror(errno));
exit(1);
}
/* save for later */
socks[i] = sock;
FD_SET(sock, &fullset);
}
/* end of loop: "sock" is the largest one */
while(1) {
struct timeval tv;
set = fullset;
i = select(sock+1, &set, NULL, NULL, NULL);
gettimeofday(&tv, NULL);
if (i < 0 && errno == EINTR)
continue;
if (i <= 0)
exit(1);
/* retrieve data */
for (i = 0; i < argc-1; i++) {
if (!FD_ISSET(socks[i], &set))
continue;
while ( (len = recv(socks[i], packet, sizeof(packet),
MSG_DONTWAIT | MSG_TRUNC)) >= 0)
dumpone(argv[i+1], &tv, packet, len);
if (errno != EAGAIN) {
fprintf(stderr, "%s: revb(%s): %sn",
argv[0], argv[i+1], strerror(errno));
}