iPXE
Functions | Variables
ethernet.c File Reference

Ethernet protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/if_arp.h>
#include <ipxe/if_ether.h>
#include <ipxe/in.h>
#include <ipxe/netdevice.h>
#include <ipxe/iobuf.h>
#include <ipxe/ethernet.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int eth_is_llc_packet (struct ethhdr *ethhdr)
 Check if Ethernet packet has an 802.3 LLC header.
int eth_push (struct net_device *netdev __unused, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto)
 Add Ethernet link-layer header.
int eth_pull (struct net_device *netdev __unused, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags)
 Remove Ethernet link-layer header.
void eth_init_addr (const void *hw_addr, void *ll_addr)
 Initialise Ethernet address.
void eth_random_addr (void *hw_addr)
 Generate random Ethernet address.
const char * eth_ntoa (const void *ll_addr)
 Transcribe Ethernet address.
int eth_mc_hash (unsigned int af, const void *net_addr, void *ll_addr)
 Hash multicast address.
int eth_eth_addr (const void *ll_addr, void *eth_addr)
 Generate Ethernet-compatible compressed link-layer address.
int eth_eui64 (const void *ll_addr, void *eui64)
 Generate EUI-64 address.
struct net_devicealloc_etherdev (size_t priv_size)
 Allocate Ethernet device.
 REQUIRING_SYMBOL (ethernet_protocol)
 REQUIRE_OBJECT (config_ethernet)

Variables

