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