iPXE
Data Structures | Macros | Functions | Variables
tcpip_test.c File Reference

TCP/IP self-tests. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ipxe/test.h>
#include <ipxe/profile.h>
#include <ipxe/tcpip.h>

Go to the source code of this file.

Data Structures

struct  tcpip_test
 A TCP/IP fixed-data test. More...
 
struct  tcpip_random_test
 A TCP/IP pseudorandom-data test. More...
 

Macros

#define PROFILE_COUNT   16
 Number of sample iterations for profiling. More...
 
#define DATA(...)   { __VA_ARGS__ }
 Define inline data. More...
 
#define TCPIP_TEST(name, DATA)
 Define a TCP/IP fixed-data test. More...
 
#define TCPIP_RANDOM_TEST(name, SEED, LEN, OFFSET)
 Define a TCP/IP pseudorandom-data test. More...
 
#define tcpip_ok(test)   tcpip_okx ( test, __FILE__, __LINE__ )
 
#define tcpip_random_ok(test)   tcpip_random_okx ( test, __FILE__, __LINE__ )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 TCPIP_TEST (empty, DATA())
 Empty data. More...
 
 TCPIP_TEST (one_byte, DATA(0xeb))
 Single byte. More...
 
 TCPIP_TEST (two_bytes, DATA(0xba, 0xbe))
 Double byte. More...
 
 TCPIP_TEST (positive_zero, DATA(0x00, 0x00))
 Positive zero data. More...
 
 TCPIP_TEST (negative_zero, DATA(0xff, 0xff))
 Negative zero data. More...
 
 TCPIP_TEST (final_carry_big, DATA(0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01))
 Final wrap-around carry (big-endian) More...
 
 TCPIP_TEST (final_carry_little, DATA(0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00))
 Final wrap-around carry (little-endian) More...
 
 TCPIP_RANDOM_TEST (random_aligned, 0x12345678UL, 4096, 0)
 Random data (aligned) More...
 
 TCPIP_RANDOM_TEST (random_unaligned_1, 0x12345678UL, 4096, 1)
 Random data (unaligned, +1) More...
 
 TCPIP_RANDOM_TEST (random_unaligned_2, 0x12345678UL, 4096, 2)
 Random data (unaligned, +2) More...
 
 TCPIP_RANDOM_TEST (random_aligned_truncated, 0x12345678UL, 4095, 0)
 Random data (aligned, truncated) More...
 
 TCPIP_RANDOM_TEST (partial, 0xcafebabe, 121, 5)
 Random data (unaligned start and finish) More...
 
static uint16_t rfc_tcpip_chksum (const void *data, size_t len)
 Calculate TCP/IP checksum. More...
 
static void tcpip_okx (struct tcpip_test *test, const char *file, unsigned int line)
 Report TCP/IP fixed-data test result. More...
 
static void tcpip_random_okx (struct tcpip_random_test *test, const char *file, unsigned int line)
 Report TCP/IP pseudorandom-data test result. More...
 
static void tcpip_test_exec (void)
 Perform TCP/IP self-tests. More...
 

Variables

static uint8_t tcpip_data [4096+7]
 Buffer for pseudorandom-data tests. More...
 
struct self_test tcpip_test __self_test
 TCP/IP self-test. More...
 

Detailed Description

TCP/IP self-tests.

Definition in file tcpip_test.c.

Macro Definition Documentation

◆ PROFILE_COUNT

#define PROFILE_COUNT   16

Number of sample iterations for profiling.

Definition at line 44 of file tcpip_test.c.

◆ DATA

#define DATA (   ...)    { __VA_ARGS__ }

Define inline data.

Definition at line 65 of file tcpip_test.c.

◆ TCPIP_TEST

#define TCPIP_TEST (   name,
  DATA 
)
Value:
static const uint8_t __attribute__ (( aligned ( 16 ) )) \
name ## _data[] = DATA; \
static struct tcpip_test name = { \
.data = name ## _data, \
.len = sizeof ( name ## _data ), \
}
#define __attribute__(x)
Definition: compiler.h:10
const char * name
Definition: ath9k_hw.c:1984
A TCP/IP fixed-data test.
Definition: tcpip_test.c:47
unsigned char uint8_t
Definition: stdint.h:10
#define DATA(...)
Define inline data.
Definition: tcpip_test.c:65

Define a TCP/IP fixed-data test.

Definition at line 68 of file tcpip_test.c.

◆ TCPIP_RANDOM_TEST

#define TCPIP_RANDOM_TEST (   name,
  SEED,
  LEN,
  OFFSET 
)
Value:
static struct tcpip_random_test name = { \
.seed = SEED, \
.len = LEN, \
.offset = OFFSET, \
}
const char * name
Definition: ath9k_hw.c:1984
A TCP/IP pseudorandom-data test.
Definition: tcpip_test.c:55

Define a TCP/IP pseudorandom-data test.

Definition at line 77 of file tcpip_test.c.

◆ tcpip_ok

