Annotation of qemu/roms/ipxe/src/net/ethernet.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2006 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 <stdio.h>
        !            23: #include <string.h>
        !            24: #include <byteswap.h>
        !            25: #include <errno.h>
        !            26: #include <assert.h>
        !            27: #include <ipxe/if_arp.h>
        !            28: #include <ipxe/if_ether.h>
        !            29: #include <ipxe/in.h>
        !            30: #include <ipxe/netdevice.h>
        !            31: #include <ipxe/iobuf.h>
        !            32: #include <ipxe/ethernet.h>
        !            33: 
        !            34: /** @file
        !            35:  *
        !            36:  * Ethernet protocol
        !            37:  *
        !            38:  */
        !            39: 
        !            40: /** Ethernet broadcast MAC address */
        !            41: static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        !            42: 
        !            43: /**
        !            44:  * Add Ethernet link-layer header
        !            45:  *
        !            46:  * @v netdev           Network device
        !            47:  * @v iobuf            I/O buffer
        !            48:  * @v ll_dest          Link-layer destination address
        !            49:  * @v ll_source                Source link-layer address
        !            50:  * @v net_proto                Network-layer protocol, in network-byte order
        !            51:  * @ret rc             Return status code
        !            52:  */
        !            53: static int eth_push ( struct net_device *netdev __unused,
        !            54:                      struct io_buffer *iobuf, const void *ll_dest,
        !            55:                      const void *ll_source, uint16_t net_proto ) {
        !            56:        struct ethhdr *ethhdr = iob_push ( iobuf, sizeof ( *ethhdr ) );
        !            57: 
        !            58:        /* Build Ethernet header */
        !            59:        memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
        !            60:        memcpy ( ethhdr->h_source, ll_source, ETH_ALEN );
        !            61:        ethhdr->h_protocol = net_proto;
        !            62: 
        !            63:        return 0;
        !            64: }
        !            65: 
        !            66: /**
        !            67:  * Remove Ethernet link-layer header
        !            68:  *
        !            69:  * @v netdev           Network device
        !            70:  * @v iobuf            I/O buffer
        !            71:  * @ret ll_dest                Link-layer destination address
        !            72:  * @ret ll_source      Source link-layer address
        !            73:  * @ret net_proto      Network-layer protocol, in network-byte order
        !            74:  * @ret rc             Return status code
        !            75:  */
        !            76: static int eth_pull ( struct net_device *netdev __unused, 
        !            77:                      struct io_buffer *iobuf, const void **ll_dest,
        !            78:                      const void **ll_source, uint16_t *net_proto ) {
        !            79:        struct ethhdr *ethhdr = iobuf->data;
        !            80: 
        !            81:        /* Sanity check */
        !            82:        if ( iob_len ( iobuf ) < sizeof ( *ethhdr ) ) {
        !            83:                DBG ( "Ethernet packet too short (%zd bytes)\n",
        !            84:                      iob_len ( iobuf ) );
        !            85:                return -EINVAL;
        !            86:        }
        !            87: 
        !            88:        /* Strip off Ethernet header */
        !            89:        iob_pull ( iobuf, sizeof ( *ethhdr ) );
        !            90: 
        !            91:        /* Fill in required fields */
        !            92:        *ll_dest = ethhdr->h_dest;
        !            93:        *ll_source = ethhdr->h_source;
        !            94:        *net_proto = ethhdr->h_protocol;
        !            95: 
        !            96:        return 0;
        !            97: }
        !            98: 
        !            99: /**
        !           100:  * Initialise Ethernet address
        !           101:  *
        !           102:  * @v hw_addr          Hardware address
        !           103:  * @v ll_addr          Link-layer address
        !           104:  */
        !           105: void eth_init_addr ( const void *hw_addr, void *ll_addr ) {
        !           106:        memcpy ( ll_addr, hw_addr, ETH_ALEN );
        !           107: }
        !           108: 
        !           109: /**
        !           110:  * Transcribe Ethernet address
        !           111:  *
        !           112:  * @v ll_addr          Link-layer address
        !           113:  * @ret string         Link-layer address in human-readable format
        !           114:  */
        !           115: const char * eth_ntoa ( const void *ll_addr ) {
        !           116:        static char buf[18]; /* "00:00:00:00:00:00" */
        !           117:        const uint8_t *eth_addr = ll_addr;
        !           118: 
        !           119:        sprintf ( buf, "%02x:%02x:%02x:%02x:%02x:%02x",
        !           120:                  eth_addr[0], eth_addr[1], eth_addr[2],
        !           121:                  eth_addr[3], eth_addr[4], eth_addr[5] );
        !           122:        return buf;
        !           123: }
        !           124: 
        !           125: /**
        !           126:  * Hash multicast address
        !           127:  *
        !           128:  * @v af               Address family
        !           129:  * @v net_addr         Network-layer address
        !           130:  * @v ll_addr          Link-layer address to fill in
        !           131:  * @ret rc             Return status code
        !           132:  */
        !           133: int eth_mc_hash ( unsigned int af, const void *net_addr, void *ll_addr ) {
        !           134:        const uint8_t *net_addr_bytes = net_addr;
        !           135:        uint8_t *ll_addr_bytes = ll_addr;
        !           136: 
        !           137:        switch ( af ) {
        !           138:        case AF_INET:
        !           139:                ll_addr_bytes[0] = 0x01;
        !           140:                ll_addr_bytes[1] = 0x00;
        !           141:                ll_addr_bytes[2] = 0x5e;
        !           142:                ll_addr_bytes[3] = net_addr_bytes[1] & 0x7f;
        !           143:                ll_addr_bytes[4] = net_addr_bytes[2];
        !           144:                ll_addr_bytes[5] = net_addr_bytes[3];
        !           145:                return 0;
        !           146:        default:
        !           147:                return -ENOTSUP;
        !           148:        }
        !           149: }
        !           150: 
        !           151: /**
        !           152:  * Generate Ethernet-compatible compressed link-layer address
        !           153:  *
        !           154:  * @v ll_addr          Link-layer address
        !           155:  * @v eth_addr         Ethernet-compatible address to fill in
        !           156:  */
        !           157: int eth_eth_addr ( const void *ll_addr, void *eth_addr ) {
        !           158:        memcpy ( eth_addr, ll_addr, ETH_ALEN );
        !           159:        return 0;
        !           160: }
        !           161: 
        !           162: /** Ethernet protocol */
        !           163: struct ll_protocol ethernet_protocol __ll_protocol = {
        !           164:        .name           = "Ethernet",
        !           165:        .ll_proto       = htons ( ARPHRD_ETHER ),
        !           166:        .hw_addr_len    = ETH_ALEN,
        !           167:        .ll_addr_len    = ETH_ALEN,
        !           168:        .ll_header_len  = ETH_HLEN,
        !           169:        .push           = eth_push,
        !           170:        .pull           = eth_pull,
        !           171:        .init_addr      = eth_init_addr,
        !           172:        .ntoa           = eth_ntoa,
        !           173:        .mc_hash        = eth_mc_hash,
        !           174:        .eth_addr       = eth_eth_addr,
        !           175: };
        !           176: 
        !           177: /**
        !           178:  * Allocate Ethernet device
        !           179:  *
        !           180:  * @v priv_size                Size of driver private data
        !           181:  * @ret netdev         Network device, or NULL
        !           182:  */
        !           183: struct net_device * alloc_etherdev ( size_t priv_size ) {
        !           184:        struct net_device *netdev;
        !           185: 
        !           186:        netdev = alloc_netdev ( priv_size );
        !           187:        if ( netdev ) {
        !           188:                netdev->ll_protocol = &ethernet_protocol;
        !           189:                netdev->ll_broadcast = eth_broadcast;
        !           190:                netdev->max_pkt_len = ETH_FRAME_LEN;
        !           191:        }
        !           192:        return netdev;
        !           193: }
        !           194: 
        !           195: /* Drag in Ethernet slow protocols */
        !           196: REQUIRE_OBJECT ( eth_slow );

unix.superglobalmegacorp.com

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