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
27 // Determine destination MAC address to provide direct or indirect
28 // delivery of IP packets, depending on which is appropriate.
30 // Doing this, the caller must provide
31 // 1) A pointer to the interface (within the device_list)
32 // 2) The destination IP address
33 // 3) A pointer to the destination MAC address
35 // If a Class D (multicast) address is given, a proper IEEE multicast MAC
36 // address is derived.
43 // mops_hton4 (mp->ip_src, ip);
45 // mops_ip_get_dst_mac(&device_list[0], ip, mac);
52 int mops_ip_get_dst_mac(struct device_struct
*dev
, u_int8_t
*ip
, u_int8_t
*mac
)
57 if ((dev
==NULL
)||(ip
==NULL
)||(mac
==NULL
)) return 1;
60 if ((0xe0 & ip
[0]) == 0xe0) {
70 // Is destination network == local network?
72 dst_net
[i
] = ip
[i
] & (u_int8_t
) dev
->mask
[i
];
75 if (compare_ip(dst_net
, dev
->net
)==0) {
76 // dst is on local LAN => resolve MAC!
77 service_arp(dev
->dev
, ip
, mac
);
78 } else { // dst is on a remote network => use default gw!
79 for (i
=0; i
<6; i
++) mac
[i
] = dev
->mac_gw
[i
];
86 ///////////////////////////////////////////////////////////////////////////////////
90 // Accept a DSCP specification as string argument
91 // and configure the IP-ToS field accordingly.
95 // AF32 .... specify AF codepoint with class 3 and drop probability 2
96 // EF .... specify Expedited Forwarding
97 // CS7 .... specify Code Selector 7
98 // 101110 .... specify the DSCP in binary
99 // 56 .... specify the DSCP in decimal
103 // -1 general bad argument format
105 // 1 Invalid AF format (Format: AFxy, e. g. af31 or AF23)
106 // 2 Invalid CS format
107 // 3 Invalid decimal DSCP value
109 int mops_ip_dscp (struct mops
* mp
, char *argv
)
112 char cs
[4], ps
[4], str
[16];
113 u_int8_t c
=0, p
=0, dscp
=0;
115 if (strlen(argv
)==0) return -1;
116 strncpy(str
,argv
,15);
118 if (strncasecmp(str
, "af", 2)==0) // e.g. 'AF32' or 'af41'
120 if (strlen(str
)!=4) return 1; // ERROR: Invalid AF codepoint
121 i
=sscanf(str
, "%*[afAF]%c%c", cs
, ps
);
122 cs
[1]=0x00; ps
[1]=0x00;
123 c
=(u_int8_t
) str2int(cs
);
124 p
=(u_int8_t
) str2int(ps
);
125 if ((c
<1)||(c
>4)||(p
<1)||(p
>3)) return 1;
126 // Now create correct ToS-byte representation: This is simple, since if a=3 and b=1
127 // we have in binary already a=0000 0011 and b=0000 0001 and with bit-shifting we
128 // get the desired dscp=011 01 000 (the least signfificant three bits are always 0).
133 else if (strncasecmp(str
, "cs", 2)==0) // e.g. 'CS7' or 'cs4'
135 if (strlen(str
)!=2) return 2; // ERROR: Invalid Code Selector
136 i
=sscanf(str
, "%*[afAF]%c", cs
);
138 c
=(u_int8_t
) str2int(cs
);
143 else if (mz_strcmp(str
, "ef", 2)==0) // e.g. 'ef' or 'EF'
145 dscp
= 0xb8; // = DSCP 46 = 101110 00 or 1011 1000
147 else if (mz_strisbinary(str
)==6) // binary, e. g. 101110
149 for (i
=0; i
<6; i
++) if (str
[i
]=='1') dscp
|= ( 0x01 << (5-i
) );
152 else if (strlen(str
)==2) // decimal DSCP value
154 if ( !(isdigit(str
[0])) || !(isdigit(str
[1]))) return 3;
155 dscp
= (u_int8_t
) str2int(str
);
156 if (dscp
>63) return 3;
161 // TEST: printf("dscp=%02x\n",dscp);
175 // IP TOS-FIELD FORMAT
179 // +-----+-----+-----+-----+-----+-----+-----+-----+ Note that the bit numbering is usually from right
180 // | | Del Trp Rel Cst | | to left, but here is the original pic of the RFC
181 // | PRECEDENCE | TOS | MBZ | 1349. Also here, the MSB is left (strangely bit 0)
182 // | | | | and the LSB is right (strangely bit 7).
183 // +-----+-----+-----+-----+-----+-----+-----+-----+
187 // ipp ... IP Precedence (0..7) or -1
188 // tos ... Type of Service (0..15) or -1
189 // mbz ... if 1 sets MBZ or 0
190 int mops_ip_tos (struct mops
* mp
, int ipp
, int tos
, int mbz
)
196 if (ipp
>7) return 1; // Invalid IPP value
202 if (tos
>15) return 2; // Invalid ToS value
206 if (mbz
==1) // not used if mbz is either 0 or -1
220 // =================== ONLY IP OPTION HANDLING FUNCTION BELOW ================
222 ///////////////////////////////////////////////////////////////////////////////
226 ///////////////////////////////////////////////////////////////////////////////
228 // There are two cases for the format of an option:
230 // Case 1: A single octet of option-type.
231 // Case 2: An option-type octet, an option-length octet, and the
232 // actual option-data octets.
234 // The option-length octet counts the WHOLE number of bytes of the option
236 // The option-type consists of:
238 // +--------+--------+--------+--------+--------+--------+--------+--------+
239 // | copied | option class | number (identifies option) |
241 // +--------+-----------------+--------------------------------------------+
244 // The following Internet options are defined in RFC 791:
246 // CLASS NUMBER LENGTH DESCRIPTION
247 // ----- ------ ------ -----------
248 // 0 0 - End of Option list. This option occupies only
249 // 1 octet; it has no length octet.
250 // 0 1 - No Operation. This option occupies only 1
251 // octet; it has no length octet.
252 // 0 2 11 Security. Used to carry Security,
253 // Compartmentation, User Group (TCC), and
254 // Handling Restriction Codes compatible with DOD
256 // 0 3 var. Loose Source Routing. Used to route the
257 // internet datagram based on information
258 // supplied by the source.
259 // 0 9 var. Strict Source Routing. Used to route the
260 // internet datagram based on information
261 // supplied by the source.
262 // 0 7 var. Record Route. Used to trace the route an
263 // internet datagram takes.
264 // 0 8 4 Stream ID. Used to carry the stream
266 // 2 4 var. Internet Timestamp.
269 // Possible options and associated number in mp->ip_option_used
271 // 1 - Security and handling restrictions (for military applications)
274 // 8 - Loose source routing
275 // 16 - Strict source routing
279 // *** See RFCs 791, 1071, 1108 ***
281 // Remove all options
282 int mops_ip_option_remove_all (struct mops
* mp
)
284 mp
->ip_option_used
= 0;
291 int mops_ip_option_nop (struct mops
* mp
)
297 // Add end of option list
298 int mops_ip_option_eol (struct mops
* mp
)
306 // Add loose source route option
307 int mops_ip_option_lsr (struct mops
* mp
)
313 // Add strict source route option
314 int mops_ip_option_ssr (struct mops
* mp
)
320 // Add record route option
321 int mops_ip_option_rr (struct mops
* mp
)
327 // Add time stamp option
328 int mops_ip_option_ts (struct mops
* mp
)
336 // Add security option.
338 // This option provides a way for hosts to send security, compartmentation,
339 // handling restrictions, and TCC (closed user group) parameters. The format
340 // for this option is as follows:
342 // +--------+--------+---//---+---//---+---//---+---//---+
343 // |10000010|00001011|SSS SSS|CCC CCC|HHH HHH| TCC |
344 // +--------+--------+---//---+---//---+---//---+---//---+
345 // Type=130 Length=11
347 // Security (S field): 16 bits
349 // Specifies one of 16 levels of security (eight of which are
350 // reserved for future use).
352 // 00000000 00000000 - Unclassified
353 // 11110001 00110101 - Confidential
354 // 01111000 10011010 - EFTO
355 // 10111100 01001101 - MMMM
356 // 01011110 00100110 - PROG
357 // 10101111 00010011 - Restricted
358 // 11010111 10001000 - Secret
359 // 01101011 11000101 - Top Secret
360 // 00110101 11100010 - (Reserved for future use)
361 // 10011010 11110001 - (Reserved for future use)
362 // 01001101 01111000 - (Reserved for future use)
363 // 00100100 10111101 - (Reserved for future use)
364 // 00010011 01011110 - (Reserved for future use)
365 // 10001001 10101111 - (Reserved for future use)
366 // 11000100 11010110 - (Reserved for future use)
367 // 11100010 01101011 - (Reserved for future use)
370 // Compartments (C field): 16 bits
372 // An all zero value is used when the information transmitted is not
373 // compartmented. Other values for the compartments field may be obtained
374 // from the Defense Intelligence Agency.
376 // Handling Restrictions (H field): 16 bits
378 // The values for the control and release markings are alphanumeric digraphs
379 // and are defined in the Defense Intelligence Agency Manual DIAM 65-19,
380 // "Standard Security Markings".
382 // Transmission Control Code (TCC field): 24 bits
384 // Provides a means to segregate traffic and define controlled communities
385 // of interest among subscribers. The TCC values are trigraphs, and are available
386 // from HQ DCA Code 530.
388 // Must be copied on fragmentation. This option appears at most
389 // once in a datagram.
391 int mops_ip_option_sec (struct mops
* mp
)
398 // Add the IP Router Alert Option - a method to efficiently signal
399 // transit routers to more closely examine the contents of an IP packet.
400 // See RFC 2113, and FYI also 3175 (RSVP Aggregation), and RFC 5350
401 // (new IANA-defined Router Alert Options (RAO)).
403 // The Router Alert option has the following format:
405 // +--------+--------+--------+--------+
406 // |10010100|00000100| 2 octet value |
407 // +--------+--------+--------+--------+
410 // Copied flag: 1 (all fragments must carry the option)
411 // Option class: 0 (control)
412 // Option number: 20 (decimal)
416 // Value: A two octet code with the following values:
417 // 0 - Router shall examine packet
418 // 1-65535 - Reserved
420 // RETURN VALUE: 0 upon success
423 int mops_ip_option_ra (struct mops
* mp
, int value
)
428 if ((mp
==NULL
) || (value
>0xffff)) return 1;
430 val
= (u_int16_t
) value
;
432 ptr
= mp
->ip_option_s
; // add option at the end of existing option list (if any)
433 mp
->ip_option_used
=20;
435 // create option header
436 mp
->ip_option
[ptr
] = 0x94;
439 mp
->ip_option
[ptr
] = 0x04;
442 mops_hton2 (&val
, &mp
->ip_option
[ptr
]);