#define tcpip_ok (   test)    tcpip_okx ( test, __FILE__, __LINE__ )

Definition at line 186 of file tcpip_test.c.

◆ tcpip_random_ok

#define tcpip_random_ok (   test)    tcpip_random_okx ( test, __FILE__, __LINE__ )

Definition at line 234 of file tcpip_test.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ TCPIP_TEST() [1/7]

TCPIP_TEST ( empty  ,
DATA()   
)

Empty data.

◆ TCPIP_TEST() [2/7]

TCPIP_TEST ( one_byte  ,
DATA(0xeb)   
)

Single byte.

◆ TCPIP_TEST() [3/7]

TCPIP_TEST ( two_bytes  ,
DATA(0xba, 0xbe)   
)

Double byte.

◆ TCPIP_TEST() [4/7]

TCPIP_TEST ( positive_zero  ,
DATA(0x00, 0x00)   
)

Positive zero data.

◆ TCPIP_TEST() [5/7]

TCPIP_TEST ( negative_zero  ,
DATA(0xff, 0xff)   
)

Negative zero data.

◆ TCPIP_TEST() [6/7]

TCPIP_TEST ( final_carry_big  ,
DATA(0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)   
)

Final wrap-around carry (big-endian)

◆ TCPIP_TEST() [7/7]

TCPIP_TEST ( final_carry_little  ,
DATA(0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00)   
)

Final wrap-around carry (little-endian)

◆ TCPIP_RANDOM_TEST() [1/5]

TCPIP_RANDOM_TEST ( random_aligned  ,
0x12345678UL  ,
4096  ,
 
)

Random data (aligned)

◆ TCPIP_RANDOM_TEST() [2/5]

TCPIP_RANDOM_TEST ( random_unaligned_1  ,
0x12345678UL  ,
4096  ,
 
)

Random data (unaligned, +1)

◆ TCPIP_RANDOM_TEST() [3/5]

TCPIP_RANDOM_TEST ( random_unaligned_2  ,
0x12345678UL  ,
4096  ,
 
)

Random data (unaligned, +2)

◆ TCPIP_RANDOM_TEST() [4/5]

TCPIP_RANDOM_TEST ( random_aligned_truncated  ,
0x12345678UL  ,
4095  ,
 
)

Random data (aligned, truncated)

◆ TCPIP_RANDOM_TEST() [5/5]

TCPIP_RANDOM_TEST ( partial  ,
0xcafebabe  ,
121  ,
 
)

Random data (unaligned start and finish)

◆ rfc_tcpip_chksum()

static uint16_t rfc_tcpip_chksum ( const void *  data,
size_t  len 
)
static

Calculate TCP/IP checksum.

Parameters
dataData to sum
lenLength of data
Return values
cksumChecksum

This is a reference implementation taken from RFC1071 (and modified to fix compilation without warnings under gcc).

The initial value of the one's complement sum is changed from positive zero (0x0000) to negative zero (0xffff). This ensures that the return value will always use the positive representation of zero (0x0000). Without this change, the return value would use negative zero (0xffff) if the input data is zero length (or all zeros) but positive zero (0x0000) for any other data which sums to zero.

Definition at line 144 of file tcpip_test.c.

144  {
145  unsigned long sum = 0xffff;
146 
147  while ( len > 1 ) {
148  sum += *( ( uint16_t * ) data );
149  data += 2;
150  len -= 2;
151  }
152 
153  if ( len > 0 )
154  sum += *( ( uint8_t * ) data );
155 
156  while ( sum >> 16 )
157  sum = ( ( sum & 0xffff ) + ( sum >> 16 ) );
158 
159  assert ( sum != 0x0000 );
160  return ~sum;
161 }
unsigned short uint16_t
Definition: stdint.h:11
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned char uint8_t
Definition: stdint.h:10
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t len
Length.
Definition: ena.h:14

References assert(), data, and len.

Referenced by tcpip_okx(), and tcpip_random_okx().

◆ tcpip_okx()

static void tcpip_okx ( struct tcpip_test test,
const char *  file,
unsigned int  line 
)
static

Report TCP/IP fixed-data test result.

Parameters
testTCP/IP test
fileTest code file
lineTest code line

Definition at line 170 of file tcpip_test.c.

171  {
172  uint16_t expected;
173  uint16_t generic_sum;
174  uint16_t sum;
175 
176  /* Verify generic_tcpip_continue_chksum() result */
177  expected = rfc_tcpip_chksum ( test->data, test->len );
179  test->data, test->len );
180  okx ( generic_sum == expected, file, line );
181 
182  /* Verify optimised tcpip_continue_chksum() result */
183  sum = tcpip_continue_chksum ( TCPIP_EMPTY_CSUM, test->data, test->len );
184  okx ( sum == expected, file, line );
185 }
unsigned short uint16_t
Definition: stdint.h:11
uint16_t generic_tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: tcpip.c:170
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition: tcpip.h:57
static uint16_t rfc_tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checksum.
Definition: tcpip_test.c:144
#define okx(success, file, line)
Report test result.
Definition: test.h:44
static int test
Definition: epic100.c:73
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: x86_tcpip.c:45

