iPXE
Data Structures | Defines | 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...

Defines

#define PROFILE_COUNT   16
 Number of sample iterations for profiling.
#define DATA(...)   { __VA_ARGS__ }
 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)   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.
 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.


Define Documentation

#define PROFILE_COUNT   16

Number of sample iterations for profiling.

Definition at line 44 of file tcpip_test.c.

Referenced by tcpip_random_okx().

#define DATA (   ...)    { __VA_ARGS__ }

Define inline data.

Definition at line 65 of file tcpip_test.c.

#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 a TCP/IP fixed-data test.

Definition at line 68 of file tcpip_test.c.

#define TCPIP_RANDOM_TEST (   name,
  SEED,
  LEN,
  OFFSET 
)
Value:
static struct tcpip_random_test name = {                        \
                .seed = SEED,                                           \
                .len = LEN,                                             \
                .offset = OFFSET,                                       \
        }

Define a TCP/IP pseudorandom-data test.

Definition at line 77 of file tcpip_test.c.

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

Definition at line 186 of file tcpip_test.c.

Referenced by tcpip_test_exec().

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

Definition at line 234 of file tcpip_test.c.

Referenced by tcpip_test_exec().


Function Documentation

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

Random data (aligned)

TCPIP_RANDOM_TEST ( random_unaligned_1  ,
0x12345678UL  ,
4096  ,
 
)

Random data (unaligned, +1)

TCPIP_RANDOM_TEST ( random_unaligned_2  ,
0x12345678UL  ,
4096  ,
 
)

Random data (unaligned, +2)

TCPIP_RANDOM_TEST ( random_aligned_truncated  ,
0x12345678UL  ,
4095  ,
 
)

Random data (aligned, truncated)

TCPIP_RANDOM_TEST ( partial  ,
0xcafebabe  ,
121  ,
 
)

Random data (unaligned start and finish)

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.

References assert.

Referenced by tcpip_okx(), and tcpip_random_okx().

                                                                  {
        unsigned long sum = 0xffff;

        while ( len > 1 )  {
                sum += *( ( uint16_t * ) data );
                data += 2;
                len -= 2;
        }

        if ( len > 0 )
                sum += *( ( uint8_t * ) data );

        while ( sum >> 16 )
                sum = ( ( sum & 0xffff ) + ( sum >> 16 ) );

        assert ( sum != 0x0000 );
        return ~sum;
}
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.

References tcpip_test::data, generic_tcpip_continue_chksum(), tcpip_test::len, okx, rfc_tcpip_chksum(), tcpip_continue_chksum(), and TCPIP_EMPTY_CSUM.

                                            {
        uint16_t expected;
        uint16_t generic_sum;
        uint16_t sum;

        /* Verify generic_tcpip_continue_chksum() result */
        expected = rfc_tcpip_chksum ( test->data, test->len );
        generic_sum = generic_tcpip_continue_chksum ( TCPIP_EMPTY_CSUM,
                                                      test->data, test->len );
        okx ( generic_sum == expected, file, line );

        /* Verify optimised tcpip_continue_chksum() result */
        sum = tcpip_continue_chksum ( TCPIP_EMPTY_CSUM, test->data, test->len );
        okx ( sum == expected, file, line );
}
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.

References assert, data, DBG, generic_tcpip_continue_chksum(), tcpip_random_test::len, memset(), tcpip_random_test::offset, okx, PROFILE_COUNT, profile_mean(), profile_start(), profile_stddev(), profile_stop(), random(), rfc_tcpip_chksum(), tcpip_random_test::seed, srandom(), tcpip_continue_chksum(), tcpip_data, and TCPIP_EMPTY_CSUM.

                                                                     {
        uint8_t *data = ( tcpip_data + test->offset );
        struct profiler profiler;
        uint16_t expected;
        uint16_t generic_sum;
        uint16_t sum;
        unsigned int i;

        /* Sanity check */
        assert ( ( test->len + test->offset ) <= sizeof ( tcpip_data ) );

        /* Generate random data */
        srandom ( test->seed );
        for ( i = 0 ; i < test->len ; i++ )
                data[i] = random();

        /* Verify generic_tcpip_continue_chksum() result */
        expected = rfc_tcpip_chksum ( data, test->len );
        generic_sum = generic_tcpip_continue_chksum ( TCPIP_EMPTY_CSUM,
                                                      data, test->len );
        okx ( generic_sum == expected, file, line );

        /* Verify optimised tcpip_continue_chksum() result */
        sum = tcpip_continue_chksum ( TCPIP_EMPTY_CSUM, data, test->len );
        okx ( sum == expected, file, line );

        /* Profile optimised calculation */
        memset ( &profiler, 0, sizeof ( profiler ) );
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
                profile_start ( &profiler );
                sum = tcpip_continue_chksum ( TCPIP_EMPTY_CSUM, data,
                                              test->len );
                profile_stop ( &profiler );
        }
        DBG ( "TCPIP checksummed %zd bytes (+%zd) in %ld +/- %ld ticks\n",
              test->len, test->offset, profile_mean ( &profiler ),
              profile_stddev ( &profiler ) );
}
static void tcpip_test_exec ( void  ) [static]

Perform TCP/IP self-tests.

Definition at line 240 of file tcpip_test.c.

References tcpip_ok, and tcpip_random_ok.

                                     {

        tcpip_ok ( &empty );
        tcpip_ok ( &one_byte );
        tcpip_ok ( &two_bytes );
        tcpip_ok ( &positive_zero );
        tcpip_ok ( &negative_zero );
        tcpip_ok ( &final_carry_big );
        tcpip_ok ( &final_carry_little );
        tcpip_random_ok ( &random_aligned );
        tcpip_random_ok ( &random_unaligned_1 );
        tcpip_random_ok ( &random_unaligned_2 );
        tcpip_random_ok ( &random_aligned_truncated );
        tcpip_random_ok ( &partial );
}

Variable Documentation

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

Initial value:
 {
        .name = "tcpip",
        .exec = tcpip_test_exec,
}

TCP/IP self-test.

Definition at line 257 of file tcpip_test.c.