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