]> The Tcpdump Group git mirrors - tcpdump/blob - print-eap.c
NDOize EAP, IEEE CFM, lwres, SIP & Syslog decoders
[tcpdump] / print-eap.c
1 /*
2 * Copyright (c) 2004 - Michael Richardson <mcr@xelerance.com>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code distributions
6 * retain the above copyright notice and this paragraph in its entirety, (2)
7 * distributions including binary code include the above copyright notice and
8 * this paragraph in its entirety in the documentation or other materials
9 * provided with the distribution, and (3) all advertising materials mentioning
10 * features or use of this software display the following acknowledgement:
11 * ``This product includes software developed by the University of California,
12 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
13 * the University nor the names of its contributors may be used to endorse
14 * or promote products derived from this software without specific prior
15 * written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * Format and print EAP packets.
21 *
22 */
23
24 #define NETDISSECT_REWORKED
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <tcpdump-stdinc.h>
30
31 #include "netdissect.h"
32 #include "interface.h"
33 #include "extract.h"
34
35 #define EAP_FRAME_TYPE_PACKET 0
36 #define EAP_FRAME_TYPE_START 1
37 #define EAP_FRAME_TYPE_LOGOFF 2
38 #define EAP_FRAME_TYPE_KEY 3
39 #define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4
40
41 struct eap_frame_t {
42 unsigned char version;
43 unsigned char type;
44 unsigned char length[2];
45 };
46
47 static const struct tok eap_frame_type_values[] = {
48 { EAP_FRAME_TYPE_PACKET, "EAP packet" },
49 { EAP_FRAME_TYPE_START, "EAPOL start" },
50 { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" },
51 { EAP_FRAME_TYPE_KEY, "EAPOL key" },
52 { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" },
53 { 0, NULL}
54 };
55
56 /* RFC 3748 */
57 struct eap_packet_t {
58 unsigned char code;
59 unsigned char id;
60 unsigned char length[2];
61 };
62
63 #define EAP_REQUEST 1
64 #define EAP_RESPONSE 2
65 #define EAP_SUCCESS 3
66 #define EAP_FAILURE 4
67
68 static const struct tok eap_code_values[] = {
69 { EAP_REQUEST, "Request" },
70 { EAP_RESPONSE, "Response" },
71 { EAP_SUCCESS, "Success" },
72 { EAP_FAILURE, "Failure" },
73 { 0, NULL}
74 };
75
76 #define EAP_TYPE_NO_PROPOSED 0
77 #define EAP_TYPE_IDENTITY 1
78 #define EAP_TYPE_NOTIFICATION 2
79 #define EAP_TYPE_NAK 3
80 #define EAP_TYPE_MD5_CHALLENGE 4
81 #define EAP_TYPE_OTP 5
82 #define EAP_TYPE_GTC 6
83 #define EAP_TYPE_TLS 13 /* RFC 2716 */
84 #define EAP_TYPE_SIM 18 /* RFC 4186 */
85 #define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */
86 #define EAP_TYPE_AKA 23 /* RFC 4187 */
87 #define EAP_TYPE_FAST 43 /* RFC 4851 */
88 #define EAP_TYPE_EXPANDED_TYPES 254
89 #define EAP_TYPE_EXPERIMENTAL 255
90
91 static const struct tok eap_type_values[] = {
92 { EAP_TYPE_NO_PROPOSED, "No proposed" },
93 { EAP_TYPE_IDENTITY, "Identity" },
94 { EAP_TYPE_NOTIFICATION, "Notification" },
95 { EAP_TYPE_NAK, "Nak" },
96 { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" },
97 { EAP_TYPE_OTP, "OTP" },
98 { EAP_TYPE_GTC, "GTC" },
99 { EAP_TYPE_TLS, "TLS" },
100 { EAP_TYPE_SIM, "SIM" },
101 { EAP_TYPE_TTLS, "TTLS" },
102 { EAP_TYPE_AKA, "AKA" },
103 { EAP_TYPE_FAST, "FAST" },
104 { EAP_TYPE_EXPANDED_TYPES, "Expanded types" },
105 { EAP_TYPE_EXPERIMENTAL, "Experimental" },
106 { 0, NULL}
107 };
108
109 #define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7)
110
111 /* RFC 2716 - EAP TLS bits */
112 #define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7)
113 #define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6)
114 #define EAP_TLS_FLAGS_START (1 << 5)
115
116 static const struct tok eap_tls_flags_values[] = {
117 { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" },
118 { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"},
119 { EAP_TLS_FLAGS_START, "Start bit"},
120 { 0, NULL}
121 };
122
123 #define EAP_TTLS_VERSION(x) ((x)&0x07)
124
125 /* EAP-AKA and EAP-SIM - RFC 4187 */
126 #define EAP_AKA_CHALLENGE 1
127 #define EAP_AKA_AUTH_REJECT 2
128 #define EAP_AKA_SYNC_FAILURE 4
129 #define EAP_AKA_IDENTITY 5
130 #define EAP_SIM_START 10
131 #define EAP_SIM_CHALLENGE 11
132 #define EAP_AKA_NOTIFICATION 12
133 #define EAP_AKA_REAUTH 13
134 #define EAP_AKA_CLIENT_ERROR 14
135
136 static const struct tok eap_aka_subtype_values[] = {
137 { EAP_AKA_CHALLENGE, "Challenge" },
138 { EAP_AKA_AUTH_REJECT, "Auth reject" },
139 { EAP_AKA_SYNC_FAILURE, "Sync failure" },
140 { EAP_AKA_IDENTITY, "Identity" },
141 { EAP_SIM_START, "Start" },
142 { EAP_SIM_CHALLENGE, "Challenge" },
143 { EAP_AKA_NOTIFICATION, "Notification" },
144 { EAP_AKA_REAUTH, "Reauth" },
145 { EAP_AKA_CLIENT_ERROR, "Client error" },
146 { 0, NULL}
147 };
148
149 /*
150 * Print EAP requests / responses
151 */
152 void
153 eap_print(netdissect_options *ndo,
154 register const u_char *cp,
155 u_int length _U_)
156 {
157 const struct eap_frame_t *eap;
158 const u_char *tptr;
159 u_int tlen, type, subtype;
160 int count=0, len;
161
162 tptr = cp;
163 tlen = length;
164 eap = (const struct eap_frame_t *)cp;
165 ND_TCHECK(*eap);
166
167 /* in non-verbose mode just lets print the basic info */
168 if (ndo->ndo_vflag < 1) {
169 ND_PRINT((ndo, "%s (%u) v%u, len %u",
170 tok2str(eap_frame_type_values, "unknown", eap->type),
171 eap->type,
172 eap->version,
173 EXTRACT_16BITS(eap->length)));
174 return;
175 }
176
177 ND_PRINT((ndo, "%s (%u) v%u, len %u",
178 tok2str(eap_frame_type_values, "unknown", eap->type),
179 eap->type,
180 eap->version,
181 EXTRACT_16BITS(eap->length)));
182
183 tptr += sizeof(const struct eap_frame_t);
184 tlen -= sizeof(const struct eap_frame_t);
185
186 switch (eap->type) {
187 case EAP_FRAME_TYPE_PACKET:
188 type = *(tptr);
189 len = EXTRACT_16BITS(tptr+2);
190 ND_PRINT((ndo, ", %s (%u), id %u, len %u",
191 tok2str(eap_code_values, "unknown", type),
192 type,
193 *(tptr+1),
194 len));
195
196 if (!ND_TTEST2(*tptr, len))
197 goto trunc;
198
199 if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */
200 subtype = *(tptr+4);
201 ND_PRINT((ndo, "\n\t\t Type %s (%u)",
202 tok2str(eap_type_values, "unknown", *(tptr+4)),
203 *(tptr + 4)));
204
205 switch (subtype) {
206 case EAP_TYPE_IDENTITY:
207 if (len - 5 > 0) {
208 ND_PRINT((ndo, ", Identity: "));
209 safeputs(ndo, tptr + 5, len - 5);
210 }
211 break;
212
213 case EAP_TYPE_NOTIFICATION:
214 if (len - 5 > 0) {
215 ND_PRINT((ndo, ", Notification: "));
216 safeputs(ndo, tptr + 5, len - 5);
217 }
218 break;
219
220 case EAP_TYPE_NAK:
221 count = 5;
222
223 /*
224 * one or more octets indicating
225 * the desired authentication
226 * type one octet per type
227 */
228 while (count < len) {
229 ND_PRINT((ndo, " %s (%u),",
230 tok2str(eap_type_values, "unknown", *(tptr+count)),
231 *(tptr + count)));
232 count++;
233 }
234 break;
235
236 case EAP_TYPE_TTLS:
237 ND_PRINT((ndo, " TTLSv%u",
238 EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */
239 case EAP_TYPE_TLS:
240 ND_PRINT((ndo, " flags [%s] 0x%02x,",
241 bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
242 *(tptr + 5)));
243
244 if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
245 ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
246 }
247 break;
248
249 case EAP_TYPE_FAST:
250 ND_PRINT((ndo, " FASTv%u",
251 EAP_TTLS_VERSION(*(tptr + 5))));
252 ND_PRINT((ndo, " flags [%s] 0x%02x,",
253 bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
254 *(tptr + 5)));
255
256 if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
257 ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6)));
258 }
259
260 /* FIXME - TLV attributes follow */
261 break;
262
263 case EAP_TYPE_AKA:
264 case EAP_TYPE_SIM:
265 ND_PRINT((ndo, " subtype [%s] 0x%02x,",
266 tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)),
267 *(tptr + 5)));
268
269 /* FIXME - TLV attributes follow */
270 break;
271
272 case EAP_TYPE_MD5_CHALLENGE:
273 case EAP_TYPE_OTP:
274 case EAP_TYPE_GTC:
275 case EAP_TYPE_EXPANDED_TYPES:
276 case EAP_TYPE_EXPERIMENTAL:
277 default:
278 break;
279 }
280 }
281 break;
282
283 case EAP_FRAME_TYPE_LOGOFF:
284 case EAP_FRAME_TYPE_ENCAP_ASF_ALERT:
285 default:
286 break;
287 }
288 return;
289
290 trunc:
291 ND_PRINT((ndo, "\n\t[|EAP]"));
292 }
293
294 /*
295 * Local Variables:
296 * c-basic-offset: 4
297 * End:
298 */