uint8_t eth_broadcast [ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
 Ethernet broadcast MAC address.
struct ll_protocol
ethernet_protocol 
__ll_protocol
 Ethernet protocol.

Detailed Description

Ethernet protocol.

Definition in file ethernet.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int eth_is_llc_packet ( struct ethhdr ethhdr) [inline, static]

Check if Ethernet packet has an 802.3 LLC header.

Parameters:
ethhdrEthernet header
Return values:
is_llcPacket has 802.3 LLC header

Definition at line 55 of file ethernet.c.

References ethhdr::h_protocol.

Referenced by eth_pull().

                                                              {
        uint8_t len_msb;

        /* Check if the protocol field contains a value short enough
         * to be a frame length.  The slightly convoluted form of the
         * comparison is designed to reduce to a single x86
         * instruction.
         */
        len_msb = *( ( uint8_t * ) &ethhdr->h_protocol );
        return ( len_msb < 0x06 );
}
int eth_push ( struct net_device *netdev  __unused,
struct io_buffer iobuf,
const void *  ll_dest,
const void *  ll_source,
uint16_t  net_proto 
)

Add Ethernet link-layer header.

Parameters:
netdevNetwork device
iobufI/O buffer
ll_destLink-layer destination address
ll_sourceSource link-layer address
net_protoNetwork-layer protocol, in network-byte order
Return values:
rcReturn status code

Definition at line 77 of file ethernet.c.

References ETH_ALEN, ethhdr::h_dest, ethhdr::h_protocol, ethhdr::h_source, iob_push, memcpy(), and net_proto.

                                    {
        struct ethhdr *ethhdr = iob_push ( iobuf, sizeof ( *ethhdr ) );

        /* Build Ethernet header */
        memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
        memcpy ( ethhdr->h_source, ll_source, ETH_ALEN );
        ethhdr->h_protocol = net_proto;

        return 0;
}
int eth_pull ( struct net_device *netdev  __unused,
struct io_buffer iobuf,
const void **  ll_dest,
const void **  ll_source,
uint16_t net_proto,
unsigned int *  flags 
)

Remove Ethernet link-layer header.

Parameters:
netdevNetwork device
iobufI/O buffer
Return values:
ll_destLink-layer destination address
ll_sourceSource link-layer address
net_protoNetwork-layer protocol, in network-byte order
flagsPacket flags
rcReturn status code

Definition at line 101 of file ethernet.c.

References io_buffer::data, DBG, EINVAL, eth_is_llc_packet(), ethhdr::h_dest, ethhdr::h_protocol, ethhdr::h_source, iob_len(), iob_pull, is_broadcast_ether_addr(), is_multicast_ether_addr(), LL_BROADCAST, and LL_MULTICAST.

Referenced by undinet_transmit().

                                                          {
        struct ethhdr *ethhdr = iobuf->data;
        uint16_t *llc_proto;

        /* Sanity check.  While in theory we could receive a one-byte
         * packet, this will never happen in practice and performing
         * the combined length check here avoids the need for an
         * additional comparison if we detect an LLC frame.
         */
        if ( iob_len ( iobuf ) < ( sizeof ( *ethhdr ) + sizeof ( *llc_proto ))){
                DBG ( "Ethernet packet too short (%zd bytes)\n",
                      iob_len ( iobuf ) );
                return -EINVAL;
        }

        /* Strip off Ethernet header */
        iob_pull ( iobuf, sizeof ( *ethhdr ) );

        /* Fill in required fields */
        *ll_dest = ethhdr->h_dest;
        *ll_source = ethhdr->h_source;
        *net_proto = ethhdr->h_protocol;
        *flags = ( ( is_multicast_ether_addr ( ethhdr->h_dest ) ?
                     LL_MULTICAST : 0 ) |
                   ( is_broadcast_ether_addr ( ethhdr->h_dest ) ?
                     LL_BROADCAST : 0 ) );

        /* If this is an LLC frame (with a length in place of the
         * protocol field), then use the next two bytes (which happen
         * to be the LLC DSAP and SSAP) as the protocol.  This allows
         * for minimal-overhead support for receiving (rare) LLC
         * frames, without requiring a full LLC protocol layer.
         */
        if ( eth_is_llc_packet ( ethhdr ) ) {
                llc_proto = ( &ethhdr->h_protocol + 1 );
                *net_proto = *llc_proto;
        }

        return 0;
}
void eth_init_addr ( const void *  hw_addr,
void *  ll_addr 
)

Initialise Ethernet address.

Parameters:
hw_addrHardware address
ll_addrLink-layer address

Definition at line 150 of file ethernet.c.

References ETH_ALEN, and memcpy().

                                                          {
        memcpy ( ll_addr, hw_addr, ETH_ALEN );
}
void eth_random_addr ( void *  hw_addr)

Generate random Ethernet address.

Parameters:
hw_addrGenerated hardware address

Definition at line 159 of file ethernet.c.

References addr, ETH_ALEN, and random().

Referenced by igbvf_probe(), intelvf_mbox_reset(), lan78xx_fetch_mac(), smsc95xx_fetch_mac(), and txnic_bgx_mac().

                                       {
        uint8_t *addr = hw_addr;
        unsigned int i;

        for ( i = 0 ; i < ETH_ALEN ; i++ )
                addr[i] = random();
        addr[0] &= ~0x01; /* Clear multicast bit */
        addr[0] |= 0x02; /* Set locally-assigned bit */
}
const char* eth_ntoa ( const void *  ll_addr)

Transcribe Ethernet address.

Parameters:
ll_addrLink-layer address
Return values:
stringLink-layer address in human-readable format

Definition at line 175 of file ethernet.c.

References sprintf.

Referenced by amd8111e_get_mac_address(), b44_probe(), bnx2_probe(), bofm_en(), bofm_test(), corkscrew_probe1(), cs89x0_probe(), davicom_probe(), dmfe_probe(), eepro_probe(), ena_get_device_attributes(), eoib_create(), eoib_rx_av(), eoib_tx_av(), epic100_probe(), eth_probe(), eth_slow_lacp_dump(), eth_slow_marker_dump(), exanic_probe(), fcoe_expired(), fcoe_fip_rx(), fcoe_fip_rx_advertisement(), fcoe_fip_rx_els_response(), fcoe_fip_rx_vlan(), fcoe_rx(), hermon_bofm_harvest(), hermon_bofm_update(), ibft_fill_nic(), intel_fetch_mac(), intel_fetch_mac_eeprom(), intelvf_mbox_reset(), intelx_try_fetch_mac(), intelxl_fetch_mac(), ipoib_find_remac(), ipoib_translate_tx_arp(), ipoib_transmit(), iwlist(), lan78xx_fetch_mac(), ne_probe(), net80211_probe_step(), net80211_step_associate(), nv_setup_mac_addr(), pcnet32_probe(), phantom_add_macaddr(), phantom_del_macaddr(), phantom_get_macaddr(), prism2_probe(), smc9000_probe(), smsc95xx_fetch_mac(), smsc95xx_vm3_fetch_mac(), smscusb_eeprom_fetch_mac(), smscusb_otp_fetch_mac(), stp_rx(), t595_probe(), t5x9_probe(), tlan_probe(), tulip_probe(), txnic_lmac_probe(), undinet_probe(), virtnet_probe_legacy(), virtnet_probe_modern(), vxge_probe(), w89c840_probe(), wpa_derive_ptk(), xsmp_rx_xve_install(), and xve_create().

                                              {
        static char buf[18]; /* "00:00:00:00:00:00" */
        const uint8_t *eth_addr = ll_addr;

        sprintf ( buf, "%02x:%02x:%02x:%02x:%02x:%02x",
                  eth_addr[0], eth_addr[1], eth_addr[2],
                  eth_addr[3], eth_addr[4], eth_addr[5] );
        return buf;
}
int eth_mc_hash ( unsigned int  af,
const void *  net_addr,
void *  ll_addr 
)

Hash multicast address.

Parameters:
afAddress family
net_addrNetwork-layer address
ll_addrLink-layer address to fill in
Return values:
rcReturn status code

Definition at line 193 of file ethernet.c.

References AF_INET, AF_INET6, ENOTSUP, and memcpy().

                                                                         {
        const uint8_t *net_addr_bytes = net_addr;
        uint8_t *ll_addr_bytes = ll_addr;

        switch ( af ) {
        case AF_INET:
                ll_addr_bytes[0] = 0x01;
                ll_addr_bytes[1] = 0x00;
                ll_addr_bytes[2] = 0x5e;
                ll_addr_bytes[3] = net_addr_bytes[1] & 0x7f;
                ll_addr_bytes[4] = net_addr_bytes[2];
                ll_addr_bytes[5] = net_addr_bytes[3];
                return 0;
        case AF_INET6:
                ll_addr_bytes[0] = 0x33;
                ll_addr_bytes[1] = 0x33;
                memcpy ( &ll_addr_bytes[2], &net_addr_bytes[12], 4 );
                return 0;
        default:
                return -ENOTSUP;
        }
}
int eth_eth_addr ( const void *  ll_addr,
void *  eth_addr 
)

Generate Ethernet-compatible compressed link-layer address.

Parameters:
ll_addrLink-layer address
eth_addrEthernet-compatible address to fill in

Definition at line 222 of file ethernet.c.

References ETH_ALEN, and memcpy().

                                                         {
        memcpy ( eth_addr, ll_addr, ETH_ALEN );
        return 0;
}
int eth_eui64 ( const void *  ll_addr,
void *  eui64 
)

Generate EUI-64 address.

Parameters:
ll_addrLink-layer address
eui64EUI-64 address to fill in
Return values:
rcReturn status code

Definition at line 234 of file ethernet.c.

References htons, and memcpy().

                                                   {

        memcpy ( ( eui64 + 0 ), ( ll_addr + 0 ), 3 );
        memcpy ( ( eui64 + 5 ), ( ll_addr + 3 ), 3 );
        *( ( uint16_t * ) ( eui64 + 3 ) ) = htons ( 0xfffe );
        return 0;
}
struct net_device* alloc_etherdev ( size_t  priv_size) [read]
REQUIRING_SYMBOL ( ethernet_protocol  )
REQUIRE_OBJECT ( config_ethernet  )

Variable Documentation

uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }

Ethernet broadcast MAC address.

Definition at line 47 of file ethernet.c.

Referenced by alloc_etherdev(), alloc_ipoibdev(), ath9k_init_misc(), ipoib_complete_recv(), net80211_alloc(), and net80211_probe_step().

struct ll_protocol ethernet_protocol __ll_protocol
Initial value:
 {
        .name           = "Ethernet",
        .ll_proto       = htons ( ARPHRD_ETHER ),
        .hw_addr_len    = ETH_ALEN,
        .ll_addr_len    = ETH_ALEN,
        .ll_header_len  = ETH_HLEN,
        .push           = eth_push,
        .pull           = eth_pull,
        .init_addr      = eth_init_addr,
        .ntoa           = eth_ntoa,
        .mc_hash        = eth_mc_hash,
        .eth_addr       = eth_eth_addr,
        .eui64          = eth_eui64,
}

Ethernet protocol.

Definition at line 243 of file ethernet.c.