11556Srgrimes/*
21556Srgrimes * Copyright (C) 2000 Alfredo Andres Omella.  All rights reserved.
31556Srgrimes *
41556Srgrimes * Redistribution and use in source and binary forms, with or without
51556Srgrimes * modification, are permitted provided that the following conditions
61556Srgrimes * are met:
71556Srgrimes *
81556Srgrimes *   1. Redistributions of source code must retain the above copyright
91556Srgrimes *      notice, this list of conditions and the following disclaimer.
101556Srgrimes *   2. Redistributions in binary form must reproduce the above copyright
111556Srgrimes *      notice, this list of conditions and the following disclaimer in
121556Srgrimes *      the documentation and/or other materials provided with the
131556Srgrimes *      distribution.
141556Srgrimes *   3. The names of the authors may not be used to endorse or promote
151556Srgrimes *      products derived from this software without specific prior
161556Srgrimes *      written permission.
171556Srgrimes *
181556Srgrimes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
191556Srgrimes * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
201556Srgrimes * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
211556Srgrimes */
221556Srgrimes/*
231556Srgrimes * Radius printer routines as specified on:
241556Srgrimes *
251556Srgrimes * RFC 2865:
261556Srgrimes *      "Remote Authentication Dial In User Service (RADIUS)"
271556Srgrimes *
281556Srgrimes * RFC 2866:
291556Srgrimes *      "RADIUS Accounting"
301556Srgrimes *
311556Srgrimes * RFC 2867:
321556Srgrimes *      "RADIUS Accounting Modifications for Tunnel Protocol Support"
331556Srgrimes *
341556Srgrimes * RFC 2868:
351556Srgrimes *      "RADIUS Attributes for Tunnel Protocol Support"
361556Srgrimes *
371556Srgrimes * RFC 2869:
3827967Ssteve *      "RADIUS Extensions"
3927967Ssteve *
4027967Ssteve * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
4127958Ssteve *
4250471Speter * TODO: Among other things to print ok MacIntosh and Vendor values
4327967Ssteve */
441556Srgrimes
451556Srgrimes#ifndef lint
461556Srgrimesstatic const char rcsid[] _U_ =
471556Srgrimes    "$Id: print-radius.c,v 1.28 2005-09-26 01:01:55 guy Exp $";
481556Srgrimes#endif
491556Srgrimes
501556Srgrimes#ifdef HAVE_CONFIG_H
511556Srgrimes#include "config.h"
521556Srgrimes#endif
5374566Sache
541556Srgrimes#include <tcpdump-stdinc.h>
551556Srgrimes
561556Srgrimes#include <string.h>
571556Srgrimes
581556Srgrimes#include <stdio.h>
591556Srgrimes
6061294Sache#include "interface.h"
6161294Sache#include "addrtoname.h"
6261294Sache#include "extract.h"
6361294Sache#include "oui.h"
6461294Sache
651556Srgrimes#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
661556Srgrimes
671556Srgrimes#define PRINT_HEX(bytes_len, ptr_data)                               \
681556Srgrimes           while(bytes_len)                                          \
691556Srgrimes           {                                                         \
701556Srgrimes              printf("%02X", *ptr_data );                            \
711556Srgrimes              ptr_data++;                                            \
721556Srgrimes              bytes_len--;                                           \
7361321Sache           }
7461321Sache
7561321Sache
7661321Sache/* Radius packet codes */
771556Srgrimes#define RADCMD_ACCESS_REQ   1 /* Access-Request      */
781556Srgrimes#define RADCMD_ACCESS_ACC   2 /* Access-Accept       */
791556Srgrimes#define RADCMD_ACCESS_REJ   3 /* Access-Reject       */
8061268Sjoe#define RADCMD_ACCOUN_REQ   4 /* Accounting-Request  */
8161178Sjoe#define RADCMD_ACCOUN_RES   5 /* Accounting-Response */
8261178Sjoe#define RADCMD_ACCESS_CHA  11 /* Access-Challenge    */
8388586Sjoe#define RADCMD_STATUS_SER  12 /* Status-Server       */
8488586Sjoe#define RADCMD_STATUS_CLI  13 /* Status-Client       */
8588586Sjoe#define RADCMD_RESERVED   255 /* Reserved            */
8688586Sjoe
8788586Sjoestatic struct tok radius_command_values[] = {
8888586Sjoe    { RADCMD_ACCESS_REQ, "Access Request" },
8988586Sjoe    { RADCMD_ACCESS_ACC, "Access Accept" },
9088586Sjoe    { RADCMD_ACCESS_REJ, "Access Reject" },
9188586Sjoe    { RADCMD_ACCOUN_REQ, "Accounting Request" },
9288586Sjoe    { RADCMD_ACCOUN_RES, "Accounting Response" },
9388586Sjoe    { RADCMD_ACCESS_CHA, "Access Challenge" },
9488586Sjoe    { RADCMD_STATUS_SER, "Status Server" },
9588586Sjoe    { RADCMD_STATUS_CLI, "Status Client" },
9661178Sjoe    { RADCMD_RESERVED,   "Reserved" },
9788587Sjoe    { 0, NULL}
9861178Sjoe};
9988583Sjoe
10088583Sjoe/********************************/
10188586Sjoe/* Begin Radius Attribute types */
10288586Sjoe/********************************/
10388583Sjoe#define SERV_TYPE    6
10488583Sjoe#define FRM_IPADDR   8
10561268Sjoe#define LOG_IPHOST  14
10661178Sjoe#define LOG_SERVICE 15
1071556Srgrimes#define FRM_IPX     23
1081556Srgrimes#define SESSION_TIMEOUT   27
10988586Sjoe#define IDLE_TIMEOUT      28
1101556Srgrimes#define FRM_ATALK_LINK    37
11188586Sjoe#define FRM_ATALK_NETWORK 38
1121556Srgrimes
1131556Srgrimes#define ACCT_DELAY        41
1141556Srgrimes#define ACCT_SESSION_TIME 46
1151556Srgrimes
1161556Srgrimes#define TUNNEL_TYPE        64
1171556Srgrimes#define TUNNEL_MEDIUM      65
1181556Srgrimes#define TUNNEL_CLIENT_END  66
1191556Srgrimes#define TUNNEL_SERVER_END  67
1201556Srgrimes#define TUNNEL_PASS        69
12162597Sassar
12262597Sassar#define ARAP_PASS          70
12362597Sassar#define ARAP_FEATURES      71
12462597Sassar
12562597Sassar#define TUNNEL_PRIV_GROUP  81
12662597Sassar#define TUNNEL_ASSIGN_ID   82
12762597Sassar#define TUNNEL_PREFERENCE  83
12862597Sassar
12962597Sassar#define ARAP_CHALLENGE_RESP 84
13062597Sassar#define ACCT_INT_INTERVAL   85
13162597Sassar
13262597Sassar#define TUNNEL_CLIENT_AUTH 90
13362597Sassar#define TUNNEL_SERVER_AUTH 91
13462597Sassar/********************************/
13562597Sassar/* End Radius Attribute types */
1361556Srgrimes/********************************/
1371556Srgrimes
1381556Srgrimes
1391556Srgrimesstatic void print_attr_string(register u_char *, u_int, u_short );
1401556Srgrimesstatic void print_attr_num(register u_char *, u_int, u_short );
14188586Sjoestatic void print_vendor_attr(register u_char *, u_int, u_short );
14288586Sjoestatic void print_attr_address(register u_char *, u_int, u_short);
14388586Sjoestatic void print_attr_time(register u_char *, u_int, u_short);
14461292Sachestatic void print_attr_strange(register u_char *, u_int, u_short);
14588586Sjoe
14661292Sache
1471556Srgrimesstruct radius_hdr { u_int8_t  code; /* Radius packet code  */
1481556Srgrimes                    u_int8_t  id;   /* Radius packet id    */
1491556Srgrimes                    u_int16_t len;  /* Radius total length */
1501556Srgrimes                    u_int8_t  auth[16]; /* Authenticator   */
1511556Srgrimes                  };
1521556Srgrimes
1531556Srgrimes#define MIN_RADIUS_LEN	20
1541556Srgrimes
1551556Srgrimesstruct radius_attr { u_int8_t type; /* Attribute type   */
15620417Ssteve                     u_int8_t len;  /* Attribute length */
1571556Srgrimes                   };
1581556Srgrimes
1591556Srgrimes
1601556Srgrimes/* Service-Type Attribute standard values */
1611556Srgrimesstatic const char *serv_type[]={ NULL,
1621556Srgrimes                                "Login",
1631556Srgrimes                                "Framed",
1641556Srgrimes                                "Callback Login",
1651556Srgrimes                                "Callback Framed",
1661556Srgrimes                                "Outbound",
16786922Sgreen                                "Administrative",
16886922Sgreen                                "NAS Prompt",
1691556Srgrimes                                "Authenticate Only",
17055514Sbde                                "Callback NAS Prompt",
17113120Sjoerg                                "Call Check",
17255514Sbde                                "Callback Administrative",
17355514Sbde                               };
17413120Sjoerg
17513120Sjoerg/* Framed-Protocol Attribute standard values */
17613120Sjoergstatic const char *frm_proto[]={ NULL,
1771556Srgrimes                                 "PPP",
1781556Srgrimes                                 "SLIP",
1791556Srgrimes                                 "ARAP",
1801556Srgrimes                                 "Gandalf proprietary",
1811556Srgrimes                                 "Xylogics IPX/SLIP",
1821556Srgrimes                                 "X.75 Synchronous",
1831556Srgrimes                               };
1841556Srgrimes
1851556Srgrimes/* Framed-Routing Attribute standard values */
1861556Srgrimesstatic const char *frm_routing[]={ "None",
1871556Srgrimes                                   "Send",
18861268Sjoe                                   "Listen",
18961178Sjoe                                   "Send&Listen",
19061291Sache                                 };
19161268Sjoe
19262597Sassar/* Framed-Compression Attribute standard values */
19361268Sjoestatic const char *frm_comp[]={ "None",
19461291Sache                                "VJ TCP/IP",
19561321Sache                                "IPX",
19661268Sjoe                                "Stac-LZS",
1971556Srgrimes                              };
1981556Srgrimes
1991556Srgrimes/* Login-Service Attribute standard values */
2001556Srgrimesstatic const char *login_serv[]={ "Telnet",
2011556Srgrimes                                  "Rlogin",
2021556Srgrimes                                  "TCP Clear",
2031556Srgrimes                                  "PortMaster(proprietary)",
2041556Srgrimes                                  "LAT",
2051556Srgrimes                                  "X.25-PAD",
2061556Srgrimes                                  "X.25-T3POS",
20788586Sjoe                                  "Unassigned",
2081556Srgrimes                                  "TCP Clear Quiet",
2091556Srgrimes                                };
2101556Srgrimes
2111556Srgrimes
21288586Sjoe/* Termination-Action Attribute standard values */
21388586Sjoestatic const char *term_action[]={ "Default",
21488586Sjoe                                   "RADIUS-Request",
21588586Sjoe                                 };
21688586Sjoe
21788586Sjoe/* NAS-Port-Type Attribute standard values */
21888586Sjoestatic const char *nas_port_type[]={ "Async",
21988586Sjoe                                     "Sync",
22088586Sjoe                                     "ISDN Sync",
22188586Sjoe                                     "ISDN Async V.120",
22288586Sjoe                                     "ISDN Async V.110",
22388586Sjoe                                     "Virtual",
2241556Srgrimes                                     "PIAFS",
22537932Shoek                                     "HDLC Clear Channel",
22637932Shoek                                     "X.25",
22737932Shoek                                     "X.75",
22837932Shoek                                     "G.3 Fax",
22937932Shoek                                     "SDSL",
2301556Srgrimes                                     "ADSL-CAP",
2311556Srgrimes                                     "ADSL-DMT",
2321556Srgrimes                                     "ISDN-DSL",
2331556Srgrimes                                     "Ethernet",
2341556Srgrimes                                     "xDSL",
2351556Srgrimes                                     "Cable",
2361556Srgrimes                                     "Wireless - Other",
2371556Srgrimes                                     "Wireless - IEEE 802.11",
2381556Srgrimes                                   };
2391556Srgrimes
2401556Srgrimes/* Acct-Status-Type Accounting Attribute standard values */
2411556Srgrimesstatic const char *acct_status[]={ NULL,
2421556Srgrimes                                   "Start",
2431556Srgrimes                                   "Stop",
2441556Srgrimes                                   "Interim-Update",
2451556Srgrimes                                   "Unassigned",
2461556Srgrimes                                   "Unassigned",
2471556Srgrimes                                   "Unassigned",
2481556Srgrimes                                   "Accounting-On",
2491556Srgrimes                                   "Accounting-Off",
2501556Srgrimes                                   "Tunnel-Start",
2511556Srgrimes                                   "Tunnel-Stop",
2521556Srgrimes                                   "Tunnel-Reject",
2531556Srgrimes                                   "Tunnel-Link-Start",
25437932Shoek                                   "Tunnel-Link-Stop",
2551556Srgrimes                                   "Tunnel-Link-Reject",
2561556Srgrimes                                   "Failed",
2571556Srgrimes                                 };
2581556Srgrimes
2591556Srgrimes/* Acct-Authentic Accounting Attribute standard values */
2601556Srgrimesstatic const char *acct_auth[]={ NULL,
2611556Srgrimes                                 "RADIUS",
2621556Srgrimes                                 "Local",
2631556Srgrimes                                 "Remote",
2641556Srgrimes                               };
2651556Srgrimes
2661556Srgrimes/* Acct-Terminate-Cause Accounting Attribute standard values */
2671556Srgrimesstatic const char *acct_term[]={ NULL,
2681556Srgrimes                                 "User Request",
2691556Srgrimes                                 "Lost Carrier",
2701556Srgrimes                                 "Lost Service",
2711556Srgrimes                                 "Idle Timeout",
2721556Srgrimes                                 "Session Timeout",
2731556Srgrimes                                 "Admin Reset",
27437932Shoek                                 "Admin Reboot",
27537932Shoek                                 "Port Error",
27637932Shoek                                 "NAS Error",
2771556Srgrimes                                 "NAS Request",
2781556Srgrimes                                 "NAS Reboot",
2791556Srgrimes                                 "Port Unneeded",
2801556Srgrimes                                 "Port Preempted",
2811556Srgrimes                                 "Port Suspended",
2821556Srgrimes                                 "Service Unavailable",
2831556Srgrimes                                 "Callback",
2841556Srgrimes                                 "User Error",
2851556Srgrimes                                 "Host Request",
2861556Srgrimes                               };
2871556Srgrimes
2881556Srgrimes/* Tunnel-Type Attribute standard values */
2891556Srgrimesstatic const char *tunnel_type[]={ NULL,
2901556Srgrimes                                   "PPTP",
29188586Sjoe                                   "L2F",
29288586Sjoe                                   "L2TP",
29388586Sjoe                                   "ATMP",
2941556Srgrimes                                   "VTP",
2951556Srgrimes                                   "AH",
29688586Sjoe                                   "IP-IP",
29761292Sache                                   "MIN-IP-IP",
29888586Sjoe                                   "ESP",
29961292Sache                                   "GRE",
3001556Srgrimes                                   "DVS",
3011556Srgrimes                                   "IP-in-IP Tunneling",
3021556Srgrimes                                 };
3031556Srgrimes
30420417Ssteve/* Tunnel-Medium-Type Attribute standard values */
3051556Srgrimesstatic const char *tunnel_medium[]={ NULL,
3061556Srgrimes                                     "IPv4",
3071556Srgrimes                                     "IPv6",
30861268Sjoe                                     "NSAP",
30961178Sjoe                                     "HDLC",
31061291Sache                                     "BBN 1822",
31161268Sjoe                                     "802",
31262597Sassar                                     "E.163",
31361268Sjoe                                     "E.164",
31461291Sache                                     "F.69",
31561321Sache                                     "X.121",
31661268Sjoe                                     "IPX",
3171556Srgrimes                                     "Appletalk",
3181556Srgrimes                                     "Decnet IV",
3191556Srgrimes                                     "Banyan Vines",
3201556Srgrimes                                     "E.164 with NSAP subaddress",
3211556Srgrimes                                   };
3221556Srgrimes
3231556Srgrimes/* ARAP-Zone-Access Attribute standard values */
32488586Sjoestatic const char *arap_zone[]={ NULL,
3251556Srgrimes                                 "Only access to dfl zone",
32688586Sjoe                                 "Use zone filter inc.",
32788586Sjoe                                 "Not used",
32888586Sjoe                                 "Use zone filter exc.",
32988586Sjoe                               };
3301556Srgrimes
33174566Sachestatic const char *prompt[]={ "No Echo",
33274566Sache                              "Echo",
33321545Smpp                            };
33421545Smpp
33521545Smpp
3369987Swollmanstruct attrtype { const char *name;      /* Attribute name                 */
3371556Srgrimes                  const char **subtypes; /* Standard Values (if any)       */
33861920Sjoe                  u_char siz_subtypes;   /* Size of total standard values  */
33974566Sache                  u_char first_subtype;  /* First standard value is 0 or 1 */
34021545Smpp                  void (*print_func)(register u_char *, u_int, u_short );
34161920Sjoe                } attr_type[]=
34274566Sache  {
34361814Sjoe     { NULL,                              NULL, 0, 0, NULL               },
34461920Sjoe     { "Username",                        NULL, 0, 0, print_attr_string  },
34574566Sache     { "Password",                        NULL, 0, 0, NULL               },
34661814Sjoe     { "CHAP Password",                   NULL, 0, 0, NULL               },
34761814Sjoe     { "NAS IP Address",                  NULL, 0, 0, print_attr_address },
3481556Srgrimes     { "NAS Port",                        NULL, 0, 0, print_attr_num     },
3491556Srgrimes     { "Service Type",                    serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num },
3501556Srgrimes     { "Framed Protocol",                 frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num },
3511556Srgrimes     { "Framed IP Address",               NULL, 0, 0, print_attr_address },
35288586Sjoe     { "Framed IP Network",               NULL, 0, 0, print_attr_address },
3531556Srgrimes     { "Framed Routing",                  frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num },
3541556Srgrimes     { "Filter ID",                       NULL, 0, 0, print_attr_string  },
3551556Srgrimes     { "Framed MTU",                      NULL, 0, 0, print_attr_num     },
3561556Srgrimes     { "Framed Compression",              frm_comp, TAM_SIZE(frm_comp),   0, print_attr_num },
3571556Srgrimes     { "Login IP Host",                   NULL, 0, 0, print_attr_address },
3581556Srgrimes     { "Login Service",                   login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
3591556Srgrimes     { "Login TCP Port",                  NULL, 0, 0, print_attr_num     },
3601556Srgrimes     { "Unassigned",                      NULL, 0, 0, NULL }, /*17*/
3611556Srgrimes     { "Reply",                           NULL, 0, 0, print_attr_string },
3621556Srgrimes     { "Callback-number",                 NULL, 0, 0, print_attr_string },
3631556Srgrimes     { "Callback-ID",                     NULL, 0, 0, print_attr_string },
3641556Srgrimes     { "Unassigned",                      NULL, 0, 0, NULL }, /*21*/
3651556Srgrimes     { "Framed Route",                    NULL, 0, 0, print_attr_string },
3661556Srgrimes     { "Framed IPX Network",              NULL, 0, 0, print_attr_num    },
36720417Ssteve     { "State",                           NULL, 0, 0, print_attr_string },
36820417Ssteve     { "Class",                           NULL, 0, 0, print_attr_string },
36920417Ssteve     { "Vendor Specific",                 NULL, 0, 0, print_vendor_attr },
3701556Srgrimes     { "Session Timeout",                 NULL, 0, 0, print_attr_num    },
3711556Srgrimes     { "Idle Timeout",                    NULL, 0, 0, print_attr_num    },
3721556Srgrimes     { "Termination Action",              term_action, TAM_SIZE(term_action), 0, print_attr_num },
3731556Srgrimes     { "Called Station",                  NULL, 0, 0, print_attr_string },
3741556Srgrimes     { "Calling Station",                 NULL, 0, 0, print_attr_string },
3751556Srgrimes     { "NAS ID",                          NULL, 0, 0, print_attr_string },
3761556Srgrimes     { "Proxy State",                     NULL, 0, 0, print_attr_string },
3771556Srgrimes     { "Login LAT Service",               NULL, 0, 0, print_attr_string },
37861268Sjoe     { "Login LAT Node",                  NULL, 0, 0, print_attr_string },
37961323Sache     { "Login LAT Group",                 NULL, 0, 0, print_attr_string },
38061323Sache     { "Framed Appletalk Link",           NULL, 0, 0, print_attr_num    },
38188586Sjoe     { "Framed Appltalk Net",             NULL, 0, 0, print_attr_num    },
38261291Sache     { "Framed Appletalk Zone",           NULL, 0, 0, print_attr_string },
38361321Sache     { "Accounting Status",               acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num },
38461321Sache     { "Accounting Delay",                NULL, 0, 0, print_attr_num    },
38561291Sache     { "Accounting Input Octets",         NULL, 0, 0, print_attr_num    },
38661291Sache     { "Accounting Output Octets",        NULL, 0, 0, print_attr_num    },
38761323Sache     { "Accounting Session ID",           NULL, 0, 0, print_attr_string },
38861323Sache     { "Accounting Authentication",       acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num },
38988586Sjoe     { "Accounting Session Time",         NULL, 0, 0, print_attr_num },
39061321Sache     { "Accounting Input Packets",        NULL, 0, 0, print_attr_num },
39188586Sjoe     { "Accounting Output Packets",       NULL, 0, 0, print_attr_num },
39261291Sache     { "Accounting Termination Cause",    acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num },
39361321Sache     { "Accounting Multilink Session ID", NULL, 0, 0, print_attr_string },
39461321Sache     { "Accounting Link Count",           NULL, 0, 0, print_attr_num },
39561321Sache     { "Accounting Input Giga",           NULL, 0, 0, print_attr_num },
39661321Sache     { "Accounting Output Giga",          NULL, 0, 0, print_attr_num },
39761323Sache     { "Unassigned",                      NULL, 0, 0, NULL }, /*54*/
39861178Sjoe     { "Event Timestamp",                 NULL, 0, 0, print_attr_time },
39988586Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }, /*56*/
40061178Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }, /*57*/
40188586Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }, /*58*/
40261268Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }, /*59*/
40388583Sjoe     { "CHAP challenge",                  NULL, 0, 0, print_attr_string },
40488583Sjoe     { "NAS Port Type",                   nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num },
40588583Sjoe     { "Port Limit",                      NULL, 0, 0, print_attr_num },
40688583Sjoe     { "Login LAT Port",                  NULL, 0, 0, print_attr_string }, /*63*/
40788583Sjoe     { "Tunnel Type",                     tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num },
40861321Sache     { "Tunnel Medium",                   tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num },
40961291Sache     { "Tunnel Client End",               NULL, 0, 0, print_attr_string },
41061178Sjoe     { "Tunnel Server End",               NULL, 0, 0, print_attr_string },
41161268Sjoe     { "Accounting Tunnel connect",       NULL, 0, 0, print_attr_string },
41288583Sjoe     { "Tunnel Password",                 NULL, 0, 0, print_attr_string  },
41388583Sjoe     { "ARAP Password",                   NULL, 0, 0, print_attr_strange },
41461321Sache     { "ARAP Feature",                    NULL, 0, 0, print_attr_strange },
41561291Sache     { "ARAP Zone Acces",                 arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/
41661268Sjoe     { "ARAP Security",                   NULL, 0, 0, print_attr_string },
41761178Sjoe     { "ARAP Security Data",              NULL, 0, 0, print_attr_string },
41861178Sjoe     { "Password Retry",                  NULL, 0, 0, print_attr_num    },
41961321Sache     { "Prompt",                          prompt, TAM_SIZE(prompt), 0, print_attr_num },
42061321Sache     { "Connect Info",                    NULL, 0, 0, print_attr_string   },
42188586Sjoe     { "Config Token",                    NULL, 0, 0, print_attr_string   },
42261268Sjoe     { "EAP Message",                     NULL, 0, 0, print_attr_string   },
42361321Sache     { "Message Authentication",          NULL, 0, 0, print_attr_string }, /*80*/
42488583Sjoe     { "Tunnel Private Group",            NULL, 0, 0, print_attr_string },
42561268Sjoe     { "Tunnel Assigned ID",              NULL, 0, 0, print_attr_string },
42661268Sjoe     { "Tunnel Preference",               NULL, 0, 0, print_attr_num    },
42761321Sache     { "ARAP Challenge Response",         NULL, 0, 0, print_attr_strange },
42861178Sjoe     { "Accounting Interim Interval",     NULL, 0, 0, print_attr_num     },
42988586Sjoe     { "Accounting Tunnel packets lost",  NULL, 0, 0, print_attr_num }, /*86*/
43061178Sjoe     { "NAS Port ID",                     NULL, 0, 0, print_attr_string },
43161178Sjoe     { "Framed Pool",                     NULL, 0, 0, print_attr_string },
43261178Sjoe     { "Unassigned",                      NULL, 0, 0, NULL },
43361178Sjoe     { "Tunnel Client Authentication ID", NULL, 0, 0, print_attr_string },
43461178Sjoe     { "Tunnel Server Authentication ID", NULL, 0, 0, print_attr_string },
43561178Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }, /*92*/
43661178Sjoe     { "Unassigned",                      NULL, 0, 0, NULL }  /*93*/
43761178Sjoe  };
43861178Sjoe
43961178Sjoe
44061178Sjoe/*****************************/
44161178Sjoe/* Print an attribute string */
44261178Sjoe/* value pointed by 'data'   */
44361178Sjoe/* and 'length' size.        */
44461178Sjoe/*****************************/
44561178Sjoe/* Returns nothing.          */
44661178Sjoe/*****************************/
44761178Sjoestatic void
44861178Sjoeprint_attr_string(register u_char *data, u_int length, u_short attr_code )
44961178Sjoe{
45061178Sjoe   register u_int i;
45161178Sjoe
45261178Sjoe   TCHECK2(data[0],length);
45361178Sjoe
45461178Sjoe   switch(attr_code)
45561178Sjoe   {
45661178Sjoe      case TUNNEL_PASS:
45761178Sjoe           if (length < 3)
45861178Sjoe           {
45961178Sjoe              printf(" [|radius]");
46061178Sjoe              return;
46161178Sjoe           }
46261178Sjoe           if (*data && (*data <=0x1F) )
46361178Sjoe              printf("Tag %u, ",*data);
46461178Sjoe           data++;
46561178Sjoe           length--;
46661178Sjoe           printf("Salt %u ",EXTRACT_16BITS(data) );
46761178Sjoe           data+=2;
46861178Sjoe           length-=2;
46961178Sjoe        break;
47061178Sjoe      case TUNNEL_CLIENT_END:
47188587Sjoe      case TUNNEL_SERVER_END:
47261178Sjoe      case TUNNEL_PRIV_GROUP:
47388586Sjoe      case TUNNEL_ASSIGN_ID:
47488586Sjoe      case TUNNEL_CLIENT_AUTH:
47588586Sjoe      case TUNNEL_SERVER_AUTH:
47688586Sjoe           if (*data <= 0x1F)
47788586Sjoe           {
47861321Sache              if (length < 1)
47988586Sjoe              {
48088586Sjoe                 printf(" [|radius]");
48161178Sjoe                 return;
48261178Sjoe              }
48388583Sjoe              printf("Tag %u",*data);
48488583Sjoe              data++;
48588586Sjoe              length--;
48688586Sjoe           }
48788586Sjoe        break;
48861178Sjoe   }
48961178Sjoe
49088586Sjoe   for (i=0; *data && i < length ; i++, data++)
49188586Sjoe       printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
49261178Sjoe
49361178Sjoe   return;
49488583Sjoe
49588583Sjoe   trunc:
49688583Sjoe      printf(" [|radius]");
49788583Sjoe}
49888583Sjoe
49988583Sjoe/*
50088583Sjoe * print vendor specific attributes
50188583Sjoe */
50288583Sjoe
50388583Sjoestatic void
50488583Sjoeprint_vendor_attr(register u_char *data, u_int length, u_short attr_code _U_)
50588583Sjoe{
50688583Sjoe    u_int idx;
50788583Sjoe    u_int vendor_id;
50888583Sjoe    u_int vendor_type;
50988583Sjoe    u_int vendor_length;
51088583Sjoe
51188583Sjoe    if (length < 4)
51261178Sjoe        goto trunc;
51388583Sjoe    TCHECK2(*data, 4);
51488583Sjoe    vendor_id = EXTRACT_32BITS(data);
51588584Sjoe    data+=4;
51661178Sjoe    length-=4;
51761178Sjoe
51861178Sjoe    printf("Vendor: %s (%u)",
51961178Sjoe           tok2str(smi_values,"Unknown",vendor_id),
52061291Sache           vendor_id);
52161323Sache
52261323Sache    while (length >= 2) {
52388586Sjoe	TCHECK2(*data, 2);
52461291Sache
52561321Sache        vendor_type = *(data);
52661294Sache        vendor_length = *(data+1);
52761294Sache
52861294Sache        if (vendor_length < 2)
52961291Sache        {
53061268Sjoe            printf("\n\t    Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
53161178Sjoe                   vendor_type,
5321556Srgrimes                   vendor_length);
5331556Srgrimes            return;
53488586Sjoe        }
5351556Srgrimes        if (vendor_length > length)
53688586Sjoe        {
53788586Sjoe            printf("\n\t    Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
53888586Sjoe                   vendor_type,
5391556Srgrimes                   vendor_length);
5401556Srgrimes            return;
5411556Srgrimes        }
5428855Srgrimes        data+=2;
5431556Srgrimes        vendor_length-=2;
5441556Srgrimes        length-=2;
5451556Srgrimes	TCHECK2(*data, vendor_length);
5461556Srgrimes
5471556Srgrimes        printf("\n\t    Vendor Attribute: %u, Length: %u, Value: ",
5481556Srgrimes               vendor_type,
5491556Srgrimes               vendor_length);
55062597Sassar        for (idx = 0; idx < vendor_length ; idx++, data++)
55162597Sassar            printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
5521556Srgrimes        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/******************************/
569static void
570print_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/*****************************/
685static void
686print_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/*************************************/
729static 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/***********************************/
761static 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
832static void
833radius_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
888trunc:
889   printf(" [|radius]");
890}
891
892
893void
894radius_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
935trunc:
936   printf(" [|radius]");
937}
938