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/mz.h | 931 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 staging/mz.h (limited to 'staging/mz.h') diff --git a/staging/mz.h b/staging/mz.h new file mode 100644 index 0000000..cad091f --- /dev/null +++ b/staging/mz.h @@ -0,0 +1,931 @@ +/* + * 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 __MAUSEZAHN__ +#define __MAUSEZAHN__ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int verbose_level; + +static inline void verbose_l1(const char *format, ...) +{ + va_list vl; + + if (verbose_level < 1) + return; + + va_start(vl, format); + vfprintf(stderr, format, vl); + va_end(vl); +} + +static inline void verbose_l2(const char *format, ...) +{ + va_list vl; + + if (verbose_level < 2) + return; + + va_start(vl, format); + vfprintf(stderr, format, vl); + va_end(vl); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +#define MAUSEZAHN_VERSION "Mausezahn 0.40 - (C) 2007-2010 by Herbert Haas - http://www.perihel.at/sec/mz/" +#define MAUSEZAHN_VERSION_SHORT "0.40" +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +// "Dies ist ein schrecklicher Ort." + +#define MZ_DEFAULT_CONFIG_PATH "/etc/mausezahn/" // see also mz_default_config_path below +#define MZ_DEFAULT_LOG_PATH "/var/log/mausezahn/" // see also mz_default_log_path below + +#define SLEEP usleep // The sleep function to use. Consider 'nanosleep' in future. +#define DEFAULT_DELAY 0 +#define PCAP_READ_TIMEOUT_MSEC 1 // The read timeout for pcap_open_live() +#define MZ_MAX_DEVICES 10 // Max number of network devices supported +#define MAX_PAYLOAD_SIZE 3*8192 +#define MAX_DNS_NAME 256 +#define MAX_8021Q_TAGS 16 +#define TIME_COUNT_MAX 10000 // the size of the timestamp arrays timeRX and timeTX upon creation +#define TIME_COUNT 100 // the default used-size of the timestamp arrays timeRX and timeTX +#define MAX_DATA_BLOCKS 1000 // how many data blocks of size TIME_COUNT-1 should be written per file +#define MAXBYTES_TO_READ 1500 // how many bytes the pcap routine should read from net +#define RCV_RTP_MAX_BAR_WIDTH 500 // max line-width printed in BAR mode (see rcv_rtp.c) + +#define ETH_SRC 1 // These are only some symbols used by some functions. (Don't touch) +#define ETH_DST 2 // These are only some symbols used by some functions. +#define SRC_PORT 1 // These are only some symbols used by some functions. +#define DST_PORT 2 // These are only some symbols used by some functions. + +#define TEST fprintf(stderr, "HERE at line %i in file %s\n", __LINE__,__FILE__ ); fflush(stderr); + + +// ----- PCAP-specific definitions: --------------------- +#define IPADDRSIZE 46 + + +int MZ_SIZE_LONG_INT; + +char mz_default_config_path[256]; +char mz_default_log_path[256]; + + +struct arp_table_struct { + int index; // an entry index (1, 2, ...) for easier user access + u_int8_t sa[6]; // sent by this MAC SA + u_int8_t smac[6]; // announced MAC + u_int8_t smac_prev[6]; // previously announced MAC + u_int8_t sip[4]; // announced IP + unsigned long int uni_rq; // count unidirectional ARP requests for this IP + unsigned long int bc_resp; // count broadcast ARP responses for this IP + unsigned long int uni_resp; // count normal (unidir) ARP responses for this IP + unsigned long int changed; // count how often the MAC address has changed! + int locked; // 1=this entry cannot be overidden anymore + int dynamic; // 1=learned dynamically, 0=configured by user + int flags; // anomaly information (length anomaly: bit 0, sa!=smac: bit 1 , ...) + int gw; // 1=Default GW + char when[10]; // human readable timestamp (e. g. "11:42:53") + u_int32_t sec, nsec; // timestamp of last ARP response + u_int32_t sec_prev, nsec_prev; // timestamp of previous ARP response + //-----------------// + struct arp_table_struct *next; +}; + +// Device list +struct device_struct +{ + char dev[16]; // Device name + int index; // Device index (assigned by OS) + int phy; // 1 if physical, 0 if not (e. g. loopback) + int mtu; + int cli; // if set to 1 then the CLI connection must terminate here + int mgmt_only; // if set to 1 then no data traffic is allowed through that interface + // ---- MAC addresses ---- + u_int8_t mac[6]; // Real MAC address + u_int8_t mac_mops[6]; // MAC address to be used + // ---- IP related ----- + char ip_str[IPADDRSIZE+1]; // Real IP address as string in dotted decimal notation + u_int8_t ip[4]; // Real IP address + u_int8_t net[4]; // Real network + u_int8_t mask[4]; // Real mask + u_int8_t ip_mops[4]; // IP address to be used + // ---- Default Gateway per interface: + u_int8_t mac_gw[6]; // MAC address of default gateway + u_int8_t ip_gw[4]; // IP address of default gateway + // ---- various device-specific handles ---- + pthread_t arprx_thread; + struct pcap *p_arp; // pcap handle + struct arp_table_struct *arp_table; // dedicated ARP table + int ps; // packet socket +} device_list[MZ_MAX_DEVICES]; + +int device_list_entries; + + +#pragma pack(1) +struct struct_ethernet +{ + u_int8_t eth_da[6]; + u_int8_t eth_sa[6]; + u_int16_t eth_type; +}; + +struct struct_arp +{ + u_int16_t arp_hrd; // hardware address format + u_int16_t arp_pro; // protocol address format + u_int8_t arp_hln; // hardware address length + u_int8_t arp_pln; // protocol address length + u_int16_t arp_op; // ARP operation type + u_int8_t arp_smac[6]; // sender's hardware address + u_int8_t arp_sip[4]; // sender's protocol address + u_int8_t arp_tmac[6]; // target hardware address + u_int8_t arp_tip[4]; // target protocol address +}; + + + +//#pragma pack(1) +struct struct_ip +{ + u_int8_t + hlen :4, + ver :4; + u_int8_t + tos; + u_int16_t + len; + + u_int16_t + id, + offset; // flags and fragment offset field + + u_int8_t + ttl, + proto; + u_int16_t + sum; + + u_int8_t src[4]; + u_int8_t dst[4]; +}; + +//#pragma pack(1) +struct struct_udp { + u_int16_t + sp, + dp, + len, + sum; +}; + +//#pragma pack(1) +struct struct_rtp { + u_int8_t + byte1, + ptype; + u_int16_t + sqnr; + u_int32_t + timestamp, // official timestamp, created by codecs + ssrc; + // csrc, // only used by mixers + u_int16_t + ext_id, + ext_len; + u_int32_t + time_sec, + time_nsec, + time_sec2, + time_nsec2; +}; + +// ---------End of PCAP-specific definitions--------------- + + + + +// ************************************ +// +// Global variables +// +// ************************************ + +enum operating_modes +{ + BYTE_STREAM, + ARP, + BPDU, + IP, + ICMP, + ICMP6, + UDP, + TCP, + DNS, + CDP, + RTP, + RX_RTP, + SYSLOG, + LLDP +} mode; + + +int ipv6_mode; +int quiet; // don't even print 'important standard short messages' +int verbose; // report character +int simulate; // if 1 then don't really send frames + +char path[256]; +char filename[256]; +FILE *fp, *fp2; // global multipurpose file pointer + +long double total_d; +clock_t mz_start, mz_stop; + +enum rtp_display_mode { + BAR, NCURSES, TEXT +} rtp_dm; + + +int mz_rand; +int bwidth; + +struct mz_timestamp { + u_int32_t sec; + u_int32_t nsec; +}; + +struct mz_timestamp + tv, + timeTX[TIME_COUNT_MAX], + timeRX[TIME_COUNT_MAX]; + +int32_t + time0, + jitter_rfc, + jitter[TIME_COUNT_MAX]; + +int + rtp_log, + time0_flag, // If set then time0 has valid data + sqnr0_flag; + +u_int8_t + mz_ssrc[4]; // holds RTP stream identifier for rcv_rtp() + +u_int16_t + sqnr_cur, + sqnr_last, + sqnr_next; + +u_int32_t + drop, // packet drop count + dis, // packet disorder count + gind, // a global index to run through deltaRX, deltaTX, and jitter + gind_max, // the amount of entries used in the (ugly oversized) arrays; per default set to TIME_COUNT + gtotal; // counts number of file write cycles (see "got_rtp_packet()") + + +char rtp_filter_str[64]; + +struct tx_struct +{ + // Management issues for TX + char device[16]; // every packet could be sent through a different device + int packet_mode; // 0 means use LIBNET_LINK_ADV, 1 means LIBNET_RAW4 + unsigned int count; // 0 means infinite, 1 is default + unsigned int delay; // Delay in microseconds, 0 means no delay (default) + char arg_string[MAX_PAYLOAD_SIZE]; // Argument-string when -t is used + + // Ethernet and 802.3 parameters + int eth_params_already_set; // if set to 1 then send_eth should only send the frame + u_int8_t eth_mac_own[6]; // Contains own interface MAC if needed by some modules + char eth_dst_txt[32]; // Text version of eth_dst (or keyword such as 'rand') + u_int8_t eth_dst[6]; + int eth_dst_rand; // 1 if random + char eth_src_txt[32]; // Text version of eth_src (or keyword such as 'rand') + u_int8_t eth_src[6]; + int eth_src_rand; // 1 if random + u_int16_t eth_type; + u_int16_t eth_len; + u_int8_t eth_payload[MAX_PAYLOAD_SIZE]; + u_int32_t eth_payload_s; + unsigned int padding; + + // CDP parameters + u_int8_t + cdp_version, + cdp_ttl, + cdp_payload[MAX_PAYLOAD_SIZE], + cdp_tlv_id[2048]; // The ID is the only required TLV + u_int16_t + cdp_sum; + u_int32_t + cdp_tlv_id_len, + cdp_payload_s; + + // 802.1Q VLAN Tag + int dot1Q; // 1 if specified + char dot1Q_txt[32]; // contains 802.1p(CoS) and VLAN-ID ("5:130" or only VLAN "130") + u_int8_t dot1Q_CoS; + u_int16_t dot1Q_vlan; + u_int8_t dot1Q_header[256]; // Contains the complete 802.1Q/P headers (but NOT the Ethernet header!) + u_int8_t dot1Q_header_s; + int dot1Q_at_least_two_headers; // If '1' then we have at least QinQ (or more VLAN tags) + + // ASCII PAYLOAD + int ascii; // 1 if specified + u_int8_t ascii_payload[MAX_PAYLOAD_SIZE]; + + // HEX PAYLOAD + u_int8_t hex_payload[MAX_PAYLOAD_SIZE]; + u_int32_t hex_payload_s; // >0 if hex payload is specified + + // MPLS Parameters + char mpls_txt[128]; // contains MPLS parameters (label, exp, S, TTL) + char mpls_verbose_string[1024]; // contains all labels for print_frame_details() + int mpls; // 1 if specified + u_int32_t mpls_label; + u_int8_t mpls_exp; + u_int8_t mpls_bos; + u_int8_t mpls_ttl; + + // IP parameters + u_int32_t ip_src; // has always network byte order(!) + struct libnet_in6_addr ip6_src; + char ip_src_txt[256]; + int ip_src_rand; // if set to 1 then SA should be random + u_int32_t ip_src_h; // mirror of ip_src (NOT network byte order => easy to count) + u_int32_t ip_src_start; // start of range (NOT network byte order => easy to count) + u_int32_t ip_src_stop; // stop of range (NOT network byte order => easy to count) + int ip_src_isrange; // if set to 1 then the start/stop values above are valid. + u_int32_t ip_dst; // has always network byte order(!) + struct libnet_in6_addr ip6_dst; + char ip_dst_txt[256]; + u_int32_t ip_dst_h; // mirror of ip_dst (NOT network byte order => easy to count) + 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, // Flags and Offset !!! + ip_sum; + u_int8_t + ip_tos, + ip_ttl, + ip6_rtype, + ip6_segs, + ip_proto; + u_int8_t + ip_option[1024], + ip_payload[MAX_PAYLOAD_SIZE]; + u_int32_t + ip_flow, + ip6_id, + ip_option_s, + ip_payload_s; + + // ICMP + char + icmp_verbose_txt[256]; // used for verbose messages in send.c + u_int8_t + icmp_type, + icmp_code; + u_int16_t icmp_ident; // ATTENTION: libnet.h already #defines 'icmp_id', 'icmp_sum', and 'icmp_num' + u_int16_t icmp_chksum; // therefore I needed a renaming here -- be careful in future... + u_int16_t icmp_sqnr; // + u_int32_t + icmp_gateway, + icmp_payload_s; + u_int8_t + icmp_payload[MAX_PAYLOAD_SIZE]; + + // General L4 parameters: + char *layer4; + u_int16_t + sp, dp, + sp_start, sp_stop, + dp_start, dp_stop; + int + 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; + u_int8_t + udp_payload[MAX_PAYLOAD_SIZE]; + u_int32_t + udp_payload_s; + + // TCP parameters + u_int32_t + tcp_seq, + tcp_seq_start, + tcp_seq_stop, // is always set! Usually seq_start = seq_stop (=no range) + tcp_seq_delta, // Also used instead of an 'isrange' variable + tcp_ack; + u_int8_t + tcp_offset, + tcp_control; + u_int16_t + tcp_win, + tcp_sum, + tcp_urg, + tcp_len; // only needed by libnet and must include header size + u_int8_t + tcp_payload[MAX_PAYLOAD_SIZE]; + u_int32_t + tcp_sum_part, + tcp_payload_s; + + // RTP parameters + u_int32_t + rtp_sqnr, + rtp_stmp; + +} tx; // NOTE: tx elements are considered as default values for MOPS + + + + + +u_int8_t gbuf[MAX_PAYLOAD_SIZE]; // This is only a generic global buffer to handover data more easily +u_int32_t gbuf_s; // + + +// ************************************ +// +// Prototypes: General Tools +// +// ************************************ + +void clean_up(int sig); +int getopts(int argc, char *argv[]); +int getarg(char *str, char *arg_name, char *arg_value); +unsigned long int str2int(char *str); // converts "65535" to 65535 +unsigned long long int str2lint(char *str); // same but allows 64-bit integers +unsigned long int xstr2int(char *str); // converts "ffff" to 65535 +unsigned long long int xstr2lint(char *str); // same but allows 64-bit integers +int mz_strisbinary(char *str); +int mz_strisnum(char *str); +int mz_strishex(char *str); +int str2bin8 (char *str); +long int str2bin16 (char *str); +int char2bits (char c, char *str); +int mz_strcmp(char* usr, char* str, int min); +int mz_tok(char * str, char * delim, int anz, ...); +int delay_parse (struct timespec *t, char *a, char *b); +int reset(); + +// ************************************ +// +// Prototypes: Layer1 +// +// ************************************ + +int send_eth(void); +libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t t4); + +// ************************************ +// +// Prototypes: Layer 2 +// +// ************************************ + +int send_arp (void); +int send_bpdu (void); +int send_cdp (void); + +// ************************************ +// +// Prototypes: Layer 3 +// +// ************************************ + + +libnet_t* get_link_context(void); +libnet_ptag_t create_ip_packet (libnet_t *l); +libnet_ptag_t create_ip6_packet (libnet_t *l); +int send_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t t4); + + + +// ************************************ +// +// Prototypes: Layer 4 +// +// ************************************ +libnet_ptag_t create_udp_packet (libnet_t *l); +libnet_ptag_t create_icmp_packet (libnet_t *l); +libnet_ptag_t create_icmp6_packet (libnet_t *l); +libnet_ptag_t create_tcp_packet (libnet_t *l); + + +// ************************************ +// +// Prototypes: Layer 7 +// +// ************************************ +int create_dns_packet (void); +int create_rtp_packet(void); +int create_syslog_packet(void); + +// ************************************ +// +// Prototypes: Helper functions for +// byte manipulation, +// address conversion, +// etc +// +// ************************************ + +// Converts MAC address specified in str into u_int8_t array +// Usage: str2hex_mac ( "00:01:02:aa:ff:ee", src_addr ) +int str2hex_mac (char* str, u_int8_t *addr); + +// Converts ascii hex values (string) into integer array, similarly as above but for any size. +// Example: "1a 00:00-2f" => {26, 0, 0, 47} +// Note: apply any improvements here and prefer this function in future! +// Return value: Number of converted elements (=length of array) +int str2hex (char* str, u_int8_t *hp, int n); + +// Converts ascii numbers (string) into integer array +// Every byte can be specified as integers {0..255} +// For example "192.16.1.1" will be converted to {C0, 10, 01, 01} +int num2hex(char* str, u_int8_t *hp); + +// Convert array of integers into string of hex. Useful for verification messages. +// Example: {0,1,10} => "00-01-0A" +// Usage: bs2str ( src_mac, src_mac_txt, 6 ) +int bs2str (u_int8_t *bs, char* str, int len); + +// Extract contiguous sequence of bytes from an array. First element has index 1 !!! +// Usage: getbytes (bs, da, 1, 6); +int getbytes(u_int8_t *source, u_int8_t *target, int from, int to); + +// For any IP address given in 'dotted decimal' returns an unsigned 32-bit integer. +// Example: "192.168.0.1" => 3232235521 +// Note: Result is in LITTLE ENDIAN but usually with IP you need BIG ENDIAN, see next. +u_int32_t str2ip32 (char* str); + +// For any IP address given in 'dotted decimal' into an unsigned 32-bit integer +// This version does the same as str2ip32() but in BIG ENDIAN. +// Note: With netlib you need this one, not the previous function. +u_int32_t str2ip32_rev (char* str); + +// Converts a 2-byte value (e. g. a EtherType field) +// into a nice string using hex notation. +// Useful for verification messages. +// Example: type2str (tx.eth_type, msg) may result in msg="08:00" +// Return value: how many hex digits have been found. +int type2str(u_int16_t type, char *str); + + +// Parses string 'arg' for an IP range and finds start and stop IP addresses. +// Return value: 0 upon success, 1 upon failure. +// +// NOTE: The results are written in the following variables: +// +// (u_int32_t) tx.ip_dst_start ... contains start value +// (u_int32_t) tx.ip_dst_stop ... contains stop value +// int tx.ip_dst_isrange ... set to 1 if above values valid +// +// The other function does the same for the source address! +// +// Possible range specifications: +// +// 1) 192.168.0.0-192.168.0.12 +// 2) 10.2.11.0-10.55.13.2 +// 3) 172.18.96.0/19 +// +// That is: +// +// FIRST detect a range by scanning for the "-" OR "/" chars +// THEN determine start and stop value and store them as normal unsigned integers +// +int get_ip_range_dst (char *arg); +int get_ip_range_src (char *arg); + +// Sets a random SA for a given IP packet. +// Return value: 0 upon success, 1 upon failure +// +int set_rand_SA (libnet_t *l, libnet_ptag_t t3); + +// Scans tx.eth_dst_txt or tx.eth_src_txt and sets the corresponding +// MAC addresses (tx.eth_dst or tx.eth_src) accordingly. +// Argument: What string should be checked, ETH_SRC or ETH_DST. +// Return value: +// 0 when a MAC address has been set or +// 1 upon failure. +// Currently eth_src|dst_txt can be: +// 'rand', 'own', 'bc'|'bcast', 'stp', 'pvst', +// or a real mac address. +// +int check_eth_mac_txt(int src_or_dst); + +// Scans argument for a port number or range +// and sets the corresponding values in the +// tx struct. +// +// Arguments: sp_or_dp is either SRC_PORT or DST_PORT +// Return value: 0 on success, 1 upon failure +// +int get_port_range (int sp_or_dp, char *arg); + +// Return a 4-byte unsigned int random number +u_int32_t mz_rand32 (void); + +// Scans argument for TCP flags and sets +// tx.tcp_control accordingly. +// +// Valid keywords are: fin, syn, rst, psh, ack, urg, ecn, cwr +// Valid delimiters are: | or + or - +// Return value: 0 on success, 1 upon failure +// +int get_tcp_flags (char* flags); + +// Scans string 'params' for MPLS parameters +// and sets tx.mpls_* accordingly. +// +// CLI Syntax Examples: +// +// -M help .... shows syntax +// +// -M 800 .... label=800 +// -M 800:S .... label=800 and BOS flag set +// -M 800:S:64 .... label=800, BOS, TTL=64 +// -M 800:64:S .... same +// -M 64:77 .... label=64, TTL=77 +// -M 64:800 .... INVALID +// -M 800:64 .... label=800, TTL=64 +// -M 800:3:S:64 .... additionall the experimental bits are set (all fields required!) +// +// Note: S = BOS(1), s = NOT-BOS(0) +// +// Valid delimiters: :-.,+ +// Return value: 0 on success, 1 upon failure +int get_mpls_params(char *params); + +// Parses str for occurence of character or sequence ch. +// Returns number of occurences +int exists(char* str, char* ch); + + +// Applies another random Ethernet source address to a given Ethernet-PTAG. +// (The calling function should check 'tx.eth_src_rand' whether the SA +// should be randomized.) +int update_Eth_SA(libnet_t *l, libnet_ptag_t t); + + +// Update timestamp and sequence number in the RTP header. +// The actual RTP message is stored in tx.udp_payload. +int update_RTP(libnet_t *l, libnet_ptag_t t); + + +// Applies another SOURCE IP address, +// - either a random one (tx.ip_src_rand==1) +// - or from a specified range (tx.ip_src_isrange==1) +// to a given IP-PTAG. +// +// Note: tx.ip_src MUST be already initialized with tx.ip_src_start. +// This is done by 'get_ip_range_src()' in tools.c. +// +// RETURNS '1' if tx.ip_src restarts +int update_IP_SA (libnet_t *l, libnet_ptag_t t); + + +// Applies another DESTINATION IP address from a specified range (tx.ip_dst_isrange==1) +// to a given IP-PTAG. +// +// Note: tx.ip_dst MUST be already initialized with tx.ip_dst_start. +// This is done by 'get_ip_range_dst()' in tools.c. +// +// RETURN VALUE: '1' if tx.ip_dst restarts +int update_IP_DA(libnet_t *l, libnet_ptag_t t); + + +// Applies another DESTINATION PORT from a specified range to a given UDP- or TCP-PTAG. +// +// Note: tx.dp MUST be already initialized with tx.dp_start +// This is done by 'get_port_range()' in tools.c. +// +// RETURN VALUE: '1' if tx.dp restarts +int update_DPORT(libnet_t *l, libnet_ptag_t t); + + +// Applies another SOURCE PORT from a specified range to a given UDP- or TCP-PTAG. +// +// Note: tx.sp MUST be already initialized with tx.sp_start +// This is done by 'get_port_range()' in tools.c. +// +// RETURN VALUE: '1' if tx.sp restarts +int update_SPORT(libnet_t *l, libnet_ptag_t t); + + +// Applies another TCP SQNR from a specified range to a given TCP-PTAG +// +// RETURN VALUE: '1' if tx.txp_seq restarts +// +int update_TCP_SQNR(libnet_t *l, libnet_ptag_t t); + +int update_ISUM(libnet_t *l, libnet_ptag_t t); +int update_USUM(libnet_t *l, libnet_ptag_t t); +int update_TSUM(libnet_t *l, libnet_ptag_t t); + +// +// +int print_frame_details(void); + + +// Calculates the number of frames to be sent. +// Should be used as standard output except the +// 'quiet' option (-q) has been specified. +int complexity(void); + + +// Purpose: Calculate time deltas of two timestamps stored in struct timeval. +// Subtract the "struct timeval" values X and Y, storing the result in RESULT. +// Return 1 if the difference is negative, otherwise 0. +int timestamp_subtract (struct mz_timestamp *x, + struct mz_timestamp *y, + struct mz_timestamp *result); + +void timestamp_add (struct mz_timestamp *x, + struct mz_timestamp *y, + struct mz_timestamp *result); + +// Returns a human readable timestamp in the string result. +// Optionally a prefix can be specified, for example if the +// timestamp is part of a filename. +// +// Example: +// char myTimeStamp[128]; +// +// timestamp_human(myTimeStamp, NULL); +// +// => "20080718_155521" +// +// /* or with prefix */ +// +// timestamp_human(myTimeStamp, "MZ_RTP_jitter_"); +// +// => MZ_RTP_jitter_20080718_155521 +// +int timestamp_human(char* result, const char* prefix); + +// Returns a human readable timestamp in the string result. +// Optionally a prefix can be specified, for example if the +// timestamp is part of a filename. +// +// Example: +// char myTimeStamp[8]; +// +// timestamp_hms (myTimeStamp); +// +// => "15:55:21" +int timestamp_hms(char* result); + +// Initialize the rcv_rtp process: Read user parameters and initialize globals +int rcv_rtp_init(void); + +// Defines the pcap handler and the callback function +int rcv_rtp(void); + +// Print current RFC-Jitter on screen +void print_jitterbar (long int j, unsigned int d); + +// Compares two 4-byte variables byte by byte +// returns 0 if identical, 1 if different +int compare4B (u_int8_t *ip1, u_int8_t *ip2); + +// PURPOSE: Find usable network devices +// +// NOTE: +// +// 1. Ignores devices without IP address +// 2. Ignores loopback (etc) +// +// RETURN VALUES: +// +// 0 if usable device found (device_list[] and tx.device set) +// 1 if no usable device found +// +int lookupdev(void); + + +// For a given device name, find out the following parameters: +// +// - MTU +// - Network +// - Mask +// - Default GW (IP) +// +int get_dev_params (char *name); + +// Handler function to do something when RTP messages are received +void got_rtp_packet(u_char *args, + const struct pcap_pkthdr *header, // statistics about the packet (see 'struct pcap_pkthdr') + const u_char *packet); // the bytestring sniffed + + +// Check if current system supports the nanosecond timer functions. +// Additionally, measure the precision. +// This function should be called upon program start. +// +int check_timer(void); + +// This is the replacement for gettimeofday() which would result in 'jumps' if +// the system clock is adjusted (e. g. via a NTP process) and finally the jitter +// measurement would include wrong datapoints. +// +// Furthermore the function below utilizes the newer hi-res nanosecond timers. +void getcurtime (struct mz_timestamp *t); + +// Only print out the help text for the 02.1Q option +void print_dot1Q_help(void); + +// Determines ip and mac address of specified interface 'ifname' +// Caller must provide an unsigned char ip[4], mac[6] +// +int get_if_addr (char *ifname, unsigned char *ip, unsigned char *mac); + +// Takes filename and prepends valid configuration/logging directory +// NOTE: filename is overwritten and must be big enough to hold full path! +int getfullpath_cfg (char *filename); +int getfullpath_log (char *filename); + +// A safer replacement for strncpy which ensures \0-termination +char * mz_strncpy(char *dest, const char *src, size_t n); + +// Helper function to count the number of arguments +// in the Mausezahn argument string (comma separated args) +// RETURN VALUE: Number of arguments +int number_of_args (char *str); + +int arptable_add(struct device_struct *dev, + u_int8_t *sa, + u_int8_t *da, + u_int8_t *smac, + u_int8_t *sip, + u_int32_t sec, + u_int32_t nsec); + +// Validate ARP requests +int arpwatch(struct device_struct *dev, + u_int8_t *sa, + u_int8_t *da, + u_int8_t *smac, + u_int8_t *sip, + u_int8_t *tmac, + u_int8_t *tip, + u_int32_t sec, + u_int32_t nsec); + + +#endif -- cgit v1.2.3-54-g00ecf