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