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