Annotation of qemu/roms/ipxe/src/net/ethernet.c, revision 1.1.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.