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