Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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 }