References generic_tcpip_continue_chksum(), okx, rfc_tcpip_chksum(), tcpip_continue_chksum(), TCPIP_EMPTY_CSUM, and test.

◆ tcpip_random_okx()

static void tcpip_random_okx ( struct tcpip_random_test test,
const char *  file,
unsigned int  line 
)
static

Report TCP/IP pseudorandom-data test result.

Parameters
testTCP/IP test
fileTest code file
lineTest code line

Definition at line 195 of file tcpip_test.c.

196  {
197  uint8_t *data = ( tcpip_data + test->offset );
198  struct profiler profiler;
199  uint16_t expected;
200  uint16_t generic_sum;
201  uint16_t sum;
202  unsigned int i;
203 
204  /* Sanity check */
205  assert ( ( test->len + test->offset ) <= sizeof ( tcpip_data ) );
206 
207  /* Generate random data */
208  srandom ( test->seed );
209  for ( i = 0 ; i < test->len ; i++ )
210  data[i] = random();
211 
212  /* Verify generic_tcpip_continue_chksum() result */
213  expected = rfc_tcpip_chksum ( data, test->len );
215  data, test->len );
216  okx ( generic_sum == expected, file, line );
217 
218  /* Verify optimised tcpip_continue_chksum() result */
220  okx ( sum == expected, file, line );
221 
222  /* Profile optimised calculation */
223  memset ( &profiler, 0, sizeof ( profiler ) );
224  for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
225  profile_start ( &profiler );
227  test->len );
228  profile_stop ( &profiler );
229  }
230  DBG ( "TCPIP checksummed %zd bytes (+%zd) in %ld +/- %ld ticks\n",
231  test->len, test->offset, profile_mean ( &profiler ),
232  profile_stddev ( &profiler ) );
233 }
unsigned long profile_mean(struct profiler *profiler)
Get mean sample value.
Definition: profile.c:241
unsigned short uint16_t
Definition: stdint.h:11
uint16_t generic_tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: tcpip.c:170
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition: tcpip.h:57
static uint16_t rfc_tcpip_chksum(const void *data, size_t len)
Calculate TCP/IP checksum.
Definition: tcpip_test.c:144
A data structure for storing profiling information.
Definition: profile.h:26
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:173
unsigned long profile_stddev(struct profiler *profiler)
Get sample standard deviation.
Definition: profile.c:275
void srandom(unsigned int seed)
Seed the pseudo-random number generator.
Definition: random.c:20
#define okx(success, file, line)
Report test result.
Definition: test.h:44
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:160
static uint8_t tcpip_data[4096+7]
Buffer for pseudorandom-data tests.
Definition: tcpip_test.c:86
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define PROFILE_COUNT
Number of sample iterations for profiling.
Definition: tcpip_test.c:44
static int test
Definition: epic100.c:73
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition: x86_tcpip.c:45
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), data, DBG, generic_tcpip_continue_chksum(), memset(), okx, PROFILE_COUNT, profile_mean(), profile_start(), profile_stddev(), profile_stop(), random(), rfc_tcpip_chksum(), srandom(), tcpip_continue_chksum(), tcpip_data, TCPIP_EMPTY_CSUM, and test.

◆ tcpip_test_exec()

static void tcpip_test_exec ( void  )
static

Perform TCP/IP self-tests.

Definition at line 240 of file tcpip_test.c.

240  {
241 
242  tcpip_ok ( &empty );
243  tcpip_ok ( &one_byte );
244  tcpip_ok ( &two_bytes );
245  tcpip_ok ( &positive_zero );
246  tcpip_ok ( &negative_zero );
247  tcpip_ok ( &final_carry_big );
248  tcpip_ok ( &final_carry_little );
249  tcpip_random_ok ( &random_aligned );
250  tcpip_random_ok ( &random_unaligned_1 );
251  tcpip_random_ok ( &random_unaligned_2 );
252  tcpip_random_ok ( &random_aligned_truncated );
253  tcpip_random_ok ( &partial );
254 }
#define tcpip_ok(test)
Definition: tcpip_test.c:186
#define tcpip_random_ok(test)
Definition: tcpip_test.c:234

References tcpip_ok, and tcpip_random_ok.

Variable Documentation

◆ tcpip_data

uint8_t tcpip_data[4096+7]
static

Buffer for pseudorandom-data tests.

Definition at line 86 of file tcpip_test.c.

Referenced by tcpip_random_okx().

◆ __self_test

struct self_test tcpip_test __self_test
Initial value:
= {
.name = "tcpip",
.exec = tcpip_test_exec,
}
static void tcpip_test_exec(void)
Perform TCP/IP self-tests.
Definition: tcpip_test.c:240

TCP/IP self-test.

Definition at line 257 of file tcpip_test.c.