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