flowtop: make function nested
[netsniff-ng.git] / src / mops_ip.c
blob46102d757def3c9470eecb031c9634f5ce4d51be
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
4 *
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.
8 *
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
12 * details.
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
20 #include "mz.h"
21 #include "mops.h"
22 #include "cli.h"
25 // PURPOSE
26 //
27 // Determine destination MAC address to provide direct or indirect
28 // delivery of IP packets, depending on which is appropriate.
29 //
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.
37 //
38 // EXAMPLE
39 //
40 // u_int8_t ip[4],
41 // mac[6];
42 //
43 // mops_hton4 (mp->ip_src, ip);
44 //
45 // mops_ip_get_dst_mac(&device_list[0], ip, mac);
46 //
47 // RETURN VALUES
48 //
49 // 0 upon success
50 // 1 upon error
51 //
52 int mops_ip_get_dst_mac(struct device_struct *dev, u_int8_t *ip, u_int8_t *mac)
54 int i;
55 u_int8_t dst_net[4];
57 if ((dev==NULL)||(ip==NULL)||(mac==NULL)) return 1;
59 // Multicast address?
60 if ((0xe0 & ip[0]) == 0xe0) {
61 mac[0] = 0x01;
62 mac[1] = 0x00;
63 mac[2] = 0x5e;
64 mac[3] = ip[1] & 127;
65 mac[4] = ip[2];
66 mac[5] = ip[3];
67 return 0;
70 // Is destination network == local network?
71 for (i=0; i<4; i++) {
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];
82 return 0;
86 ///////////////////////////////////////////////////////////////////////////////////
88 // PURPOSE
90 // Accept a DSCP specification as string argument
91 // and configure the IP-ToS field accordingly.
92 //
93 // EXAMPLE STRINGS
94 //
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
101 // RETURN VALUES
103 // -1 general bad argument format
104 // 0 upon success
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)
111 int i;
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).
129 c <<=5;
130 p <<=3;
131 dscp = c | p;
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);
137 cs[1]=0x00;
138 c=(u_int8_t) str2int(cs);
139 if (c>7) return 2;
140 c <<=5;
141 dscp = c;
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) );
150 dscp <<= 2;
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;
157 dscp <<= 2;
159 else return -1;
161 // TEST: printf("dscp=%02x\n",dscp);
162 mp->ip_tos = dscp;
164 return 0;
175 // IP TOS-FIELD FORMAT
177 // MSB LSB
178 // 0 1 2 3 4 5 6 7
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 // +-----+-----+-----+-----+-----+-----+-----+-----+
185 // ARGUMENTS
186 // if unused
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)
192 u_int8_t TOS=0;
194 if (ipp!=-1)
196 if (ipp>7) return 1; // Invalid IPP value
197 TOS |= (ipp << 5);
200 if (tos!=-1)
202 if (tos>15) return 2; // Invalid ToS value
203 TOS |= (tos << 1);
206 if (mbz==1) // not used if mbz is either 0 or -1
208 TOS |= 0x01; // set
211 mp->ip_tos = TOS;
213 return 0;
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) |
240 // | flag | | |
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
255 // requirements.
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
265 // identifier.
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)
272 // 2 - Record route
273 // 4 - Timestamp
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;
285 mp->ip_option_s = 0;
286 return 0;
290 // Add no-option
291 int mops_ip_option_nop (struct mops* mp)
294 return 0;
297 // Add end of option list
298 int mops_ip_option_eol (struct mops* mp)
301 return 0;
306 // Add loose source route option
307 int mops_ip_option_lsr (struct mops* mp)
310 return 0;
313 // Add strict source route option
314 int mops_ip_option_ssr (struct mops* mp)
317 return 0;
320 // Add record route option
321 int mops_ip_option_rr (struct mops* mp)
324 return 0;
327 // Add time stamp option
328 int mops_ip_option_ts (struct mops* mp)
331 return 0;
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)
394 return 0;
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 // +--------+--------+--------+--------+
409 // Type:
410 // Copied flag: 1 (all fragments must carry the option)
411 // Option class: 0 (control)
412 // Option number: 20 (decimal)
414 // Length: 4
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
421 // 1 upon failure
423 int mops_ip_option_ra (struct mops* mp, int value)
425 int ptr;
426 u_int16_t val;
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;
438 ptr++;
439 mp->ip_option[ptr] = 0x04;
441 ptr++;
442 mops_hton2 (&val, &mp->ip_option[ptr]);
443 ptr+=2;
444 mp->ip_option_s=4;
446 return 0;