summaryrefslogtreecommitdiff
path: root/staging/mops.h
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-05-13 13:53:27 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-05-13 15:10:16 +0200
commitd0009856814c13d13770db5aadd7b2fabf947776 (patch)
tree6d18a94439f27f3c2685f05c57435116673f40cc /staging/mops.h
parent2b100f7515dbd01032967c2d1b81d2f8d63bf9b5 (diff)
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 <dborkman@redhat.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'staging/mops.h')
-rw-r--r--staging/mops.h1023
1 files changed, 1023 insertions, 0 deletions
diff --git a/staging/mops.h b/staging/mops.h
new file mode 100644
index 0000000..fd9884c
--- /dev/null
+++ b/staging/mops.h
@@ -0,0 +1,1023 @@
+/*
+ * Mausezahn - A fast versatile traffic generator
+ * Copyright (C) 2008-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
+ *
+*/
+
+
+#ifndef __MOPS__
+#define __MOPS__
+
+
+#define MOPS_VERSION "0.3"
+#define MOPS_CODENAME "Cyanistes caeruleus (DE+150)"
+#define AUTOMOPS_ENABLED 0 // Automops subsystem (currently in development)
+#define MAX_MOPS_FRAME_SIZE 8192 // total max frame size (=all headers plus payload)
+#define MIN_MOPS_FRAME_SIZE 15 // total min frame size
+#define MOPS_SIZE_MARGIN 50 // User limit: MAX_MOPS_FRAME_SIZE - MOPS_SIZE_MARGIN
+#define MAX_MOPS_MSG_SIZE 7500 // payload limit
+#define MAX_MOPS_MSG_CHUNK_SIZE 1000 // Chunks size when read data from a file for the payload
+#define MAX_MOPS_COUNTERS_PER_PACKET 10 // number of user-defined counters per packet
+#define MAX_MOPS_PACKET_NAME_LEN 32 // Each packet must have an unique name
+#define MAX_MOPS_DESCRIPTION_LEN 80 // Max length of packet description string
+#define MAX_MOPS_DOT1Q_TAGS 64 // Max number of 802.1Q tags within a frame (too many, practically ;-))
+#define MAX_MOPS_MPLS_TAGS 64 // Max number of MPLS tags within a frame (again too many, practically)
+#define XN_MAX_STACK 7 // max nesting depth
+
+#define AUTOMOPS_MAX_FILE_SIZE 200000 // Max file size in bytes for AMP protocol definitions
+#define AUTOMOPS_MAX_NAME_LEN 32 // used for all names (valname, field name, protocol name)
+#define AUTOMOPS_MAX_SHORTDESC_LEN 64
+
+#define XML_MAX_TAG_LEN 16
+#define XML_STRLEN 64 // required length of user string to hold tag
+ // but also alternatively an error message
+
+
+#define MAX_LLDP_OPT_TLVS 500 // How many bytes are reserved for optional TLVs within an LLDP message?
+
+//#define MAX_MOPS_PACKETS 1000 // number of packet slots *** DEPRECATED ***
+#define MAX_CLI_LINE_BYTES 32 // How many bytes 'mops_print_frame' should print before line break
+
+// Basic layers; see mops_clear_layers()
+// Also used by automops (see layers_on, layers_off)
+#define MOPS_ALL 127
+#define MOPS_ETH 1
+#define MOPS_SNAP 2 // either LLC, LLC+SNAP
+#define MOPS_dot1Q 4
+#define MOPS_MPLS 8
+#define MOPS_IP 16
+#define MOPS_UDP 32
+#define MOPS_TCP 64
+
+// The following definitions are needed as values for (int) p_desc_type
+// which identifies the exact type of (void *) p_desc.
+#define MOPS_NO_PDESC 100
+#define MOPS_ARP 101
+#define MOPS_BPDU 102
+#define MOPS_CDP 103
+#define MOPS_DNS 104
+#define MOPS_ICMP 105
+#define MOPS_LLDP 106
+#define MOPS_RTP 107
+#define MOPS_SYSLOG 108
+#define MOPS_IGMP 109
+
+// packet states (variable 'state')
+// NOTE: every state >2 (i. e. 3, 4, ...) is an active state, i. e. packet should
+// be blocked from configurations etc.
+#define MOPS_STATE_NULL 0 // transition state, only initially
+#define MOPS_STATE_INIT 1
+#define MOPS_STATE_CONFIG 2 // normal state (when configured)
+#define MOPS_STATE_ACTIVE 3 // has associated sending thread
+#define MOPS_STATE_SEQACT 4 // packet is member of an active sequence
+
+// Return values of mops_pdesc utility functions (see mops_ext.c)
+#define MOPS_PDESC_SUCCESS 0 // Value assigned properly | string present
+#define MOPS_PDESC_FAILURE 1 // Unspecified problem | string not present
+#define MOPS_PDESC_LOW 2 // Value smaller than lower bound - but will set
+#define MOPS_PDESC_HIGH 3 // Value larger than upper bound - but will set
+#define MOPS_PDESC_OVERFLOW 4 // Value exceeded possible range
+#define MOPS_PDESC_NO_MAC 5 // Invalid MAC address
+#define MOPS_PDESC_NO_IP 6 // Invalid IP address
+
+// These definitions are (should be) only used in mops_ext.c
+#define MOPS_EXT_ARP struct mops_ext_arp *
+#define MOPS_EXT_BPDU struct mops_ext_bpdu *
+#define MOPS_EXT_CDP struct mops_ext_cdp *
+#define MOPS_EXT_DNS struct mops_ext_dns *
+#define MOPS_EXT_ICMP struct mops_ext_icmp *
+#define MOPS_EXT_LLDP struct mops_ext_lldp *
+#define MOPS_EXT_RTP struct mops_ext_rtp *
+#define MOPS_EXT_SYSLOG struct mops_ext_syslog *
+#define MOPS_EXT_IGMP struct mops_ext_igmp *
+
+// Very specific definitions here:
+#define MOPS_RTP_EXT_MZID 0xcaca // first 16 bit of the Mausezahn RTP extension header
+#define DSP_SOURCE 100 // any number >0 indicating /dev/dsp to be used as RTP payload
+#define MOPS_RTP_MAX_PAYLOAD_SIZE 200
+
+#include <pthread.h>
+
+
+// These are initialized with the definitions MIN_MOPS_FRAME_SIZE and
+// MAX_MOPS_FRAME_SIZE above but can be overridden by the user (without
+// extending these limits)
+unsigned int min_frame_s;
+unsigned int max_frame_s;
+
+struct mops_counter
+{
+ int use; // 1 = counter active
+ int offset; // points to counter location in *msg*
+ int random; // 1=random, 0=use start/stop/step
+ u_int32_t start; // HOST BYTE ORDER
+ u_int32_t stop; // HOST BYTE ORDER
+ u_int32_t step; // HOST BYTE ORDER
+ u_int32_t cur; // current value (HOST BYTE ORDER)
+ int bytes; // number of bytes used (1|2|4) - selects hton2 or hton4
+ // and enables proper wraparounds (mod 256, mod 65536, ...)
+};
+
+
+enum amperr {
+ ampSuccess,
+ ampInvalidIndex,
+ ampInvalidName,
+ ampDuplicateName,
+ ampDescTooLong,
+ ampInvalidType,
+ ampInvalidLayer,
+ ampTCPandUDP,
+ ampUnknownKeyword,
+ ampSingleWordRequired,
+ ampRangeError,
+ ampPayloadLen,
+ ampPayloadType,
+ ampUnknownTag
+};
+
+enum fieldtypes {
+ Byte8, Byte16, Byte32, Flag_in_Byte, MultiBytes, MultiBytesHex,
+ TLV // TODO: different/standard TLV formats (Cisco CDP, LLCP, ...)
+};
+
+
+struct fields {
+ struct fields *next;
+ char name[AUTOMOPS_MAX_NAME_LEN+1]; // Official name of field -- CASE INSENSITIVE
+ char shortdesc[AUTOMOPS_MAX_SHORTDESC_LEN+1]; // One-line description
+ char * longdesc; // Long (multiline) description (helptext)
+ enum fieldtypes type; // Field type corresponds to length
+ int constant; // 1: only default value allowed, not changeable
+
+ int i; // unique internal field entry index (strongly monotonic increasing!)
+ // Note: first entry starts with 0.
+
+ int index; // protocol field index; Note: First field has index 1.
+ // successive fields have same index in two cases:
+ // 1) several flags within same byte
+ // 2) several different valname/val pairs for same field index. In this
+ // case the successive field-entries must only contain the valname
+ // and a corresponding value.
+
+ // may contain a reserved value *name*, usually used with multiple
+ // successive fields with same field index N.
+ char valname[AUTOMOPS_MAX_NAME_LEN+1];
+
+ u_int32_t
+ tlv_type,
+ tlv_len,
+ val, // default initial value
+ min, // range min value
+ max; // range max value
+
+ int leftshift; // when type=Flag_in_Byte
+
+ u_int8_t *str; // default initial characters or hex values (when type=MultiByte or TLV)
+ int str_s; // length of str
+};
+
+
+// Each automops object identifies another dynamically specified protocol.
+//
+// Usage and structure:
+//
+// 1) Doubly linked list to store new (dynamically defined) protocols.
+// Protocol definitions are typically loaded from a file and converted
+// to an automops entry via parse_protocol() defined in parse_xml.c
+//
+// 2) When the user chooses one of these protocols to be used for a mops
+// then best is to copy the whole automops to the current mops; this
+// way the protocol's field values can be easily modified and
+// automops_update() can be directly applied to that automops entity.
+//
+// If you cannot understand anything you are maybe already mausezahn'ed ;-)
+//
+struct automops {
+ struct automops *next;
+ struct automops *prev;
+
+ char name[AUTOMOPS_MAX_NAME_LEN+1]; // Protocol name
+ char desc[AUTOMOPS_MAX_SHORTDESC_LEN+1]; // One-line description
+
+ // Specify required and allowed layers using the definitions above
+ // for example MOPS_ETH, MOPS_SNAP, MOPS_dot1Q, MOPS_MPLS,
+ // MOPS_IP, MOPS_UDP, and MOPS_TCP
+ int
+ layers_on, // which layers are REQUIRED
+ layers_off; // which layers MUST be DISABLED because of conflicts
+ // Not mentioned layers are arbitrary (e. g. MOPS_dot1Q)
+ // Protocol-specific addresses
+ // Usually only destination address/port is specific but there are some
+ // exceptions (e. g. DHCP uses well known sp/dp pair).
+ // Value zero means ignore; otherwise copy to mops.
+ u_int16_t etype; // EtherType
+ u_int8_t proto; // IP protocol number
+ u_int8_t sa[6], da[6]; // source/destination MAC address
+ u_int32_t SA, DA; // source/destination IPv4 address
+ int sp, dp; // Well-known port numbers
+
+
+ int payload_type; // 0=none, 1=ascii, 2=hex, 3=any
+ char *payload; // default payload data (if above is true)
+ int payload_s;
+
+ struct fields *field; // points to single linked list describing each field
+ // or NULL
+
+ /// ---- internal data -----
+ int defined_externally; // 0=built-in, 1=file, -1=undefined
+ int used; // number of mopses using this automops;
+ // = -1 when allocated
+ // = 0 when got valid data
+ // = >0 when used by some mopses
+};
+
+
+struct automops * amp_head;
+
+
+struct mops
+{
+ struct mops *next;
+ struct mops *prev;
+
+ // *** The Header ***
+ // Management issues for TX
+ int state; // see above
+ int id; // UNIQUE Identifier (NOTE: MUST ALLOW -1)
+ int mz_system; // identifies user and system packets (such as ARP)
+ int verbose; // Be more or less verbose when processing that MOPS
+ char packet_name[MAX_MOPS_PACKET_NAME_LEN]; // Each packet must have unique name
+ char description[MAX_MOPS_DESCRIPTION_LEN]; // An optional short packet description
+
+ pthread_t mops_thread; // associated transmission thread
+ pthread_t interval_thread;
+
+ pthread_mutex_t mops_mutex; // mutex to savely access mops data
+
+ char device[16]; // every packet could be sent through a different device
+ // NOTE that we do NOT store the index of device_list[] because after
+ // a re-discovery of the network interfaces the same index could map
+ // to a different physical network device. Instead the device's name
+ // does not change (however, might be not available, but then we report
+ // an error message and the user can assign another interface)
+ //
+ // See function mops_get_device_index()
+
+ unsigned long count; // Desired number of packets to be sent. 0 means infinite.
+ unsigned long cntx; // This value actually counts sent packets.
+ // NOTE: Count _down_ for finite count, count _up_ for infinite count.
+
+ struct timespec ndelay; // Inter-packet delay; contains two members:
+ // tv_sec and tv_nsec (0 to 999999999)
+
+ struct timespec interval; // An optional global interval
+ int interval_used; // 0=none, 1=configured, 2=active (i. e. interval_thread is valid)
+
+ struct timespec delay_sigma; // Standard deviation
+
+ int delay_pd; // Which propability distribution (density)
+ // MOPS_DELAY_GAUSS
+ // MOPS_DELAY_EXP will result in a Poisson process with lambda=delay
+
+
+ int auto_delivery_off; // 0 means, the destination MAC address will be chosen automatically (for IP packets)
+ // depending on the IP destination address ('direct or indirect delivery', i. e. based
+ // on ARP).
+ //
+ // 1 means, the user-provided destination MAC address will be used.
+
+ // ******************
+
+ // Data section
+
+ int
+ use_ETHER, // if unset (=0) then complete raw frame given in frame[]
+ use_SNAP, // NOTE: use_SNAP=1 may indicate either 802.3+LLC alone or 802.3+LLC+SNAP
+ use_dot1Q,
+ use_MPLS,
+ use_IP,
+ use_UDP,
+ use_TCP;
+
+ int // pointers to important positions
+ begin_IP, // marks byte position of IP header within frame
+ begin_UDP, // marks byte position of UDP header within frame
+ begin_TCP, // marks byte position of TCP header within frame
+ begin_MSG; // marks byte position of first message byte (=payload) within frame
+
+ int // **** get payload (message) from a file ****
+ MSG_use_RAW_FILE, // 1 means update function should copy next chunk from file
+ MSG_use_HEX_FILE, // same but assumes file content such as "aa:bb:cc:f3:1e:..."
+ MSG_use_ASC_FILE; // same but interpretes file content as ASCII characters
+ // NOTE: if one of these are set to 1 then a filepointer is open !!!
+
+ // A protocol descriptor (p_desc) is only used for some statically
+ // defined protocols. Originally intended for more complicated protocols
+ // such as DNS.
+ void * p_desc; // optionally points to protocol descriptor (e. g. for DNS, CDP, etc)
+ int p_desc_type; // identifies the exact type of p_desc
+
+
+
+ // AutoMOPS provides a dynamic method to define new protocols. Here we need a pointer
+ // to the protocol definition for convenience and the complete protocol header field
+ // which is created by automops_update()
+ //
+ // Note: The used 'amp' should be memcpy'd for this particular mops
+ // because then we can store current PDU values here and the
+ // user can modify it later arbitrarily.
+ //
+ // Use automops_clone_automops() in automops.c for this.
+ //
+ struct automops *amp; // points to protocol definition
+ u_int8_t *amp_pdu; // contains the complete PDU as bytestring
+ int amp_pdu_s;
+
+
+ // Resulting frame:
+ u_int8_t frame[MAX_MOPS_FRAME_SIZE]; // will hold the complete frame
+ u_int32_t frame_s; // indicates the total frame size
+
+
+ // Ethernet parameters:
+ u_int8_t eth_dst[6];
+ u_int8_t eth_src[6];
+ int eth_src_israndom; // if set to 1 then the source address is to be randomized
+ u_int16_t eth_type;
+ u_int16_t eth_type_backup; // if original type must be restored (e. g. when removing MPLS labels)
+
+ // 802.3 parameters: LLC/SNAP
+ u_int16_t eth_len;
+ u_int8_t eth_snap[16]; // AA-AA-03-<OUI>-<TYPE>
+ int eth_snap_s; // usually 8 bytes
+
+
+ // 802.1Q VLAN Tag !!! NOTE: outer tag has lower index number (same byte-order as in frame[]) !!!
+ u_int8_t dot1Q[MAX_MOPS_DOT1Q_TAGS*4]; // All successive 802.1Q/P headers, 4 bytes per header: 0x8100, pri, cfi, id
+ int dot1Q_s; // how many bytes from above are really used
+ int dot1Q_isrange; // if 1, only the outer tag loops through the range.
+ int dot1Q_start;
+ int dot1Q_stop;
+
+
+ // MPLS label stack
+ u_int8_t mpls[MAX_MOPS_MPLS_TAGS*4]; // All successive labels
+ int mpls_s; // how many bytes from above are really used
+ int mpls_isrange; // if 1, only the outer tag loops through the range.
+ int mpls_start;
+ int mpls_stop;
+
+ // IP parameters -- NOTE: Everything here is in HOST BYTE ORDER !!!
+
+ u_int32_t ip_src; // By default interface address
+ u_int32_t ip_src_start; // start of range (HOST byte order => easy to count)
+ u_int32_t ip_src_stop; // stop of range (HOST byte order => easy to count)
+ int ip_src_isrange; // if set to 1 then the start/stop values above are valid.
+ int ip_src_israndom; // if set to 1 then the source address is to be randomized
+ u_int32_t ip_dst; // (HOST byte order)
+ u_int32_t ip_dst_start; // start of range (NOT network byte order => easy to count)
+ u_int32_t ip_dst_stop; // stop of range (NOT network byte order => easy to count)
+ int ip_dst_isrange; // if set to 1 then the start/stop values above are valid.
+ u_int16_t
+ ip_len,
+ ip_id,
+ ip_frag_offset, // 13 bit Offset: allowed values: 0..8191
+ ip_sum; // TODO: provide variable 'ip_sum_false' to create false checksum for various tests
+ int ip_IHL_false; // Default=0, set to 1 if user configured own (typically false) header length
+ int ip_len_false; // Default=0, set to 1 if user configured own (typically false) total length
+ int ip_sum_false; // Default=0, set to 1 if user configured own (typcially false) checksum
+ u_int8_t
+ ip_version,
+ ip_IHL, // header length (4 bits = 0..15)
+ ip_tos,
+ ip_flags_RS, // 0|1 ... Reserved flag "must be zero"
+ ip_flags_DF, // 0|1 ... Don't Fragment
+ ip_flags_MF, // 0|1 ... More Fragments
+ ip_fragsize, // if >0 it activates auto-fragmentation
+ ip_frag_overlap, // if >0 then all fragments overlap. Must be multiple of 8 but smaller than fragsize.
+ ip_ttl,
+ ip_proto;
+ u_int8_t
+ ip_option[1024]; // Any IP Option used?
+ int ip_option_used; // >0 if yes. The exact number also indicates which option(s) used - see mops_ip.c
+ u_int32_t
+ ip_option_s;
+
+
+ // General L4 parameters:
+ u_int16_t
+ sp, dp,
+ sp_start, sp_stop,
+ dp_start, dp_stop;
+ int
+ sp_isrand, // if set to 1 then use random port number for each sent packet
+ dp_isrand, // if set to 1 then use random port number for each sent packet
+ sp_isrange, // if set to 1 then start/stop values above are valid
+ dp_isrange; // if set to 1 then start/stop values above are valid
+
+ // UDP parameters
+ u_int16_t
+ udp_len, // includes header size (8 bytes)
+ udp_sum;
+ int udp_sum_false; // Default=0, set to 1 if user configured own (typcially false) checksum
+ int udp_len_false; // Default=0, set to 1 if user configured own (typcially false) length
+
+ // TCP parameters (RFC 793)
+ //
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Source Port | Destination Port |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Sequence Number |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Acknowledgment Number |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Data | |U|A|P|R|S|F| |
+ // | Offset| Reserved |R|C|S|S|Y|I| Window |
+ // | | |G|K|H|T|N|N| |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Checksum | Urgent Pointer |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Options | Padding |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | data |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ //
+ u_int32_t
+ tcp_seq,
+ tcp_seq_start,
+ tcp_seq_stop,
+ tcp_seq_delta, // Also used instead of an 'isrange' variable
+ tcp_ack,
+ tcp_ack_start,
+ tcp_ack_stop,
+ tcp_ack_delta; // Also used instead of an 'isrange' variable
+ u_int8_t
+ tcp_offset, // Header length in multiples of 32 bit (4 bit value, 0..15)
+ tcp_res, // reserved (4 bits)
+ tcp_ctrl_CWR, // 0|1 - Congestion Window Reduced [RFC-3168]
+ tcp_ctrl_ECE, // 0|1 - ECN-Echo [RFC-3168]
+ tcp_ctrl_URG, // 0|1
+ tcp_ctrl_ACK, // 0|1
+ tcp_ctrl_PSH, // 0|1
+ tcp_ctrl_RST, // 0|1
+ tcp_ctrl_SYN, // 0|1
+ tcp_ctrl_FIN; // 0|1
+ u_int16_t
+ tcp_win,
+ tcp_sum,
+ tcp_urg,
+ tcp_len; // Only needed for the checksum calculation and is not transmitted (host order!)
+
+ int
+ tcp_sum_false, // Default=0, set to 1 if user configured own (typcially false) checksum
+ tcp_offset_false; // Default=0, set to 1 if user configured own (typcially false) offset
+ u_int8_t
+ tcp_option[1024];
+ u_int32_t
+ tcp_option_s;
+ int tcp_option_used; // >0 if yes. The exact number also indicates which option(s) used - see mops_tcp.c
+
+
+ // Message:
+ u_int8_t msg[MAX_MOPS_MSG_SIZE];
+ u_int32_t msg_s;
+ FILE *fp; // points to file if MSG_use_RAW_FILE or MSG_use_HEX_FILE or MSG_use_ASC_FILE is set to 1
+ u_int32_t chunk_s; // max chunk size to be copied from file
+
+
+ // User-defined counters:
+ struct mops_counter counter[MAX_MOPS_COUNTERS_PER_PACKET];
+ int used_counters; // number of currently defined counters
+
+};
+
+
+
+struct mops_ext_arp
+{
+ u_int16_t hw_type;
+ u_int16_t pr_type;
+ u_int8_t hw_size;
+ u_int8_t pr_size;
+ u_int16_t opcode;
+ u_int8_t sender_mac[6];
+ u_int8_t sender_ip[4];
+ u_int8_t target_mac[6];
+ u_int8_t target_ip[4];
+ u_int16_t trailer;
+};
+
+
+
+struct mops_ext_bpdu // TODO
+{
+ u_int16_t id;
+ u_int8_t version; // 0=802.1D, 2=RSTP(802.1w)
+ u_int8_t bpdu_type; // 0=conf, 1=topology change (actually in big endian!), 2=RSTP/MSTP
+ u_int8_t flags; // X... .... = TCN ACK
+ // .X.. .... = Agreement
+ // ..X. .... = Forwarding
+ // ...X .... = Learning
+ // .... XX.. = Port Role (e. g. 11=Desgn)
+ // .... ..X. = Proposal
+ // .... ...X = TCN
+ u_int8_t root_id[8]; // Root BID
+ u_int32_t root_pc; // Root Path Cost
+ u_int8_t bridge_id[8]; // Own BID
+ u_int16_t port_id; // Port Identifier
+ u_int16_t message_age; // All timers are multiples of 1/256 sec. Thus times range from 0 to 256 seconds.
+ u_int16_t max_age;
+ u_int16_t hello_time;
+ u_int16_t f_delay;
+ u_int8_t trailer[8]; // either all-zero or 34:00:02:VLAN(16bit):00:00 when PVST+
+
+ int rstp; // 1 = RSTP
+ int pvst; // 1=PVST+ , 0 = 802.1D
+ int mstp; // 1 = Multiple Instance STP
+
+};
+
+struct mops_ext_lldp {
+ int non_conform; // if 1 then the order of TLVs is arbitrary
+ int chassis_id_subtype;
+ int chassis_id_len;
+ u_int8_t *chassis_id;
+ int port_id_subtype;
+ int port_id_len;
+ u_int8_t *port_id;
+ int TTL;
+ int optional_tlvs_s;
+ u_int8_t *optional_tlvs;
+
+};
+
+enum igmp_type {IGMP_GENERAL_QUERY,
+ IGMP_GSPEC_QUERY,
+ IGMP_V2_REPORT,
+ IGMP_V1_REPORT,
+ IGMP_LEAVE};
+
+struct igmp_sa_struct { // For single linked list to hold unicast addresses for IGMPv3 query
+ u_int32_t sa;
+ struct igmp_sa_struct *next;
+};
+
+struct igmp_aux_struct { // For single linked list to hold auxilary data for IGMPv3 report
+ u_int32_t aux_data;
+ struct igmp_aux_struct *next;
+};
+
+
+struct igmp_group_struct { // For single linked list to hold IGMPv3 group records
+ u_int8_t record_type;
+ u_int8_t aux_data_len;
+ u_int16_t nr_sources;
+ u_int32_t mcast_addr;
+ struct igmp_sa_struct *sa_list;
+ struct igmp_aux_struct *aux_list;
+ struct igmp_group_struct *next;
+};
+
+
+
+struct mops_ext_igmp {
+ int version; // internal, not in header
+ u_int8_t type;
+ u_int8_t max_resp_code; // equally: 'max response time' for IGMPv2
+ u_int16_t sum;
+ int sum_false; // if '1' then sum contains user-provided checksum; if '0' then autocompute!
+ u_int32_t group_addr;
+ u_int8_t
+ resv4, // resv4 + S + QRV => one byte in IGMPv3 query
+ S, // S = Suppress Router-Side Processing
+ QRV; // QRV = Querier's Robustness Variable
+ u_int8_t resv8; // needed in IGMPv3 response AND IGMPv1 query+response
+ u_int16_t resv16; // needed in IGMPv3 response
+ u_int8_t QQIC; // Querier's Query Interval Code
+ u_int16_t nr_entries; // either number of sources (=query) or group records (=response)
+ struct igmp_sa_struct *sa_list;
+};
+
+
+struct mops_ext_cdp // TODO
+{
+ u_int8_t id;
+ u_int16_t hw_type;
+};
+
+struct mops_ext_dns // TODO: complete
+{
+ // Main 16-bit fields
+ u_int16_t id;
+ u_int16_t num_queries;
+ u_int16_t num_answers;
+ u_int16_t num_author;
+ u_int16_t num_add;
+ u_int16_t type;
+
+ // Flags (1 bit, except where noted)
+ u_int8_t qr;
+ u_int8_t opcode; // 4 bits
+ u_int8_t aa;
+ u_int8_t tc;
+ u_int8_t rd;
+ u_int8_t ra;
+ u_int8_t z; // 3 bits
+ u_int8_t rcode; // 4 bits
+
+};
+
+
+struct mops_ext_icmp // TODO
+{
+ u_int8_t id;
+ u_int16_t hw_type;
+};
+
+struct mops_ext_rtp
+{
+ // Vars to hold flag values:
+ u_int8_t v,
+ p,
+ x, // only sets the flag; if you really want an extension header also set "x_type" (see below)
+ cc, // csrc_count visible in header (has no further meaning, thus support for "wrong" headers)
+ cc_real, // real csrc_count (only used internally to create CSRC list)
+ m,
+ pt; // selects inter-packet delay and payload_s;
+
+ u_int16_t sqnr; // initial sqnr
+ u_int32_t tst; // initial timestamp
+ u_int32_t ssrc; // !!! also used to identify measurement streams !!!
+ u_int32_t csrc[16]; // NOTE: only up to 15 CSRC's are allowed according RFC 3550
+
+ // additionally:
+ int tst_inc; // The increment of the tst (depends on codec)
+ u_int8_t payload[MOPS_RTP_MAX_PAYLOAD_SIZE]; //
+ int payload_s; // is the same as tst_inc when codec is G.711 but different with other codecs!
+ int source; // Optionally draw data from file or /dev/dsp or such [TODO]
+ int rtp_header_len; // will be set by mops_update_rtp()
+ // one optional header extension:
+ int x_type; // IMPORTANT: which extension header to use: 0 = none, 42 = Mausezahn, 1 = Aero
+ u_int8_t extension[64]; // a user configurable extension header [CURRENTLY UNUSED]
+};
+
+
+
+struct mops_ext_syslog //TODO
+{
+ u_int16_t hw_type;
+ u_int16_t pr_type;
+};
+
+
+/////////////////////////////////////////////////////////////////
+
+struct mops *mp_head; // This global will point to the head of the mops list
+
+/////////////////////////////////////////////////////////////////
+// MOPS Prototypes:
+
+void mops_hton2 (u_int16_t *host16, u_int8_t *net16);
+void mops_hton4 (u_int32_t *host32, u_int8_t *net32);
+
+int mops_get_proto_info (struct mops *mp, char *layers, char *proto);
+
+// Inserts value in 'flag' (up to 7 bits are useful) into the target
+// with an optional left-shift. For example if flag contains a 4-bit value
+// and should be placed within the target in bit positions 3-6 like:
+//
+// 7 6 5 4 3 2 1 0
+// +--+--+--+--+--+--+--+--+
+// | | FLAGS | | | |
+// +--+--+--+--+--+--+--+--+
+//
+// then simply call:
+//
+// (void) mops_flags ( &target, &flag, 3 );
+//
+// Note:
+// 1) shift=0 means no shift
+// 2) Because of speed we do not check if the arguments are reasonable
+//
+void mops_flags (u_int8_t *target, u_int8_t *flag, int shift);
+
+u_int16_t mops_sum16 (u_int16_t len, u_int8_t buff[]);
+
+struct mops * mops_init ();
+struct mops * mops_alloc_packet (struct mops *cur);
+struct mops * mops_delete_packet (struct mops *cur);
+int mops_reset_packet(struct mops *cur);
+
+int mops_dump_all (struct mops* list, char* str);
+struct mops * mops_search_name (struct mops* list, char *key);
+struct mops * mops_search_id (struct mops* list, u_int32_t key);
+
+void mops_delete_all (struct mops* list);
+void mops_cleanup (struct mops* list);
+
+// State functions
+int mops_state (struct mops *mp);
+int mops_is_active (struct mops *mp);
+void mops_set_conf (struct mops *mp);
+void mops_set_active (struct mops *mp);
+void mops_set_seqact (struct mops *mp);
+int mops_is_seqact (struct mops *mp);
+int mops_is_any_active (struct mops *mp);
+
+// For debugging purposes
+int mops_print_frame (struct mops *mp, char *str);
+
+// sets UDP or TCP checksum within mp->frame
+// TODO: copying the whole segment is ugly and slow;
+// make it more efficient and realize it in-place.
+//
+int mops_get_transport_sum (struct mops *mp);
+
+// returns new counter index for given packet
+// or -1 if all counters used already
+int mops_get_counter (struct mops *mp);
+
+// This is the very basic MOPS update function. It simply updates the whole
+// MOPS frame specified by pointer mp. If you only want to update specific
+// details then please see the other related specialized functions which are
+// faster.
+int mops_update (struct mops *mp);
+
+int mops_set_defaults (struct mops *mp);
+
+// Get global device index for a given device name.
+int mops_get_device_index(char *devname);
+
+// Assign device-specific addresses to packet.
+int mops_use_device(struct mops * clipkt, int i);
+
+// Find and returns a new unique packet id
+// If none can be found, returns -1.
+int mops_get_new_pkt_id (struct mops *mp);
+
+// Simply sets specified 'layer switches' in struct mops to zero
+int mops_clear_layers (struct mops *mp, int l);
+
+// Transmission functions
+int mops_tx_simple (struct mops *mp);
+void *mops_tx_thread_native (void *arg);
+void *mops_interval_thread (void *arg);
+void *mops_sequence_thread (void *arg);
+
+
+int mops_destroy_thread (struct mops *mp);
+
+// Utility functions for packet headers (aka *** METHODS *** for the object-oriented nerds)
+int mops_dot1Q_remove (struct mops *mp, int k);
+int mops_dot1Q_nocfi (struct mops *mp, int k);
+int mops_dot1Q_cfi (struct mops *mp, int k);
+int mops_dot1Q (struct mops *mp, int i, int m, u_int16_t v, u_int16_t c);
+
+int mops_mpls_remove (struct mops *mp, int j);
+int mops_mpls_bos (struct mops *mp, int k);
+int mops_mpls_nobos (struct mops *mp, int k);
+int mops_mpls(struct mops *mp, int i, int m, u_int32_t Label, u_int8_t Exp, u_int8_t TTL);
+
+int mops_ip_get_dst_mac(struct device_struct *dev, u_int8_t *ip, u_int8_t *mac);
+int mops_ip_dscp(struct mops *mp, char *argv);
+int mops_ip_tos (struct mops* mp, int ipp, int tos, int mbz);
+int mops_ip_option_ra (struct mops* mp, int value);
+int mops_ip_option_remove_all (struct mops* mp);
+
+u_int32_t mops_tcp_complexity_sqnr (struct mops * mp);
+u_int32_t mops_tcp_complexity_acknr (struct mops * mp);
+
+// Prints current flag settings in the provided string 'str'.
+int mops_tcp_flags2str (struct mops* mp, char *str);
+
+int mops_tcp_add_option (struct mops* mp,
+ int mss,
+ int sack,
+ int scale,
+ u_int32_t tsval,
+ u_int32_t tsecr);
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// ****** The following are important to easily create new packet types ******
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// Adds single byte to msg
+int mops_msg_add_byte (struct mops *mp, u_int8_t data);
+
+// Adds bit field in *previous* msg-byte using optional left-shift
+int mops_msg_add_field (struct mops *mp, u_int8_t data, int shift);
+
+// Adds two bytes in network byte order to msg
+int mops_msg_add_2bytes (struct mops *mp, u_int16_t data);
+
+// Adds four bytes in network byte order to msg
+int mops_msg_add_4bytes (struct mops *mp, u_int32_t data);
+
+// Adds string of bytes with lenght len
+int mops_msg_add_string (struct mops *mp, u_int8_t *str, int len);
+
+// Add counter to message
+int mops_msg_add_counter (struct mops *mp,
+ int random, // 1=random, 0=use start/stop/step
+ u_int32_t start, // HOST BYTE ORDER
+ u_int32_t stop, // HOST BYTE ORDER
+ u_int32_t step, // HOST BYTE ORDER
+ int bytes // number of bytes used (1|2|4) - selects hton2 or hton4
+ );
+
+// Returns 0 if identical, 1 if different
+int compare_ip (u_int8_t *ip1, u_int8_t *ip2);
+
+// Returns 0 if identical, 1 if different
+int compare_mac (u_int8_t *mac1, u_int8_t *mac2);
+
+// Converts a 'struct timespec' value into a human readable string
+int timespec2str(struct timespec *t, char *str);
+
+// -------------------------------------------------------------------------------
+
+// Add protocol descriptor of type ptype
+//
+// Smart behaviour: If a p_desc has been already assigned, this function
+// clears and frees everything before assigning another p_desc structure.
+//
+int mops_ext_add_pdesc (struct mops *mp, int ptype);
+
+// Create msg based on p_desc data.
+// After that call mops_update and the frame is complete.
+int mops_ext_update (struct mops *mp);
+
+// Delete any protocol descriptor
+int mops_ext_del_pdesc (struct mops *mp);
+
+// Initialization functions for p_desc
+int mops_init_pdesc_arp(struct mops *mp);
+int mops_init_pdesc_bpdu(struct mops *mp);
+int mops_init_pdesc_cdp(struct mops *mp);
+int mops_init_pdesc_dns(struct mops *mp);
+int mops_init_pdesc_icmp(struct mops *mp);
+int mops_init_pdesc_igmp(struct mops *mp);
+int mops_init_pdesc_lldp(struct mops *mp);
+int mops_init_pdesc_syslog(struct mops *mp);
+int mops_init_pdesc_rtp(struct mops *mp);
+
+int mops_create_igmpv2 (struct mops *mp,
+ int override, // normally zero, but if '1' the user want to override defaults
+ int igmp_type, // IGMP_GENERAL_QUERY, IGMP_GSPEC_QUERY, IGMP_V2_REPORT, IGMP_V1_REPORT, IGMP_LEAVE
+ int mrt, // max response time
+ int sum, //-1 means auto-compute, other values means 'use this user-defined value'
+ u_int32_t group_addr);
+
+
+// Update functions for p_desc => msg
+int mops_update_arp(struct mops * mp);
+int mops_update_bpdu(struct mops * mp);
+int mops_update_igmp (struct mops * mp);
+int mops_update_lldp (struct mops * mp);
+int mops_update_rtp (struct mops * mp);
+int mops_update_rtp_dynamics (struct mops * mp);
+
+// Utility functions for p_desc
+int mops_pdesc_mstrings (char *dst, char* argv[], int argc, int max);
+int mops_pdesc_1byte (u_int8_t *dst, char* usr, int spec, int min, int max);
+int mops_pdesc_2byte (u_int16_t *dst, char* usr, int spec, int min, int max);
+int mops_pdesc_4byte (u_int32_t *dst, char* usr, int spec, unsigned long int min, unsigned long int max);
+int mops_pdesc_mac (u_int8_t *dst, char* usr);
+int mops_pdesc_ip (u_int8_t *dst, char* usr);
+
+// Other p_desc related functions
+int mops_create_bpdu_bid(struct mops * mp, int pri, int esi, char *mac, int bid_or_rid);
+int mops_create_bpdu_trailer (struct mops * mp, u_int16_t vlan);
+int mops_lldp_tlv (u_int8_t *tlv, int type, int len, u_int8_t *value);
+int mops_lldp_tlv_chassis (u_int8_t *tlv, int subtype, int len, u_int8_t *cid);
+int mops_lldp_tlv_port (u_int8_t *tlv, int subtype, int len, u_int8_t *pid);
+int mops_lldp_tlv_TTL (u_int8_t *tlv, int ttl);
+int mops_lldp_tlv_end (u_int8_t *tlv);
+int mops_lldp_opt_tlv_bad (struct mops *mp, int type, int badlen, int len, u_int8_t *value);
+int mops_lldp_opt_tlv_org (struct mops *mp, int oui, int subtype, int len, u_int8_t *inf);
+int mops_lldp_opt_tlv_chassis (struct mops *mp, int subtype, int len, u_int8_t *cid);
+int mops_lldp_opt_tlv_port (struct mops *mp, int subtype, int len, u_int8_t *pid);
+int mops_lldp_opt_tlv_TTL (struct mops *mp, int ttl);
+int mops_lldp_opt_tlv_vlan (struct mops *mp, int vlan);
+int mops_lldp_opt_tlv (struct mops *mp, int type, int len, u_int8_t *value);
+int mops_lldp_opt_tlv_end (struct mops *mp) ;
+
+
+/////////////////////////// Services /////////////////////////////
+
+// ARP Service: Resolves MAC address of given IP address and interface
+int service_arp(char *dev, u_int8_t *ip, u_int8_t *mac);
+
+int mops_rx_arp ();
+void *rx_arp (void *arg);
+void got_arp_packet (u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
+
+
+//////////////////// directmops prototypes: ///////////////////////////
+int mops_direct(char* dev, int mops_type, char* argstring);
+
+
+//////////////////// automops prototypes: //////////////////////////////////
+
+
+struct automops * automops_init();
+struct automops * automops_alloc_protocol();
+struct automops * automops_delete_protocol();
+struct automops * automops_search_protocol();
+int automops_dump_all (struct automops* list);
+void automops_set_defaults(struct automops * cur);
+struct fields * automops_add_field (struct automops *amp);
+void automops_field_set_defaults(struct fields *f);
+int automops_delete_fields (struct automops *amp);
+int mops_str2layers(char *d);
+int amp_add_pentry (struct automops *amp, int xntag, char *d);
+int amp_add_fentry (struct automops *amp, struct fields *f, int xntag, char *d);
+int amp_checkindex(struct automops *amp, int i);
+int amp_str2type(char *d);
+int amp_type2str(int t, char *s);
+struct fields * amp_getfield_byname(struct automops *amp, char *d);
+struct automops * amp_getamp_byname(struct automops *head, char *d);
+// Creates an independent automops element for mops
+// (it will be not part of any linked list so, next=prev=NULL)
+struct automops * automops_clone_automops(struct automops * amp);
+int amperr2str (int e, char *s);
+
+// Create automops PDU within *mp based on data in *amp
+//
+int automops_update (struct mops *mp, struct automops *amp);
+void automops_cleanup (struct automops *list);
+
+char * mapfile (char *fn);
+
+////////////////////////// XML support //////////////////////////////
+//
+//
+
+
+// Simple stack needed to check proper XML nesting.
+// The corresponding methods are defined at the bottom.
+struct xnstack {
+ int data[XN_MAX_STACK];
+ int cursize;
+};
+
+enum xml_tags { // mention all allowed tags here!
+ xml_protocol,
+ xml_field,
+ xml_name,
+ xml_desc,
+ xml_requires,
+ xml_conflicts,
+ xml_payloadtype,
+ xml_payload,
+ xml_payloadhex,
+ xml_index,
+ xml_longdesc,
+ xml_type,
+ xml_constant,
+ xml_value,
+ xml_valname,
+ xml_min,
+ xml_max,
+ xml_tlvt,
+ xml_tlvl,
+ xml_lshift
+};
+
+
+int xml_check_parent(int t, int p);
+int xml_tag2int (char *t);
+
+int parse_protocol (char *p);
+int xml_getnext_tag (char *p, char *t);
+int xml_canonic (char *p);
+int xml_get_data (char *p, char *t);
+int xml_readin (struct automops *amp, char *p);
+
+void xnstack_init(struct xnstack *s);
+int xnstack_get_top(struct xnstack *s);
+int xnstack_push(struct xnstack *s, int d);
+int xnstack_pop(struct xnstack *s);
+int xnstack_size(struct xnstack *s);
+
+#endif
+