eap_common.c
Go to the documentation of this file.
00001 /*
00002  * EAP common peer/server definitions
00003  * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eap_defs.h"
00019 #include "eap_common.h"
00020 
00037 const u8 * eap_hdr_validate(int vendor, EapType eap_type,
00038                             const struct wpabuf *msg, size_t *plen)
00039 {
00040         const struct eap_hdr *hdr;
00041         const u8 *pos;
00042         size_t len;
00043 
00044         hdr = wpabuf_head(msg);
00045 
00046         if (wpabuf_len(msg) < sizeof(*hdr)) {
00047                 wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
00048                 return NULL;
00049         }
00050 
00051         len = be_to_host16(hdr->length);
00052         if (len < sizeof(*hdr) + 1 || len > wpabuf_len(msg)) {
00053                 wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
00054                 return NULL;
00055         }
00056 
00057         pos = (const u8 *) (hdr + 1);
00058 
00059         if (*pos == EAP_TYPE_EXPANDED) {
00060                 int exp_vendor;
00061                 u32 exp_type;
00062                 if (len < sizeof(*hdr) + 8) {
00063                         wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP "
00064                                    "length");
00065                         return NULL;
00066                 }
00067                 pos++;
00068                 exp_vendor = WPA_GET_BE24(pos);
00069                 pos += 3;
00070                 exp_type = WPA_GET_BE32(pos);
00071                 pos += 4;
00072                 if (exp_vendor != vendor || exp_type != (u32) eap_type) {
00073                         wpa_printf(MSG_INFO, "EAP: Invalid expanded frame "
00074                                    "type");
00075                         return NULL;
00076                 }
00077 
00078                 *plen = len - sizeof(*hdr) - 8;
00079                 return pos;
00080         } else {
00081                 if (vendor != EAP_VENDOR_IETF || *pos != eap_type) {
00082                         wpa_printf(MSG_INFO, "EAP: Invalid frame type");
00083                         return NULL;
00084                 }
00085                 *plen = len - sizeof(*hdr) - 1;
00086                 return pos + 1;
00087         }
00088 }
00089 
00090 
00107 struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
00108                               u8 code, u8 identifier)
00109 {
00110         struct wpabuf *buf;
00111         struct eap_hdr *hdr;
00112         size_t len;
00113 
00114         len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
00115                 payload_len;
00116         buf = wpabuf_alloc(len);
00117         if (buf == NULL)
00118                 return NULL;
00119 
00120         hdr = wpabuf_put(buf, sizeof(*hdr));
00121         hdr->code = code;
00122         hdr->identifier = identifier;
00123         hdr->length = host_to_be16(len);
00124 
00125         if (vendor == EAP_VENDOR_IETF) {
00126                 wpabuf_put_u8(buf, type);
00127         } else {
00128                 wpabuf_put_u8(buf, EAP_TYPE_EXPANDED);
00129                 wpabuf_put_be24(buf, vendor);
00130                 wpabuf_put_be32(buf, type);
00131         }
00132 
00133         return buf;
00134 }
00135 
00136 
00146 void eap_update_len(struct wpabuf *msg)
00147 {
00148         struct eap_hdr *hdr;
00149         hdr = wpabuf_mhead(msg);
00150         if (wpabuf_len(msg) < sizeof(*hdr))
00151                 return;
00152         hdr->length = host_to_be16(wpabuf_len(msg));
00153 }
00154 
00155 
00161 u8 eap_get_id(const struct wpabuf *msg)
00162 {
00163         const struct eap_hdr *eap;
00164 
00165         if (wpabuf_len(msg) < sizeof(*eap))
00166                 return 0;
00167 
00168         eap = wpabuf_head(msg);
00169         return eap->identifier;
00170 }
00171 
00172 
00178 EapType eap_get_type(const struct wpabuf *msg)
00179 {
00180         if (wpabuf_len(msg) < sizeof(struct eap_hdr) + 1)
00181                 return EAP_TYPE_NONE;
00182 
00183         return ((const u8 *) wpabuf_head(msg))[sizeof(struct eap_hdr)];
00184 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34