2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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.
25 #include <gpxe/if_arp.h>
26 #include <gpxe/if_ether.h>
27 #include <gpxe/netdevice.h>
28 #include <gpxe/iobuf.h>
29 #include <gpxe/ethernet.h>
37 /** Ethernet broadcast MAC address */
38 static uint8_t eth_broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
41 * Transmit Ethernet packet
44 * @v netdev Network device
45 * @v net_protocol Network-layer protocol
46 * @v ll_dest Link-layer destination address
48 * Prepends the Ethernet link-layer header and transmits the packet.
50 static int eth_tx ( struct io_buffer
*iobuf
, struct net_device
*netdev
,
51 struct net_protocol
*net_protocol
, const void *ll_dest
) {
52 struct ethhdr
*ethhdr
= iob_push ( iobuf
, sizeof ( *ethhdr
) );
54 /* Build Ethernet header */
55 memcpy ( ethhdr
->h_dest
, ll_dest
, ETH_ALEN
);
56 memcpy ( ethhdr
->h_source
, netdev
->ll_addr
, ETH_ALEN
);
57 ethhdr
->h_protocol
= net_protocol
->net_proto
;
59 /* Hand off to network device */
60 return netdev_tx ( netdev
, iobuf
);
64 * Process received Ethernet packet
67 * @v netdev Network device
69 * Strips off the Ethernet link-layer header and passes up to the
70 * network-layer protocol.
72 static int eth_rx ( struct io_buffer
*iobuf
, struct net_device
*netdev
) {
73 struct ethhdr
*ethhdr
= iobuf
->data
;
76 if ( iob_len ( iobuf
) < sizeof ( *ethhdr
) ) {
77 DBG ( "Ethernet packet too short (%zd bytes)\n",
83 /* Strip off Ethernet header */
84 iob_pull ( iobuf
, sizeof ( *ethhdr
) );
86 /* Hand off to network-layer protocol */
87 return net_rx ( iobuf
, netdev
, ethhdr
->h_protocol
, ethhdr
->h_source
);
91 * Transcribe Ethernet address
93 * @v ll_addr Link-layer address
94 * @ret string Link-layer address in human-readable format
96 const char * eth_ntoa ( const void *ll_addr
) {
97 static char buf
[18]; /* "00:00:00:00:00:00" */
98 const uint8_t *eth_addr
= ll_addr
;
100 sprintf ( buf
, "%02x:%02x:%02x:%02x:%02x:%02x",
101 eth_addr
[0], eth_addr
[1], eth_addr
[2],
102 eth_addr
[3], eth_addr
[4], eth_addr
[5] );
106 /** Ethernet protocol */
107 struct ll_protocol ethernet_protocol __ll_protocol
= {
109 .ll_proto
= htons ( ARPHRD_ETHER
),
110 .ll_addr_len
= ETH_ALEN
,
111 .ll_header_len
= ETH_HLEN
,
112 .ll_broadcast
= eth_broadcast
,