Annotation of qemu/roms/ipxe/src/usr/lotest.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2010 Michael Brown <[email protected]>.
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of the
        !             7:  * License, or any later version.
        !             8:  *
        !             9:  * This program is distributed in the hope that it will be useful, but
        !            10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            12:  * General Public License for more details.
        !            13:  *
        !            14:  * You should have received a copy of the GNU General Public License
        !            15:  * along with this program; if not, write to the Free Software
        !            16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE ( GPL2_OR_LATER );
        !            20: 
        !            21: #include <stdint.h>
        !            22: #include <stdlib.h>
        !            23: #include <string.h>
        !            24: #include <stdio.h>
        !            25: #include <errno.h>
        !            26: #include <byteswap.h>
        !            27: #include <ipxe/iobuf.h>
        !            28: #include <ipxe/netdevice.h>
        !            29: #include <ipxe/if_ether.h>
        !            30: #include <ipxe/keys.h>
        !            31: #include <ipxe/console.h>
        !            32: #include <usr/ifmgmt.h>
        !            33: #include <usr/lotest.h>
        !            34: 
        !            35: /** @file
        !            36:  *
        !            37:  * Loopback testing
        !            38:  *
        !            39:  */
        !            40: 
        !            41: #define LINK_WAIT_MS 15000
        !            42: 
        !            43: /**
        !            44:  * Process received packet
        !            45:  *
        !            46:  * @v iobuf            I/O buffer
        !            47:  * @v netdev           Network device
        !            48:  * @v ll_dest          Link-layer destination address
        !            49:  * @v ll_source                Link-layer source address
        !            50:  * @ret rc             Return status code
        !            51:  */
        !            52: static int lotest_rx ( struct io_buffer *iobuf,
        !            53:                       struct net_device *netdev __unused,
        !            54:                       const void *ll_dest __unused,
        !            55:                       const void *ll_source __unused ) {
        !            56:        free_iob ( iobuf );
        !            57:        return -ENOTSUP;
        !            58: }
        !            59: 
        !            60: /**
        !            61:  * Transcribe network-layer address
        !            62:  *
        !            63:  * @v net_addr         Network-layer address
        !            64:  * @ret string         Human-readable transcription of address
        !            65:  */
        !            66: static const char * lotest_ntoa ( const void *net_addr __unused ) {
        !            67:        return "<INVALID>";
        !            68: }
        !            69: 
        !            70: /**
        !            71:  * Loopback test network-layer protocol
        !            72:  *
        !            73:  * Using a dedicated network-layer protocol avoids problems caused by
        !            74:  * cards supporting features such as IPv4 checksum offload trying to
        !            75:  * interpret the (randomly generated) network-layer content.
        !            76:  */
        !            77: static struct net_protocol lotest_protocol __net_protocol = {
        !            78:        .name = "LOTEST",
        !            79:        .rx = lotest_rx,
        !            80:        .ntoa = lotest_ntoa,
        !            81:        .net_proto = htons ( 0x6950 ), /* Not a genuine protocol number */
        !            82:        .net_addr_len = 0,
        !            83: };
        !            84: 
        !            85: /**
        !            86:  * Perform loopback test between two network devices
        !            87:  *
        !            88:  * @v sender           Sending network device
        !            89:  * @v receiver         Received network device
        !            90:  * @v mtu              Packet size (excluding link-layer headers)
        !            91:  * @ret rc             Return status code
        !            92:  */
        !            93: int loopback_test ( struct net_device *sender, struct net_device *receiver,
        !            94:                    size_t mtu ) {
        !            95:        uint8_t buf[mtu];
        !            96:        struct io_buffer *iobuf;
        !            97:        const void *ll_dest;
        !            98:        const void *ll_source;
        !            99:        uint16_t net_proto;
        !           100:        unsigned int i;
        !           101:        unsigned int successes;
        !           102:        int rc;
        !           103: 
        !           104:        /* Open network devices */
        !           105:        if ( ( rc = ifopen ( sender ) ) != 0 )
        !           106:                return rc;
        !           107:        if ( ( rc = ifopen ( receiver ) ) != 0 )
        !           108:                return rc;
        !           109: 
        !           110:        /* Wait for link-up */
        !           111:        if ( ( rc = iflinkwait ( sender, LINK_WAIT_MS ) ) != 0 )
        !           112:                return rc;
        !           113:        if ( ( rc = iflinkwait ( receiver, LINK_WAIT_MS ) ) != 0 )
        !           114:                return rc;
        !           115: 
        !           116:        /* Print initial statistics */
        !           117:        printf ( "Performing loopback test from %s to %s with %zd byte MTU\n",
        !           118:                 sender->name, receiver->name, mtu );
        !           119:        ifstat ( sender );
        !           120:        ifstat ( receiver );
        !           121: 
        !           122:        /* Freeze receive queue processing on the receiver, so that we
        !           123:         * can extract all received packets.
        !           124:         */
        !           125:        netdev_rx_freeze ( receiver );
        !           126: 
        !           127:        /* Perform loopback test */
        !           128:        for ( successes = 0 ; ; successes++ ) {
        !           129: 
        !           130:                /* Print running total */
        !           131:                printf ( "\r%d", successes );
        !           132: 
        !           133:                /* Generate random packet */
        !           134:                for ( i = 0 ; i < sizeof ( buf ) ; i++ )
        !           135:                        buf[i] = random();
        !           136:                iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( buf ) );
        !           137:                if ( ! iobuf ) {
        !           138:                        printf ( "\nFailed to allocate I/O buffer" );
        !           139:                        rc = -ENOMEM;
        !           140:                        goto done;
        !           141:                }
        !           142:                iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
        !           143:                memcpy ( iob_put ( iobuf, sizeof ( buf ) ),
        !           144:                         buf, sizeof ( buf ) );
        !           145: 
        !           146:                /* Transmit packet */
        !           147:                if ( ( rc = net_tx ( iob_disown ( iobuf ), sender,
        !           148:                                     &lotest_protocol, receiver->ll_addr,
        !           149:                                     sender->ll_addr ) ) != 0 ) {
        !           150:                        printf ( "\nFailed to transmit packet: %s",
        !           151:                                 strerror ( rc ) );
        !           152:                        goto done;
        !           153:                }
        !           154: 
        !           155:                /* Poll until packet arrives */
        !           156:                do {
        !           157:                        /* Check for cancellation */
        !           158:                        if ( iskey() && ( getchar() == CTRL_C ) ) {
        !           159:                                rc = -ECANCELED;
        !           160:                                goto done;
        !           161:                        }
        !           162:                        /* Poll network devices */
        !           163:                        net_poll();
        !           164:                } while ( ( iobuf = netdev_rx_dequeue ( receiver ) ) == NULL );
        !           165: 
        !           166:                /* Check received packet */
        !           167:                if ( ( rc = receiver->ll_protocol->pull ( receiver, iobuf,
        !           168:                                                          &ll_dest, &ll_source,
        !           169:                                                          &net_proto ) ) != 0 ){
        !           170:                        printf ( "\nFailed to strip link-layer header: %s",
        !           171:                                 strerror ( rc ) );
        !           172:                        goto done;
        !           173:                }
        !           174:                if ( net_proto == lotest_protocol.net_proto ) {
        !           175:                        if ( iob_len ( iobuf ) != sizeof ( buf ) ) {
        !           176:                                printf ( "\nLength mismatch: sent %zd, "
        !           177:                                         "received %zd",
        !           178:                                         sizeof ( buf ), iob_len ( iobuf ) );
        !           179:                                DBG ( "\nSent:\n" );
        !           180:                                DBG_HDA ( 0, buf, sizeof ( buf ) );
        !           181:                                DBG ( "Received:\n" );
        !           182:                                DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
        !           183:                                rc = -EINVAL;
        !           184:                                goto done;
        !           185:                        }
        !           186:                        if ( memcmp ( iobuf->data, buf, sizeof ( buf ) ) != 0){
        !           187:                                printf ( "\nContent mismatch" );
        !           188:                                DBG ( "\nSent:\n" );
        !           189:                                DBG_HDA ( 0, buf, sizeof ( buf ) );
        !           190:                                DBG ( "Received:\n" );
        !           191:                                DBG_HDA ( 0, iobuf->data, iob_len ( iobuf ) );
        !           192:                                rc = -EINVAL;
        !           193:                                goto done;
        !           194:                        }
        !           195:                } else {
        !           196:                        printf ( "\nReceived spurious packet type %04x\n",
        !           197:                                 ntohs ( net_proto ) );
        !           198:                        /* Continue; this allows for the fact that
        !           199:                         * there may have been packets outstanding on
        !           200:                         * the wire when we started the test.
        !           201:                         */
        !           202:                }
        !           203: 
        !           204:                free_iob ( iob_disown ( iobuf ) );
        !           205:        }
        !           206: 
        !           207:  done:
        !           208:        printf ( "\n");
        !           209:        free_iob ( iobuf );
        !           210:        netdev_rx_unfreeze ( receiver );
        !           211: 
        !           212:        /* Dump final statistics */
        !           213:        ifstat ( sender );
        !           214:        ifstat ( receiver );
        !           215: 
        !           216:        return 0;
        !           217: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.