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