iPXE
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.
#define DATA(...)
 Define inline data.
#define TCPIP_TEST(name, DATA)
 Define a TCP/IP fixed-data test.
#define TCPIP_RANDOM_TEST(name, SEED, LEN, OFFSET)
 Define a TCP/IP pseudorandom-data test.
#define tcpip_ok(test)
#define tcpip_random_ok(test)

Functions

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

Variables

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

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 ( ...)
Value:
{ __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 DATA(...)
Define inline data.
Definition acpi_test.c:74
unsigned char uint8_t
Definition stdint.h:10
const char * name
Definition ath9k_hw.c:1986
#define __attribute__(x)
Definition compiler.h:10
A TCP/IP fixed-data test.
Definition tcpip_test.c:47

Define a TCP/IP fixed-data test.

Definition at line 68 of file tcpip_test.c.

68#define TCPIP_TEST( name, DATA ) \
69 static const uint8_t __attribute__ (( aligned ( 16 ) )) \
70 name ## _data[] = DATA; \
71 static struct tcpip_test name = { \
72 .data = name ## _data, \
73 .len = sizeof ( name ## _data ), \
74 }

Referenced by TCPIP_TEST(), TCPIP_TEST(), TCPIP_TEST(), TCPIP_TEST(), TCPIP_TEST(), TCPIP_TEST(), and TCPIP_TEST().

◆ TCPIP_RANDOM_TEST

#define TCPIP_RANDOM_TEST ( name,
SEED,
LEN,
OFFSET )
Value:
static struct tcpip_random_test name = { \
.seed = SEED, \
.len = LEN, \
.offset = OFFSET, \
}
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.

77#define TCPIP_RANDOM_TEST( name, SEED, LEN, OFFSET ) \
78 static struct tcpip_random_test name = { \
79 .seed = SEED, \
80 .len = LEN, \
81 .offset = OFFSET, \
82 }

Referenced by TCPIP_RANDOM_TEST(), TCPIP_RANDOM_TEST(), TCPIP_RANDOM_TEST(), TCPIP_RANDOM_TEST(), and TCPIP_RANDOM_TEST().

◆ tcpip_ok

#define tcpip_ok ( test)
Value:
tcpip_okx ( test, __FILE__, __LINE__ )
static int test
Definition epic100.c:73
static void tcpip_okx(struct tcpip_test *test, const char *file, unsigned int line)
Report TCP/IP fixed-data test result.
Definition tcpip_test.c:170

Definition at line 186 of file tcpip_test.c.

Referenced by tcpip_test_exec().

◆ tcpip_random_ok

#define tcpip_random_ok ( test)
Value:
tcpip_random_okx ( test, __FILE__, __LINE__ )
static void tcpip_random_okx(struct tcpip_random_test *test, const char *file, unsigned int line)
Report TCP/IP pseudorandom-data test result.
Definition tcpip_test.c:195

Definition at line 234 of file tcpip_test.c.

Referenced by tcpip_test_exec().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ TCPIP_TEST() [1/7]

TCPIP_TEST ( empty ,
DATA()  )

Empty data.

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [2/7]

TCPIP_TEST ( one_byte ,
DATA(0xeb)  )

Single byte.

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [3/7]

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

Double byte.

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [4/7]

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

Positive zero data.

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [5/7]

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

Negative zero data.

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [6/7]

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

Final wrap-around carry (big-endian)

References DATA, and TCPIP_TEST.

◆ TCPIP_TEST() [7/7]

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

Final wrap-around carry (little-endian)

References DATA, and TCPIP_TEST.

◆ TCPIP_RANDOM_TEST() [1/5]

TCPIP_RANDOM_TEST ( random_aligned ,
0x12345678UL ,
4096 ,
0  )

Random data (aligned)

References TCPIP_RANDOM_TEST.

◆ TCPIP_RANDOM_TEST() [2/5]

TCPIP_RANDOM_TEST ( random_unaligned_1 ,
0x12345678UL ,
4096 ,
1  )

Random data (unaligned, +1)

References TCPIP_RANDOM_TEST.

◆ TCPIP_RANDOM_TEST() [3/5]

TCPIP_RANDOM_TEST ( random_unaligned_2 ,
0x12345678UL ,
4096 ,
2  )

Random data (unaligned, +2)

References TCPIP_RANDOM_TEST.

◆ TCPIP_RANDOM_TEST() [4/5]

TCPIP_RANDOM_TEST ( random_aligned_truncated ,
0x12345678UL ,
4095 ,
0  )

Random data (aligned, truncated)

References TCPIP_RANDOM_TEST.

◆ TCPIP_RANDOM_TEST() [5/5]

TCPIP_RANDOM_TEST ( partial ,
0xcafebabe ,
121 ,
5  )

Random data (unaligned start and finish)

References TCPIP_RANDOM_TEST.

◆ rfc_tcpip_chksum()

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
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11

References assert, data, len, and rfc_tcpip_chksum().

Referenced by rfc_tcpip_chksum(), tcpip_okx(), and tcpip_random_okx().

◆ tcpip_okx()

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}
#define TCPIP_EMPTY_CSUM
Empty checksum value.
Definition tcpip.h:58
uint16_t generic_tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition tcpip.c:171
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
uint16_t tcpip_continue_chksum(uint16_t partial, const void *data, size_t len)
Calculate continued TCP/IP checkum.
Definition x86_tcpip.c:46

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

◆ tcpip_random_okx()

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++ ) {
227 test->len );
229 }
230 DBG ( "TCPIP checksummed %zd bytes (+%zd) in %ld +/- %ld ticks\n",
231 test->len, test->offset, profile_mean ( &profiler ),
233}
#define PROFILE_COUNT
Number of sample iterations for profiling.
Definition cipher_test.c:45
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
void * memset(void *dest, int character, size_t len) __nonnull
unsigned long profile_mean(struct profiler *profiler)
Get mean sample value.
Definition profile.c:242
unsigned long profile_stddev(struct profiler *profiler)
Get sample standard deviation.
Definition profile.c:276
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
void srandom(unsigned int seed)
Seed the pseudo-random number generator.
Definition random.c:21
A data structure for storing profiling information.
Definition profile.h:27
static uint8_t tcpip_data[4096+7]
Buffer for pseudorandom-data tests.
Definition tcpip_test.c:86

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()

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.

257 {
258 .name = "tcpip",
259 .exec = tcpip_test_exec,
260};