Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (c) 2009 Joshua Oreman <oremanj (at) rwcr.net>.
      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 /** @file
     22  *
     23  * 802.1X Extensible Authentication Protocol over LANs demultiplexer
     24  *
     25  */
     26 
     27 #include <gpxe/netdevice.h>
     28 #include <gpxe/iobuf.h>
     29 #include <gpxe/if_ether.h>
     30 #include <gpxe/eapol.h>
     31 #include <errno.h>
     32 #include <byteswap.h>
     33 
     34 /**
     35  * Receive EAPOL network-layer packet
     36  *
     37  * @v iob	I/O buffer
     38  * @v netdev	Network device
     39  * @v ll_source	Link-layer source address
     40  *
     41  * This function takes ownership of the I/O buffer passed to it.
     42  */
     43 static int eapol_rx ( struct io_buffer *iob, struct net_device *netdev,
     44 		      const void *ll_source )
     45 {
     46 	struct eapol_frame *eapol = iob->data;
     47 	struct eapol_handler *handler;
     48 
     49 	if ( iob_len ( iob ) < EAPOL_HDR_LEN ) {
     50 		free_iob ( iob );
     51 		return -EINVAL;
     52 	}
     53 
     54 	for_each_table_entry ( handler, EAPOL_HANDLERS ) {
     55 		if ( handler->type == eapol->type ) {
     56 			iob_pull ( iob, EAPOL_HDR_LEN );
     57 			return handler->rx ( iob, netdev, ll_source );
     58 		}
     59 	}
     60 
     61 	free_iob ( iob );
     62 	return -( ENOTSUP | ( ( eapol->type & 0x1f ) << 8 ) );
     63 }
     64 
     65 /**
     66  * Transcribe EAPOL network-layer address
     67  *
     68  * @v net_addr	Network-layer address
     69  * @ret str	String representation of network-layer address
     70  *
     71  * EAPOL doesn't have network-layer addresses, so we just return the
     72  * string @c "<EAPOL>".
     73  */
     74 static const char * eapol_ntoa ( const void *net_addr __unused )
     75 {
     76 	return "<EAPOL>";
     77 }
     78 
     79 /** EAPOL network protocol */
     80 struct net_protocol eapol_protocol __net_protocol = {
     81 	.name = "EAPOL",
     82 	.rx = eapol_rx,
     83 	.ntoa = eapol_ntoa,
     84 	.net_proto = htons ( ETH_P_EAPOL ),
     85 };
     86