From d0009856814c13d13770db5aadd7b2fabf947776 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 13 May 2013 13:53:27 +0200 Subject: staging: add mausezahn staging directory After some back and forth, we decided that it is easier to maintain mausezahn in a staging directory until it is fully reworked and cleaned up to be ready to be fully integrated. This way, it is better than having it in a separate branch, and we can also accept patches from outside more easily. Also, while at it, fix up some function mismatches with libcli. Signed-off-by: Daniel Borkmann Signed-off-by: Tobias Klauser --- staging/mops_ip.c | 447 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 staging/mops_ip.c (limited to 'staging/mops_ip.c') diff --git a/staging/mops_ip.c b/staging/mops_ip.c new file mode 100644 index 0000000..46102d7 --- /dev/null +++ b/staging/mops_ip.c @@ -0,0 +1,447 @@ +/* + * 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 + * +*/ + + +#include "mz.h" +#include "mops.h" +#include "cli.h" + + +// PURPOSE +// +// Determine destination MAC address to provide direct or indirect +// delivery of IP packets, depending on which is appropriate. +// +// Doing this, the caller must provide +// 1) A pointer to the interface (within the device_list) +// 2) The destination IP address +// 3) A pointer to the destination MAC address +// +// If a Class D (multicast) address is given, a proper IEEE multicast MAC +// address is derived. +// +// EXAMPLE +// +// u_int8_t ip[4], +// mac[6]; +// +// mops_hton4 (mp->ip_src, ip); +// +// mops_ip_get_dst_mac(&device_list[0], ip, mac); +// +// RETURN VALUES +// +// 0 upon success +// 1 upon error +// +int mops_ip_get_dst_mac(struct device_struct *dev, u_int8_t *ip, u_int8_t *mac) +{ + int i; + u_int8_t dst_net[4]; + + if ((dev==NULL)||(ip==NULL)||(mac==NULL)) return 1; + + // Multicast address? + if ((0xe0 & ip[0]) == 0xe0) { + mac[0] = 0x01; + mac[1] = 0x00; + mac[2] = 0x5e; + mac[3] = ip[1] & 127; + mac[4] = ip[2]; + mac[5] = ip[3]; + return 0; + } + + // Is destination network == local network? + for (i=0; i<4; i++) { + dst_net[i] = ip[i] & (u_int8_t) dev->mask[i]; + } + + if (compare_ip(dst_net, dev->net)==0) { + // dst is on local LAN => resolve MAC! + service_arp(dev->dev, ip, mac); + } else { // dst is on a remote network => use default gw! + for (i=0; i<6; i++) mac[i] = dev->mac_gw[i]; + } + + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////////// +// +// PURPOSE +// +// Accept a DSCP specification as string argument +// and configure the IP-ToS field accordingly. +// +// EXAMPLE STRINGS +// +// AF32 .... specify AF codepoint with class 3 and drop probability 2 +// EF .... specify Expedited Forwarding +// CS7 .... specify Code Selector 7 +// 101110 .... specify the DSCP in binary +// 56 .... specify the DSCP in decimal +// +// RETURN VALUES +// +// -1 general bad argument format +// 0 upon success +// 1 Invalid AF format (Format: AFxy, e. g. af31 or AF23) +// 2 Invalid CS format +// 3 Invalid decimal DSCP value +// +int mops_ip_dscp (struct mops* mp, char *argv) +{ + int i; + char cs[4], ps[4], str[16]; + u_int8_t c=0, p=0, dscp=0; + + if (strlen(argv)==0) return -1; + strncpy(str,argv,15); + + if (strncasecmp(str, "af", 2)==0) // e.g. 'AF32' or 'af41' + { + if (strlen(str)!=4) return 1; // ERROR: Invalid AF codepoint + i=sscanf(str, "%*[afAF]%c%c", cs, ps); + cs[1]=0x00; ps[1]=0x00; + c=(u_int8_t) str2int(cs); + p=(u_int8_t) str2int(ps); + if ((c<1)||(c>4)||(p<1)||(p>3)) return 1; + // Now create correct ToS-byte representation: This is simple, since if a=3 and b=1 + // we have in binary already a=0000 0011 and b=0000 0001 and with bit-shifting we + // get the desired dscp=011 01 000 (the least signfificant three bits are always 0). + c <<=5; + p <<=3; + dscp = c | p; + } + else if (strncasecmp(str, "cs", 2)==0) // e.g. 'CS7' or 'cs4' + { + if (strlen(str)!=2) return 2; // ERROR: Invalid Code Selector + i=sscanf(str, "%*[afAF]%c", cs); + cs[1]=0x00; + c=(u_int8_t) str2int(cs); + if (c>7) return 2; + c <<=5; + dscp = c; + } + else if (mz_strcmp(str, "ef", 2)==0) // e.g. 'ef' or 'EF' + { + dscp = 0xb8; // = DSCP 46 = 101110 00 or 1011 1000 + } + else if (mz_strisbinary(str)==6) // binary, e. g. 101110 + { + for (i=0; i<6; i++) if (str[i]=='1') dscp |= ( 0x01 << (5-i) ); + dscp <<= 2; + } + else if (strlen(str)==2) // decimal DSCP value + { + if ( !(isdigit(str[0])) || !(isdigit(str[1]))) return 3; + dscp = (u_int8_t) str2int(str); + if (dscp>63) return 3; + dscp <<= 2; + } + else return -1; + + // TEST: printf("dscp=%02x\n",dscp); + mp->ip_tos = dscp; + + return 0; +} + + + + + + + + +// +// IP TOS-FIELD FORMAT +// +// MSB LSB +// 0 1 2 3 4 5 6 7 +// +-----+-----+-----+-----+-----+-----+-----+-----+ Note that the bit numbering is usually from right +// | | Del Trp Rel Cst | | to left, but here is the original pic of the RFC +// | PRECEDENCE | TOS | MBZ | 1349. Also here, the MSB is left (strangely bit 0) +// | | | | and the LSB is right (strangely bit 7). +// +-----+-----+-----+-----+-----+-----+-----+-----+ +// +// ARGUMENTS +// if unused +// ipp ... IP Precedence (0..7) or -1 +// tos ... Type of Service (0..15) or -1 +// mbz ... if 1 sets MBZ or 0 +int mops_ip_tos (struct mops* mp, int ipp, int tos, int mbz) +{ + u_int8_t TOS=0; + + if (ipp!=-1) + { + if (ipp>7) return 1; // Invalid IPP value + TOS |= (ipp << 5); + } + + if (tos!=-1) + { + if (tos>15) return 2; // Invalid ToS value + TOS |= (tos << 1); + } + + if (mbz==1) // not used if mbz is either 0 or -1 + { + TOS |= 0x01; // set + } + + mp->ip_tos = TOS; + + return 0; +} + + + +// +// +// =================== ONLY IP OPTION HANDLING FUNCTION BELOW ================ +// +/////////////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////////////// +// +// There are two cases for the format of an option: +// +// Case 1: A single octet of option-type. +// Case 2: An option-type octet, an option-length octet, and the +// actual option-data octets. +// +// The option-length octet counts the WHOLE number of bytes of the option +// +// The option-type consists of: +// +// +--------+--------+--------+--------+--------+--------+--------+--------+ +// | copied | option class | number (identifies option) | +// | flag | | | +// +--------+-----------------+--------------------------------------------+ +// +// +// The following Internet options are defined in RFC 791: +// +// CLASS NUMBER LENGTH DESCRIPTION +// ----- ------ ------ ----------- +// 0 0 - End of Option list. This option occupies only +// 1 octet; it has no length octet. +// 0 1 - No Operation. This option occupies only 1 +// octet; it has no length octet. +// 0 2 11 Security. Used to carry Security, +// Compartmentation, User Group (TCC), and +// Handling Restriction Codes compatible with DOD +// requirements. +// 0 3 var. Loose Source Routing. Used to route the +// internet datagram based on information +// supplied by the source. +// 0 9 var. Strict Source Routing. Used to route the +// internet datagram based on information +// supplied by the source. +// 0 7 var. Record Route. Used to trace the route an +// internet datagram takes. +// 0 8 4 Stream ID. Used to carry the stream +// identifier. +// 2 4 var. Internet Timestamp. +// +// +// Possible options and associated number in mp->ip_option_used +// +// 1 - Security and handling restrictions (for military applications) +// 2 - Record route +// 4 - Timestamp +// 8 - Loose source routing +// 16 - Strict source routing +// +// + +// *** See RFCs 791, 1071, 1108 *** + +// Remove all options +int mops_ip_option_remove_all (struct mops* mp) +{ + mp->ip_option_used = 0; + mp->ip_option_s = 0; + return 0; +} + + +// Add no-option +int mops_ip_option_nop (struct mops* mp) +{ + + return 0; +} + +// Add end of option list +int mops_ip_option_eol (struct mops* mp) +{ + + return 0; +} + + + +// Add loose source route option +int mops_ip_option_lsr (struct mops* mp) +{ + + return 0; +} + +// Add strict source route option +int mops_ip_option_ssr (struct mops* mp) +{ + + return 0; +} + +// Add record route option +int mops_ip_option_rr (struct mops* mp) +{ + + return 0; +} + +// Add time stamp option +int mops_ip_option_ts (struct mops* mp) +{ + + return 0; +} + + + +// Add security option. +// +// This option provides a way for hosts to send security, compartmentation, +// handling restrictions, and TCC (closed user group) parameters. The format +// for this option is as follows: +// +// +--------+--------+---//---+---//---+---//---+---//---+ +// |10000010|00001011|SSS SSS|CCC CCC|HHH HHH| TCC | +// +--------+--------+---//---+---//---+---//---+---//---+ +// Type=130 Length=11 +// +// Security (S field): 16 bits +// +// Specifies one of 16 levels of security (eight of which are +// reserved for future use). +// +// 00000000 00000000 - Unclassified +// 11110001 00110101 - Confidential +// 01111000 10011010 - EFTO +// 10111100 01001101 - MMMM +// 01011110 00100110 - PROG +// 10101111 00010011 - Restricted +// 11010111 10001000 - Secret +// 01101011 11000101 - Top Secret +// 00110101 11100010 - (Reserved for future use) +// 10011010 11110001 - (Reserved for future use) +// 01001101 01111000 - (Reserved for future use) +// 00100100 10111101 - (Reserved for future use) +// 00010011 01011110 - (Reserved for future use) +// 10001001 10101111 - (Reserved for future use) +// 11000100 11010110 - (Reserved for future use) +// 11100010 01101011 - (Reserved for future use) +// +// +// Compartments (C field): 16 bits +// +// An all zero value is used when the information transmitted is not +// compartmented. Other values for the compartments field may be obtained +// from the Defense Intelligence Agency. +// +// Handling Restrictions (H field): 16 bits +// +// The values for the control and release markings are alphanumeric digraphs +// and are defined in the Defense Intelligence Agency Manual DIAM 65-19, +// "Standard Security Markings". +// +// Transmission Control Code (TCC field): 24 bits +// +// Provides a means to segregate traffic and define controlled communities +// of interest among subscribers. The TCC values are trigraphs, and are available +// from HQ DCA Code 530. +// +// Must be copied on fragmentation. This option appears at most +// once in a datagram. + +int mops_ip_option_sec (struct mops* mp) +{ + + return 0; +} + + +// Add the IP Router Alert Option - a method to efficiently signal +// transit routers to more closely examine the contents of an IP packet. +// See RFC 2113, and FYI also 3175 (RSVP Aggregation), and RFC 5350 +// (new IANA-defined Router Alert Options (RAO)). +// +// The Router Alert option has the following format: +// +// +--------+--------+--------+--------+ +// |10010100|00000100| 2 octet value | +// +--------+--------+--------+--------+ +// +// Type: +// Copied flag: 1 (all fragments must carry the option) +// Option class: 0 (control) +// Option number: 20 (decimal) +// +// Length: 4 +// +// Value: A two octet code with the following values: +// 0 - Router shall examine packet +// 1-65535 - Reserved +// +// RETURN VALUE: 0 upon success +// 1 upon failure +// +int mops_ip_option_ra (struct mops* mp, int value) +{ + int ptr; + u_int16_t val; + + if ((mp==NULL) || (value>0xffff)) return 1; + + val = (u_int16_t) value; + + ptr = mp->ip_option_s; // add option at the end of existing option list (if any) + mp->ip_option_used=20; + + // create option header + mp->ip_option[ptr] = 0x94; + + ptr++; + mp->ip_option[ptr] = 0x04; + + ptr++; + mops_hton2 (&val, &mp->ip_option[ptr]); + ptr+=2; + mp->ip_option_s=4; + + return 0; +} -- cgit v1.2.3-54-g00ecf