eap_common.c
Go to the documentation of this file.00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "eap_defs.h"
00020 #include "eap_common.h"
00021
00039 const u8 * eap_hdr_validate(int vendor, EapType eap_type,
00040 const struct wpabuf *msg, size_t *plen)
00041 {
00042 const struct eap_hdr *hdr;
00043 const u8 *pos;
00044 size_t len;
00045
00046 hdr = wpabuf_head(msg);
00047
00048 if (wpabuf_len(msg) < sizeof(*hdr)) {
00049 wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
00050 return NULL;
00051 }
00052
00053 len = be_to_host16(hdr->length);
00054 if (len < sizeof(*hdr) + 1 || len > wpabuf_len(msg)) {
00055 wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
00056 return NULL;
00057 }
00058
00059 pos = (const u8 *) (hdr + 1);
00060
00061 if (*pos == EAP_TYPE_EXPANDED) {
00062 int exp_vendor;
00063 u32 exp_type;
00064 if (len < sizeof(*hdr) + 8) {
00065 wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP "
00066 "length");
00067 return NULL;
00068 }
00069 pos++;
00070 exp_vendor = WPA_GET_BE24(pos);
00071 pos += 3;
00072 exp_type = WPA_GET_BE32(pos);
00073 pos += 4;
00074 if (exp_vendor != vendor || exp_type != (u32) eap_type) {
00075 wpa_printf(MSG_INFO, "EAP: Invalid expanded frame "
00076 "type");
00077 return NULL;
00078 }
00079
00080 *plen = len - sizeof(*hdr) - 8;
00081 return pos;
00082 } else {
00083 if (vendor != EAP_VENDOR_IETF || *pos != eap_type) {
00084 wpa_printf(MSG_INFO, "EAP: Invalid frame type");
00085 return NULL;
00086 }
00087 *plen = len - sizeof(*hdr) - 1;
00088 return pos + 1;
00089 }
00090 }
00091
00092
00110 struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
00111 u8 code, u8 identifier)
00112 {
00113 struct wpabuf *buf;
00114 struct eap_hdr *hdr;
00115 size_t len;
00116
00117 len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
00118 payload_len;
00119 buf = wpabuf_alloc(len);
00120 if (buf == NULL)
00121 return NULL;
00122
00123 hdr = wpabuf_put(buf, sizeof(*hdr));
00124 hdr->code = code;
00125 hdr->identifier = identifier;
00126 hdr->length = host_to_be16(len);
00127
00128 if (vendor == EAP_VENDOR_IETF) {
00129 wpabuf_put_u8(buf, type);
00130 } else {
00131 wpabuf_put_u8(buf, EAP_TYPE_EXPANDED);
00132 wpabuf_put_be24(buf, vendor);
00133 wpabuf_put_be32(buf, type);
00134 }
00135
00136 return buf;
00137 }
00138
00139
00150 void eap_update_len(struct wpabuf *msg)
00151 {
00152 struct eap_hdr *hdr;
00153 hdr = wpabuf_mhead(msg);
00154 if (wpabuf_len(msg) < sizeof(*hdr))
00155 return;
00156 hdr->length = host_to_be16(wpabuf_len(msg));
00157 }
00158
00159
00166 u8 eap_get_id(const struct wpabuf *msg)
00167 {
00168 const struct eap_hdr *eap;
00169
00170 if (wpabuf_len(msg) < sizeof(*eap))
00171 return 0;
00172
00173 eap = wpabuf_head(msg);
00174 return eap->identifier;
00175 }
00176
00177
00184 EapType eap_get_type(const struct wpabuf *msg)
00185 {
00186 if (wpabuf_len(msg) < sizeof(struct eap_hdr) + 1)
00187 return EAP_TYPE_NONE;
00188
00189 return ((const u8 *) wpabuf_head(msg))[sizeof(struct eap_hdr)];
00190 }
00191