trafgen: parser: Add 'drnd()' function for proto fields
[netsniff-ng.git] / staging / mops_checksums.c
blobbe20f21886d8e5f9c76d3f0a9776c758c1ef70d1
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
19 #include "mz.h"
20 #include "mops.h"
25 // -- TOC: --
27 // u_int16_t mops_sum16 (u_int16_t len, u_int8_t buff[])
28 // int mops_get_transport_sum (struct mops *mp)
31 //////////////////////////////////////////////////////////////////////////////////
33 // See also:
34 //
35 // RFC1071 - Computing the Internet checksum
36 //
37 //////////////////////////////////////////////////////////////////////////////////
41 // Generic 16-bit checksum code as required for IP and other headers.
42 // The checksum is calculated over buff[] which is of length len.
44 // RETURN VALUE: The checksum! (Validated - correct!!!)
45 //
46 // Example: t16 = mops_sum16 (20, &mp->frame[fp]);
47 //
48 u_int16_t mops_sum16 (u_int16_t len, u_int8_t buff[])
51 u_int16_t word16;
52 u_int32_t sum=0;
53 u_int16_t i;
55 // make 16 bit words out of every two adjacent 8 bit words in the packet and add them up
56 for (i=0; i<len; i=i+2)
58 word16 =((buff[i]<<8)&0xFF00)+buff[i+1];
59 sum = sum + (u_int32_t) word16;
62 // take only 16 bits out of the 32 bit sum and add up the carries
63 while (sum>>16)
64 sum = (sum & 0xFFFF)+(sum >> 16);
66 // one's complement the result
67 sum = ~sum;
69 return ((u_int16_t) sum);
76 // sets UDP or TCP checksum within mp[]->frame
77 // TODO: copying the whole segment is ugly and slow;
78 // make it more efficient and realize it in-place.
79 //
80 int mops_get_transport_sum(struct mops *mp)
82 u_int8_t buf[MAX_PAYLOAD_SIZE];
83 u_int16_t len;
84 int udp_used;
86 u_int16_t sum;
88 udp_used = mp->use_UDP; // 0 or 1, 0 means TCP
90 // IP Pseudoheader (12 Bytes)
91 mops_hton4(&mp->ip_src, &buf[0]);
92 mops_hton4(&mp->ip_dst, &buf[4]);
93 buf[9]=0x00;
96 // Copy segment
97 if (udp_used)
99 buf[10]=0x11; // proto UDP (17 dec)
100 len = mp->udp_len;
101 mops_hton2(&len, &buf[11]);
102 memcpy(&buf[13], &mp->frame[mp->begin_UDP], len);
103 // reset checksum to zero
104 buf[19] = 0x00;
105 buf[20] = 0x00;
106 sum = mops_sum16(len+12, buf);
107 // insert checksum in UDP header (in frame)
108 mops_hton2 (&sum, &mp->frame[(mp->begin_UDP)+7]);
111 else
113 buf[10]=0x06; // proto TCP
114 len = mp->ip_len - mp->ip_IHL;
115 mops_hton2((u_int16_t*)&len, &buf[11]);
116 memcpy(&buf[13], &mp->frame[mp->begin_TCP], len);
117 // reset checksum to zero
118 buf[29] = 0x00;
119 buf[30] = 0x00;
120 sum = mops_sum16(len+12, buf);
121 // insert checksum in TCP header (in frame)
122 mops_hton2 (&sum, &mp->frame[(mp->begin_TCP)+17]);
126 return 0;