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