xref: /freebsd/contrib/tcpdump/print-radius.c (revision f9218d3d4fd34f082473b3a021c6d4d109fb47cf)
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.10.2.2 2002/07/03 16:35:04 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 }
885