2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
24 #define MOPS_VERSION "0.3"
25 #define MOPS_CODENAME "Cyanistes caeruleus (DE+150)"
26 #define AUTOMOPS_ENABLED 0 // Automops subsystem (currently in development)
27 #define MAX_MOPS_FRAME_SIZE 8192 // total max frame size (=all headers plus payload)
28 #define MIN_MOPS_FRAME_SIZE 15 // total min frame size
29 #define MOPS_SIZE_MARGIN 50 // User limit: MAX_MOPS_FRAME_SIZE - MOPS_SIZE_MARGIN
30 #define MAX_MOPS_MSG_SIZE 7500 // payload limit
31 #define MAX_MOPS_MSG_CHUNK_SIZE 1000 // Chunks size when read data from a file for the payload
32 #define MAX_MOPS_COUNTERS_PER_PACKET 10 // number of user-defined counters per packet
33 #define MAX_MOPS_PACKET_NAME_LEN 32 // Each packet must have an unique name
34 #define MAX_MOPS_DESCRIPTION_LEN 80 // Max length of packet description string
35 #define MAX_MOPS_DOT1Q_TAGS 64 // Max number of 802.1Q tags within a frame (too many, practically ;-))
36 #define MAX_MOPS_MPLS_TAGS 64 // Max number of MPLS tags within a frame (again too many, practically)
37 #define XN_MAX_STACK 7 // max nesting depth
39 #define AUTOMOPS_MAX_FILE_SIZE 200000 // Max file size in bytes for AMP protocol definitions
40 #define AUTOMOPS_MAX_NAME_LEN 32 // used for all names (valname, field name, protocol name)
41 #define AUTOMOPS_MAX_SHORTDESC_LEN 64
43 #define XML_MAX_TAG_LEN 16
44 #define XML_STRLEN 64 // required length of user string to hold tag
45 // but also alternatively an error message
48 #define MAX_LLDP_OPT_TLVS 500 // How many bytes are reserved for optional TLVs within an LLDP message?
50 //#define MAX_MOPS_PACKETS 1000 // number of packet slots *** DEPRECATED ***
51 #define MAX_CLI_LINE_BYTES 32 // How many bytes 'mops_print_frame' should print before line break
53 // Basic layers; see mops_clear_layers()
54 // Also used by automops (see layers_on, layers_off)
57 #define MOPS_SNAP 2 // either LLC, LLC+SNAP
64 // The following definitions are needed as values for (int) p_desc_type
65 // which identifies the exact type of (void *) p_desc.
66 #define MOPS_NO_PDESC 100
74 #define MOPS_SYSLOG 108
77 // packet states (variable 'state')
78 // NOTE: every state >2 (i. e. 3, 4, ...) is an active state, i. e. packet should
79 // be blocked from configurations etc.
80 #define MOPS_STATE_NULL 0 // transition state, only initially
81 #define MOPS_STATE_INIT 1
82 #define MOPS_STATE_CONFIG 2 // normal state (when configured)
83 #define MOPS_STATE_ACTIVE 3 // has associated sending thread
84 #define MOPS_STATE_SEQACT 4 // packet is member of an active sequence
86 // Return values of mops_pdesc utility functions (see mops_ext.c)
87 #define MOPS_PDESC_SUCCESS 0 // Value assigned properly | string present
88 #define MOPS_PDESC_FAILURE 1 // Unspecified problem | string not present
89 #define MOPS_PDESC_LOW 2 // Value smaller than lower bound - but will set
90 #define MOPS_PDESC_HIGH 3 // Value larger than upper bound - but will set
91 #define MOPS_PDESC_OVERFLOW 4 // Value exceeded possible range
92 #define MOPS_PDESC_NO_MAC 5 // Invalid MAC address
93 #define MOPS_PDESC_NO_IP 6 // Invalid IP address
95 // These definitions are (should be) only used in mops_ext.c
96 #define MOPS_EXT_ARP struct mops_ext_arp *
97 #define MOPS_EXT_BPDU struct mops_ext_bpdu *
98 #define MOPS_EXT_CDP struct mops_ext_cdp *
99 #define MOPS_EXT_DNS struct mops_ext_dns *
100 #define MOPS_EXT_ICMP struct mops_ext_icmp *
101 #define MOPS_EXT_LLDP struct mops_ext_lldp *
102 #define MOPS_EXT_RTP struct mops_ext_rtp *
103 #define MOPS_EXT_SYSLOG struct mops_ext_syslog *
104 #define MOPS_EXT_IGMP struct mops_ext_igmp *
106 // Very specific definitions here:
107 #define MOPS_RTP_EXT_MZID 0xcaca // first 16 bit of the Mausezahn RTP extension header
108 #define DSP_SOURCE 100 // any number >0 indicating /dev/dsp to be used as RTP payload
109 #define MOPS_RTP_MAX_PAYLOAD_SIZE 200
114 // These are initialized with the definitions MIN_MOPS_FRAME_SIZE and
115 // MAX_MOPS_FRAME_SIZE above but can be overridden by the user (without
116 // extending these limits)
117 unsigned int min_frame_s
;
118 unsigned int max_frame_s
;
122 int use
; // 1 = counter active
123 int offset
; // points to counter location in *msg*
124 int random
; // 1=random, 0=use start/stop/step
125 u_int32_t start
; // HOST BYTE ORDER
126 u_int32_t stop
; // HOST BYTE ORDER
127 u_int32_t step
; // HOST BYTE ORDER
128 u_int32_t cur
; // current value (HOST BYTE ORDER)
129 int bytes
; // number of bytes used (1|2|4) - selects hton2 or hton4
130 // and enables proper wraparounds (mod 256, mod 65536, ...)
144 ampSingleWordRequired
,
152 Byte8
, Byte16
, Byte32
, Flag_in_Byte
, MultiBytes
, MultiBytesHex
,
153 TLV
// TODO: different/standard TLV formats (Cisco CDP, LLCP, ...)
159 char name
[AUTOMOPS_MAX_NAME_LEN
+1]; // Official name of field -- CASE INSENSITIVE
160 char shortdesc
[AUTOMOPS_MAX_SHORTDESC_LEN
+1]; // One-line description
161 char * longdesc
; // Long (multiline) description (helptext)
162 enum fieldtypes type
; // Field type corresponds to length
163 int constant
; // 1: only default value allowed, not changeable
165 int i
; // unique internal field entry index (strongly monotonic increasing!)
166 // Note: first entry starts with 0.
168 int index
; // protocol field index; Note: First field has index 1.
169 // successive fields have same index in two cases:
170 // 1) several flags within same byte
171 // 2) several different valname/val pairs for same field index. In this
172 // case the successive field-entries must only contain the valname
173 // and a corresponding value.
175 // may contain a reserved value *name*, usually used with multiple
176 // successive fields with same field index N.
177 char valname
[AUTOMOPS_MAX_NAME_LEN
+1];
182 val
, // default initial value
183 min
, // range min value
184 max
; // range max value
186 int leftshift
; // when type=Flag_in_Byte
188 u_int8_t
*str
; // default initial characters or hex values (when type=MultiByte or TLV)
189 int str_s
; // length of str
193 // Each automops object identifies another dynamically specified protocol.
195 // Usage and structure:
197 // 1) Doubly linked list to store new (dynamically defined) protocols.
198 // Protocol definitions are typically loaded from a file and converted
199 // to an automops entry via parse_protocol() defined in parse_xml.c
201 // 2) When the user chooses one of these protocols to be used for a mops
202 // then best is to copy the whole automops to the current mops; this
203 // way the protocol's field values can be easily modified and
204 // automops_update() can be directly applied to that automops entity.
206 // If you cannot understand anything you are maybe already mausezahn'ed ;-)
209 struct automops
*next
;
210 struct automops
*prev
;
212 char name
[AUTOMOPS_MAX_NAME_LEN
+1]; // Protocol name
213 char desc
[AUTOMOPS_MAX_SHORTDESC_LEN
+1]; // One-line description
215 // Specify required and allowed layers using the definitions above
216 // for example MOPS_ETH, MOPS_SNAP, MOPS_dot1Q, MOPS_MPLS,
217 // MOPS_IP, MOPS_UDP, and MOPS_TCP
219 layers_on
, // which layers are REQUIRED
220 layers_off
; // which layers MUST be DISABLED because of conflicts
221 // Not mentioned layers are arbitrary (e. g. MOPS_dot1Q)
222 // Protocol-specific addresses
223 // Usually only destination address/port is specific but there are some
224 // exceptions (e. g. DHCP uses well known sp/dp pair).
225 // Value zero means ignore; otherwise copy to mops.
226 u_int16_t etype
; // EtherType
227 u_int8_t proto
; // IP protocol number
228 u_int8_t sa
[6], da
[6]; // source/destination MAC address
229 u_int32_t SA
, DA
; // source/destination IPv4 address
230 int sp
, dp
; // Well-known port numbers
233 int payload_type
; // 0=none, 1=ascii, 2=hex, 3=any
234 char *payload
; // default payload data (if above is true)
237 struct fields
*field
; // points to single linked list describing each field
240 /// ---- internal data -----
241 int defined_externally
; // 0=built-in, 1=file, -1=undefined
242 int used
; // number of mopses using this automops;
243 // = -1 when allocated
244 // = 0 when got valid data
245 // = >0 when used by some mopses
249 struct automops
* amp_head
;
257 // *** The Header ***
258 // Management issues for TX
259 int state
; // see above
260 int id
; // UNIQUE Identifier (NOTE: MUST ALLOW -1)
261 int mz_system
; // identifies user and system packets (such as ARP)
262 int verbose
; // Be more or less verbose when processing that MOPS
263 char packet_name
[MAX_MOPS_PACKET_NAME_LEN
]; // Each packet must have unique name
264 char description
[MAX_MOPS_DESCRIPTION_LEN
]; // An optional short packet description
266 pthread_t mops_thread
; // associated transmission thread
267 pthread_t interval_thread
;
269 pthread_mutex_t mops_mutex
; // mutex to savely access mops data
271 char device
[16]; // every packet could be sent through a different device
272 // NOTE that we do NOT store the index of device_list[] because after
273 // a re-discovery of the network interfaces the same index could map
274 // to a different physical network device. Instead the device's name
275 // does not change (however, might be not available, but then we report
276 // an error message and the user can assign another interface)
278 // See function mops_get_device_index()
280 unsigned long count
; // Desired number of packets to be sent. 0 means infinite.
281 unsigned long cntx
; // This value actually counts sent packets.
282 // NOTE: Count _down_ for finite count, count _up_ for infinite count.
284 struct timespec ndelay
; // Inter-packet delay; contains two members:
285 // tv_sec and tv_nsec (0 to 999999999)
287 struct timespec interval
; // An optional global interval
288 int interval_used
; // 0=none, 1=configured, 2=active (i. e. interval_thread is valid)
290 struct timespec delay_sigma
; // Standard deviation
292 int delay_pd
; // Which propability distribution (density)
294 // MOPS_DELAY_EXP will result in a Poisson process with lambda=delay
297 int auto_delivery_off
; // 0 means, the destination MAC address will be chosen automatically (for IP packets)
298 // depending on the IP destination address ('direct or indirect delivery', i. e. based
301 // 1 means, the user-provided destination MAC address will be used.
303 // ******************
308 use_ETHER
, // if unset (=0) then complete raw frame given in frame[]
309 use_SNAP
, // NOTE: use_SNAP=1 may indicate either 802.3+LLC alone or 802.3+LLC+SNAP
316 int // pointers to important positions
317 begin_IP
, // marks byte position of IP header within frame
318 begin_UDP
, // marks byte position of UDP header within frame
319 begin_TCP
, // marks byte position of TCP header within frame
320 begin_MSG
; // marks byte position of first message byte (=payload) within frame
322 int // **** get payload (message) from a file ****
323 MSG_use_RAW_FILE
, // 1 means update function should copy next chunk from file
324 MSG_use_HEX_FILE
, // same but assumes file content such as "aa:bb:cc:f3:1e:..."
325 MSG_use_ASC_FILE
; // same but interpretes file content as ASCII characters
326 // NOTE: if one of these are set to 1 then a filepointer is open !!!
328 // A protocol descriptor (p_desc) is only used for some statically
329 // defined protocols. Originally intended for more complicated protocols
331 void * p_desc
; // optionally points to protocol descriptor (e. g. for DNS, CDP, etc)
332 int p_desc_type
; // identifies the exact type of p_desc
336 // AutoMOPS provides a dynamic method to define new protocols. Here we need a pointer
337 // to the protocol definition for convenience and the complete protocol header field
338 // which is created by automops_update()
340 // Note: The used 'amp' should be memcpy'd for this particular mops
341 // because then we can store current PDU values here and the
342 // user can modify it later arbitrarily.
344 // Use automops_clone_automops() in automops.c for this.
346 struct automops
*amp
; // points to protocol definition
347 u_int8_t
*amp_pdu
; // contains the complete PDU as bytestring
352 u_int8_t frame
[MAX_MOPS_FRAME_SIZE
]; // will hold the complete frame
353 u_int32_t frame_s
; // indicates the total frame size
356 // Ethernet parameters:
359 int eth_src_israndom
; // if set to 1 then the source address is to be randomized
361 u_int16_t eth_type_backup
; // if original type must be restored (e. g. when removing MPLS labels)
363 // 802.3 parameters: LLC/SNAP
365 u_int8_t eth_snap
[16]; // AA-AA-03-<OUI>-<TYPE>
366 int eth_snap_s
; // usually 8 bytes
369 // 802.1Q VLAN Tag !!! NOTE: outer tag has lower index number (same byte-order as in frame[]) !!!
370 u_int8_t dot1Q
[MAX_MOPS_DOT1Q_TAGS
*4]; // All successive 802.1Q/P headers, 4 bytes per header: 0x8100, pri, cfi, id
371 int dot1Q_s
; // how many bytes from above are really used
372 int dot1Q_isrange
; // if 1, only the outer tag loops through the range.
378 u_int8_t mpls
[MAX_MOPS_MPLS_TAGS
*4]; // All successive labels
379 int mpls_s
; // how many bytes from above are really used
380 int mpls_isrange
; // if 1, only the outer tag loops through the range.
384 // IP parameters -- NOTE: Everything here is in HOST BYTE ORDER !!!
386 u_int32_t ip_src
; // By default interface address
387 u_int32_t ip_src_start
; // start of range (HOST byte order => easy to count)
388 u_int32_t ip_src_stop
; // stop of range (HOST byte order => easy to count)
389 int ip_src_isrange
; // if set to 1 then the start/stop values above are valid.
390 int ip_src_israndom
; // if set to 1 then the source address is to be randomized
391 u_int32_t ip_dst
; // (HOST byte order)
392 u_int32_t ip_dst_start
; // start of range (NOT network byte order => easy to count)
393 u_int32_t ip_dst_stop
; // stop of range (NOT network byte order => easy to count)
394 int ip_dst_isrange
; // if set to 1 then the start/stop values above are valid.
398 ip_frag_offset
, // 13 bit Offset: allowed values: 0..8191
399 ip_sum
; // TODO: provide variable 'ip_sum_false' to create false checksum for various tests
400 int ip_IHL_false
; // Default=0, set to 1 if user configured own (typically false) header length
401 int ip_len_false
; // Default=0, set to 1 if user configured own (typically false) total length
402 int ip_sum_false
; // Default=0, set to 1 if user configured own (typcially false) checksum
405 ip_IHL
, // header length (4 bits = 0..15)
407 ip_flags_RS
, // 0|1 ... Reserved flag "must be zero"
408 ip_flags_DF
, // 0|1 ... Don't Fragment
409 ip_flags_MF
, // 0|1 ... More Fragments
410 ip_fragsize
, // if >0 it activates auto-fragmentation
411 ip_frag_overlap
, // if >0 then all fragments overlap. Must be multiple of 8 but smaller than fragsize.
415 ip_option
[1024]; // Any IP Option used?
416 int ip_option_used
; // >0 if yes. The exact number also indicates which option(s) used - see mops_ip.c
421 // General L4 parameters:
427 sp_isrand
, // if set to 1 then use random port number for each sent packet
428 dp_isrand
, // if set to 1 then use random port number for each sent packet
429 sp_isrange
, // if set to 1 then start/stop values above are valid
430 dp_isrange
; // if set to 1 then start/stop values above are valid
434 udp_len
, // includes header size (8 bytes)
436 int udp_sum_false
; // Default=0, set to 1 if user configured own (typcially false) checksum
437 int udp_len_false
; // Default=0, set to 1 if user configured own (typcially false) length
439 // TCP parameters (RFC 793)
442 // 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
443 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
444 // | Source Port | Destination Port |
445 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
446 // | Sequence Number |
447 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
448 // | Acknowledgment Number |
449 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
450 // | Data | |U|A|P|R|S|F| |
451 // | Offset| Reserved |R|C|S|S|Y|I| Window |
452 // | | |G|K|H|T|N|N| |
453 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
454 // | Checksum | Urgent Pointer |
455 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
456 // | Options | Padding |
457 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
459 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
465 tcp_seq_delta
, // Also used instead of an 'isrange' variable
469 tcp_ack_delta
; // Also used instead of an 'isrange' variable
471 tcp_offset
, // Header length in multiples of 32 bit (4 bit value, 0..15)
472 tcp_res
, // reserved (4 bits)
473 tcp_ctrl_CWR
, // 0|1 - Congestion Window Reduced [RFC-3168]
474 tcp_ctrl_ECE
, // 0|1 - ECN-Echo [RFC-3168]
485 tcp_len
; // Only needed for the checksum calculation and is not transmitted (host order!)
488 tcp_sum_false
, // Default=0, set to 1 if user configured own (typcially false) checksum
489 tcp_offset_false
; // Default=0, set to 1 if user configured own (typcially false) offset
494 int tcp_option_used
; // >0 if yes. The exact number also indicates which option(s) used - see mops_tcp.c
498 u_int8_t msg
[MAX_MOPS_MSG_SIZE
];
500 FILE *fp
; // points to file if MSG_use_RAW_FILE or MSG_use_HEX_FILE or MSG_use_ASC_FILE is set to 1
501 u_int32_t chunk_s
; // max chunk size to be copied from file
504 // User-defined counters:
505 struct mops_counter counter
[MAX_MOPS_COUNTERS_PER_PACKET
];
506 int used_counters
; // number of currently defined counters
519 u_int8_t sender_mac
[6];
520 u_int8_t sender_ip
[4];
521 u_int8_t target_mac
[6];
522 u_int8_t target_ip
[4];
528 struct mops_ext_bpdu
// TODO
531 u_int8_t version
; // 0=802.1D, 2=RSTP(802.1w)
532 u_int8_t bpdu_type
; // 0=conf, 1=topology change (actually in big endian!), 2=RSTP/MSTP
533 u_int8_t flags
; // X... .... = TCN ACK
534 // .X.. .... = Agreement
535 // ..X. .... = Forwarding
536 // ...X .... = Learning
537 // .... XX.. = Port Role (e. g. 11=Desgn)
538 // .... ..X. = Proposal
540 u_int8_t root_id
[8]; // Root BID
541 u_int32_t root_pc
; // Root Path Cost
542 u_int8_t bridge_id
[8]; // Own BID
543 u_int16_t port_id
; // Port Identifier
544 u_int16_t message_age
; // All timers are multiples of 1/256 sec. Thus times range from 0 to 256 seconds.
546 u_int16_t hello_time
;
548 u_int8_t trailer
[8]; // either all-zero or 34:00:02:VLAN(16bit):00:00 when PVST+
550 int rstp
; // 1 = RSTP
551 int pvst
; // 1=PVST+ , 0 = 802.1D
552 int mstp
; // 1 = Multiple Instance STP
556 struct mops_ext_lldp
{
557 int non_conform
; // if 1 then the order of TLVs is arbitrary
558 int chassis_id_subtype
;
560 u_int8_t
*chassis_id
;
566 u_int8_t
*optional_tlvs
;
570 enum igmp_type
{IGMP_GENERAL_QUERY
,
576 struct igmp_sa_struct
{ // For single linked list to hold unicast addresses for IGMPv3 query
578 struct igmp_sa_struct
*next
;
581 struct igmp_aux_struct
{ // For single linked list to hold auxilary data for IGMPv3 report
583 struct igmp_aux_struct
*next
;
587 struct igmp_group_struct
{ // For single linked list to hold IGMPv3 group records
588 u_int8_t record_type
;
589 u_int8_t aux_data_len
;
590 u_int16_t nr_sources
;
591 u_int32_t mcast_addr
;
592 struct igmp_sa_struct
*sa_list
;
593 struct igmp_aux_struct
*aux_list
;
594 struct igmp_group_struct
*next
;
599 struct mops_ext_igmp
{
600 int version
; // internal, not in header
602 u_int8_t max_resp_code
; // equally: 'max response time' for IGMPv2
604 int sum_false
; // if '1' then sum contains user-provided checksum; if '0' then autocompute!
605 u_int32_t group_addr
;
607 resv4
, // resv4 + S + QRV => one byte in IGMPv3 query
608 S
, // S = Suppress Router-Side Processing
609 QRV
; // QRV = Querier's Robustness Variable
610 u_int8_t resv8
; // needed in IGMPv3 response AND IGMPv1 query+response
611 u_int16_t resv16
; // needed in IGMPv3 response
612 u_int8_t QQIC
; // Querier's Query Interval Code
613 u_int16_t nr_entries
; // either number of sources (=query) or group records (=response)
614 struct igmp_sa_struct
*sa_list
;
618 struct mops_ext_cdp
// TODO
624 struct mops_ext_dns
// TODO: complete
626 // Main 16-bit fields
628 u_int16_t num_queries
;
629 u_int16_t num_answers
;
630 u_int16_t num_author
;
634 // Flags (1 bit, except where noted)
636 u_int8_t opcode
; // 4 bits
641 u_int8_t z
; // 3 bits
642 u_int8_t rcode
; // 4 bits
647 struct mops_ext_icmp
// TODO
655 // Vars to hold flag values:
658 x
, // only sets the flag; if you really want an extension header also set "x_type" (see below)
659 cc
, // csrc_count visible in header (has no further meaning, thus support for "wrong" headers)
660 cc_real
, // real csrc_count (only used internally to create CSRC list)
662 pt
; // selects inter-packet delay and payload_s;
664 u_int16_t sqnr
; // initial sqnr
665 u_int32_t tst
; // initial timestamp
666 u_int32_t ssrc
; // !!! also used to identify measurement streams !!!
667 u_int32_t csrc
[16]; // NOTE: only up to 15 CSRC's are allowed according RFC 3550
670 int tst_inc
; // The increment of the tst (depends on codec)
671 u_int8_t payload
[MOPS_RTP_MAX_PAYLOAD_SIZE
]; //
672 int payload_s
; // is the same as tst_inc when codec is G.711 but different with other codecs!
673 int source
; // Optionally draw data from file or /dev/dsp or such [TODO]
674 int rtp_header_len
; // will be set by mops_update_rtp()
675 // one optional header extension:
676 int x_type
; // IMPORTANT: which extension header to use: 0 = none, 42 = Mausezahn, 1 = Aero
677 u_int8_t extension
[64]; // a user configurable extension header [CURRENTLY UNUSED]
682 struct mops_ext_syslog
//TODO
689 /////////////////////////////////////////////////////////////////
691 struct mops
*mp_head
; // This global will point to the head of the mops list
693 /////////////////////////////////////////////////////////////////
696 void mops_hton2 (u_int16_t
*host16
, u_int8_t
*net16
);
697 void mops_hton4 (u_int32_t
*host32
, u_int8_t
*net32
);
699 int mops_get_proto_info (struct mops
*mp
, char *layers
, char *proto
);
701 // Inserts value in 'flag' (up to 7 bits are useful) into the target
702 // with an optional left-shift. For example if flag contains a 4-bit value
703 // and should be placed within the target in bit positions 3-6 like:
706 // +--+--+--+--+--+--+--+--+
708 // +--+--+--+--+--+--+--+--+
712 // (void) mops_flags ( &target, &flag, 3 );
715 // 1) shift=0 means no shift
716 // 2) Because of speed we do not check if the arguments are reasonable
718 void mops_flags (u_int8_t
*target
, u_int8_t
*flag
, int shift
);
720 u_int16_t
mops_sum16 (u_int16_t len
, u_int8_t buff
[]);
722 struct mops
* mops_init ();
723 struct mops
* mops_alloc_packet (struct mops
*cur
);
724 struct mops
* mops_delete_packet (struct mops
*cur
);
725 int mops_reset_packet(struct mops
*cur
);
727 int mops_dump_all (struct mops
* list
, char* str
);
728 struct mops
* mops_search_name (struct mops
* list
, char *key
);
729 struct mops
* mops_search_id (struct mops
* list
, u_int32_t key
);
731 void mops_delete_all (struct mops
* list
);
732 void mops_cleanup (struct mops
* list
);
735 int mops_state (struct mops
*mp
);
736 int mops_is_active (struct mops
*mp
);
737 void mops_set_conf (struct mops
*mp
);
738 void mops_set_active (struct mops
*mp
);
739 void mops_set_seqact (struct mops
*mp
);
740 int mops_is_seqact (struct mops
*mp
);
741 int mops_is_any_active (struct mops
*mp
);
743 // For debugging purposes
744 int mops_print_frame (struct mops
*mp
, char *str
);
746 // sets UDP or TCP checksum within mp->frame
747 // TODO: copying the whole segment is ugly and slow;
748 // make it more efficient and realize it in-place.
750 int mops_get_transport_sum (struct mops
*mp
);
752 // returns new counter index for given packet
753 // or -1 if all counters used already
754 int mops_get_counter (struct mops
*mp
);
756 // This is the very basic MOPS update function. It simply updates the whole
757 // MOPS frame specified by pointer mp. If you only want to update specific
758 // details then please see the other related specialized functions which are
760 int mops_update (struct mops
*mp
);
762 int mops_set_defaults (struct mops
*mp
);
764 // Get global device index for a given device name.
765 int mops_get_device_index(char *devname
);
767 // Assign device-specific addresses to packet.
768 int mops_use_device(struct mops
* clipkt
, int i
);
770 // Find and returns a new unique packet id
771 // If none can be found, returns -1.
772 int mops_get_new_pkt_id (struct mops
*mp
);
774 // Simply sets specified 'layer switches' in struct mops to zero
775 int mops_clear_layers (struct mops
*mp
, int l
);
777 // Transmission functions
778 int mops_tx_simple (struct mops
*mp
);
779 void *mops_tx_thread_native (void *arg
);
780 void *mops_interval_thread (void *arg
);
781 void *mops_sequence_thread (void *arg
);
784 int mops_destroy_thread (struct mops
*mp
);
786 // Utility functions for packet headers (aka *** METHODS *** for the object-oriented nerds)
787 int mops_dot1Q_remove (struct mops
*mp
, int k
);
788 int mops_dot1Q_nocfi (struct mops
*mp
, int k
);
789 int mops_dot1Q_cfi (struct mops
*mp
, int k
);
790 int mops_dot1Q (struct mops
*mp
, int i
, int m
, u_int16_t v
, u_int16_t c
);
792 int mops_mpls_remove (struct mops
*mp
, int j
);
793 int mops_mpls_bos (struct mops
*mp
, int k
);
794 int mops_mpls_nobos (struct mops
*mp
, int k
);
795 int mops_mpls(struct mops
*mp
, int i
, int m
, u_int32_t Label
, u_int8_t Exp
, u_int8_t TTL
);
797 int mops_ip_get_dst_mac(struct device_struct
*dev
, u_int8_t
*ip
, u_int8_t
*mac
);
798 int mops_ip_dscp(struct mops
*mp
, char *argv
);
799 int mops_ip_tos (struct mops
* mp
, int ipp
, int tos
, int mbz
);
800 int mops_ip_option_ra (struct mops
* mp
, int value
);
801 int mops_ip_option_remove_all (struct mops
* mp
);
803 u_int32_t
mops_tcp_complexity_sqnr (struct mops
* mp
);
804 u_int32_t
mops_tcp_complexity_acknr (struct mops
* mp
);
806 // Prints current flag settings in the provided string 'str'.
807 int mops_tcp_flags2str (struct mops
* mp
, char *str
);
809 int mops_tcp_add_option (struct mops
* mp
,
817 //////////////////////////////////////////////////////////////////////////////
819 // ****** The following are important to easily create new packet types ******
821 //////////////////////////////////////////////////////////////////////////////
823 // Adds single byte to msg
824 int mops_msg_add_byte (struct mops
*mp
, u_int8_t data
);
826 // Adds bit field in *previous* msg-byte using optional left-shift
827 int mops_msg_add_field (struct mops
*mp
, u_int8_t data
, int shift
);
829 // Adds two bytes in network byte order to msg
830 int mops_msg_add_2bytes (struct mops
*mp
, u_int16_t data
);
832 // Adds four bytes in network byte order to msg
833 int mops_msg_add_4bytes (struct mops
*mp
, u_int32_t data
);
835 // Adds string of bytes with lenght len
836 int mops_msg_add_string (struct mops
*mp
, u_int8_t
*str
, int len
);
838 // Add counter to message
839 int mops_msg_add_counter (struct mops
*mp
,
840 int random
, // 1=random, 0=use start/stop/step
841 u_int32_t start
, // HOST BYTE ORDER
842 u_int32_t stop
, // HOST BYTE ORDER
843 u_int32_t step
, // HOST BYTE ORDER
844 int bytes
// number of bytes used (1|2|4) - selects hton2 or hton4
847 // Returns 0 if identical, 1 if different
848 int compare_ip (u_int8_t
*ip1
, u_int8_t
*ip2
);
850 // Returns 0 if identical, 1 if different
851 int compare_mac (u_int8_t
*mac1
, u_int8_t
*mac2
);
853 // Converts a 'struct timespec' value into a human readable string
854 int timespec2str(struct timespec
*t
, char *str
);
856 // -------------------------------------------------------------------------------
858 // Add protocol descriptor of type ptype
860 // Smart behaviour: If a p_desc has been already assigned, this function
861 // clears and frees everything before assigning another p_desc structure.
863 int mops_ext_add_pdesc (struct mops
*mp
, int ptype
);
865 // Create msg based on p_desc data.
866 // After that call mops_update and the frame is complete.
867 int mops_ext_update (struct mops
*mp
);
869 // Delete any protocol descriptor
870 int mops_ext_del_pdesc (struct mops
*mp
);
872 // Initialization functions for p_desc
873 int mops_init_pdesc_arp(struct mops
*mp
);
874 int mops_init_pdesc_bpdu(struct mops
*mp
);
875 int mops_init_pdesc_cdp(struct mops
*mp
);
876 int mops_init_pdesc_dns(struct mops
*mp
);
877 int mops_init_pdesc_icmp(struct mops
*mp
);
878 int mops_init_pdesc_igmp(struct mops
*mp
);
879 int mops_init_pdesc_lldp(struct mops
*mp
);
880 int mops_init_pdesc_syslog(struct mops
*mp
);
881 int mops_init_pdesc_rtp(struct mops
*mp
);
883 int mops_create_igmpv2 (struct mops
*mp
,
884 int override
, // normally zero, but if '1' the user want to override defaults
885 int igmp_type
, // IGMP_GENERAL_QUERY, IGMP_GSPEC_QUERY, IGMP_V2_REPORT, IGMP_V1_REPORT, IGMP_LEAVE
886 int mrt
, // max response time
887 int sum
, //-1 means auto-compute, other values means 'use this user-defined value'
888 u_int32_t group_addr
);
891 // Update functions for p_desc => msg
892 int mops_update_arp(struct mops
* mp
);
893 int mops_update_bpdu(struct mops
* mp
);
894 int mops_update_igmp (struct mops
* mp
);
895 int mops_update_lldp (struct mops
* mp
);
896 int mops_update_rtp (struct mops
* mp
);
897 int mops_update_rtp_dynamics (struct mops
* mp
);
899 // Utility functions for p_desc
900 int mops_pdesc_mstrings (char *dst
, char* argv
[], int argc
, int max
);
901 int mops_pdesc_1byte (u_int8_t
*dst
, char* usr
, int spec
, int min
, int max
);
902 int mops_pdesc_2byte (u_int16_t
*dst
, char* usr
, int spec
, int min
, int max
);
903 int mops_pdesc_4byte (u_int32_t
*dst
, char* usr
, int spec
, unsigned long int min
, unsigned long int max
);
904 int mops_pdesc_mac (u_int8_t
*dst
, char* usr
);
905 int mops_pdesc_ip (u_int8_t
*dst
, char* usr
);
907 // Other p_desc related functions
908 int mops_create_bpdu_bid(struct mops
* mp
, int pri
, int esi
, char *mac
, int bid_or_rid
);
909 int mops_create_bpdu_trailer (struct mops
* mp
, u_int16_t vlan
);
910 int mops_lldp_tlv (u_int8_t
*tlv
, int type
, int len
, u_int8_t
*value
);
911 int mops_lldp_tlv_chassis (u_int8_t
*tlv
, int subtype
, int len
, u_int8_t
*cid
);
912 int mops_lldp_tlv_port (u_int8_t
*tlv
, int subtype
, int len
, u_int8_t
*pid
);
913 int mops_lldp_tlv_TTL (u_int8_t
*tlv
, int ttl
);
914 int mops_lldp_tlv_end (u_int8_t
*tlv
);
915 int mops_lldp_opt_tlv_bad (struct mops
*mp
, int type
, int badlen
, int len
, u_int8_t
*value
);
916 int mops_lldp_opt_tlv_org (struct mops
*mp
, int oui
, int subtype
, int len
, u_int8_t
*inf
);
917 int mops_lldp_opt_tlv_chassis (struct mops
*mp
, int subtype
, int len
, u_int8_t
*cid
);
918 int mops_lldp_opt_tlv_port (struct mops
*mp
, int subtype
, int len
, u_int8_t
*pid
);
919 int mops_lldp_opt_tlv_TTL (struct mops
*mp
, int ttl
);
920 int mops_lldp_opt_tlv_vlan (struct mops
*mp
, int vlan
);
921 int mops_lldp_opt_tlv (struct mops
*mp
, int type
, int len
, u_int8_t
*value
);
922 int mops_lldp_opt_tlv_end (struct mops
*mp
) ;
925 /////////////////////////// Services /////////////////////////////
927 // ARP Service: Resolves MAC address of given IP address and interface
928 int service_arp(char *dev
, u_int8_t
*ip
, u_int8_t
*mac
);
931 void *rx_arp (void *arg
);
932 void got_arp_packet (u_char
*args
, const struct pcap_pkthdr
*header
, const u_char
*packet
);
935 //////////////////// directmops prototypes: ///////////////////////////
936 int mops_direct(char* dev
, int mops_type
, char* argstring
);
939 //////////////////// automops prototypes: //////////////////////////////////
942 struct automops
* automops_init();
943 struct automops
* automops_alloc_protocol();
944 struct automops
* automops_delete_protocol();
945 struct automops
* automops_search_protocol();
946 int automops_dump_all (struct automops
* list
);
947 void automops_set_defaults(struct automops
* cur
);
948 struct fields
* automops_add_field (struct automops
*amp
);
949 void automops_field_set_defaults(struct fields
*f
);
950 int automops_delete_fields (struct automops
*amp
);
951 int mops_str2layers(char *d
);
952 int amp_add_pentry (struct automops
*amp
, int xntag
, char *d
);
953 int amp_add_fentry (struct automops
*amp
, struct fields
*f
, int xntag
, char *d
);
954 int amp_checkindex(struct automops
*amp
, int i
);
955 int amp_str2type(char *d
);
956 int amp_type2str(int t
, char *s
);
957 struct fields
* amp_getfield_byname(struct automops
*amp
, char *d
);
958 struct automops
* amp_getamp_byname(struct automops
*head
, char *d
);
959 // Creates an independent automops element for mops
960 // (it will be not part of any linked list so, next=prev=NULL)
961 struct automops
* automops_clone_automops(struct automops
* amp
);
962 int amperr2str (int e
, char *s
);
964 // Create automops PDU within *mp based on data in *amp
966 int automops_update (struct mops
*mp
, struct automops
*amp
);
967 void automops_cleanup (struct automops
*list
);
969 char * mapfile (char *fn
);
971 ////////////////////////// XML support //////////////////////////////
976 // Simple stack needed to check proper XML nesting.
977 // The corresponding methods are defined at the bottom.
979 int data
[XN_MAX_STACK
];
983 enum xml_tags
{ // mention all allowed tags here!
1007 int xml_check_parent(int t
, int p
);
1008 int xml_tag2int (char *t
);
1010 int parse_protocol (char *p
);
1011 int xml_getnext_tag (char *p
, char *t
);
1012 int xml_canonic (char *p
);
1013 int xml_get_data (char *p
, char *t
);
1014 int xml_readin (struct automops
*amp
, char *p
);
1016 void xnstack_init(struct xnstack
*s
);
1017 int xnstack_get_top(struct xnstack
*s
);
1018 int xnstack_push(struct xnstack
*s
, int d
);
1019 int xnstack_pop(struct xnstack
*s
);
1020 int xnstack_size(struct xnstack
*s
);