]> The Tcpdump Group git mirrors - tcpdump/blob - print-radius.c
Don't try to print entries before the first one in subtypes.
[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.13 2002-07-03 16:27:12 fenner 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 data_value >= attr_type[attr_code].first_subtype )
531 printf("{%s}",table[data_value]);
532 else
533 printf("{#%d}",data_value);
534 }
535 else
536 {
537 switch(attr_code) /* Be aware of special cases... */
538 {
539 case FRM_IPX:
540 if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
541 printf("{NAS_select}");
542 else
543 printf("{%d}",EXTRACT_32BITS( data) );
544 break;
545
546 case SESSION_TIMEOUT:
547 case IDLE_TIMEOUT:
548 case ACCT_DELAY:
549 case ACCT_SESSION_TIME:
550 case ACCT_INT_INTERVAL:
551 timeout = EXTRACT_32BITS( data);
552 if ( timeout < 60 )
553 printf( "{%02d secs}", timeout);
554 else
555 {
556 if ( timeout < 3600 )
557 printf( "{%02d:%02d min}",
558 timeout / 60, timeout % 60);
559 else
560 printf( "{%02d:%02d:%02d hours}",
561 timeout / 3600, (timeout % 3600) / 60,
562 timeout % 60);
563 }
564 break;
565
566 case FRM_ATALK_LINK:
567 if (EXTRACT_32BITS(data) )
568 printf("{%d}",EXTRACT_32BITS(data) );
569 else
570 printf("{Unnumbered}" );
571 break;
572
573 case FRM_ATALK_NETWORK:
574 if (EXTRACT_32BITS(data) )
575 printf("{%d}",EXTRACT_32BITS(data) );
576 else
577 printf("{NAS_assign}" );
578 break;
579
580 case TUNNEL_PREFERENCE:
581 tag = *data;
582 data++;
583 if (tag == 0)
584 printf("{Tag[Unused] %d}",EXTRACT_24BITS(data) );
585 else
586 printf("{Tag[%d] %d}", tag, EXTRACT_24BITS(data) );
587 break;
588
589 default:
590 printf("{%d}",EXTRACT_32BITS( data) );
591 break;
592
593 } /* switch */
594
595 } /* if-else */
596
597 return;
598
599 trunc:
600 printf("|radius}");
601 }
602
603
604 /*****************************/
605 /* Print an attribute IPv4 */
606 /* address value pointed by */
607 /* 'data' and 'length' size. */
608 /*****************************/
609 /* Returns nothing. */
610 /*****************************/
611 static void
612 print_attr_address(register u_char *data, u_int length, u_short attr_code )
613 {
614 if (length != 4)
615 {
616 printf("{length %u != 4}", length);
617 return;
618 }
619
620 TCHECK2(data[0],4);
621
622 switch(attr_code)
623 {
624 case FRM_IPADDR:
625 case LOG_IPHOST:
626 if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
627 printf("{User_select}");
628 else
629 if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
630 printf("{NAS_select}");
631 else
632 printf("{%s}",ipaddr_string(data));
633 break;
634
635 default:
636 printf("{%s}",ipaddr_string(data) );
637 break;
638 }
639
640 return;
641
642 trunc:
643 printf("{|radius}");
644 }
645
646
647 /*************************************/
648 /* Print an attribute of 'secs since */
649 /* January 1, 1970 00:00 UTC' value */
650 /* pointed by 'data' and 'length' */
651 /* size. */
652 /*************************************/
653 /* Returns nothing. */
654 /*************************************/
655 static void print_attr_time(register u_char *data, u_int length, u_short attr_code)
656 {
657 time_t attr_time;
658 char string[26];
659
660 if (length != 4)
661 {
662 printf("{length %u != 4}", length);
663 return;
664 }
665
666 TCHECK2(data[0],4);
667
668 attr_time = EXTRACT_32BITS(data);
669 strlcpy(string, ctime(&attr_time), sizeof(string));
670 /* Get rid of the newline */
671 string[24] = '\0';
672 printf("{%.24s}", string);
673 return;
674
675 trunc:
676 printf("{|radius}");
677 }
678
679
680 /***********************************/
681 /* Print an attribute of 'strange' */
682 /* data format pointed by 'data' */
683 /* and 'length' size. */
684 /***********************************/
685 /* Returns nothing. */
686 /***********************************/
687 static void print_attr_strange(register u_char *data, u_int length, u_short attr_code)
688 {
689 u_short len_data;
690
691 switch(attr_code)
692 {
693 case ARAP_PASS:
694 if (length != 16)
695 {
696 printf("{length %u != 16}", length);
697 return;
698 }
699 printf("{User_challenge[");
700 TCHECK2(data[0],8);
701 len_data = 8;
702 PRINT_HEX(len_data, data);
703 printf("] User_resp[");
704 TCHECK2(data[0],8);
705 len_data = 8;
706 PRINT_HEX(len_data, data);
707 printf("]}");
708 break;
709
710 case ARAP_FEATURES:
711 if (length != 14)
712 {
713 printf("{length %u != 14}", length);
714 return;
715 }
716 TCHECK2(data[0],1);
717 if (*data)
718 printf("{User_can_change_pass");
719 else
720 printf("{User_cant_change_pass");
721 data++;
722 TCHECK2(data[0],1);
723 printf(" Min_pass_len[%d]",*data);
724 data++;
725 printf(" Pass_created_at[");
726 TCHECK2(data[0],4);
727 len_data = 4;
728 PRINT_HEX(len_data, data);
729 printf("] Pass_expired_in[");
730 TCHECK2(data[0],4);
731 len_data = 4;
732 PRINT_HEX(len_data, data);
733 printf("] Current_time[");
734 len_data = 4;
735 TCHECK2(data[0],4);
736 PRINT_HEX(len_data, data);
737 printf("]}");
738 break;
739
740 case ARAP_CHALLENGE_RESP:
741 if (length < 8)
742 {
743 printf("{length %u != 8}", length);
744 return;
745 }
746 printf("{");
747 TCHECK2(data[0],8);
748 len_data = 8;
749 PRINT_HEX(len_data, data);
750 printf("}");
751 break;
752 }
753
754 trunc:
755 printf("|radius}");
756 }
757
758
759
760 static void
761 radius_attr_print(register const u_char *attr, u_int length)
762 {
763 register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
764
765 if (length < 3)
766 {
767 printf(" [|radius]");
768 return;
769 }
770
771 printf(" Attr[ ");
772 while (length > 0)
773 {
774 if (rad_attr->len == 0)
775 {
776 printf("(zero-length attribute)");
777 return;
778 }
779 if ( rad_attr->len <= length )
780 {
781 if ( !rad_attr->type || (rad_attr->type > (TAM_SIZE(attr_type)-1)) )
782 printf("#%d",rad_attr->type);
783 else
784 {
785 printf(" %s",attr_type[rad_attr->type].name);
786
787 if (rad_attr->len > 2)
788 {
789 if ( attr_type[rad_attr->type].print_func )
790 (*attr_type[rad_attr->type].print_func)(
791 ((u_char *)(rad_attr+1)),
792 rad_attr->len - 2, rad_attr->type);
793 }
794 }
795 }
796 else
797 {
798 printf(" [|radius]");
799 return;
800 }
801 length-=(rad_attr->len);
802 rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len);
803 }
804
805 printf(" ]");
806 }
807
808
809 void
810 radius_print(const u_char *dat, u_int length)
811 {
812 register const struct radius_hdr *rad;
813 register int i;
814 int len;
815
816 i = min(length, snapend - dat);
817
818 if (i < MIN_RADIUS_LEN)
819 {
820 printf(" [|radius]");
821 return;
822 }
823
824 rad = (struct radius_hdr *)dat;
825 len = ntohs(rad->len);
826
827 if (len < MIN_RADIUS_LEN)
828 {
829 printf(" [|radius]");
830 return;
831 }
832
833 if (len < i)
834 i = len;
835
836 i -= MIN_RADIUS_LEN;
837
838 switch (rad->code)
839 {
840 case RADCMD_ACCESS_REQ:
841 printf(" rad-access-req %d", length);
842 break;
843
844 case RADCMD_ACCESS_ACC:
845 printf(" rad-access-accept %d", length);
846 break;
847
848 case RADCMD_ACCESS_REJ:
849 printf(" rad-access-reject %d", length);
850 break;
851
852 case RADCMD_ACCOUN_REQ:
853 printf(" rad-account-req %d", length);
854 break;
855
856 case RADCMD_ACCOUN_RES:
857 printf(" rad-account-resp %d", length);
858 break;
859
860 case RADCMD_ACCESS_CHA:
861 printf(" rad-access-cha %d", length);
862 break;
863
864 case RADCMD_STATUS_SER:
865 printf(" rad-status-serv %d", length);
866 break;
867
868 case RADCMD_STATUS_CLI:
869 printf(" rad-status-cli %d", length);
870 break;
871
872 case RADCMD_RESERVED:
873 printf(" rad-reserved %d", length);
874 break;
875
876 default:
877 printf(" rad-#%d %d", rad->code, length);
878 break;
879 }
880 printf(" [id %d]", rad->id);
881
882 if (i)
883 radius_attr_print( dat + MIN_RADIUS_LEN, i);
884 }