summaryrefslogtreecommitdiff
path: root/staging/mops_ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'staging/mops_ip.c')
-rw-r--r--staging/mops_ip.c447
1 files changed, 447 insertions, 0 deletions
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;
+}