]> The Tcpdump Group git mirrors - tcpdump/blob - print-radius.c
Fix a bunch of de-constifications.
[tcpdump] / print-radius.c
1 /*
2 * Copyright (C) 2000 Alfredo Andres Omella. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 * 3. The names of the authors may not be used to endorse or promote
15 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22 /*
23 * Radius printer routines as specified on:
24 *
25 * RFC 2865:
26 * "Remote Authentication Dial In User Service (RADIUS)"
27 *
28 * RFC 2866:
29 * "RADIUS Accounting"
30 *
31 * RFC 2867:
32 * "RADIUS Accounting Modifications for Tunnel Protocol Support"
33 *
34 * RFC 2868:
35 * "RADIUS Attributes for Tunnel Protocol Support"
36 *
37 * RFC 2869:
38 * "RADIUS Extensions"
39 *
40 * RFC 4675:
41 * "RADIUS Attributes for Virtual LAN and Priority Support"
42 *
43 * RFC 5176:
44 * "Dynamic Authorization Extensions to RADIUS"
45 *
46 * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
47 *
48 * TODO: Among other things to print ok MacIntosh and Vendor values
49 */
50
51 #ifdef HAVE_CONFIG_H
52 #include "config.h"
53 #endif
54
55 #include <tcpdump-stdinc.h>
56
57 #include <string.h>
58
59 #include "interface.h"
60 #include "addrtoname.h"
61 #include "extract.h"
62 #include "oui.h"
63
64 static const char tstr[] = " [|radius]";
65
66 #define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
67
68 #define PRINT_HEX(bytes_len, ptr_data) \
69 while(bytes_len) \
70 { \
71 ND_PRINT((ndo, "%02X", *ptr_data )); \
72 ptr_data++; \
73 bytes_len--; \
74 }
75
76
77 /* Radius packet codes */
78 #define RADCMD_ACCESS_REQ 1 /* Access-Request */
79 #define RADCMD_ACCESS_ACC 2 /* Access-Accept */
80 #define RADCMD_ACCESS_REJ 3 /* Access-Reject */
81 #define RADCMD_ACCOUN_REQ 4 /* Accounting-Request */
82 #define RADCMD_ACCOUN_RES 5 /* Accounting-Response */
83 #define RADCMD_ACCESS_CHA 11 /* Access-Challenge */
84 #define RADCMD_STATUS_SER 12 /* Status-Server */
85 #define RADCMD_STATUS_CLI 13 /* Status-Client */
86 #define RADCMD_DISCON_REQ 40 /* Disconnect-Request */
87 #define RADCMD_DISCON_ACK 41 /* Disconnect-ACK */
88 #define RADCMD_DISCON_NAK 42 /* Disconnect-NAK */
89 #define RADCMD_COA_REQ 43 /* CoA-Request */
90 #define RADCMD_COA_ACK 44 /* CoA-ACK */
91 #define RADCMD_COA_NAK 45 /* CoA-NAK */
92 #define RADCMD_RESERVED 255 /* Reserved */
93
94 static const struct tok radius_command_values[] = {
95 { RADCMD_ACCESS_REQ, "Access-Request" },
96 { RADCMD_ACCESS_ACC, "Access-Accept" },
97 { RADCMD_ACCESS_REJ, "Access-Reject" },
98 { RADCMD_ACCOUN_REQ, "Accounting-Request" },
99 { RADCMD_ACCOUN_RES, "Accounting-Response" },
100 { RADCMD_ACCESS_CHA, "Access-Challenge" },
101 { RADCMD_STATUS_SER, "Status-Server" },
102 { RADCMD_STATUS_CLI, "Status-Client" },
103 { RADCMD_DISCON_REQ, "Disconnect-Request" },
104 { RADCMD_DISCON_ACK, "Disconnect-ACK" },
105 { RADCMD_DISCON_NAK, "Disconnect-NAK" },
106 { RADCMD_COA_REQ, "CoA-Request" },
107 { RADCMD_COA_ACK, "CoA-ACK" },
108 { RADCMD_COA_NAK, "CoA-NAK" },
109 { RADCMD_RESERVED, "Reserved" },
110 { 0, NULL}
111 };
112
113 /********************************/
114 /* Begin Radius Attribute types */
115 /********************************/
116 #define SERV_TYPE 6
117 #define FRM_IPADDR 8
118 #define LOG_IPHOST 14
119 #define LOG_SERVICE 15
120 #define FRM_IPX 23
121 #define SESSION_TIMEOUT 27
122 #define IDLE_TIMEOUT 28
123 #define FRM_ATALK_LINK 37
124 #define FRM_ATALK_NETWORK 38
125
126 #define ACCT_DELAY 41
127 #define ACCT_SESSION_TIME 46
128
129 #define EGRESS_VLAN_ID 56
130 #define EGRESS_VLAN_NAME 58
131
132 #define TUNNEL_TYPE 64
133 #define TUNNEL_MEDIUM 65
134 #define TUNNEL_CLIENT_END 66
135 #define TUNNEL_SERVER_END 67
136 #define TUNNEL_PASS 69
137
138 #define ARAP_PASS 70
139 #define ARAP_FEATURES 71
140
141 #define TUNNEL_PRIV_GROUP 81
142 #define TUNNEL_ASSIGN_ID 82
143 #define TUNNEL_PREFERENCE 83
144
145 #define ARAP_CHALLENGE_RESP 84
146 #define ACCT_INT_INTERVAL 85
147
148 #define TUNNEL_CLIENT_AUTH 90
149 #define TUNNEL_SERVER_AUTH 91
150 /********************************/
151 /* End Radius Attribute types */
152 /********************************/
153
154 #define RFC4675_TAGGED 0x31
155 #define RFC4675_UNTAGGED 0x32
156
157 static const struct tok rfc4675_tagged[] = {
158 { RFC4675_TAGGED, "Tagged" },
159 { RFC4675_UNTAGGED, "Untagged" },
160 { 0, NULL}
161 };
162
163
164 static void print_attr_string(netdissect_options *, register const u_char *, u_int, u_short );
165 static void print_attr_num(netdissect_options *, register const u_char *, u_int, u_short );
166 static void print_vendor_attr(netdissect_options *, register const u_char *, u_int, u_short );
167 static void print_attr_address(netdissect_options *, register const u_char *, u_int, u_short);
168 static void print_attr_time(netdissect_options *, register const u_char *, u_int, u_short);
169 static void print_attr_strange(netdissect_options *, register const u_char *, u_int, u_short);
170
171
172 struct radius_hdr { uint8_t code; /* Radius packet code */
173 uint8_t id; /* Radius packet id */
174 uint16_t len; /* Radius total length */
175 uint8_t auth[16]; /* Authenticator */
176 };
177
178 #define MIN_RADIUS_LEN 20
179
180 struct radius_attr { uint8_t type; /* Attribute type */
181 uint8_t len; /* Attribute length */
182 };
183
184
185 /* Service-Type Attribute standard values */
186 static const char *serv_type[]={ NULL,
187 "Login",
188 "Framed",
189 "Callback Login",
190 "Callback Framed",
191 "Outbound",
192 "Administrative",
193 "NAS Prompt",
194 "Authenticate Only",
195 "Callback NAS Prompt",
196 "Call Check",
197 "Callback Administrative",
198 };
199
200 /* Framed-Protocol Attribute standard values */
201 static const char *frm_proto[]={ NULL,
202 "PPP",
203 "SLIP",
204 "ARAP",
205 "Gandalf proprietary",
206 "Xylogics IPX/SLIP",
207 "X.75 Synchronous",
208 };
209
210 /* Framed-Routing Attribute standard values */
211 static const char *frm_routing[]={ "None",
212 "Send",
213 "Listen",
214 "Send&Listen",
215 };
216
217 /* Framed-Compression Attribute standard values */
218 static const char *frm_comp[]={ "None",
219 "VJ TCP/IP",
220 "IPX",
221 "Stac-LZS",
222 };
223
224 /* Login-Service Attribute standard values */
225 static const char *login_serv[]={ "Telnet",
226 "Rlogin",
227 "TCP Clear",
228 "PortMaster(proprietary)",
229 "LAT",
230 "X.25-PAD",
231 "X.25-T3POS",
232 "Unassigned",
233 "TCP Clear Quiet",
234 };
235
236
237 /* Termination-Action Attribute standard values */
238 static const char *term_action[]={ "Default",
239 "RADIUS-Request",
240 };
241
242 /* Ingress-Filters Attribute standard values */
243 static const char *ingress_filters[]={ NULL,
244 "Enabled",
245 "Disabled",
246 };
247
248 /* NAS-Port-Type Attribute standard values */
249 static const char *nas_port_type[]={ "Async",
250 "Sync",
251 "ISDN Sync",
252 "ISDN Async V.120",
253 "ISDN Async V.110",
254 "Virtual",
255 "PIAFS",
256 "HDLC Clear Channel",
257 "X.25",
258 "X.75",
259 "G.3 Fax",
260 "SDSL",
261 "ADSL-CAP",
262 "ADSL-DMT",
263 "ISDN-DSL",
264 "Ethernet",
265 "xDSL",
266 "Cable",
267 "Wireless - Other",
268 "Wireless - IEEE 802.11",
269 };
270
271 /* Acct-Status-Type Accounting Attribute standard values */
272 static const char *acct_status[]={ NULL,
273 "Start",
274 "Stop",
275 "Interim-Update",
276 "Unassigned",
277 "Unassigned",
278 "Unassigned",
279 "Accounting-On",
280 "Accounting-Off",
281 "Tunnel-Start",
282 "Tunnel-Stop",
283 "Tunnel-Reject",
284 "Tunnel-Link-Start",
285 "Tunnel-Link-Stop",
286 "Tunnel-Link-Reject",
287 "Failed",
288 };
289
290 /* Acct-Authentic Accounting Attribute standard values */
291 static const char *acct_auth[]={ NULL,
292 "RADIUS",
293 "Local",
294 "Remote",
295 };
296
297 /* Acct-Terminate-Cause Accounting Attribute standard values */
298 static const char *acct_term[]={ NULL,
299 "User Request",
300 "Lost Carrier",
301 "Lost Service",
302 "Idle Timeout",
303 "Session Timeout",
304 "Admin Reset",
305 "Admin Reboot",
306 "Port Error",
307 "NAS Error",
308 "NAS Request",
309 "NAS Reboot",
310 "Port Unneeded",
311 "Port Preempted",
312 "Port Suspended",
313 "Service Unavailable",
314 "Callback",
315 "User Error",
316 "Host Request",
317 };
318
319 /* Tunnel-Type Attribute standard values */
320 static const char *tunnel_type[]={ NULL,
321 "PPTP",
322 "L2F",
323 "L2TP",
324 "ATMP",
325 "VTP",
326 "AH",
327 "IP-IP",
328 "MIN-IP-IP",
329 "ESP",
330 "GRE",
331 "DVS",
332 "IP-in-IP Tunneling",
333 };
334
335 /* Tunnel-Medium-Type Attribute standard values */
336 static const char *tunnel_medium[]={ NULL,
337 "IPv4",
338 "IPv6",
339 "NSAP",
340 "HDLC",
341 "BBN 1822",
342 "802",
343 "E.163",
344 "E.164",
345 "F.69",
346 "X.121",
347 "IPX",
348 "Appletalk",
349 "Decnet IV",
350 "Banyan Vines",
351 "E.164 with NSAP subaddress",
352 };
353
354 /* ARAP-Zone-Access Attribute standard values */
355 static const char *arap_zone[]={ NULL,
356 "Only access to dfl zone",
357 "Use zone filter inc.",
358 "Not used",
359 "Use zone filter exc.",
360 };
361
362 static const char *prompt[]={ "No Echo",
363 "Echo",
364 };
365
366
367 struct attrtype { const char *name; /* Attribute name */
368 const char **subtypes; /* Standard Values (if any) */
369 u_char siz_subtypes; /* Size of total standard values */
370 u_char first_subtype; /* First standard value is 0 or 1 */
371 void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short);
372 } attr_type[]=
373 {
374 { NULL, NULL, 0, 0, NULL },
375 { "User-Name", NULL, 0, 0, print_attr_string },
376 { "User-Password", NULL, 0, 0, NULL },
377 { "CHAP-Password", NULL, 0, 0, NULL },
378 { "NAS-IP-Address", NULL, 0, 0, print_attr_address },
379 { "NAS-Port", NULL, 0, 0, print_attr_num },
380 { "Service-Type", serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num },
381 { "Framed-Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num },
382 { "Framed-IP-Address", NULL, 0, 0, print_attr_address },
383 { "Framed-IP-Netmask", NULL, 0, 0, print_attr_address },
384 { "Framed-Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num },
385 { "Filter-Id", NULL, 0, 0, print_attr_string },
386 { "Framed-MTU", NULL, 0, 0, print_attr_num },
387 { "Framed-Compression", frm_comp, TAM_SIZE(frm_comp), 0, print_attr_num },
388 { "Login-IP-Host", NULL, 0, 0, print_attr_address },
389 { "Login-Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
390 { "Login-TCP-Port", NULL, 0, 0, print_attr_num },
391 { "Unassigned", NULL, 0, 0, NULL }, /*17*/
392 { "Reply-Message", NULL, 0, 0, print_attr_string },
393 { "Callback-Number", NULL, 0, 0, print_attr_string },
394 { "Callback-Id", NULL, 0, 0, print_attr_string },
395 { "Unassigned", NULL, 0, 0, NULL }, /*21*/
396 { "Framed-Route", NULL, 0, 0, print_attr_string },
397 { "Framed-IPX-Network", NULL, 0, 0, print_attr_num },
398 { "State", NULL, 0, 0, print_attr_string },
399 { "Class", NULL, 0, 0, print_attr_string },
400 { "Vendor-Specific", NULL, 0, 0, print_vendor_attr },
401 { "Session-Timeout", NULL, 0, 0, print_attr_num },
402 { "Idle-Timeout", NULL, 0, 0, print_attr_num },
403 { "Termination-Action", term_action, TAM_SIZE(term_action), 0, print_attr_num },
404 { "Called-Station-Id", NULL, 0, 0, print_attr_string },
405 { "Calling-Station-Id", NULL, 0, 0, print_attr_string },
406 { "NAS-Identifier", NULL, 0, 0, print_attr_string },
407 { "Proxy-State", NULL, 0, 0, print_attr_string },
408 { "Login-LAT-Service", NULL, 0, 0, print_attr_string },
409 { "Login-LAT-Node", NULL, 0, 0, print_attr_string },
410 { "Login-LAT-Group", NULL, 0, 0, print_attr_string },
411 { "Framed-AppleTalk-Link", NULL, 0, 0, print_attr_num },
412 { "Framed-AppleTalk-Network", NULL, 0, 0, print_attr_num },
413 { "Framed-AppleTalk-Zone", NULL, 0, 0, print_attr_string },
414 { "Acct-Status-Type", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num },
415 { "Acct-Delay-Time", NULL, 0, 0, print_attr_num },
416 { "Acct-Input-Octets", NULL, 0, 0, print_attr_num },
417 { "Acct-Output-Octets", NULL, 0, 0, print_attr_num },
418 { "Acct-Session-Id", NULL, 0, 0, print_attr_string },
419 { "Acct-Authentic", acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num },
420 { "Acct-Session-Time", NULL, 0, 0, print_attr_num },
421 { "Acct-Input-Packets", NULL, 0, 0, print_attr_num },
422 { "Acct-Output-Packets", NULL, 0, 0, print_attr_num },
423 { "Acct-Terminate-Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num },
424 { "Acct-Multi-Session-Id", NULL, 0, 0, print_attr_string },
425 { "Acct-Link-Count", NULL, 0, 0, print_attr_num },
426 { "Acct-Input-Gigawords", NULL, 0, 0, print_attr_num },
427 { "Acct-Output-Gigawords", NULL, 0, 0, print_attr_num },
428 { "Unassigned", NULL, 0, 0, NULL }, /*54*/
429 { "Event-Timestamp", NULL, 0, 0, print_attr_time },
430 { "Egress-VLANID", NULL, 0, 0, print_attr_num },
431 { "Ingress-Filters", ingress_filters, TAM_SIZE(ingress_filters)-1, 1, print_attr_num },
432 { "Egress-VLAN-Name", NULL, 0, 0, print_attr_string },
433 { "User-Priority-Table", NULL, 0, 0, NULL },
434 { "CHAP-Challenge", NULL, 0, 0, print_attr_string },
435 { "NAS-Port-Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num },
436 { "Port-Limit", NULL, 0, 0, print_attr_num },
437 { "Login-LAT-Port", NULL, 0, 0, print_attr_string }, /*63*/
438 { "Tunnel-Type", tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num },
439 { "Tunnel-Medium-Type", tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num },
440 { "Tunnel-Client-Endpoint", NULL, 0, 0, print_attr_string },
441 { "Tunnel-Server-Endpoint", NULL, 0, 0, print_attr_string },
442 { "Acct-Tunnel-Connection", NULL, 0, 0, print_attr_string },
443 { "Tunnel-Password", NULL, 0, 0, print_attr_string },
444 { "ARAP-Password", NULL, 0, 0, print_attr_strange },
445 { "ARAP-Features", NULL, 0, 0, print_attr_strange },
446 { "ARAP-Zone-Access", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/
447 { "ARAP-Security", NULL, 0, 0, print_attr_string },
448 { "ARAP-Security-Data", NULL, 0, 0, print_attr_string },
449 { "Password-Retry", NULL, 0, 0, print_attr_num },
450 { "Prompt", prompt, TAM_SIZE(prompt), 0, print_attr_num },
451 { "Connect-Info", NULL, 0, 0, print_attr_string },
452 { "Configuration-Token", NULL, 0, 0, print_attr_string },
453 { "EAP-Message", NULL, 0, 0, print_attr_string },
454 { "Message-Authenticator", NULL, 0, 0, print_attr_string }, /*80*/
455 { "Tunnel-Private-Group-ID", NULL, 0, 0, print_attr_string },
456 { "Tunnel-Assignment-ID", NULL, 0, 0, print_attr_string },
457 { "Tunnel-Preference", NULL, 0, 0, print_attr_num },
458 { "ARAP-Challenge-Response", NULL, 0, 0, print_attr_strange },
459 { "Acct-Interim-Interval", NULL, 0, 0, print_attr_num },
460 { "Acct-Tunnel-Packets-Lost", NULL, 0, 0, print_attr_num }, /*86*/
461 { "NAS-Port-Id", NULL, 0, 0, print_attr_string },
462 { "Framed-Pool", NULL, 0, 0, print_attr_string },
463 { "CUI", NULL, 0, 0, print_attr_string },
464 { "Tunnel-Client-Auth-ID", NULL, 0, 0, print_attr_string },
465 { "Tunnel-Server-Auth-ID", NULL, 0, 0, print_attr_string },
466 { "Unassigned", NULL, 0, 0, NULL }, /*92*/
467 { "Unassigned", NULL, 0, 0, NULL } /*93*/
468 };
469
470
471 /*****************************/
472 /* Print an attribute string */
473 /* value pointed by 'data' */
474 /* and 'length' size. */
475 /*****************************/
476 /* Returns nothing. */
477 /*****************************/
478 static void
479 print_attr_string(netdissect_options *ndo,
480 register const u_char *data, u_int length, u_short attr_code)
481 {
482 register u_int i;
483
484 ND_TCHECK2(data[0],length);
485
486 switch(attr_code)
487 {
488 case TUNNEL_PASS:
489 if (length < 3)
490 {
491 ND_PRINT((ndo, "%s", tstr));
492 return;
493 }
494 if (*data && (*data <=0x1F) )
495 ND_PRINT((ndo, "Tag[%u] ", *data));
496 else
497 ND_PRINT((ndo, "Tag[Unused] "));
498 data++;
499 length--;
500 ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data)));
501 data+=2;
502 length-=2;
503 break;
504 case TUNNEL_CLIENT_END:
505 case TUNNEL_SERVER_END:
506 case TUNNEL_PRIV_GROUP:
507 case TUNNEL_ASSIGN_ID:
508 case TUNNEL_CLIENT_AUTH:
509 case TUNNEL_SERVER_AUTH:
510 if (*data <= 0x1F)
511 {
512 if (length < 1)
513 {
514 ND_PRINT((ndo, "%s", tstr));
515 return;
516 }
517 if (*data)
518 ND_PRINT((ndo, "Tag[%u] ", *data));
519 else
520 ND_PRINT((ndo, "Tag[Unused] "));
521 data++;
522 length--;
523 }
524 break;
525 case EGRESS_VLAN_NAME:
526 ND_PRINT((ndo, "%s (0x%02x) ",
527 tok2str(rfc4675_tagged,"Unknown tag",*data),
528 *data));
529 data++;
530 length--;
531 break;
532 }
533
534 for (i=0; *data && i < length ; i++, data++)
535 ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data));
536
537 return;
538
539 trunc:
540 ND_PRINT((ndo, "%s", tstr));
541 }
542
543 /*
544 * print vendor specific attributes
545 */
546 static void
547 print_vendor_attr(netdissect_options *ndo,
548 register const u_char *data, u_int length, u_short attr_code _U_)
549 {
550 u_int idx;
551 u_int vendor_id;
552 u_int vendor_type;
553 u_int vendor_length;
554
555 if (length < 4)
556 goto trunc;
557 ND_TCHECK2(*data, 4);
558 vendor_id = EXTRACT_32BITS(data);
559 data+=4;
560 length-=4;
561
562 ND_PRINT((ndo, "Vendor: %s (%u)",
563 tok2str(smi_values,"Unknown",vendor_id),
564 vendor_id));
565
566 while (length >= 2) {
567 ND_TCHECK2(*data, 2);
568
569 vendor_type = *(data);
570 vendor_length = *(data+1);
571
572 if (vendor_length < 2)
573 {
574 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
575 vendor_type,
576 vendor_length));
577 return;
578 }
579 if (vendor_length > length)
580 {
581 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
582 vendor_type,
583 vendor_length));
584 return;
585 }
586 data+=2;
587 vendor_length-=2;
588 length-=2;
589 ND_TCHECK2(*data, vendor_length);
590
591 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u, Value: ",
592 vendor_type,
593 vendor_length));
594 for (idx = 0; idx < vendor_length ; idx++, data++)
595 ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data));
596 length-=vendor_length;
597 }
598 return;
599
600 trunc:
601 ND_PRINT((ndo, "%s", tstr));
602 }
603
604 /******************************/
605 /* Print an attribute numeric */
606 /* value pointed by 'data' */
607 /* and 'length' size. */
608 /******************************/
609 /* Returns nothing. */
610 /******************************/
611 static void
612 print_attr_num(netdissect_options *ndo,
613 register const u_char *data, u_int length, u_short attr_code)
614 {
615 uint32_t timeout;
616
617 if (length != 4)
618 {
619 ND_PRINT((ndo, "ERROR: length %u != 4", length));
620 return;
621 }
622
623 ND_TCHECK2(data[0],4);
624 /* This attribute has standard values */
625 if (attr_type[attr_code].siz_subtypes)
626 {
627 static const char **table;
628 uint32_t data_value;
629 table = attr_type[attr_code].subtypes;
630
631 if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
632 {
633 if (!*data)
634 ND_PRINT((ndo, "Tag[Unused] "));
635 else
636 ND_PRINT((ndo, "Tag[%d] ", *data));
637 data++;
638 data_value = EXTRACT_24BITS(data);
639 }
640 else
641 {
642 data_value = EXTRACT_32BITS(data);
643 }
644 if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 +
645 attr_type[attr_code].first_subtype) &&
646 data_value >= attr_type[attr_code].first_subtype )
647 ND_PRINT((ndo, "%s", table[data_value]));
648 else
649 ND_PRINT((ndo, "#%u", data_value));
650 }
651 else
652 {
653 switch(attr_code) /* Be aware of special cases... */
654 {
655 case FRM_IPX:
656 if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
657 ND_PRINT((ndo, "NAS Select"));
658 else
659 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
660 break;
661
662 case SESSION_TIMEOUT:
663 case IDLE_TIMEOUT:
664 case ACCT_DELAY:
665 case ACCT_SESSION_TIME:
666 case ACCT_INT_INTERVAL:
667 timeout = EXTRACT_32BITS( data);
668 if ( timeout < 60 )
669 ND_PRINT((ndo, "%02d secs", timeout));
670 else
671 {
672 if ( timeout < 3600 )
673 ND_PRINT((ndo, "%02d:%02d min",
674 timeout / 60, timeout % 60));
675 else
676 ND_PRINT((ndo, "%02d:%02d:%02d hours",
677 timeout / 3600, (timeout % 3600) / 60,
678 timeout % 60));
679 }
680 break;
681
682 case FRM_ATALK_LINK:
683 if (EXTRACT_32BITS(data) )
684 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
685 else
686 ND_PRINT((ndo, "Unnumbered"));
687 break;
688
689 case FRM_ATALK_NETWORK:
690 if (EXTRACT_32BITS(data) )
691 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
692 else
693 ND_PRINT((ndo, "NAS assigned"));
694 break;
695
696 case TUNNEL_PREFERENCE:
697 if (*data)
698 ND_PRINT((ndo, "Tag[%d] ", *data));
699 else
700 ND_PRINT((ndo, "Tag[Unused] "));
701 data++;
702 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
703 break;
704
705 case EGRESS_VLAN_ID:
706 ND_PRINT((ndo, "%s (0x%02x) ",
707 tok2str(rfc4675_tagged,"Unknown tag",*data),
708 *data));
709 data++;
710 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
711 break;
712
713 default:
714 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
715 break;
716
717 } /* switch */
718
719 } /* if-else */
720
721 return;
722
723 trunc:
724 ND_PRINT((ndo, "%s", tstr));
725 }
726
727 /*****************************/
728 /* Print an attribute IPv4 */
729 /* address value pointed by */
730 /* 'data' and 'length' size. */
731 /*****************************/
732 /* Returns nothing. */
733 /*****************************/
734 static void
735 print_attr_address(netdissect_options *ndo,
736 register const u_char *data, u_int length, u_short attr_code)
737 {
738 if (length != 4)
739 {
740 ND_PRINT((ndo, "ERROR: length %u != 4", length));
741 return;
742 }
743
744 ND_TCHECK2(data[0],4);
745
746 switch(attr_code)
747 {
748 case FRM_IPADDR:
749 case LOG_IPHOST:
750 if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
751 ND_PRINT((ndo, "User Selected"));
752 else
753 if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
754 ND_PRINT((ndo, "NAS Select"));
755 else
756 ND_PRINT((ndo, "%s",ipaddr_string(ndo, data)));
757 break;
758
759 default:
760 ND_PRINT((ndo, "%s", ipaddr_string(ndo, data)));
761 break;
762 }
763
764 return;
765
766 trunc:
767 ND_PRINT((ndo, "%s", tstr));
768 }
769
770 /*************************************/
771 /* Print an attribute of 'secs since */
772 /* January 1, 1970 00:00 UTC' value */
773 /* pointed by 'data' and 'length' */
774 /* size. */
775 /*************************************/
776 /* Returns nothing. */
777 /*************************************/
778 static void
779 print_attr_time(netdissect_options *ndo,
780 register const u_char *data, u_int length, u_short attr_code _U_)
781 {
782 time_t attr_time;
783 char string[26];
784
785 if (length != 4)
786 {
787 ND_PRINT((ndo, "ERROR: length %u != 4", length));
788 return;
789 }
790
791 ND_TCHECK2(data[0],4);
792
793 attr_time = EXTRACT_32BITS(data);
794 strlcpy(string, ctime(&attr_time), sizeof(string));
795 /* Get rid of the newline */
796 string[24] = '\0';
797 ND_PRINT((ndo, "%.24s", string));
798 return;
799
800 trunc:
801 ND_PRINT((ndo, "%s", tstr));
802 }
803
804 /***********************************/
805 /* Print an attribute of 'strange' */
806 /* data format pointed by 'data' */
807 /* and 'length' size. */
808 /***********************************/
809 /* Returns nothing. */
810 /***********************************/
811 static void
812 print_attr_strange(netdissect_options *ndo,
813 register const u_char *data, u_int length, u_short attr_code)
814 {
815 u_short len_data;
816
817 switch(attr_code)
818 {
819 case ARAP_PASS:
820 if (length != 16)
821 {
822 ND_PRINT((ndo, "ERROR: length %u != 16", length));
823 return;
824 }
825 ND_PRINT((ndo, "User_challenge ("));
826 ND_TCHECK2(data[0],8);
827 len_data = 8;
828 PRINT_HEX(len_data, data);
829 ND_PRINT((ndo, ") User_resp("));
830 ND_TCHECK2(data[0],8);
831 len_data = 8;
832 PRINT_HEX(len_data, data);
833 ND_PRINT((ndo, ")"));
834 break;
835
836 case ARAP_FEATURES:
837 if (length != 14)
838 {
839 ND_PRINT((ndo, "ERROR: length %u != 14", length));
840 return;
841 }
842 ND_TCHECK2(data[0],1);
843 if (*data)
844 ND_PRINT((ndo, "User can change password"));
845 else
846 ND_PRINT((ndo, "User cannot change password"));
847 data++;
848 ND_TCHECK2(data[0],1);
849 ND_PRINT((ndo, ", Min password length: %d", *data));
850 data++;
851 ND_PRINT((ndo, ", created at: "));
852 ND_TCHECK2(data[0],4);
853 len_data = 4;
854 PRINT_HEX(len_data, data);
855 ND_PRINT((ndo, ", expires in: "));
856 ND_TCHECK2(data[0],4);
857 len_data = 4;
858 PRINT_HEX(len_data, data);
859 ND_PRINT((ndo, ", Current Time: "));
860 ND_TCHECK2(data[0],4);
861 len_data = 4;
862 PRINT_HEX(len_data, data);
863 break;
864
865 case ARAP_CHALLENGE_RESP:
866 if (length < 8)
867 {
868 ND_PRINT((ndo, "ERROR: length %u != 8", length));
869 return;
870 }
871 ND_TCHECK2(data[0],8);
872 len_data = 8;
873 PRINT_HEX(len_data, data);
874 break;
875 }
876 return;
877
878 trunc:
879 ND_PRINT((ndo, "%s", tstr));
880 }
881
882 static void
883 radius_attrs_print(netdissect_options *ndo,
884 register const u_char *attr, u_int length)
885 {
886 register const struct radius_attr *rad_attr = (const struct radius_attr *)attr;
887 const char *attr_string;
888
889 while (length > 0)
890 {
891 if (length < 2)
892 goto trunc;
893 ND_TCHECK(*rad_attr);
894
895 if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type))
896 attr_string = attr_type[rad_attr->type].name;
897 else
898 attr_string = "Unknown";
899 if (rad_attr->len < 2)
900 {
901 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)",
902 attr_string,
903 rad_attr->type,
904 rad_attr->len));
905 return;
906 }
907 if (rad_attr->len > length)
908 {
909 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)",
910 attr_string,
911 rad_attr->type,
912 rad_attr->len));
913 return;
914 }
915 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u, Value: ",
916 attr_string,
917 rad_attr->type,
918 rad_attr->len));
919
920 if (rad_attr->type < TAM_SIZE(attr_type))
921 {
922 if (rad_attr->len > 2)
923 {
924 if ( attr_type[rad_attr->type].print_func )
925 (*attr_type[rad_attr->type].print_func)(
926 ndo, ((const u_char *)(rad_attr+1)),
927 rad_attr->len - 2, rad_attr->type);
928 }
929 }
930 /* do we also want to see a hex dump ? */
931 if (ndo->ndo_vflag> 1)
932 print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2);
933
934 length-=(rad_attr->len);
935 rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len);
936 }
937 return;
938
939 trunc:
940 ND_PRINT((ndo, "%s", tstr));
941 }
942
943 void
944 radius_print(netdissect_options *ndo,
945 const u_char *dat, u_int length)
946 {
947 register const struct radius_hdr *rad;
948 u_int len, auth_idx;
949
950 ND_TCHECK2(*dat, MIN_RADIUS_LEN);
951 rad = (const struct radius_hdr *)dat;
952 len = EXTRACT_16BITS(&rad->len);
953
954 if (len < MIN_RADIUS_LEN)
955 {
956 ND_PRINT((ndo, "%s", tstr));
957 return;
958 }
959
960 if (len > length)
961 len = length;
962
963 if (ndo->ndo_vflag < 1) {
964 ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u",
965 tok2str(radius_command_values,"Unknown Command",rad->code),
966 rad->code,
967 rad->id,
968 len));
969 return;
970 }
971 else {
972 ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
973 len,
974 tok2str(radius_command_values,"Unknown Command",rad->code),
975 rad->code,
976 rad->id));
977
978 for(auth_idx=0; auth_idx < 16; auth_idx++)
979 ND_PRINT((ndo, "%02x", rad->auth[auth_idx]));
980 }
981
982 if (len > MIN_RADIUS_LEN)
983 radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN);
984 return;
985
986 trunc:
987 ND_PRINT((ndo, "%s", tstr));
988 }