]> The Tcpdump Group git mirrors - tcpdump/blob - print-radius.c
Add bounds checks.
[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 * 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.19.2.4 2004-02-06 14:38:51 hannes 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 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
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 (*data && (*data <=0x1F) )
458 printf("Tag %u, ",*data);
459 data++;
460 printf("Salt %u ",EXTRACT_16BITS(data) );
461 data+=2;
462 length-=2;
463 break;
464 case TUNNEL_CLIENT_END:
465 case TUNNEL_SERVER_END:
466 case TUNNEL_PRIV_GROUP:
467 case TUNNEL_ASSIGN_ID:
468 case TUNNEL_CLIENT_AUTH:
469 case TUNNEL_SERVER_AUTH:
470 if (*data <= 0x1F)
471 {
472 printf("Tag %u",*data);
473 data++;
474 length--;
475 }
476 break;
477 }
478
479 for (i=0; *data && i < length ; i++, data++)
480 printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
481
482 return;
483
484 trunc:
485 printf("|radius");
486 }
487
488 /*
489 * print vendor specific attributes
490 */
491
492 static void
493 print_vendor_attr(register u_char *data, u_int length, u_short attr_code _U_)
494 {
495 u_int idx;
496 u_int vendor_id;
497 u_int vendor_type;
498 u_int vendor_length;
499
500 /* FIXME: all sort of boundary checks */
501 vendor_id = EXTRACT_32BITS(data);
502 data+=4;
503 length-=4;
504
505 printf("Vendor: %s (%u)",
506 tok2str(smi_values,"Unknown",vendor_id),
507 vendor_id);
508
509 while (length >= 2) {
510 if(!TTEST2(*data, 2))
511 return;
512
513 vendor_type = *(data);
514 vendor_length = *(data+1);
515
516 data+=2;
517 if(!TTEST2(*data, vendor_length))
518 return;
519
520 printf("\n\t Vendor Attribute: %u, Length: %u, Value: ",
521 vendor_type,
522 vendor_length);
523 for (idx = 0; idx < vendor_length ; idx++, data++)
524 printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
525 length-=vendor_length;
526 }
527 }
528
529
530
531 /******************************/
532 /* Print an attribute numeric */
533 /* value pointed by 'data' */
534 /* and 'length' size. */
535 /******************************/
536 /* Returns nothing. */
537 /******************************/
538 static void
539 print_attr_num(register u_char *data, u_int length, u_short attr_code )
540 {
541 u_int8_t tag;
542 u_int32_t timeout;
543
544 if (length != 4)
545 {
546 printf("ERROR: length %u != 4", length);
547 return;
548 }
549
550 TCHECK2(data[0],4);
551 /* This attribute has standard values */
552 if (attr_type[attr_code].siz_subtypes)
553 {
554 static const char **table;
555 u_int32_t data_value;
556 table = attr_type[attr_code].subtypes;
557
558 if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
559 {
560 if (!*data)
561 printf("Tag[Unused]");
562 else
563 printf("Tag[%d]", *data);
564 data++;
565 data_value = EXTRACT_24BITS(data);
566 }
567 else
568 {
569 data_value = EXTRACT_32BITS(data);
570 }
571 if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 +
572 attr_type[attr_code].first_subtype) &&
573 data_value >= attr_type[attr_code].first_subtype )
574 printf("%s",table[data_value]);
575 else
576 printf("#%u",data_value);
577 }
578 else
579 {
580 switch(attr_code) /* Be aware of special cases... */
581 {
582 case FRM_IPX:
583 if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
584 printf("NAS Select");
585 else
586 printf("%d",EXTRACT_32BITS( data) );
587 break;
588
589 case SESSION_TIMEOUT:
590 case IDLE_TIMEOUT:
591 case ACCT_DELAY:
592 case ACCT_SESSION_TIME:
593 case ACCT_INT_INTERVAL:
594 timeout = EXTRACT_32BITS( data);
595 if ( timeout < 60 )
596 printf( "%02d secs", timeout);
597 else
598 {
599 if ( timeout < 3600 )
600 printf( "%02d:%02d min",
601 timeout / 60, timeout % 60);
602 else
603 printf( "%02d:%02d:%02d hours",
604 timeout / 3600, (timeout % 3600) / 60,
605 timeout % 60);
606 }
607 break;
608
609 case FRM_ATALK_LINK:
610 if (EXTRACT_32BITS(data) )
611 printf("%d",EXTRACT_32BITS(data) );
612 else
613 printf("Unnumbered" );
614 break;
615
616 case FRM_ATALK_NETWORK:
617 if (EXTRACT_32BITS(data) )
618 printf("%d",EXTRACT_32BITS(data) );
619 else
620 printf("NAS assigned" );
621 break;
622
623 case TUNNEL_PREFERENCE:
624 tag = *data;
625 data++;
626 if (tag == 0)
627 printf("Tag (Unused) %d",EXTRACT_24BITS(data) );
628 else
629 printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) );
630 break;
631
632 default:
633 printf("%d",EXTRACT_32BITS( data) );
634 break;
635
636 } /* switch */
637
638 } /* if-else */
639
640 return;
641
642 trunc:
643 printf("|radius}");
644 }
645
646
647 /*****************************/
648 /* Print an attribute IPv4 */
649 /* address value pointed by */
650 /* 'data' and 'length' size. */
651 /*****************************/
652 /* Returns nothing. */
653 /*****************************/
654 static void
655 print_attr_address(register u_char *data, u_int length, u_short attr_code )
656 {
657 if (length != 4)
658 {
659 printf("ERROR: length %u != 4", length);
660 return;
661 }
662
663 TCHECK2(data[0],4);
664
665 switch(attr_code)
666 {
667 case FRM_IPADDR:
668 case LOG_IPHOST:
669 if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
670 printf("User Selected");
671 else
672 if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
673 printf("NAS Select");
674 else
675 printf("%s",ipaddr_string(data));
676 break;
677
678 default:
679 printf("%s",ipaddr_string(data) );
680 break;
681 }
682
683 return;
684
685 trunc:
686 printf("|radius");
687 }
688
689
690 /*************************************/
691 /* Print an attribute of 'secs since */
692 /* January 1, 1970 00:00 UTC' value */
693 /* pointed by 'data' and 'length' */
694 /* size. */
695 /*************************************/
696 /* Returns nothing. */
697 /*************************************/
698 static void print_attr_time(register u_char *data, u_int length, u_short attr_code _U_)
699 {
700 time_t attr_time;
701 char string[26];
702
703 if (length != 4)
704 {
705 printf("ERROR: length %u != 4", length);
706 return;
707 }
708
709 TCHECK2(data[0],4);
710
711 attr_time = EXTRACT_32BITS(data);
712 strlcpy(string, ctime(&attr_time), sizeof(string));
713 /* Get rid of the newline */
714 string[24] = '\0';
715 printf("%.24s", string);
716 return;
717
718 trunc:
719 printf("|radius");
720 }
721
722
723 /***********************************/
724 /* Print an attribute of 'strange' */
725 /* data format pointed by 'data' */
726 /* and 'length' size. */
727 /***********************************/
728 /* Returns nothing. */
729 /***********************************/
730 static void print_attr_strange(register u_char *data, u_int length, u_short attr_code)
731 {
732 u_short len_data;
733
734 switch(attr_code)
735 {
736 case ARAP_PASS:
737 if (length != 16)
738 {
739 printf("ERROR: length %u != 16", length);
740 return;
741 }
742 printf("User_challenge (");
743 TCHECK2(data[0],8);
744 len_data = 8;
745 PRINT_HEX(len_data, data);
746 printf(") User_resp(");
747 TCHECK2(data[0],8);
748 len_data = 8;
749 PRINT_HEX(len_data, data);
750 printf(")");
751 break;
752
753 case ARAP_FEATURES:
754 if (length != 14)
755 {
756 printf("ERROR: length %u != 14", length);
757 return;
758 }
759 TCHECK2(data[0],1);
760 if (*data)
761 printf("User can change password");
762 else
763 printf("User cannot change password");
764 data++;
765 TCHECK2(data[0],1);
766 printf(", Min password length: %d",*data);
767 data++;
768 printf(", created at: ");
769 TCHECK2(data[0],4);
770 len_data = 4;
771 PRINT_HEX(len_data, data);
772 printf(", expires in: ");
773 TCHECK2(data[0],4);
774 len_data = 4;
775 PRINT_HEX(len_data, data);
776 printf(", Current Time: ");
777 len_data = 4;
778 TCHECK2(data[0],4);
779 PRINT_HEX(len_data, data);
780 break;
781
782 case ARAP_CHALLENGE_RESP:
783 if (length < 8)
784 {
785 printf("ERROR: length %u != 8", length);
786 return;
787 }
788 TCHECK2(data[0],8);
789 len_data = 8;
790 PRINT_HEX(len_data, data);
791 break;
792 }
793
794 trunc:
795 printf("|radius}");
796 }
797
798
799
800 static void
801 radius_attr_print(register const u_char *attr, u_int length)
802 {
803 register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
804
805 if (length < 3)
806 {
807 printf(" [|radius]");
808 return;
809 }
810
811 while (length > 0)
812 {
813 if (rad_attr->len == 0 && rad_attr->type < (TAM_SIZE(attr_type)-1))
814 {
815 printf("\n\t %s Attribute (%u), zero-length",
816 attr_type[rad_attr->type].name,
817 rad_attr->type);
818 return;
819 }
820 if ( rad_attr->len <= length && rad_attr->type < (TAM_SIZE(attr_type)-1))
821 {
822 printf("\n\t %s Attribute (%u), length: %u, Value: ",
823 attr_type[rad_attr->type].name,
824 rad_attr->type,
825 rad_attr->len);
826
827 if ( !rad_attr->type || (rad_attr->type > (TAM_SIZE(attr_type)-1)) ) {
828 }
829 else {
830 if (rad_attr->len > 2)
831 {
832 if ( attr_type[rad_attr->type].print_func )
833 (*attr_type[rad_attr->type].print_func)(
834 ((u_char *)(rad_attr+1)),
835 rad_attr->len - 2, rad_attr->type);
836 }
837 }
838 }
839 else {
840 printf(" [|radius]");
841 return;
842 }
843 /* do we want to see an additionally hexdump ? */
844 if (vflag> 1 && rad_attr->len >= 2)
845 print_unknown_data((char *)rad_attr+2,"\n\t ",(rad_attr->len)-2);
846
847 length-=(rad_attr->len);
848 rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len);
849 }
850 }
851
852
853 void
854 radius_print(const u_char *dat, u_int length)
855 {
856 register const struct radius_hdr *rad;
857 register u_int i;
858 u_int len, auth_idx;
859
860 if (snapend < dat)
861 {
862 printf(" [|radius]");
863 return;
864 }
865 i = snapend - dat;
866 if (i > length)
867 i = length;
868
869 if (i < MIN_RADIUS_LEN)
870 {
871 printf(" [|radius]");
872 return;
873 }
874
875 rad = (struct radius_hdr *)dat;
876 len = EXTRACT_16BITS(&rad->len);
877
878 if (len < MIN_RADIUS_LEN)
879 {
880 printf(" [|radius]");
881 return;
882 }
883
884 if (len < i)
885 i = len;
886
887 i -= MIN_RADIUS_LEN;
888
889 if (vflag < 1) {
890 printf("RADIUS, %s (%u), id: 0x%02x length: %u",
891 tok2str(radius_command_values,"Unknown Command",rad->code),
892 rad->code,
893 rad->id,
894 length);
895 return;
896 }
897 else {
898 printf("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
899 length,
900 tok2str(radius_command_values,"Unknown Command",rad->code),
901 rad->code,
902 rad->id);
903
904 for(auth_idx=0; auth_idx < 16; auth_idx++)
905 printf("%02x", rad->auth[auth_idx] );
906 }
907
908 if (i)
909 radius_attr_print( dat + MIN_RADIUS_LEN, i);
910 }