iPXE
Functions
lotest.h File Reference

Loopback testing. More...

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int loopback_test (struct net_device *sender, struct net_device *receiver, size_t mtu, int broadcast)
 Perform loopback test between two network devices.

Detailed Description

Loopback testing.

Definition in file lotest.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int loopback_test ( struct net_device sender,
struct net_device receiver,
size_t  mtu,
int  broadcast 
)

Perform loopback test between two network devices.

Parameters:
senderSending network device
receiverReceived network device
mtuPacket size (excluding link-layer headers)
broadcastUse broadcast link-layer address
Return values:
rcReturn status code

Definition at line 194 of file lotest.c.

References alloc_iob(), ENOMEM, free, htonl, iflinkwait(), ifopen(), ifstat(), iob_disown, iob_put, iob_reserve, net_device::ll_addr, net_device::ll_broadcast, loopback_wait(), lotest_flush(), malloc(), MAX_LL_HEADER_LEN, memcpy(), mtu, net_device::name, net_tx(), NULL, printf(), random(), rc, seq, and strerror().

Referenced by lotest_exec().

                                                {
        uint8_t *buf;
        uint32_t *seq;
        struct io_buffer *iobuf;
        const void *ll_dest;
        unsigned int i;
        unsigned int successes;
        int rc;

        /* Open network devices */
        if ( ( rc = ifopen ( sender ) ) != 0 )
                return rc;
        if ( ( rc = ifopen ( receiver ) ) != 0 )
                return rc;

        /* Wait for link-up */
        if ( ( rc = iflinkwait ( sender, 0 ) ) != 0 )
                return rc;
        if ( ( rc = iflinkwait ( receiver, 0 ) ) != 0 )
                return rc;

        /* Allocate data buffer */
        if ( mtu < sizeof ( *seq ) )
                mtu = sizeof ( *seq );
        buf = malloc ( mtu );
        if ( ! buf )
                return -ENOMEM;
        seq = ( ( void * ) buf );

        /* Determine destination address */
        ll_dest = ( broadcast ? sender->ll_broadcast : receiver->ll_addr );

        /* Print initial statistics */
        printf ( "Performing %sloopback test from %s to %s with %zd byte MTU\n",
                 ( broadcast ? "broadcast " : "" ), sender->name,
                 receiver->name, mtu );
        ifstat ( sender );
        ifstat ( receiver );

        /* Start loopback test */
        lotest_flush();
        lotest_receiver = receiver;

        /* Perform loopback test */
        for ( successes = 0 ; ; successes++ ) {

                /* Print running total */
                printf ( "\r%d", successes );

                /* Generate random packet */
                *seq = htonl ( successes );
                for ( i = sizeof ( *seq ) ; i < mtu ; i++ )
                        buf[i] = random();
                iobuf = alloc_iob ( MAX_LL_HEADER_LEN + mtu );
                if ( ! iobuf ) {
                        printf ( "\nFailed to allocate I/O buffer" );
                        rc = -ENOMEM;
                        break;
                }
                iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
                memcpy ( iob_put ( iobuf, mtu ), buf, mtu );

                /* Transmit packet */
                if ( ( rc = net_tx ( iob_disown ( iobuf ), sender,
                                     &lotest_protocol, ll_dest,
                                     sender->ll_addr ) ) != 0 ) {
                        printf ( "\nFailed to transmit packet: %s",
                                 strerror ( rc ) );
                        break;
                }

                /* Wait for received packet */
                if ( ( rc = loopback_wait ( buf, mtu ) ) != 0 )
                        break;
        }

        printf ( "\n");

        /* Stop loopback testing */
        lotest_receiver = NULL;
        lotest_flush();

        /* Dump final statistics */
        ifstat ( sender );
        ifstat ( receiver );

        /* Free buffer */
        free ( buf );

        return 0;
}