[cloud] Allow aws-import script to run on Python 3.6
[ipxe.git] / src / net / eapol.c
1 /*
2 * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <assert.h>
27 #include <errno.h>
28 #include <byteswap.h>
29 #include <ipxe/iobuf.h>
30 #include <ipxe/if_ether.h>
31 #include <ipxe/netdevice.h>
32 #include <ipxe/eap.h>
33 #include <ipxe/eapol.h>
34
35 /** @file
36 *
37 * Extensible Authentication Protocol over LAN (EAPoL)
38 *
39 */
40
41 /**
42 * Process EAPoL packet
43 *
44 * @v iobuf I/O buffer
45 * @v netdev Network device
46 * @v ll_dest Link-layer destination address
47 * @v ll_source Link-layer source address
48 * @v flags Packet flags
49 * @ret rc Return status code
50 */
51 static int eapol_rx ( struct io_buffer *iobuf, struct net_device *netdev,
52 const void *ll_dest __unused, const void *ll_source,
53 unsigned int flags __unused ) {
54 struct eapol_header *eapol;
55 struct eapol_handler *handler;
56 size_t remaining;
57 size_t len;
58 int rc;
59
60 /* Sanity checks */
61 if ( iob_len ( iobuf ) < sizeof ( *eapol ) ) {
62 DBGC ( netdev, "EAPOL %s underlength header:\n",
63 netdev->name );
64 DBGC_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
65 rc = -EINVAL;
66 goto drop;
67 }
68 eapol = iobuf->data;
69 remaining = ( iob_len ( iobuf ) - sizeof ( *eapol ) );
70 len = ntohs ( eapol->len );
71 if ( len > remaining ) {
72 DBGC ( netdev, "EAPOL %s v%d type %d len %zd underlength "
73 "payload:\n", netdev->name, eapol->version,
74 eapol->type, len );
75 DBGC_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
76 rc = -EINVAL;
77 goto drop;
78 }
79
80 /* Strip any trailing padding */
81 iob_unput ( iobuf, ( len - remaining ) );
82
83 /* Handle according to type */
84 for_each_table_entry ( handler, EAPOL_HANDLERS ) {
85 if ( handler->type == eapol->type ) {
86 return handler->rx ( iob_disown ( iobuf ) , netdev,
87 ll_source );
88 }
89 }
90 rc = -ENOTSUP;
91 DBGC ( netdev, "EAPOL %s v%d type %d unsupported\n",
92 netdev->name, eapol->version, eapol->type );
93 DBGC_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
94
95 drop:
96 free_iob ( iobuf );
97 return rc;
98 }
99
100 /** EAPoL protocol */
101 struct net_protocol eapol_protocol __net_protocol = {
102 .name = "EAPOL",
103 .net_proto = htons ( ETH_P_EAPOL ),
104 .rx = eapol_rx,
105 };
106
107 /**
108 * Process EAPoL-encapsulated EAP packet
109 *
110 * @v netdev Network device
111 * @v ll_source Link-layer source address
112 * @ret rc Return status code
113 */
114 static int eapol_eap_rx ( struct io_buffer *iobuf, struct net_device *netdev,
115 const void *ll_source __unused ) {
116 struct eapol_header *eapol;
117 int rc;
118
119 /* Sanity check */
120 assert ( iob_len ( iobuf ) >= sizeof ( *eapol ) );
121
122 /* Strip EAPoL header */
123 eapol = iob_pull ( iobuf, sizeof ( *eapol ) );
124
125 /* Process EAP packet */
126 if ( ( rc = eap_rx ( netdev, iobuf->data, iob_len ( iobuf ) ) ) != 0 ) {
127 DBGC ( netdev, "EAPOL %s v%d EAP failed: %s\n",
128 netdev->name, eapol->version, strerror ( rc ) );
129 goto drop;
130 }
131
132 drop:
133 free_iob ( iobuf );
134 return rc;
135 }
136
137 /** EAPoL handler for EAP packets */
138 struct eapol_handler eapol_eap __eapol_handler = {
139 .type = EAPOL_TYPE_EAP,
140 .rx = eapol_eap_rx,
141 };