blob: e1753f479d83116c5271050a03e462f149b200b9 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
#include "EPTF_Transport_PerfTest_Testcases.hh"
/*
UDP CHECKSUM CALCULATION
(see also short Description of Internet Checksum)
To calculate UDP checksum a "pseudo header" is added to the UDP header. This includes:
IP Source Address 4 bytes
IP Destination Address 4 bytes
Protocol 2 bytes
UDP Length 2 bytes
The checksum is calculated over all the octets of the pseudo header, UDP header and data.
If the data contains an odd number of octets a pad, zero octet is added to the end of data.
The pseudo header and the pad are not transmitted with the packet.
In the example code,
u16 buff[] is an array containing all the octets in the UDP header and data.
u16 len_udp is the length (number of octets) of the UDP header and data.
BOOL padding is 1 if data has an even number of octets and 0 for an odd number.
u16 src_addr[4] and u16 dest_addr[4] are the IP source and destination address octets
*/
/*
**************************************************************************
Function: udp_sum_calc()
Description: Calculate UDP checksum
***************************************************************************
*/
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned char u8;
u16 udp_sum_calc(u16 len_udp, u8 src_addr[],u8 dest_addr[], bool padding, u8 buff[])
{
u16 prot_udp=17;
u16 padd=0;
u16 word16;
u32 sum;
u32 i;
// Find out if the length of data is even or odd number. If odd,
// add a padding byte = 0 at the end of packet
if ((padding&1)==1){
padd=1;
buff[len_udp]=0;
}
//initialize sum to zero
sum=0;
// make 16 bit words out of every two adjacent 8 bit words and
// calculate the sum of all 16 vit words
for (i=0;i<len_udp+padd;i=i+2){
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
sum = sum + (unsigned long)word16;
}
// add the UDP pseudo header which contains the IP source and destinationn addresses
for (i=0;i<4;i=i+2){
word16 =((src_addr[i]<<8)&0xFF00)+(src_addr[i+1]&0xFF);
sum=sum+word16;
}
for (i=0;i<4;i=i+2){
word16 =((dest_addr[i]<<8)&0xFF00)+(dest_addr[i+1]&0xFF);
sum=sum+word16;
}
// the protocol number and the length of the UDP packet
sum = sum + prot_udp + len_udp;
// keep only the last 16 bits of the 32 bit calculated sum and add the carries
while (sum>>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// Take the one's complement of sum
sum = ~sum;
return ((u16) sum);
}
INTEGER EPTF__Transport__PerfTest__Testcases::f__calc__internetChecksum(const INTEGER& len_udp, const OCTETSTRING& src_addr, const OCTETSTRING& dest_addr, const OCTETSTRING& buff) {
return udp_sum_calc((u16)(int)len_udp, (u8*)(const unsigned char*)src_addr, (u8*)(const unsigned char*)dest_addr, buff.lengthof()%2, (u8*)(const unsigned char*)buff);
}
//--------------------------------------------------------------
//
// The following "C" code algorithm computes the checksum with an inner
// loop that sums 16-bits at a time in a 32-bit accumulator.
//
// in 6
// {
// /* Compute Internet Checksum for "count" bytes
// * beginning at location "addr".
// */
// register long sum = 0;
//
// while( count > 1 ) {
// /* This is the inner loop */
// sum += * (unsigned short) addr++;
// count -= 2;
// }
//
// /* Add left-over byte, if any */
// if( count > 0 )
// sum += * (unsigned char *) addr;
//
// /* Fold 32-bit sum to 16 bits */
// while (sum>>16)
// sum = (sum & 0xffff) + (sum >> 16);
//
// checksum = ~sum;
// }
//