From d0009856814c13d13770db5aadd7b2fabf947776 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 13 May 2013 13:53:27 +0200 Subject: staging: add mausezahn staging directory After some back and forth, we decided that it is easier to maintain mausezahn in a staging directory until it is fully reworked and cleaned up to be ready to be fully integrated. This way, it is better than having it in a separate branch, and we can also accept patches from outside more easily. Also, while at it, fix up some function mismatches with libcli. Signed-off-by: Daniel Borkmann Signed-off-by: Tobias Klauser --- staging/mops_sequence.c | 303 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 staging/mops_sequence.c (limited to 'staging/mops_sequence.c') diff --git a/staging/mops_sequence.c b/staging/mops_sequence.c new file mode 100644 index 0000000..32e7895 --- /dev/null +++ b/staging/mops_sequence.c @@ -0,0 +1,303 @@ +/* + * Mausezahn - A fast versatile traffic generator + * Copyright (C) 2010 Herbert Haas + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html + * +*/ + + +#include "mz.h" +#include "cli.h" +#include "mops.h" +#include "llist.h" + + +///////////////////// TOC ///////////////////// +// +// int mops_delete_sequence (char *name) +// struct mz_ll * mops_create_sequence (char *name) +// int mops_dump_sequence (char* str) +// int mops_add_packet_to_sequence (struct mz_ll *seq, struct mops *mp) +// int mops_add_delay_to_sequence (struct mz_ll *seq, struct timespec *t) +// int mops_delete_packet_from_pseq (struct mz_ll *seq, int index) +// int stop_sequence (char *name) +// int stop_all_sequences () + + +// delete one sequence element (from the global packet_sequence list) +// which must be specified by its name +// +int mops_delete_sequence (char *name) +{ + struct mz_ll *v; + + v = mz_ll_search_name (packet_sequences, name); + if (v==NULL) return 1; // name not found + + if (v->state) return 2; // sequence is currently active! + + if (mz_ll_delete_element (v)) + return -1; // cannot delete head element! + return 0; +} + + + +struct mz_ll * mops_create_sequence (char *name) +{ + struct mz_ll *cur; + struct pseq *seq; + int i; + + cur = mz_ll_create_new_element(packet_sequences); + if (cur==NULL) return NULL; + strncpy(cur->name, name, MZ_LL_NAME_LEN); + // add data + cur->data = (struct pseq*) malloc (sizeof(struct pseq)); + // initialize data + seq = (struct pseq*) cur->data; + seq->count = 0; + for (i=0; ipacket[i] = NULL; // pointer to the packets + seq->gap[i].tv_sec = 0; + seq->gap[i].tv_nsec = 0; + } + return cur; +} + + + +// PURPOSE: dumps all sequence objects line-by-line +// +// ARGUMENTS: Caller must provide a pointer to a string of size MZ_LL_NAME_LEN+(MAX_PACKET_SEQUENCE_LEN*6) +// (recommendation: 512 bytes !) +// +// RETURN VALUE: 0 if list is finished, 1 otherwise +// +// EXAMPLE: char str[512]; +// while (mops_dump_sequence(str) +// printf("%s\n", str); +// +int mops_dump_sequence (char* str) +{ + static int init=0; + static struct mz_ll *cur; + struct pseq *seq; + struct mops *pkt; + + char tmp[256], t[16]; + int i, c; + + tmp[0]='\0'; + + if (init==-1) { // last turn said stop now! + init=0; + return 0; + } + + if (init==0) { + cur=packet_sequences->next; + if (cur==NULL) { + str[0]='\0'; + return 0; + } + init=1; + } + + seq = (struct pseq*) cur->data; + if (seq==NULL) { + init=-1; + sprintf(str, "(no sequences found)"); + return 1; + } + + c = seq->count; // amount of currently stored packets in this sequence object + + // create string with all packet IDs: + for (i=0; ipacket[i]; + if (pkt == NULL) break; + snprintf(t, 15, "%i", pkt->id); + if (strnlen(tmp,256)>249) break; + strncat(tmp, t, 6); + if (iname, tmp); + + cur=cur->next; + if (cur==packet_sequences) init=-1; // stop next turn! + return 1; +} + + +// finds next free slot in sequence seq and adds packet mp +// +// RETURN VALUE: 0 upon success +// -1 failure: array full +// -2 failure: cannot add packets with infinite count +// +int mops_add_packet_to_sequence (struct mz_ll *seq, struct mops *mp) +{ + struct pseq *cur; + int i; + + if (seq==NULL) return 1; + + // don't add packets with count=0 + if (mp->count==0) return -2; + + cur = (struct pseq*) seq->data; + if (cur->count >= MAX_PACKET_SEQUENCE_LEN) return -1; // packet array full! + for (i=0; ipacket[i]==NULL) { // found empty slot + cur->packet[i]=mp; + cur->count++; + return 0; + } + } + return 1; // never reach here +} + + +// adds the given delay 't' to the last packet in the sequence's pseq +// +// NOTE: return index number of pseq where delay had been added +// or upon failure: -1 if there is no packet yet defined +// -2 if array is full +int mops_add_delay_to_sequence (struct mz_ll *seq, struct timespec *t) +{ + struct pseq *cur; + int i; + + if (seq==NULL) return 1; + + cur = (struct pseq*) seq->data; + i = cur->count; + if (i>= MAX_PACKET_SEQUENCE_LEN) return -2; // packet array full! + + cur->gap[i-1].tv_sec = t->tv_sec; + cur->gap[i-1].tv_nsec = t->tv_nsec; + + return i-1; // note: is -1 if there is no packet yet (count=0) +} + + +// Deletes packet and associated delay from a pseq for given index +// If index == -1 then the last packet/delay is removed +// +// NOTE: index range is {1..count} +// +// RETURN VALUES: 0 upon success +// 1 upon failure +// 2 upon failure, index too big +// +int mops_delete_packet_from_pseq (struct mz_ll *seq, int index) +{ + struct pseq *cur; + int i; + + if (seq==NULL) return 1; + cur = (struct pseq*) seq->data; + if (cur->count==0) return 1; // list is empty, nothing to delete + if (index>cur->count) return 2; + if ((index==0) || (index<-1)) return 1; // total invalid index values + if (index==-1) { // remove last element + cur->packet[cur->count-1]=NULL; + cur->gap[cur->count-1].tv_sec=0; + cur->gap[cur->count-1].tv_nsec=0; + } else { + for (i=index-1; i<(cur->count-1); i++) { + cur->packet[i] = cur->packet[i+1]; + cur->gap[i].tv_sec = cur->gap[i+1].tv_sec; + cur->gap[i].tv_nsec=cur->gap[i+1].tv_nsec; + } + } + cur->count--; + return 0; +} + + +int mops_delete_all_packets_from_pseq (struct mz_ll *seq) +{ + struct pseq *cur; + int i; + + if (seq==NULL) return 1; + cur = (struct pseq*) seq->data; + if (cur->count==0) return 1; // list is empty, nothing to delete + // DELETE ALL: + cur->count = 0; + for (i=0; ipacket[i] = NULL; // pointer to the packets + cur->gap[i].tv_sec = 0; + cur->gap[i].tv_nsec = 0; + } + return 0; +} + + + +// Stops an active sequence and sets all involved packets from state SEQACT to CONFIG. +// +// RETURN VALUE: 0 upon success +// 1 if sequence does not exist +// 2 if sequence is not actice +int stop_sequence (char *name) +{ + struct mz_ll *v; + struct pseq *cur; + int i; + + v = mz_ll_search_name (packet_sequences, name); + if (v==NULL) return 1; // name not found + if (!v->state) return 2; // sequence is not currently active! + + // now stop thread: + pthread_cancel(v->sequence_thread); + + // reset packet states: + cur = (struct pseq*) v->data; + for (i=0; icount; i++) + cur->packet[i]->state=MOPS_STATE_CONFIG; + + // reset sequence state: + v->state = 0; + return 0; +} + + +// runs through 'packet_sequences' and cancels all active sequences +// (i. e. stops threads and sets states appropriately) +// +// Comment: It might seem a bit inefficient to call 'stop_sequence' for the +// detailed work, but this is the more safer way and it is fast enough. +// +// RETURN VALUE: Number of stopped sequences. +// +int stop_all_sequences () +{ + struct mz_ll *cur=packet_sequences->next; + int i=0; + + while (cur!=packet_sequences) { + if (cur!=packet_sequences) { // just for safety + if (stop_sequence(cur->name)==0) i++; + } + cur=cur->next; + } + + return i; +} + -- cgit v1.2.3-54-g00ecf