xref: /aosp_15_r20/external/tcpdump/print-radius.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (C) 2000 Alfredo Andres Omella.  All rights reserved.
3*05b00f60SXin Li  *
4*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
5*05b00f60SXin Li  * modification, are permitted provided that the following conditions
6*05b00f60SXin Li  * are met:
7*05b00f60SXin Li  *
8*05b00f60SXin Li  *   1. Redistributions of source code must retain the above copyright
9*05b00f60SXin Li  *      notice, this list of conditions and the following disclaimer.
10*05b00f60SXin Li  *   2. Redistributions in binary form must reproduce the above copyright
11*05b00f60SXin Li  *      notice, this list of conditions and the following disclaimer in
12*05b00f60SXin Li  *      the documentation and/or other materials provided with the
13*05b00f60SXin Li  *      distribution.
14*05b00f60SXin Li  *   3. The names of the authors may not be used to endorse or promote
15*05b00f60SXin Li  *      products derived from this software without specific prior
16*05b00f60SXin Li  *      written permission.
17*05b00f60SXin Li  *
18*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19*05b00f60SXin Li  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20*05b00f60SXin Li  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21*05b00f60SXin Li  */
22*05b00f60SXin Li 
23*05b00f60SXin Li /* \summary: Radius protocol printer */
24*05b00f60SXin Li 
25*05b00f60SXin Li /*
26*05b00f60SXin Li  * Radius printer routines as specified on:
27*05b00f60SXin Li  *
28*05b00f60SXin Li  * RFC 2865:
29*05b00f60SXin Li  *      "Remote Authentication Dial In User Service (RADIUS)"
30*05b00f60SXin Li  *
31*05b00f60SXin Li  * RFC 2866:
32*05b00f60SXin Li  *      "RADIUS Accounting"
33*05b00f60SXin Li  *
34*05b00f60SXin Li  * RFC 2867:
35*05b00f60SXin Li  *      "RADIUS Accounting Modifications for Tunnel Protocol Support"
36*05b00f60SXin Li  *
37*05b00f60SXin Li  * RFC 2868:
38*05b00f60SXin Li  *      "RADIUS Attributes for Tunnel Protocol Support"
39*05b00f60SXin Li  *
40*05b00f60SXin Li  * RFC 2869:
41*05b00f60SXin Li  *      "RADIUS Extensions"
42*05b00f60SXin Li  *
43*05b00f60SXin Li  * RFC 3162:
44*05b00f60SXin Li  *      "RADIUS and IPv6"
45*05b00f60SXin Li  *
46*05b00f60SXin Li  * RFC 3580:
47*05b00f60SXin Li  *      "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)"
48*05b00f60SXin Li  *      "Usage Guidelines"
49*05b00f60SXin Li  *
50*05b00f60SXin Li  * RFC 4072:
51*05b00f60SXin Li  *      "Diameter Extensible Authentication Protocol (EAP) Application"
52*05b00f60SXin Li  *
53*05b00f60SXin Li  * RFC 4675:
54*05b00f60SXin Li  *      "RADIUS Attributes for Virtual LAN and Priority Support"
55*05b00f60SXin Li  *
56*05b00f60SXin Li  * RFC 4818:
57*05b00f60SXin Li  *      "RADIUS Delegated-IPv6-Prefix Attribute"
58*05b00f60SXin Li  *
59*05b00f60SXin Li  * RFC 4849:
60*05b00f60SXin Li  *      "RADIUS Filter Rule Attribute"
61*05b00f60SXin Li  *
62*05b00f60SXin Li  * RFC 5090:
63*05b00f60SXin Li  *      "RADIUS Extension for Digest Authentication"
64*05b00f60SXin Li  *
65*05b00f60SXin Li  * RFC 5176:
66*05b00f60SXin Li  *      "Dynamic Authorization Extensions to RADIUS"
67*05b00f60SXin Li  *
68*05b00f60SXin Li  * RFC 5447:
69*05b00f60SXin Li  *      "Diameter Mobile IPv6"
70*05b00f60SXin Li  *
71*05b00f60SXin Li  * RFC 5580:
72*05b00f60SXin Li  *      "Carrying Location Objects in RADIUS and Diameter"
73*05b00f60SXin Li  *
74*05b00f60SXin Li  * RFC 6572:
75*05b00f60SXin Li  *      "RADIUS Support for Proxy Mobile IPv6"
76*05b00f60SXin Li  *
77*05b00f60SXin Li  * RFC 7155:
78*05b00f60SXin Li  *      "Diameter Network Access Server Application"
79*05b00f60SXin Li  *
80*05b00f60SXin Li  * Alfredo Andres Omella ([email protected]) v0.1 2000/09/15
81*05b00f60SXin Li  *
82*05b00f60SXin Li  * TODO: Among other things to print ok MacIntosh and Vendor values
83*05b00f60SXin Li  */
84*05b00f60SXin Li 
85*05b00f60SXin Li #ifdef HAVE_CONFIG_H
86*05b00f60SXin Li #include <config.h>
87*05b00f60SXin Li #endif
88*05b00f60SXin Li 
89*05b00f60SXin Li #include "netdissect-stdinc.h"
90*05b00f60SXin Li 
91*05b00f60SXin Li #include <string.h>
92*05b00f60SXin Li 
93*05b00f60SXin Li #include "netdissect-ctype.h"
94*05b00f60SXin Li 
95*05b00f60SXin Li #include "netdissect.h"
96*05b00f60SXin Li #include "addrtoname.h"
97*05b00f60SXin Li #include "extract.h"
98*05b00f60SXin Li #include "oui.h"
99*05b00f60SXin Li #include "ntp.h"
100*05b00f60SXin Li 
101*05b00f60SXin Li 
102*05b00f60SXin Li #define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
103*05b00f60SXin Li 
104*05b00f60SXin Li #define PRINT_HEX(bytes_len, ptr_data)                               \
105*05b00f60SXin Li            while(bytes_len)                                          \
106*05b00f60SXin Li            {                                                         \
107*05b00f60SXin Li               ND_PRINT("%02X", GET_U_1(ptr_data));                   \
108*05b00f60SXin Li               ptr_data++;                                            \
109*05b00f60SXin Li               bytes_len--;                                           \
110*05b00f60SXin Li            }
111*05b00f60SXin Li 
112*05b00f60SXin Li 
113*05b00f60SXin Li /* Radius packet codes */
114*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-27 */
115*05b00f60SXin Li #define RADCMD_ACCESS_REQ   1 /* Access-Request      */
116*05b00f60SXin Li #define RADCMD_ACCESS_ACC   2 /* Access-Accept       */
117*05b00f60SXin Li #define RADCMD_ACCESS_REJ   3 /* Access-Reject       */
118*05b00f60SXin Li #define RADCMD_ACCOUN_REQ   4 /* Accounting-Request  */
119*05b00f60SXin Li #define RADCMD_ACCOUN_RES   5 /* Accounting-Response */
120*05b00f60SXin Li #define RADCMD_ACCESS_CHA  11 /* Access-Challenge    */
121*05b00f60SXin Li #define RADCMD_STATUS_SER  12 /* Status-Server       */
122*05b00f60SXin Li #define RADCMD_STATUS_CLI  13 /* Status-Client       */
123*05b00f60SXin Li #define RADCMD_DISCON_REQ  40 /* Disconnect-Request  */
124*05b00f60SXin Li #define RADCMD_DISCON_ACK  41 /* Disconnect-ACK      */
125*05b00f60SXin Li #define RADCMD_DISCON_NAK  42 /* Disconnect-NAK      */
126*05b00f60SXin Li #define RADCMD_COA_REQ     43 /* CoA-Request         */
127*05b00f60SXin Li #define RADCMD_COA_ACK     44 /* CoA-ACK             */
128*05b00f60SXin Li #define RADCMD_COA_NAK     45 /* CoA-NAK             */
129*05b00f60SXin Li #define RADCMD_RESERVED   255 /* Reserved            */
130*05b00f60SXin Li 
131*05b00f60SXin Li static const struct tok radius_command_values[] = {
132*05b00f60SXin Li     { RADCMD_ACCESS_REQ, "Access-Request" },
133*05b00f60SXin Li     { RADCMD_ACCESS_ACC, "Access-Accept" },
134*05b00f60SXin Li     { RADCMD_ACCESS_REJ, "Access-Reject" },
135*05b00f60SXin Li     { RADCMD_ACCOUN_REQ, "Accounting-Request" },
136*05b00f60SXin Li     { RADCMD_ACCOUN_RES, "Accounting-Response" },
137*05b00f60SXin Li     { RADCMD_ACCESS_CHA, "Access-Challenge" },
138*05b00f60SXin Li     { RADCMD_STATUS_SER, "Status-Server" },
139*05b00f60SXin Li     { RADCMD_STATUS_CLI, "Status-Client" },
140*05b00f60SXin Li     { RADCMD_DISCON_REQ, "Disconnect-Request" },
141*05b00f60SXin Li     { RADCMD_DISCON_ACK, "Disconnect-ACK" },
142*05b00f60SXin Li     { RADCMD_DISCON_NAK, "Disconnect-NAK" },
143*05b00f60SXin Li     { RADCMD_COA_REQ,    "CoA-Request" },
144*05b00f60SXin Li     { RADCMD_COA_ACK,    "CoA-ACK" },
145*05b00f60SXin Li     { RADCMD_COA_NAK,    "CoA-NAK" },
146*05b00f60SXin Li     { RADCMD_RESERVED,   "Reserved" },
147*05b00f60SXin Li     { 0, NULL}
148*05b00f60SXin Li };
149*05b00f60SXin Li 
150*05b00f60SXin Li /********************************/
151*05b00f60SXin Li /* Begin Radius Attribute types */
152*05b00f60SXin Li /********************************/
153*05b00f60SXin Li #define SERV_TYPE    6
154*05b00f60SXin Li #define FRM_IPADDR   8
155*05b00f60SXin Li #define LOG_IPHOST  14
156*05b00f60SXin Li #define LOG_SERVICE 15
157*05b00f60SXin Li #define FRM_IPX     23
158*05b00f60SXin Li #define SESSION_TIMEOUT   27
159*05b00f60SXin Li #define IDLE_TIMEOUT      28
160*05b00f60SXin Li #define FRM_ATALK_LINK    37
161*05b00f60SXin Li #define FRM_ATALK_NETWORK 38
162*05b00f60SXin Li 
163*05b00f60SXin Li #define ACCT_DELAY        41
164*05b00f60SXin Li #define ACCT_SESSION_TIME 46
165*05b00f60SXin Li 
166*05b00f60SXin Li #define EGRESS_VLAN_ID   56
167*05b00f60SXin Li #define EGRESS_VLAN_NAME 58
168*05b00f60SXin Li 
169*05b00f60SXin Li #define TUNNEL_TYPE        64
170*05b00f60SXin Li #define TUNNEL_MEDIUM      65
171*05b00f60SXin Li #define TUNNEL_CLIENT_END  66
172*05b00f60SXin Li #define TUNNEL_SERVER_END  67
173*05b00f60SXin Li #define TUNNEL_PASS        69
174*05b00f60SXin Li 
175*05b00f60SXin Li #define ARAP_PASS          70
176*05b00f60SXin Li #define ARAP_FEATURES      71
177*05b00f60SXin Li 
178*05b00f60SXin Li #define EAP_MESSAGE        79
179*05b00f60SXin Li 
180*05b00f60SXin Li #define TUNNEL_PRIV_GROUP  81
181*05b00f60SXin Li #define TUNNEL_ASSIGN_ID   82
182*05b00f60SXin Li #define TUNNEL_PREFERENCE  83
183*05b00f60SXin Li 
184*05b00f60SXin Li #define ARAP_CHALLENGE_RESP 84
185*05b00f60SXin Li #define ACCT_INT_INTERVAL   85
186*05b00f60SXin Li 
187*05b00f60SXin Li #define TUNNEL_CLIENT_AUTH 90
188*05b00f60SXin Li #define TUNNEL_SERVER_AUTH 91
189*05b00f60SXin Li 
190*05b00f60SXin Li #define ERROR_CAUSE 101
191*05b00f60SXin Li /********************************/
192*05b00f60SXin Li /* End Radius Attribute types */
193*05b00f60SXin Li /********************************/
194*05b00f60SXin Li 
195*05b00f60SXin Li #define RFC4675_TAGGED   0x31
196*05b00f60SXin Li #define RFC4675_UNTAGGED 0x32
197*05b00f60SXin Li 
198*05b00f60SXin Li static const struct tok rfc4675_tagged[] = {
199*05b00f60SXin Li     { RFC4675_TAGGED,   "Tagged" },
200*05b00f60SXin Li     { RFC4675_UNTAGGED, "Untagged" },
201*05b00f60SXin Li     { 0, NULL}
202*05b00f60SXin Li };
203*05b00f60SXin Li 
204*05b00f60SXin Li 
205*05b00f60SXin Li static void print_attr_string(netdissect_options *, const u_char *, u_int, u_short );
206*05b00f60SXin Li static void print_attr_num(netdissect_options *, const u_char *, u_int, u_short );
207*05b00f60SXin Li static void print_vendor_attr(netdissect_options *, const u_char *, u_int, u_short );
208*05b00f60SXin Li static void print_attr_address(netdissect_options *, const u_char *, u_int, u_short);
209*05b00f60SXin Li static void print_attr_address6(netdissect_options *, const u_char *, u_int, u_short);
210*05b00f60SXin Li static void print_attr_netmask6(netdissect_options *, const u_char *, u_int, u_short);
211*05b00f60SXin Li static void print_attr_mip6_home_link_prefix(netdissect_options *, const u_char *, u_int, u_short);
212*05b00f60SXin Li static void print_attr_operator_name(netdissect_options *, const u_char *, u_int, u_short);
213*05b00f60SXin Li static void print_attr_location_information(netdissect_options *, const u_char *, u_int, u_short);
214*05b00f60SXin Li static void print_attr_location_data(netdissect_options *, const u_char *, u_int, u_short);
215*05b00f60SXin Li static void print_basic_location_policy_rules(netdissect_options *, const u_char *, u_int, u_short);
216*05b00f60SXin Li static void print_attr_time(netdissect_options *, const u_char *, u_int, u_short);
217*05b00f60SXin Li static void print_attr_vector64(netdissect_options *, register const u_char *, u_int, u_short);
218*05b00f60SXin Li static void print_attr_strange(netdissect_options *, const u_char *, u_int, u_short);
219*05b00f60SXin Li 
220*05b00f60SXin Li 
221*05b00f60SXin Li struct radius_hdr { nd_uint8_t  code;     /* Radius packet code  */
222*05b00f60SXin Li                     nd_uint8_t  id;       /* Radius packet id    */
223*05b00f60SXin Li                     nd_uint16_t len;      /* Radius total length */
224*05b00f60SXin Li                     nd_byte     auth[16]; /* Authenticator   */
225*05b00f60SXin Li                   };
226*05b00f60SXin Li 
227*05b00f60SXin Li #define MIN_RADIUS_LEN	20
228*05b00f60SXin Li 
229*05b00f60SXin Li struct radius_attr { nd_uint8_t type; /* Attribute type   */
230*05b00f60SXin Li                      nd_uint8_t len;  /* Attribute length */
231*05b00f60SXin Li                    };
232*05b00f60SXin Li 
233*05b00f60SXin Li 
234*05b00f60SXin Li /* Service-Type Attribute standard values */
235*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-4 */
236*05b00f60SXin Li static const char *serv_type[]={ NULL,
237*05b00f60SXin Li                                 "Login",
238*05b00f60SXin Li                                 "Framed",
239*05b00f60SXin Li                                 "Callback Login",
240*05b00f60SXin Li                                 "Callback Framed",
241*05b00f60SXin Li                                 "Outbound",
242*05b00f60SXin Li                                 "Administrative",
243*05b00f60SXin Li                                 "NAS Prompt",
244*05b00f60SXin Li                                 "Authenticate Only",
245*05b00f60SXin Li                                 "Callback NAS Prompt",
246*05b00f60SXin Li                                 /* ^ [0, 9] ^ */
247*05b00f60SXin Li                                 "Call Check",
248*05b00f60SXin Li                                 "Callback Administrative",
249*05b00f60SXin Li                                 "Voice",
250*05b00f60SXin Li                                 "Fax",
251*05b00f60SXin Li                                 "Modem Relay",
252*05b00f60SXin Li                                 "IAPP-Register",
253*05b00f60SXin Li                                 "IAPP-AP-Check",
254*05b00f60SXin Li                                 "Authorize Only",
255*05b00f60SXin Li                                 "Framed-Management",
256*05b00f60SXin Li                                 "Additional-Authorization",
257*05b00f60SXin Li                                 /* ^ [10, 19] ^ */
258*05b00f60SXin Li                                };
259*05b00f60SXin Li 
260*05b00f60SXin Li /* Framed-Protocol Attribute standard values */
261*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-5 */
262*05b00f60SXin Li static const char *frm_proto[]={ NULL,
263*05b00f60SXin Li                                  "PPP",
264*05b00f60SXin Li                                  "SLIP",
265*05b00f60SXin Li                                  "ARAP",
266*05b00f60SXin Li                                  "Gandalf proprietary",
267*05b00f60SXin Li                                  "Xylogics IPX/SLIP",
268*05b00f60SXin Li                                  "X.75 Synchronous",
269*05b00f60SXin Li                                  "GPRS PDP Context",
270*05b00f60SXin Li                                };
271*05b00f60SXin Li 
272*05b00f60SXin Li /* Framed-Routing Attribute standard values */
273*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-6 */
274*05b00f60SXin Li static const char *frm_routing[]={ "None",
275*05b00f60SXin Li                                    "Send",
276*05b00f60SXin Li                                    "Listen",
277*05b00f60SXin Li                                    "Send&Listen",
278*05b00f60SXin Li                                  };
279*05b00f60SXin Li 
280*05b00f60SXin Li /* Framed-Compression Attribute standard values */
281*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-7 */
282*05b00f60SXin Li static const char *frm_comp[]={ "None",
283*05b00f60SXin Li                                 "VJ TCP/IP",
284*05b00f60SXin Li                                 "IPX",
285*05b00f60SXin Li                                 "Stac-LZS",
286*05b00f60SXin Li                               };
287*05b00f60SXin Li 
288*05b00f60SXin Li /* Login-Service Attribute standard values */
289*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-8 */
290*05b00f60SXin Li static const char *login_serv[]={ "Telnet",
291*05b00f60SXin Li                                   "Rlogin",
292*05b00f60SXin Li                                   "TCP Clear",
293*05b00f60SXin Li                                   "PortMaster(proprietary)",
294*05b00f60SXin Li                                   "LAT",
295*05b00f60SXin Li                                   "X.25-PAD",
296*05b00f60SXin Li                                   "X.25-T3POS",
297*05b00f60SXin Li                                   "Unassigned",
298*05b00f60SXin Li                                   "TCP Clear Quiet",
299*05b00f60SXin Li                                 };
300*05b00f60SXin Li 
301*05b00f60SXin Li 
302*05b00f60SXin Li /* Termination-Action Attribute standard values */
303*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-9 */
304*05b00f60SXin Li static const char *term_action[]={ "Default",
305*05b00f60SXin Li                                    "RADIUS-Request",
306*05b00f60SXin Li                                  };
307*05b00f60SXin Li 
308*05b00f60SXin Li /* Ingress-Filters Attribute standard values */
309*05b00f60SXin Li static const char *ingress_filters[]={ NULL,
310*05b00f60SXin Li                                        "Enabled",
311*05b00f60SXin Li                                        "Disabled",
312*05b00f60SXin Li                                      };
313*05b00f60SXin Li 
314*05b00f60SXin Li /* NAS-Port-Type Attribute standard values */
315*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-13 */
316*05b00f60SXin Li static const char *nas_port_type[]={ "Async",
317*05b00f60SXin Li                                      "Sync",
318*05b00f60SXin Li                                      "ISDN Sync",
319*05b00f60SXin Li                                      "ISDN Async V.120",
320*05b00f60SXin Li                                      "ISDN Async V.110",
321*05b00f60SXin Li                                      "Virtual",
322*05b00f60SXin Li                                      "PIAFS",
323*05b00f60SXin Li                                      "HDLC Clear Channel",
324*05b00f60SXin Li                                      "X.25",
325*05b00f60SXin Li                                      "X.75",
326*05b00f60SXin Li                                      /* ^ [0, 9] ^ */
327*05b00f60SXin Li                                      "G.3 Fax",
328*05b00f60SXin Li                                      "SDSL",
329*05b00f60SXin Li                                      "ADSL-CAP",
330*05b00f60SXin Li                                      "ADSL-DMT",
331*05b00f60SXin Li                                      "ISDN-DSL",
332*05b00f60SXin Li                                      "Ethernet",
333*05b00f60SXin Li                                      "xDSL",
334*05b00f60SXin Li                                      "Cable",
335*05b00f60SXin Li                                      "Wireless - Other",
336*05b00f60SXin Li                                      "Wireless - IEEE 802.11",
337*05b00f60SXin Li                                      /* ^ [10, 19] ^ */
338*05b00f60SXin Li                                      "Token-Ring",
339*05b00f60SXin Li                                      "FDDI",
340*05b00f60SXin Li                                      "Wireless - CDMA200",
341*05b00f60SXin Li                                      "Wireless - UMTS",
342*05b00f60SXin Li                                      "Wireless - 1X-EV",
343*05b00f60SXin Li                                      "IAPP",
344*05b00f60SXin Li                                      "FTTP",
345*05b00f60SXin Li                                      "Wireless - IEEE 802.16",
346*05b00f60SXin Li                                      "Wireless - IEEE 802.20",
347*05b00f60SXin Li                                      "Wireless - IEEE 802.22",
348*05b00f60SXin Li                                      /* ^ [20, 29] ^ */
349*05b00f60SXin Li                                      "PPPoA",
350*05b00f60SXin Li                                      "PPPoEoA",
351*05b00f60SXin Li                                      "PPPoEoE",
352*05b00f60SXin Li                                      "PPPoEoVLAN",
353*05b00f60SXin Li                                      "PPPoEoQinQ",
354*05b00f60SXin Li                                      "xPON",
355*05b00f60SXin Li                                      "Wireless - XGP",
356*05b00f60SXin Li                                      "WiMAX Pre-Release 8 IWK Function",
357*05b00f60SXin Li                                      "WIMAX-WIFI-IWK",
358*05b00f60SXin Li                                      "WIMAX-SFF",
359*05b00f60SXin Li                                      /* ^ [30, 39] ^ */
360*05b00f60SXin Li                                      "WIMAX-HA-LMA",
361*05b00f60SXin Li                                      "WIMAX-DHCP",
362*05b00f60SXin Li                                      "WIMAX-LBS",
363*05b00f60SXin Li                                      "WIMAX-WVS",
364*05b00f60SXin Li                                    };
365*05b00f60SXin Li 
366*05b00f60SXin Li /* Acct-Status-Type Accounting Attribute standard values */
367*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-10 */
368*05b00f60SXin Li static const char *acct_status[]={ NULL,
369*05b00f60SXin Li                                    "Start",
370*05b00f60SXin Li                                    "Stop",
371*05b00f60SXin Li                                    "Interim-Update",
372*05b00f60SXin Li                                    "Unassigned",
373*05b00f60SXin Li                                    "Unassigned",
374*05b00f60SXin Li                                    "Unassigned",
375*05b00f60SXin Li                                    "Accounting-On",
376*05b00f60SXin Li                                    "Accounting-Off",
377*05b00f60SXin Li                                    "Tunnel-Start",
378*05b00f60SXin Li                                      /* ^ [0, 9] ^ */
379*05b00f60SXin Li                                    "Tunnel-Stop",
380*05b00f60SXin Li                                    "Tunnel-Reject",
381*05b00f60SXin Li                                    "Tunnel-Link-Start",
382*05b00f60SXin Li                                    "Tunnel-Link-Stop",
383*05b00f60SXin Li                                    "Tunnel-Link-Reject",
384*05b00f60SXin Li                                    "Failed",
385*05b00f60SXin Li                                  };
386*05b00f60SXin Li 
387*05b00f60SXin Li /* Acct-Authentic Accounting Attribute standard values */
388*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-11 */
389*05b00f60SXin Li static const char *acct_auth[]={ NULL,
390*05b00f60SXin Li                                  "RADIUS",
391*05b00f60SXin Li                                  "Local",
392*05b00f60SXin Li                                  "Remote",
393*05b00f60SXin Li                                  "Diameter",
394*05b00f60SXin Li                                };
395*05b00f60SXin Li 
396*05b00f60SXin Li /* Acct-Terminate-Cause Accounting Attribute standard values */
397*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-12 */
398*05b00f60SXin Li static const char *acct_term[]={ NULL,
399*05b00f60SXin Li                                  "User Request",
400*05b00f60SXin Li                                  "Lost Carrier",
401*05b00f60SXin Li                                  "Lost Service",
402*05b00f60SXin Li                                  "Idle Timeout",
403*05b00f60SXin Li                                  "Session Timeout",
404*05b00f60SXin Li                                  "Admin Reset",
405*05b00f60SXin Li                                  "Admin Reboot",
406*05b00f60SXin Li                                  "Port Error",
407*05b00f60SXin Li                                  "NAS Error",
408*05b00f60SXin Li                                  /* ^ [0, 9] ^ */
409*05b00f60SXin Li                                  "NAS Request",
410*05b00f60SXin Li                                  "NAS Reboot",
411*05b00f60SXin Li                                  "Port Unneeded",
412*05b00f60SXin Li                                  "Port Preempted",
413*05b00f60SXin Li                                  "Port Suspended",
414*05b00f60SXin Li                                  "Service Unavailable",
415*05b00f60SXin Li                                  "Callback",
416*05b00f60SXin Li                                  "User Error",
417*05b00f60SXin Li                                  "Host Request",
418*05b00f60SXin Li                                  "Supplicant Restart",
419*05b00f60SXin Li                                  /* ^ [10, 19] ^ */
420*05b00f60SXin Li                                  "Reauthentication Failure",
421*05b00f60SXin Li                                  "Port Reinitialized",
422*05b00f60SXin Li                                  "Port Administratively Disabled",
423*05b00f60SXin Li                                  "Lost Power",
424*05b00f60SXin Li                                };
425*05b00f60SXin Li 
426*05b00f60SXin Li /* Tunnel-Type Attribute standard values */
427*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-14 */
428*05b00f60SXin Li static const char *tunnel_type[]={ NULL,
429*05b00f60SXin Li                                    "PPTP",
430*05b00f60SXin Li                                    "L2F",
431*05b00f60SXin Li                                    "L2TP",
432*05b00f60SXin Li                                    "ATMP",
433*05b00f60SXin Li                                    "VTP",
434*05b00f60SXin Li                                    "AH",
435*05b00f60SXin Li                                    "IP-IP",
436*05b00f60SXin Li                                    "MIN-IP-IP",
437*05b00f60SXin Li                                    "ESP",
438*05b00f60SXin Li                                    /* ^ [0, 9] ^ */
439*05b00f60SXin Li                                    "GRE",
440*05b00f60SXin Li                                    "DVS",
441*05b00f60SXin Li                                    "IP-in-IP Tunneling",
442*05b00f60SXin Li                                    "VLAN",
443*05b00f60SXin Li                                  };
444*05b00f60SXin Li 
445*05b00f60SXin Li /* Tunnel-Medium-Type Attribute standard values */
446*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-15 */
447*05b00f60SXin Li static const char *tunnel_medium[]={ NULL,
448*05b00f60SXin Li                                      "IPv4",
449*05b00f60SXin Li                                      "IPv6",
450*05b00f60SXin Li                                      "NSAP",
451*05b00f60SXin Li                                      "HDLC",
452*05b00f60SXin Li                                      "BBN 1822",
453*05b00f60SXin Li                                      "802",
454*05b00f60SXin Li                                      "E.163",
455*05b00f60SXin Li                                      "E.164",
456*05b00f60SXin Li                                      "F.69",
457*05b00f60SXin Li                                      /* ^ [0, 9] ^ */
458*05b00f60SXin Li                                      "X.121",
459*05b00f60SXin Li                                      "IPX",
460*05b00f60SXin Li                                      "Appletalk",
461*05b00f60SXin Li                                      "Decnet IV",
462*05b00f60SXin Li                                      "Banyan Vines",
463*05b00f60SXin Li                                      "E.164 with NSAP subaddress",
464*05b00f60SXin Li                                    };
465*05b00f60SXin Li 
466*05b00f60SXin Li /* ARAP-Zone-Access Attribute standard values */
467*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-16 */
468*05b00f60SXin Li static const char *arap_zone[]={ NULL,
469*05b00f60SXin Li                                  "Only access to dfl zone",
470*05b00f60SXin Li                                  "Use zone filter inc.",
471*05b00f60SXin Li                                  "Not used",
472*05b00f60SXin Li                                  "Use zone filter exc.",
473*05b00f60SXin Li                                };
474*05b00f60SXin Li 
475*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-17 */
476*05b00f60SXin Li static const char *prompt[]={ "No Echo",
477*05b00f60SXin Li                               "Echo",
478*05b00f60SXin Li                             };
479*05b00f60SXin Li 
480*05b00f60SXin Li /* Error-Cause standard values */
481*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-18 */
482*05b00f60SXin Li #define ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED 201
483*05b00f60SXin Li #define ERROR_CAUSE_INVALID_EAP_PACKET 202
484*05b00f60SXin Li #define ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE 401
485*05b00f60SXin Li #define ERROR_CAUSE_MISSING_ATTRIBUTE 402
486*05b00f60SXin Li #define ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH 403
487*05b00f60SXin Li #define ERROR_CAUSE_INVALID_REQUEST 404
488*05b00f60SXin Li #define ERROR_CAUSE_UNSUPPORTED_SERVICE 405
489*05b00f60SXin Li #define ERROR_CAUSE_UNSUPPORTED_EXTENSION 406
490*05b00f60SXin Li #define ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE 407
491*05b00f60SXin Li #define ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED 501
492*05b00f60SXin Li #define ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE 502
493*05b00f60SXin Li #define ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND 503
494*05b00f60SXin Li #define ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE 504
495*05b00f60SXin Li #define ERROR_CAUSE_PROXY_PROCESSING_ERROR 505
496*05b00f60SXin Li #define ERROR_CAUSE_RESOURCES_UNAVAILABLE 506
497*05b00f60SXin Li #define ERROR_CAUSE_REQUEST_INITIATED 507
498*05b00f60SXin Li #define ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED 508
499*05b00f60SXin Li #define ERROR_CAUSE_LOCATION_INFO_REQUIRED 509
500*05b00f60SXin Li static const struct tok errorcausetype[] = {
501*05b00f60SXin Li                                  { ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED,               "Residual Session Context Removed" },
502*05b00f60SXin Li                                  { ERROR_CAUSE_INVALID_EAP_PACKET,                     "Invalid EAP Packet (Ignored)" },
503*05b00f60SXin Li                                  { ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE,                  "Unsupported Attribute" },
504*05b00f60SXin Li                                  { ERROR_CAUSE_MISSING_ATTRIBUTE,                      "Missing Attribute" },
505*05b00f60SXin Li                                  { ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH,            "NAS Identification Mismatch" },
506*05b00f60SXin Li                                  { ERROR_CAUSE_INVALID_REQUEST,                        "Invalid Request" },
507*05b00f60SXin Li                                  { ERROR_CAUSE_UNSUPPORTED_SERVICE,                    "Unsupported Service" },
508*05b00f60SXin Li                                  { ERROR_CAUSE_UNSUPPORTED_EXTENSION,                  "Unsupported Extension" },
509*05b00f60SXin Li                                  { ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE,                "Invalid Attribute Value" },
510*05b00f60SXin Li                                  { ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED,            "Administratively Prohibited" },
511*05b00f60SXin Li                                  { ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE,             "Request Not Routable (Proxy)" },
512*05b00f60SXin Li                                  { ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND,              "Session Context Not Found" },
513*05b00f60SXin Li                                  { ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE,          "Session Context Not Removable" },
514*05b00f60SXin Li                                  { ERROR_CAUSE_PROXY_PROCESSING_ERROR,                 "Other Proxy Processing Error" },
515*05b00f60SXin Li                                  { ERROR_CAUSE_RESOURCES_UNAVAILABLE,                  "Resources Unavailable" },
516*05b00f60SXin Li                                  { ERROR_CAUSE_REQUEST_INITIATED,                      "Request Initiated" },
517*05b00f60SXin Li                                  { ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED, "Multiple Session Selection Unsupported" },
518*05b00f60SXin Li                                  { ERROR_CAUSE_LOCATION_INFO_REQUIRED,                 "Location Info Required" },
519*05b00f60SXin Li 																 { 0, NULL }
520*05b00f60SXin Li                                };
521*05b00f60SXin Li 
522*05b00f60SXin Li /* MIP6-Feature-Vector standard values */
523*05b00f60SXin Li /* https://www.iana.org/assignments/aaa-parameters/aaa-parameters.xhtml */
524*05b00f60SXin Li #define MIP6_INTEGRATED 0x0000000000000001
525*05b00f60SXin Li #define LOCAL_HOME_AGENT_ASSIGNMENT 0x0000000000000002
526*05b00f60SXin Li #define PMIP6_SUPPORTED 0x0000010000000000
527*05b00f60SXin Li #define IP4_HOA_SUPPORTED 0x0000020000000000
528*05b00f60SXin Li #define LOCAL_MAG_ROUTING_SUPPORTED 0x0000040000000000
529*05b00f60SXin Li #define ASSIGN_LOCAL_IP 0x0000080000000000
530*05b00f60SXin Li #define MIP4_SUPPORTED 0x0000100000000000
531*05b00f60SXin Li #define OPTIMIZED_IDLE_MODE_MOBILITY 0x0000200000000000
532*05b00f60SXin Li #define GTPv2_SUPPORTED 0x0000400000000000
533*05b00f60SXin Li #define IP4_TRANSPORT_SUPPORTED 0x0000800000000000
534*05b00f60SXin Li #define IP4_HOA_ONLY_SUPPORTED 0x0001000000000000
535*05b00f60SXin Li #define INTER_MAG_ROUTING_SUPPORTED 0x0002000000000000
536*05b00f60SXin Li static const struct mip6_feature_vector {
537*05b00f60SXin Li                   uint64_t v;
538*05b00f60SXin Li                   const char *s;
539*05b00f60SXin Li                 } mip6_feature_vector[] = {
540*05b00f60SXin Li                                  { MIP6_INTEGRATED,             "MIP6_INTEGRATED" },
541*05b00f60SXin Li                                  { LOCAL_HOME_AGENT_ASSIGNMENT, "LOCAL_HOME_AGENT_ASSIGNMENT" },
542*05b00f60SXin Li                                  { PMIP6_SUPPORTED,             "PMIP6_SUPPORTED" },
543*05b00f60SXin Li                                  { IP4_HOA_SUPPORTED,           "IP4_HOA_SUPPORTED" },
544*05b00f60SXin Li                                  { LOCAL_MAG_ROUTING_SUPPORTED, "LOCAL_MAG_ROUTING_SUPPORTED" },
545*05b00f60SXin Li                                  { ASSIGN_LOCAL_IP,             "ASSIGN_LOCAL_IP" },
546*05b00f60SXin Li                                  { MIP4_SUPPORTED,              "MIP4_SUPPORTED" },
547*05b00f60SXin Li                                  { OPTIMIZED_IDLE_MODE_MOBILITY, "OPTIMIZED_IDLE_MODE_MOBILITY" },
548*05b00f60SXin Li                                  { GTPv2_SUPPORTED,             "GTPv2_SUPPORTED" },
549*05b00f60SXin Li                                  { IP4_TRANSPORT_SUPPORTED,     "IP4_TRANSPORT_SUPPORTED" },
550*05b00f60SXin Li                                  { IP4_HOA_ONLY_SUPPORTED,      "IP4_HOA_ONLY_SUPPORTED" },
551*05b00f60SXin Li                                  { INTER_MAG_ROUTING_SUPPORTED, "INTER_MAG_ROUTING_SUPPORTED" },
552*05b00f60SXin Li                                };
553*05b00f60SXin Li 
554*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-19 */
555*05b00f60SXin Li #define OPERATOR_NAME_TADIG 0x30
556*05b00f60SXin Li #define OPERATOR_NAME_REALM 0x31
557*05b00f60SXin Li #define OPERATOR_NAME_E212  0x32
558*05b00f60SXin Li #define OPERATOR_NAME_ICC   0x33
559*05b00f60SXin Li static const struct tok operator_name_vector[] = {
560*05b00f60SXin Li                                  { OPERATOR_NAME_TADIG, "TADIG" },
561*05b00f60SXin Li                                  { OPERATOR_NAME_REALM, "REALM" },
562*05b00f60SXin Li                                  { OPERATOR_NAME_E212,  "E212"  },
563*05b00f60SXin Li                                  { OPERATOR_NAME_ICC,   "ICC"   },
564*05b00f60SXin Li                                  { 0, NULL }
565*05b00f60SXin Li                                };
566*05b00f60SXin Li 
567*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-20 */
568*05b00f60SXin Li #define LOCATION_INFORMATION_CODE_CIVIC      0
569*05b00f60SXin Li #define LOCATION_INFORMATION_CODE_GEOSPATIAL 1
570*05b00f60SXin Li static const struct tok location_information_code_vector[] = {
571*05b00f60SXin Li                                  { LOCATION_INFORMATION_CODE_CIVIC     , "Civic"      },
572*05b00f60SXin Li                                  { LOCATION_INFORMATION_CODE_GEOSPATIAL, "Geospatial" },
573*05b00f60SXin Li                                  { 0, NULL }
574*05b00f60SXin Li                                };
575*05b00f60SXin Li 
576*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-21 */
577*05b00f60SXin Li #define LOCATION_INFORMATION_ENTITY_USER   0
578*05b00f60SXin Li #define LOCATION_INFORMATION_ENTITY_RADIUS 1
579*05b00f60SXin Li static const struct tok location_information_entity_vector[] = {
580*05b00f60SXin Li                                  { LOCATION_INFORMATION_ENTITY_USER,   "User"   },
581*05b00f60SXin Li                                  { LOCATION_INFORMATION_ENTITY_RADIUS, "RADIUS" },
582*05b00f60SXin Li                                  { 0, NULL }
583*05b00f60SXin Li                                };
584*05b00f60SXin Li 
585*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-22 */
586*05b00f60SXin Li static const struct tok blpr_bm[] = {
587*05b00f60SXin Li                                  { 0x0001, "MBZ-15" },
588*05b00f60SXin Li                                  { 0x0002, "MBZ-14" },
589*05b00f60SXin Li                                  { 0x0004, "MBZ-13" },
590*05b00f60SXin Li                                  { 0x0008, "MBZ-12" },
591*05b00f60SXin Li                                  { 0x0010, "MBZ-11" },
592*05b00f60SXin Li                                  { 0x0020, "MBZ-10" },
593*05b00f60SXin Li                                  { 0x0040, "MBZ-9" },
594*05b00f60SXin Li                                  { 0x0080, "MBZ-8" },
595*05b00f60SXin Li                                  { 0x0100, "MBZ-7" },
596*05b00f60SXin Li                                  { 0x0200, "MBZ-6" },
597*05b00f60SXin Li                                  { 0x0400, "MBZ-5" },
598*05b00f60SXin Li                                  { 0x0800, "MBZ-4" },
599*05b00f60SXin Li                                  { 0x1000, "MBZ-3" },
600*05b00f60SXin Li                                  { 0x2000, "MBZ-2" },
601*05b00f60SXin Li                                  { 0x4000, "MBZ-1" },
602*05b00f60SXin Li                                  { 0x8000, "Retransmission Allowed" },
603*05b00f60SXin Li                                  { 0, NULL }
604*05b00f60SXin Li                                };
605*05b00f60SXin Li 
606*05b00f60SXin Li /* https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-2 */
607*05b00f60SXin Li static const struct attrtype {
608*05b00f60SXin Li                   const char *name;      /* Attribute name                 */
609*05b00f60SXin Li                   const char **subtypes; /* Standard Values (if any)       */
610*05b00f60SXin Li                   u_char siz_subtypes;   /* Size of total standard values  */
611*05b00f60SXin Li                   u_char first_subtype;  /* First standard value is 0 or 1 */
612*05b00f60SXin Li                   void (*print_func)(netdissect_options *, const u_char *, u_int, u_short);
613*05b00f60SXin Li                 } attr_type[]=
614*05b00f60SXin Li   {
615*05b00f60SXin Li      { NULL,                              NULL, 0, 0, NULL               },
616*05b00f60SXin Li      { "User-Name",                       NULL, 0, 0, print_attr_string  },
617*05b00f60SXin Li      { "User-Password",                   NULL, 0, 0, NULL               },
618*05b00f60SXin Li      { "CHAP-Password",                   NULL, 0, 0, NULL               },
619*05b00f60SXin Li      { "NAS-IP-Address",                  NULL, 0, 0, print_attr_address },
620*05b00f60SXin Li      { "NAS-Port",                        NULL, 0, 0, print_attr_num     },
621*05b00f60SXin Li      { "Service-Type",                    serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num },
622*05b00f60SXin Li      { "Framed-Protocol",                 frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num },
623*05b00f60SXin Li      { "Framed-IP-Address",               NULL, 0, 0, print_attr_address },
624*05b00f60SXin Li      { "Framed-IP-Netmask",               NULL, 0, 0, print_attr_address },
625*05b00f60SXin Li      /* ^ [0, 9] ^ */
626*05b00f60SXin Li      { "Framed-Routing",                  frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num },
627*05b00f60SXin Li      { "Filter-Id",                       NULL, 0, 0, print_attr_string  },
628*05b00f60SXin Li      { "Framed-MTU",                      NULL, 0, 0, print_attr_num     },
629*05b00f60SXin Li      { "Framed-Compression",              frm_comp, TAM_SIZE(frm_comp),   0, print_attr_num },
630*05b00f60SXin Li      { "Login-IP-Host",                   NULL, 0, 0, print_attr_address },
631*05b00f60SXin Li      { "Login-Service",                   login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
632*05b00f60SXin Li      { "Login-TCP-Port",                  NULL, 0, 0, print_attr_num     },
633*05b00f60SXin Li      { "Unassigned",                      NULL, 0, 0, NULL }, /*17*/
634*05b00f60SXin Li      { "Reply-Message",                   NULL, 0, 0, print_attr_string },
635*05b00f60SXin Li      { "Callback-Number",                 NULL, 0, 0, print_attr_string },
636*05b00f60SXin Li      /* ^ [10, 19] ^ */
637*05b00f60SXin Li      { "Callback-Id",                     NULL, 0, 0, print_attr_string },
638*05b00f60SXin Li      { "Unassigned",                      NULL, 0, 0, NULL }, /*21*/
639*05b00f60SXin Li      { "Framed-Route",                    NULL, 0, 0, print_attr_string },
640*05b00f60SXin Li      { "Framed-IPX-Network",              NULL, 0, 0, print_attr_num    },
641*05b00f60SXin Li      { "State",                           NULL, 0, 0, print_attr_string },
642*05b00f60SXin Li      { "Class",                           NULL, 0, 0, print_attr_string },
643*05b00f60SXin Li      { "Vendor-Specific",                 NULL, 0, 0, print_vendor_attr },
644*05b00f60SXin Li      { "Session-Timeout",                 NULL, 0, 0, print_attr_num    },
645*05b00f60SXin Li      { "Idle-Timeout",                    NULL, 0, 0, print_attr_num    },
646*05b00f60SXin Li      { "Termination-Action",              term_action, TAM_SIZE(term_action), 0, print_attr_num },
647*05b00f60SXin Li      /* ^ [20, 29] ^ */
648*05b00f60SXin Li      { "Called-Station-Id",               NULL, 0, 0, print_attr_string },
649*05b00f60SXin Li      { "Calling-Station-Id",              NULL, 0, 0, print_attr_string },
650*05b00f60SXin Li      { "NAS-Identifier",                  NULL, 0, 0, print_attr_string },
651*05b00f60SXin Li      { "Proxy-State",                     NULL, 0, 0, print_attr_string },
652*05b00f60SXin Li      { "Login-LAT-Service",               NULL, 0, 0, print_attr_string },
653*05b00f60SXin Li      { "Login-LAT-Node",                  NULL, 0, 0, print_attr_string },
654*05b00f60SXin Li      { "Login-LAT-Group",                 NULL, 0, 0, print_attr_string },
655*05b00f60SXin Li      { "Framed-AppleTalk-Link",           NULL, 0, 0, print_attr_num    },
656*05b00f60SXin Li      { "Framed-AppleTalk-Network",        NULL, 0, 0, print_attr_num    },
657*05b00f60SXin Li      { "Framed-AppleTalk-Zone",           NULL, 0, 0, print_attr_string },
658*05b00f60SXin Li      /* ^ [30, 39] ^ */
659*05b00f60SXin Li      { "Acct-Status-Type",                acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num },
660*05b00f60SXin Li      { "Acct-Delay-Time",                 NULL, 0, 0, print_attr_num    },
661*05b00f60SXin Li      { "Acct-Input-Octets",               NULL, 0, 0, print_attr_num    },
662*05b00f60SXin Li      { "Acct-Output-Octets",              NULL, 0, 0, print_attr_num    },
663*05b00f60SXin Li      { "Acct-Session-Id",                 NULL, 0, 0, print_attr_string },
664*05b00f60SXin Li      { "Acct-Authentic",                  acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num },
665*05b00f60SXin Li      { "Acct-Session-Time",               NULL, 0, 0, print_attr_num },
666*05b00f60SXin Li      { "Acct-Input-Packets",              NULL, 0, 0, print_attr_num },
667*05b00f60SXin Li      { "Acct-Output-Packets",             NULL, 0, 0, print_attr_num },
668*05b00f60SXin Li      { "Acct-Terminate-Cause",            acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num },
669*05b00f60SXin Li      /* ^ [40, 49] ^ */
670*05b00f60SXin Li      { "Acct-Multi-Session-Id",           NULL, 0, 0, print_attr_string },
671*05b00f60SXin Li      { "Acct-Link-Count",                 NULL, 0, 0, print_attr_num },
672*05b00f60SXin Li      { "Acct-Input-Gigawords",            NULL, 0, 0, print_attr_num },
673*05b00f60SXin Li      { "Acct-Output-Gigawords",           NULL, 0, 0, print_attr_num },
674*05b00f60SXin Li      { "Unassigned",                      NULL, 0, 0, NULL }, /*54*/
675*05b00f60SXin Li      { "Event-Timestamp",                 NULL, 0, 0, print_attr_time },
676*05b00f60SXin Li      { "Egress-VLANID",                   NULL, 0, 0, print_attr_num },
677*05b00f60SXin Li      { "Ingress-Filters",                 ingress_filters, TAM_SIZE(ingress_filters)-1, 1, print_attr_num },
678*05b00f60SXin Li      { "Egress-VLAN-Name",                NULL, 0, 0, print_attr_string },
679*05b00f60SXin Li      { "User-Priority-Table",             NULL, 0, 0, NULL },
680*05b00f60SXin Li      /* ^ [50, 59] ^ */
681*05b00f60SXin Li      { "CHAP-Challenge",                  NULL, 0, 0, print_attr_string },
682*05b00f60SXin Li      { "NAS-Port-Type",                   nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num },
683*05b00f60SXin Li      { "Port-Limit",                      NULL, 0, 0, print_attr_num },
684*05b00f60SXin Li      { "Login-LAT-Port",                  NULL, 0, 0, print_attr_string }, /*63*/
685*05b00f60SXin Li      { "Tunnel-Type",                     tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num },
686*05b00f60SXin Li      { "Tunnel-Medium-Type",              tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num },
687*05b00f60SXin Li      { "Tunnel-Client-Endpoint",          NULL, 0, 0, print_attr_string },
688*05b00f60SXin Li      { "Tunnel-Server-Endpoint",          NULL, 0, 0, print_attr_string },
689*05b00f60SXin Li      { "Acct-Tunnel-Connection",          NULL, 0, 0, print_attr_string },
690*05b00f60SXin Li      { "Tunnel-Password",                 NULL, 0, 0, print_attr_string  },
691*05b00f60SXin Li      /* ^ [60, 69] ^ */
692*05b00f60SXin Li      { "ARAP-Password",                   NULL, 0, 0, print_attr_strange },
693*05b00f60SXin Li      { "ARAP-Features",                   NULL, 0, 0, print_attr_strange },
694*05b00f60SXin Li      { "ARAP-Zone-Access",                arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/
695*05b00f60SXin Li      { "ARAP-Security",                   NULL, 0, 0, print_attr_string },
696*05b00f60SXin Li      { "ARAP-Security-Data",              NULL, 0, 0, print_attr_string },
697*05b00f60SXin Li      { "Password-Retry",                  NULL, 0, 0, print_attr_num    },
698*05b00f60SXin Li      { "Prompt",                          prompt, TAM_SIZE(prompt), 0, print_attr_num },
699*05b00f60SXin Li      { "Connect-Info",                    NULL, 0, 0, print_attr_string   },
700*05b00f60SXin Li      { "Configuration-Token",             NULL, 0, 0, print_attr_string   },
701*05b00f60SXin Li      { "EAP-Message",                     NULL, 0, 0, print_attr_string   },
702*05b00f60SXin Li      /* ^ [70, 79] ^ */
703*05b00f60SXin Li      { "Message-Authenticator",           NULL, 0, 0, print_attr_string }, /*80*/
704*05b00f60SXin Li      { "Tunnel-Private-Group-ID",         NULL, 0, 0, print_attr_string },
705*05b00f60SXin Li      { "Tunnel-Assignment-ID",            NULL, 0, 0, print_attr_string },
706*05b00f60SXin Li      { "Tunnel-Preference",               NULL, 0, 0, print_attr_num    },
707*05b00f60SXin Li      { "ARAP-Challenge-Response",         NULL, 0, 0, print_attr_strange },
708*05b00f60SXin Li      { "Acct-Interim-Interval",           NULL, 0, 0, print_attr_num     },
709*05b00f60SXin Li      { "Acct-Tunnel-Packets-Lost",        NULL, 0, 0, print_attr_num }, /*86*/
710*05b00f60SXin Li      { "NAS-Port-Id",                     NULL, 0, 0, print_attr_string },
711*05b00f60SXin Li      { "Framed-Pool",                     NULL, 0, 0, print_attr_string },
712*05b00f60SXin Li      { "CUI",                             NULL, 0, 0, print_attr_string },
713*05b00f60SXin Li      /* ^ [80, 89] ^ */
714*05b00f60SXin Li      { "Tunnel-Client-Auth-ID",           NULL, 0, 0, print_attr_string },
715*05b00f60SXin Li      { "Tunnel-Server-Auth-ID",           NULL, 0, 0, print_attr_string },
716*05b00f60SXin Li      { "NAS-Filter-Rule",                 NULL, 0, 0, print_attr_string },
717*05b00f60SXin Li      { "Unassigned",                      NULL, 0, 0, NULL },  /*93*/
718*05b00f60SXin Li      { "Originating-Line-Info",           NULL, 0, 0, NULL },
719*05b00f60SXin Li      { "NAS-IPv6-Address",                NULL, 0, 0, print_attr_address6 },
720*05b00f60SXin Li      { "Framed-Interface-ID",             NULL, 0, 0, NULL },
721*05b00f60SXin Li      { "Framed-IPv6-Prefix",              NULL, 0, 0, print_attr_netmask6 },
722*05b00f60SXin Li      { "Login-IPv6-Host",                 NULL, 0, 0, print_attr_address6 },
723*05b00f60SXin Li      { "Framed-IPv6-Route",               NULL, 0, 0, print_attr_string },
724*05b00f60SXin Li      /* ^ [90, 99] ^ */
725*05b00f60SXin Li      { "Framed-IPv6-Pool",                NULL, 0, 0, print_attr_string },
726*05b00f60SXin Li      { "Error-Cause",                     NULL, 0, 0, print_attr_strange },
727*05b00f60SXin Li      { "EAP-Key-Name",                    NULL, 0, 0, NULL },
728*05b00f60SXin Li      { "Digest-Response",                 NULL, 0, 0, print_attr_string },
729*05b00f60SXin Li      { "Digest-Realm",                    NULL, 0, 0, print_attr_string },
730*05b00f60SXin Li      { "Digest-Nonce",                    NULL, 0, 0, print_attr_string },
731*05b00f60SXin Li      { "Digest-Response-Auth",            NULL, 0, 0, print_attr_string },
732*05b00f60SXin Li      { "Digest-Nextnonce",                NULL, 0, 0, print_attr_string },
733*05b00f60SXin Li      { "Digest-Method",                   NULL, 0, 0, print_attr_string },
734*05b00f60SXin Li      { "Digest-URI",                      NULL, 0, 0, print_attr_string },
735*05b00f60SXin Li      /* ^ [100, 109] ^ */
736*05b00f60SXin Li      { "Digest-Qop",                      NULL, 0, 0, print_attr_string },
737*05b00f60SXin Li      { "Digest-Algorithm",                NULL, 0, 0, print_attr_string },
738*05b00f60SXin Li      { "Digest-Entity-Body-Hash",         NULL, 0, 0, print_attr_string },
739*05b00f60SXin Li      { "Digest-CNonce",                   NULL, 0, 0, print_attr_string },
740*05b00f60SXin Li      { "Digest-Nonce-Count",              NULL, 0, 0, print_attr_string },
741*05b00f60SXin Li      { "Digest-Username",                 NULL, 0, 0, print_attr_string },
742*05b00f60SXin Li      { "Digest-Opaque",                   NULL, 0, 0, print_attr_string },
743*05b00f60SXin Li      { "Digest-Auth-Param",               NULL, 0, 0, print_attr_string },
744*05b00f60SXin Li      { "Digest-AKA-Auts",                 NULL, 0, 0, print_attr_string },
745*05b00f60SXin Li      { "Digest-Domain",                   NULL, 0, 0, print_attr_string },
746*05b00f60SXin Li      /* ^ [110, 119] ^ */
747*05b00f60SXin Li      { "Digest-Stale",                    NULL, 0, 0, print_attr_string },
748*05b00f60SXin Li      { "Digest-HA1",                      NULL, 0, 0, print_attr_string },
749*05b00f60SXin Li      { "SIP-AOR",                         NULL, 0, 0, print_attr_string },
750*05b00f60SXin Li      { "Delegated-IPv6-Prefix",           NULL, 0, 0, print_attr_netmask6 },
751*05b00f60SXin Li      { "MIP6-Feature-Vector",             NULL, 0, 0, print_attr_vector64 },
752*05b00f60SXin Li      { "MIP6-Home-Link-Prefix",           NULL, 0, 0, print_attr_mip6_home_link_prefix },
753*05b00f60SXin Li      { "Operator-Name",                   NULL, 0, 0, print_attr_operator_name },
754*05b00f60SXin Li      { "Location-Information",            NULL, 0, 0, print_attr_location_information },
755*05b00f60SXin Li      { "Location-Data",                   NULL, 0, 0, print_attr_location_data },
756*05b00f60SXin Li      { "Basic-Location-Policy-Rules",     NULL, 0, 0, print_basic_location_policy_rules }
757*05b00f60SXin Li      /* ^ [120, 129] ^ */
758*05b00f60SXin Li   };
759*05b00f60SXin Li 
760*05b00f60SXin Li 
761*05b00f60SXin Li /*****************************/
762*05b00f60SXin Li /* Print an attribute string */
763*05b00f60SXin Li /* value pointed by 'data'   */
764*05b00f60SXin Li /* and 'length' size.        */
765*05b00f60SXin Li /*****************************/
766*05b00f60SXin Li /* Returns nothing.          */
767*05b00f60SXin Li /*****************************/
768*05b00f60SXin Li static void
print_attr_string(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code)769*05b00f60SXin Li print_attr_string(netdissect_options *ndo,
770*05b00f60SXin Li                   const u_char *data, u_int length, u_short attr_code)
771*05b00f60SXin Li {
772*05b00f60SXin Li    u_int i;
773*05b00f60SXin Li 
774*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
775*05b00f60SXin Li 
776*05b00f60SXin Li    switch(attr_code)
777*05b00f60SXin Li    {
778*05b00f60SXin Li       case TUNNEL_PASS:
779*05b00f60SXin Li            if (length < 3)
780*05b00f60SXin Li               goto trunc;
781*05b00f60SXin Li            if (GET_U_1(data) && (GET_U_1(data) <= 0x1F))
782*05b00f60SXin Li               ND_PRINT("Tag[%u] ", GET_U_1(data));
783*05b00f60SXin Li            else
784*05b00f60SXin Li               ND_PRINT("Tag[Unused] ");
785*05b00f60SXin Li            data++;
786*05b00f60SXin Li            length--;
787*05b00f60SXin Li            ND_PRINT("Salt %u ", GET_BE_U_2(data));
788*05b00f60SXin Li            data+=2;
789*05b00f60SXin Li            length-=2;
790*05b00f60SXin Li         break;
791*05b00f60SXin Li       case TUNNEL_CLIENT_END:
792*05b00f60SXin Li       case TUNNEL_SERVER_END:
793*05b00f60SXin Li       case TUNNEL_PRIV_GROUP:
794*05b00f60SXin Li       case TUNNEL_ASSIGN_ID:
795*05b00f60SXin Li       case TUNNEL_CLIENT_AUTH:
796*05b00f60SXin Li       case TUNNEL_SERVER_AUTH:
797*05b00f60SXin Li            if (GET_U_1(data) <= 0x1F)
798*05b00f60SXin Li            {
799*05b00f60SXin Li               if (length < 1)
800*05b00f60SXin Li                  goto trunc;
801*05b00f60SXin Li               if (GET_U_1(data))
802*05b00f60SXin Li                 ND_PRINT("Tag[%u] ", GET_U_1(data));
803*05b00f60SXin Li               else
804*05b00f60SXin Li                 ND_PRINT("Tag[Unused] ");
805*05b00f60SXin Li               data++;
806*05b00f60SXin Li               length--;
807*05b00f60SXin Li            }
808*05b00f60SXin Li         break;
809*05b00f60SXin Li       case EGRESS_VLAN_NAME:
810*05b00f60SXin Li            if (length < 1)
811*05b00f60SXin Li               goto trunc;
812*05b00f60SXin Li            ND_PRINT("%s (0x%02x) ",
813*05b00f60SXin Li                   tok2str(rfc4675_tagged,"Unknown tag",GET_U_1(data)),
814*05b00f60SXin Li                   GET_U_1(data));
815*05b00f60SXin Li            data++;
816*05b00f60SXin Li            length--;
817*05b00f60SXin Li         break;
818*05b00f60SXin Li       case EAP_MESSAGE:
819*05b00f60SXin Li            if (length < 1)
820*05b00f60SXin Li               goto trunc;
821*05b00f60SXin Li            eap_print(ndo, data, length);
822*05b00f60SXin Li            return;
823*05b00f60SXin Li    }
824*05b00f60SXin Li 
825*05b00f60SXin Li    for (i=0; i < length && GET_U_1(data); i++, data++)
826*05b00f60SXin Li        ND_PRINT("%c", ND_ASCII_ISPRINT(GET_U_1(data)) ? GET_U_1(data) : '.');
827*05b00f60SXin Li 
828*05b00f60SXin Li    return;
829*05b00f60SXin Li 
830*05b00f60SXin Li    trunc:
831*05b00f60SXin Li       nd_print_trunc(ndo);
832*05b00f60SXin Li }
833*05b00f60SXin Li 
834*05b00f60SXin Li /*
835*05b00f60SXin Li  * print vendor specific attributes
836*05b00f60SXin Li  */
837*05b00f60SXin Li static void
print_vendor_attr(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)838*05b00f60SXin Li print_vendor_attr(netdissect_options *ndo,
839*05b00f60SXin Li                   const u_char *data, u_int length, u_short attr_code _U_)
840*05b00f60SXin Li {
841*05b00f60SXin Li     u_int idx;
842*05b00f60SXin Li     u_int vendor_id;
843*05b00f60SXin Li     u_int vendor_type;
844*05b00f60SXin Li     u_int vendor_length;
845*05b00f60SXin Li 
846*05b00f60SXin Li     if (length < 4)
847*05b00f60SXin Li         goto trunc;
848*05b00f60SXin Li     vendor_id = GET_BE_U_4(data);
849*05b00f60SXin Li     data+=4;
850*05b00f60SXin Li     length-=4;
851*05b00f60SXin Li 
852*05b00f60SXin Li     ND_PRINT("Vendor: %s (%u)",
853*05b00f60SXin Li            tok2str(smi_values,"Unknown",vendor_id),
854*05b00f60SXin Li            vendor_id);
855*05b00f60SXin Li 
856*05b00f60SXin Li     while (length >= 2) {
857*05b00f60SXin Li         vendor_type = GET_U_1(data);
858*05b00f60SXin Li         vendor_length = GET_U_1(data + 1);
859*05b00f60SXin Li 
860*05b00f60SXin Li         if (vendor_length < 2)
861*05b00f60SXin Li         {
862*05b00f60SXin Li             ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
863*05b00f60SXin Li                    vendor_type,
864*05b00f60SXin Li                    vendor_length);
865*05b00f60SXin Li             return;
866*05b00f60SXin Li         }
867*05b00f60SXin Li         if (vendor_length > length)
868*05b00f60SXin Li         {
869*05b00f60SXin Li             ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
870*05b00f60SXin Li                    vendor_type,
871*05b00f60SXin Li                    vendor_length);
872*05b00f60SXin Li             return;
873*05b00f60SXin Li         }
874*05b00f60SXin Li         data+=2;
875*05b00f60SXin Li         vendor_length-=2;
876*05b00f60SXin Li         length-=2;
877*05b00f60SXin Li 	ND_TCHECK_LEN(data, vendor_length);
878*05b00f60SXin Li 
879*05b00f60SXin Li         ND_PRINT("\n\t    Vendor Attribute: %u, Length: %u, Value: ",
880*05b00f60SXin Li                vendor_type,
881*05b00f60SXin Li                vendor_length);
882*05b00f60SXin Li         for (idx = 0; idx < vendor_length ; idx++, data++)
883*05b00f60SXin Li             ND_PRINT("%c", ND_ASCII_ISPRINT(GET_U_1(data)) ? GET_U_1(data) : '.');
884*05b00f60SXin Li         length-=vendor_length;
885*05b00f60SXin Li     }
886*05b00f60SXin Li     return;
887*05b00f60SXin Li 
888*05b00f60SXin Li    trunc:
889*05b00f60SXin Li      nd_print_trunc(ndo);
890*05b00f60SXin Li }
891*05b00f60SXin Li 
892*05b00f60SXin Li /******************************/
893*05b00f60SXin Li /* Print an attribute numeric */
894*05b00f60SXin Li /* value pointed by 'data'    */
895*05b00f60SXin Li /* and 'length' size.         */
896*05b00f60SXin Li /******************************/
897*05b00f60SXin Li /* Returns nothing.           */
898*05b00f60SXin Li /******************************/
899*05b00f60SXin Li static void
print_attr_num(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code)900*05b00f60SXin Li print_attr_num(netdissect_options *ndo,
901*05b00f60SXin Li                const u_char *data, u_int length, u_short attr_code)
902*05b00f60SXin Li {
903*05b00f60SXin Li    uint32_t timeout;
904*05b00f60SXin Li 
905*05b00f60SXin Li    if (length != 4)
906*05b00f60SXin Li    {
907*05b00f60SXin Li        ND_PRINT("ERROR: length %u != 4", length);
908*05b00f60SXin Li        return;
909*05b00f60SXin Li    }
910*05b00f60SXin Li 
911*05b00f60SXin Li                           /* This attribute has standard values */
912*05b00f60SXin Li    if (attr_type[attr_code].siz_subtypes)
913*05b00f60SXin Li    {
914*05b00f60SXin Li       static const char **table;
915*05b00f60SXin Li       uint32_t data_value;
916*05b00f60SXin Li       table = attr_type[attr_code].subtypes;
917*05b00f60SXin Li 
918*05b00f60SXin Li       if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
919*05b00f60SXin Li       {
920*05b00f60SXin Li          if (!GET_U_1(data))
921*05b00f60SXin Li             ND_PRINT("Tag[Unused] ");
922*05b00f60SXin Li          else
923*05b00f60SXin Li             ND_PRINT("Tag[%u] ", GET_U_1(data));
924*05b00f60SXin Li          data++;
925*05b00f60SXin Li          data_value = GET_BE_U_3(data);
926*05b00f60SXin Li       }
927*05b00f60SXin Li       else
928*05b00f60SXin Li       {
929*05b00f60SXin Li          data_value = GET_BE_U_4(data);
930*05b00f60SXin Li       }
931*05b00f60SXin Li       if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 +
932*05b00f60SXin Li             attr_type[attr_code].first_subtype) &&
933*05b00f60SXin Li 	   data_value >= attr_type[attr_code].first_subtype )
934*05b00f60SXin Li          ND_PRINT("%s", table[data_value]);
935*05b00f60SXin Li       else
936*05b00f60SXin Li          ND_PRINT("#%u", data_value);
937*05b00f60SXin Li    }
938*05b00f60SXin Li    else
939*05b00f60SXin Li    {
940*05b00f60SXin Li       switch(attr_code) /* Be aware of special cases... */
941*05b00f60SXin Li       {
942*05b00f60SXin Li         case FRM_IPX:
943*05b00f60SXin Li              if (GET_BE_U_4(data) == 0xFFFFFFFE )
944*05b00f60SXin Li                 ND_PRINT("NAS Select");
945*05b00f60SXin Li              else
946*05b00f60SXin Li                 ND_PRINT("%u", GET_BE_U_4(data));
947*05b00f60SXin Li           break;
948*05b00f60SXin Li 
949*05b00f60SXin Li         case SESSION_TIMEOUT:
950*05b00f60SXin Li         case IDLE_TIMEOUT:
951*05b00f60SXin Li         case ACCT_DELAY:
952*05b00f60SXin Li         case ACCT_SESSION_TIME:
953*05b00f60SXin Li         case ACCT_INT_INTERVAL:
954*05b00f60SXin Li              timeout = GET_BE_U_4(data);
955*05b00f60SXin Li              if ( timeout < 60 )
956*05b00f60SXin Li                 ND_PRINT("%02d secs", timeout);
957*05b00f60SXin Li              else
958*05b00f60SXin Li              {
959*05b00f60SXin Li                 if ( timeout < 3600 )
960*05b00f60SXin Li                    ND_PRINT("%02d:%02d min",
961*05b00f60SXin Li                           timeout / 60, timeout % 60);
962*05b00f60SXin Li                 else
963*05b00f60SXin Li                    ND_PRINT("%02d:%02d:%02d hours",
964*05b00f60SXin Li                           timeout / 3600, (timeout % 3600) / 60,
965*05b00f60SXin Li                           timeout % 60);
966*05b00f60SXin Li              }
967*05b00f60SXin Li           break;
968*05b00f60SXin Li 
969*05b00f60SXin Li         case FRM_ATALK_LINK:
970*05b00f60SXin Li              if (GET_BE_U_4(data))
971*05b00f60SXin Li                 ND_PRINT("%u", GET_BE_U_4(data));
972*05b00f60SXin Li              else
973*05b00f60SXin Li                 ND_PRINT("Unnumbered");
974*05b00f60SXin Li           break;
975*05b00f60SXin Li 
976*05b00f60SXin Li         case FRM_ATALK_NETWORK:
977*05b00f60SXin Li              if (GET_BE_U_4(data))
978*05b00f60SXin Li                 ND_PRINT("%u", GET_BE_U_4(data));
979*05b00f60SXin Li              else
980*05b00f60SXin Li                 ND_PRINT("NAS assigned");
981*05b00f60SXin Li           break;
982*05b00f60SXin Li 
983*05b00f60SXin Li         case TUNNEL_PREFERENCE:
984*05b00f60SXin Li             if (GET_U_1(data))
985*05b00f60SXin Li                ND_PRINT("Tag[%u] ", GET_U_1(data));
986*05b00f60SXin Li             else
987*05b00f60SXin Li                ND_PRINT("Tag[Unused] ");
988*05b00f60SXin Li             data++;
989*05b00f60SXin Li             ND_PRINT("%u", GET_BE_U_3(data));
990*05b00f60SXin Li           break;
991*05b00f60SXin Li 
992*05b00f60SXin Li         case EGRESS_VLAN_ID:
993*05b00f60SXin Li             ND_PRINT("%s (0x%02x) ",
994*05b00f60SXin Li                    tok2str(rfc4675_tagged,"Unknown tag",GET_U_1(data)),
995*05b00f60SXin Li                    GET_U_1(data));
996*05b00f60SXin Li             data++;
997*05b00f60SXin Li             ND_PRINT("%u", GET_BE_U_3(data));
998*05b00f60SXin Li           break;
999*05b00f60SXin Li 
1000*05b00f60SXin Li         default:
1001*05b00f60SXin Li              ND_PRINT("%u", GET_BE_U_4(data));
1002*05b00f60SXin Li           break;
1003*05b00f60SXin Li 
1004*05b00f60SXin Li       } /* switch */
1005*05b00f60SXin Li 
1006*05b00f60SXin Li    } /* if-else */
1007*05b00f60SXin Li }
1008*05b00f60SXin Li 
1009*05b00f60SXin Li /*****************************/
1010*05b00f60SXin Li /* Print an attribute IPv4   */
1011*05b00f60SXin Li /* address value pointed by  */
1012*05b00f60SXin Li /* 'data' and 'length' size. */
1013*05b00f60SXin Li /*****************************/
1014*05b00f60SXin Li /* Returns nothing.          */
1015*05b00f60SXin Li /*****************************/
1016*05b00f60SXin Li static void
print_attr_address(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code)1017*05b00f60SXin Li print_attr_address(netdissect_options *ndo,
1018*05b00f60SXin Li                    const u_char *data, u_int length, u_short attr_code)
1019*05b00f60SXin Li {
1020*05b00f60SXin Li    if (length != 4)
1021*05b00f60SXin Li    {
1022*05b00f60SXin Li        ND_PRINT("ERROR: length %u != 4", length);
1023*05b00f60SXin Li        return;
1024*05b00f60SXin Li    }
1025*05b00f60SXin Li 
1026*05b00f60SXin Li    switch(attr_code)
1027*05b00f60SXin Li    {
1028*05b00f60SXin Li       case FRM_IPADDR:
1029*05b00f60SXin Li       case LOG_IPHOST:
1030*05b00f60SXin Li            if (GET_BE_U_4(data) == 0xFFFFFFFF )
1031*05b00f60SXin Li               ND_PRINT("User Selected");
1032*05b00f60SXin Li            else
1033*05b00f60SXin Li               if (GET_BE_U_4(data) == 0xFFFFFFFE )
1034*05b00f60SXin Li                  ND_PRINT("NAS Select");
1035*05b00f60SXin Li               else
1036*05b00f60SXin Li                  ND_PRINT("%s",GET_IPADDR_STRING(data));
1037*05b00f60SXin Li       break;
1038*05b00f60SXin Li 
1039*05b00f60SXin Li       default:
1040*05b00f60SXin Li           ND_PRINT("%s", GET_IPADDR_STRING(data));
1041*05b00f60SXin Li       break;
1042*05b00f60SXin Li    }
1043*05b00f60SXin Li }
1044*05b00f60SXin Li 
1045*05b00f60SXin Li /*****************************/
1046*05b00f60SXin Li /* Print an attribute IPv6   */
1047*05b00f60SXin Li /* address value pointed by  */
1048*05b00f60SXin Li /* 'data' and 'length' size. */
1049*05b00f60SXin Li /*****************************/
1050*05b00f60SXin Li /* Returns nothing.          */
1051*05b00f60SXin Li /*****************************/
1052*05b00f60SXin Li static void
print_attr_address6(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1053*05b00f60SXin Li print_attr_address6(netdissect_options *ndo,
1054*05b00f60SXin Li                    const u_char *data, u_int length, u_short attr_code _U_)
1055*05b00f60SXin Li {
1056*05b00f60SXin Li    if (length != 16)
1057*05b00f60SXin Li    {
1058*05b00f60SXin Li        ND_PRINT("ERROR: length %u != 16", length);
1059*05b00f60SXin Li        return;
1060*05b00f60SXin Li    }
1061*05b00f60SXin Li 
1062*05b00f60SXin Li    ND_PRINT("%s", GET_IP6ADDR_STRING(data));
1063*05b00f60SXin Li }
1064*05b00f60SXin Li 
1065*05b00f60SXin Li static void
print_attr_netmask6(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1066*05b00f60SXin Li print_attr_netmask6(netdissect_options *ndo,
1067*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1068*05b00f60SXin Li {
1069*05b00f60SXin Li    u_char data2[16];
1070*05b00f60SXin Li 
1071*05b00f60SXin Li    if (length < 2 || length > 18)
1072*05b00f60SXin Li    {
1073*05b00f60SXin Li        ND_PRINT("ERROR: length %u not in range (2..18)", length);
1074*05b00f60SXin Li        return;
1075*05b00f60SXin Li    }
1076*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1077*05b00f60SXin Li    if (GET_U_1(data + 1) > 128)
1078*05b00f60SXin Li    {
1079*05b00f60SXin Li       ND_PRINT("ERROR: netmask %u not in range (0..128)", GET_U_1(data + 1));
1080*05b00f60SXin Li       return;
1081*05b00f60SXin Li    }
1082*05b00f60SXin Li 
1083*05b00f60SXin Li    memset(data2, 0, sizeof(data2));
1084*05b00f60SXin Li    if (length > 2)
1085*05b00f60SXin Li       memcpy(data2, data+2, length-2);
1086*05b00f60SXin Li 
1087*05b00f60SXin Li    ND_PRINT("%s/%u", ip6addr_string(ndo, data2), GET_U_1(data + 1)); /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */
1088*05b00f60SXin Li 
1089*05b00f60SXin Li    if (GET_U_1(data + 1) > 8 * (length - 2))
1090*05b00f60SXin Li       ND_PRINT(" (inconsistent prefix length)");
1091*05b00f60SXin Li 
1092*05b00f60SXin Li    return;
1093*05b00f60SXin Li 
1094*05b00f60SXin Li    trunc:
1095*05b00f60SXin Li      nd_print_trunc(ndo);
1096*05b00f60SXin Li }
1097*05b00f60SXin Li 
1098*05b00f60SXin Li static void
print_attr_mip6_home_link_prefix(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1099*05b00f60SXin Li print_attr_mip6_home_link_prefix(netdissect_options *ndo,
1100*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1101*05b00f60SXin Li {
1102*05b00f60SXin Li    if (length != 17)
1103*05b00f60SXin Li    {
1104*05b00f60SXin Li       ND_PRINT("ERROR: length %u != 17", length);
1105*05b00f60SXin Li       return;
1106*05b00f60SXin Li    }
1107*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1108*05b00f60SXin Li    if (GET_U_1(data) > 128)
1109*05b00f60SXin Li    {
1110*05b00f60SXin Li       ND_PRINT("ERROR: netmask %u not in range (0..128)", GET_U_1(data));
1111*05b00f60SXin Li       return;
1112*05b00f60SXin Li    }
1113*05b00f60SXin Li 
1114*05b00f60SXin Li    ND_PRINT("%s/%u", GET_IP6ADDR_STRING(data + 1), GET_U_1(data));
1115*05b00f60SXin Li 
1116*05b00f60SXin Li    return;
1117*05b00f60SXin Li 
1118*05b00f60SXin Li    trunc:
1119*05b00f60SXin Li      nd_print_trunc(ndo);
1120*05b00f60SXin Li }
1121*05b00f60SXin Li 
1122*05b00f60SXin Li static void
print_attr_operator_name(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1123*05b00f60SXin Li print_attr_operator_name(netdissect_options *ndo,
1124*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1125*05b00f60SXin Li {
1126*05b00f60SXin Li    u_int namespace_value;
1127*05b00f60SXin Li 
1128*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1129*05b00f60SXin Li    if (length < 2)
1130*05b00f60SXin Li    {
1131*05b00f60SXin Li       ND_PRINT("ERROR: length %u < 2", length);
1132*05b00f60SXin Li       return;
1133*05b00f60SXin Li    }
1134*05b00f60SXin Li    namespace_value = GET_U_1(data);
1135*05b00f60SXin Li    data++;
1136*05b00f60SXin Li    ND_PRINT("[%s] ", tok2str(operator_name_vector, "unknown namespace %u", namespace_value));
1137*05b00f60SXin Li 
1138*05b00f60SXin Li    (void)nd_printn(ndo, data, length - 1, NULL);
1139*05b00f60SXin Li 
1140*05b00f60SXin Li    return;
1141*05b00f60SXin Li 
1142*05b00f60SXin Li    trunc:
1143*05b00f60SXin Li       nd_print_trunc(ndo);
1144*05b00f60SXin Li }
1145*05b00f60SXin Li 
1146*05b00f60SXin Li static void
print_attr_location_information(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1147*05b00f60SXin Li print_attr_location_information(netdissect_options *ndo,
1148*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1149*05b00f60SXin Li {
1150*05b00f60SXin Li    uint16_t index;
1151*05b00f60SXin Li    uint8_t code, entity;
1152*05b00f60SXin Li 
1153*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1154*05b00f60SXin Li    if (length < 21)
1155*05b00f60SXin Li    {
1156*05b00f60SXin Li      ND_PRINT("ERROR: length %u < 21", length);
1157*05b00f60SXin Li       return;
1158*05b00f60SXin Li    }
1159*05b00f60SXin Li 
1160*05b00f60SXin Li    index = GET_BE_U_2(data);
1161*05b00f60SXin Li    data += 2;
1162*05b00f60SXin Li 
1163*05b00f60SXin Li    code = GET_U_1(data);
1164*05b00f60SXin Li    data++;
1165*05b00f60SXin Li 
1166*05b00f60SXin Li    entity = GET_U_1(data);
1167*05b00f60SXin Li    data++;
1168*05b00f60SXin Li 
1169*05b00f60SXin Li    ND_PRINT("index %u, code %s, entity %s, ",
1170*05b00f60SXin Li        index,
1171*05b00f60SXin Li        tok2str(location_information_code_vector, "Unknown (%u)", code),
1172*05b00f60SXin Li        tok2str(location_information_entity_vector, "Unknown (%u)", entity)
1173*05b00f60SXin Li    );
1174*05b00f60SXin Li 
1175*05b00f60SXin Li    ND_PRINT("sighting time ");
1176*05b00f60SXin Li    p_ntp_time(ndo, (const struct l_fixedpt *)data);
1177*05b00f60SXin Li    ND_PRINT(", ");
1178*05b00f60SXin Li    data += 8;
1179*05b00f60SXin Li 
1180*05b00f60SXin Li    ND_PRINT("time to live ");
1181*05b00f60SXin Li    p_ntp_time(ndo, (const struct l_fixedpt *)data);
1182*05b00f60SXin Li    ND_PRINT(", ");
1183*05b00f60SXin Li    data += 8;
1184*05b00f60SXin Li 
1185*05b00f60SXin Li    ND_PRINT("method \"");
1186*05b00f60SXin Li    (void)nd_printn(ndo, data, length - 20, NULL);
1187*05b00f60SXin Li    ND_PRINT("\"");
1188*05b00f60SXin Li 
1189*05b00f60SXin Li    return;
1190*05b00f60SXin Li 
1191*05b00f60SXin Li    trunc:
1192*05b00f60SXin Li       nd_print_trunc(ndo);
1193*05b00f60SXin Li }
1194*05b00f60SXin Li 
1195*05b00f60SXin Li static void
print_attr_location_data(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1196*05b00f60SXin Li print_attr_location_data(netdissect_options *ndo,
1197*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1198*05b00f60SXin Li {
1199*05b00f60SXin Li    uint16_t index;
1200*05b00f60SXin Li 
1201*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1202*05b00f60SXin Li    if (length < 3)
1203*05b00f60SXin Li    {
1204*05b00f60SXin Li      ND_PRINT("ERROR: length %u < 3", length);
1205*05b00f60SXin Li       return;
1206*05b00f60SXin Li    }
1207*05b00f60SXin Li 
1208*05b00f60SXin Li    index = GET_BE_U_2(data);
1209*05b00f60SXin Li    data += 2;
1210*05b00f60SXin Li    ND_PRINT("index %u, location", index);
1211*05b00f60SXin Li 
1212*05b00f60SXin Li    /* The Location field of the String field of the Location-Data attribute
1213*05b00f60SXin Li     * can have two completely different structures depending on the value of
1214*05b00f60SXin Li     * the Code field of a Location-Info attribute, which supposedly precedes
1215*05b00f60SXin Li     * the current attribute. Unfortunately, this choice of encoding makes it
1216*05b00f60SXin Li     * non-trivial to decode the Location field without preserving some state
1217*05b00f60SXin Li     * between the attributes.
1218*05b00f60SXin Li     */
1219*05b00f60SXin Li    hex_and_ascii_print(ndo, "\n\t    ", data, length - 2);
1220*05b00f60SXin Li 
1221*05b00f60SXin Li    return;
1222*05b00f60SXin Li 
1223*05b00f60SXin Li    trunc:
1224*05b00f60SXin Li       nd_print_trunc(ndo);
1225*05b00f60SXin Li }
1226*05b00f60SXin Li 
1227*05b00f60SXin Li static void
print_basic_location_policy_rules(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1228*05b00f60SXin Li print_basic_location_policy_rules(netdissect_options *ndo,
1229*05b00f60SXin Li                     const u_char *data, u_int length, u_short attr_code _U_)
1230*05b00f60SXin Li {
1231*05b00f60SXin Li    uint16_t flags;
1232*05b00f60SXin Li 
1233*05b00f60SXin Li    ND_TCHECK_LEN(data, length);
1234*05b00f60SXin Li    if (length < 10)
1235*05b00f60SXin Li    {
1236*05b00f60SXin Li      ND_PRINT("ERROR: length %u < 10", length);
1237*05b00f60SXin Li       return;
1238*05b00f60SXin Li    }
1239*05b00f60SXin Li 
1240*05b00f60SXin Li    flags = GET_BE_U_2(data);
1241*05b00f60SXin Li    data += 2;
1242*05b00f60SXin Li    ND_PRINT("flags [%s], ", bittok2str(blpr_bm, "none", flags));
1243*05b00f60SXin Li 
1244*05b00f60SXin Li    ND_PRINT("retention expires ");
1245*05b00f60SXin Li    p_ntp_time(ndo, (const struct l_fixedpt *)data);
1246*05b00f60SXin Li    data += 8;
1247*05b00f60SXin Li 
1248*05b00f60SXin Li    if (length > 10) {
1249*05b00f60SXin Li       ND_PRINT(", note well \"");
1250*05b00f60SXin Li       (void)nd_printn(ndo, data, length - 10, NULL);
1251*05b00f60SXin Li       ND_PRINT("\"");
1252*05b00f60SXin Li    }
1253*05b00f60SXin Li 
1254*05b00f60SXin Li    return;
1255*05b00f60SXin Li 
1256*05b00f60SXin Li    trunc:
1257*05b00f60SXin Li       nd_print_trunc(ndo);
1258*05b00f60SXin Li }
1259*05b00f60SXin Li 
1260*05b00f60SXin Li 
1261*05b00f60SXin Li /*************************************/
1262*05b00f60SXin Li /* Print an attribute of 'secs since */
1263*05b00f60SXin Li /* January 1, 1970 00:00 UTC' value  */
1264*05b00f60SXin Li /* pointed by 'data' and 'length'    */
1265*05b00f60SXin Li /* size.                             */
1266*05b00f60SXin Li /*************************************/
1267*05b00f60SXin Li /* Returns nothing.                  */
1268*05b00f60SXin Li /*************************************/
1269*05b00f60SXin Li static void
print_attr_time(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code _U_)1270*05b00f60SXin Li print_attr_time(netdissect_options *ndo,
1271*05b00f60SXin Li                 const u_char *data, u_int length, u_short attr_code _U_)
1272*05b00f60SXin Li {
1273*05b00f60SXin Li    time_t attr_time;
1274*05b00f60SXin Li    char string[26];
1275*05b00f60SXin Li 
1276*05b00f60SXin Li    if (length != 4)
1277*05b00f60SXin Li    {
1278*05b00f60SXin Li        ND_PRINT("ERROR: length %u != 4", length);
1279*05b00f60SXin Li        return;
1280*05b00f60SXin Li    }
1281*05b00f60SXin Li 
1282*05b00f60SXin Li    attr_time = GET_BE_U_4(data);
1283*05b00f60SXin Li    strlcpy(string, ctime(&attr_time), sizeof(string));
1284*05b00f60SXin Li    /* Get rid of the newline */
1285*05b00f60SXin Li    string[24] = '\0';
1286*05b00f60SXin Li    ND_PRINT("%.24s", string);
1287*05b00f60SXin Li }
1288*05b00f60SXin Li 
1289*05b00f60SXin Li static void
print_attr_vector64(netdissect_options * ndo,register const u_char * data,u_int length,u_short attr_code _U_)1290*05b00f60SXin Li print_attr_vector64(netdissect_options *ndo,
1291*05b00f60SXin Li                  register const u_char *data, u_int length, u_short attr_code _U_)
1292*05b00f60SXin Li {
1293*05b00f60SXin Li    uint64_t data_value, i;
1294*05b00f60SXin Li    const char *sep = "";
1295*05b00f60SXin Li 
1296*05b00f60SXin Li    if (length != 8)
1297*05b00f60SXin Li    {
1298*05b00f60SXin Li        ND_PRINT("ERROR: length %u != 8", length);
1299*05b00f60SXin Li        return;
1300*05b00f60SXin Li    }
1301*05b00f60SXin Li 
1302*05b00f60SXin Li    ND_PRINT("[");
1303*05b00f60SXin Li 
1304*05b00f60SXin Li    data_value = GET_BE_U_8(data);
1305*05b00f60SXin Li    /* Print the 64-bit field in a format similar to bittok2str(), less
1306*05b00f60SXin Li     * flagging any unknown bits. This way it should be easier to replace
1307*05b00f60SXin Li     * the custom code with a library function later.
1308*05b00f60SXin Li     */
1309*05b00f60SXin Li    for (i = 0; i < TAM_SIZE(mip6_feature_vector); i++) {
1310*05b00f60SXin Li        if (data_value & mip6_feature_vector[i].v) {
1311*05b00f60SXin Li            ND_PRINT("%s%s", sep, mip6_feature_vector[i].s);
1312*05b00f60SXin Li            sep = ", ";
1313*05b00f60SXin Li        }
1314*05b00f60SXin Li    }
1315*05b00f60SXin Li 
1316*05b00f60SXin Li    ND_PRINT("]");
1317*05b00f60SXin Li }
1318*05b00f60SXin Li 
1319*05b00f60SXin Li /***********************************/
1320*05b00f60SXin Li /* Print an attribute of 'strange' */
1321*05b00f60SXin Li /* data format pointed by 'data'   */
1322*05b00f60SXin Li /* and 'length' size.              */
1323*05b00f60SXin Li /***********************************/
1324*05b00f60SXin Li /* Returns nothing.                */
1325*05b00f60SXin Li /***********************************/
1326*05b00f60SXin Li static void
print_attr_strange(netdissect_options * ndo,const u_char * data,u_int length,u_short attr_code)1327*05b00f60SXin Li print_attr_strange(netdissect_options *ndo,
1328*05b00f60SXin Li                    const u_char *data, u_int length, u_short attr_code)
1329*05b00f60SXin Li {
1330*05b00f60SXin Li    u_short len_data;
1331*05b00f60SXin Li    u_int error_cause_value;
1332*05b00f60SXin Li 
1333*05b00f60SXin Li    switch(attr_code)
1334*05b00f60SXin Li    {
1335*05b00f60SXin Li       case ARAP_PASS:
1336*05b00f60SXin Li            if (length != 16)
1337*05b00f60SXin Li            {
1338*05b00f60SXin Li                ND_PRINT("ERROR: length %u != 16", length);
1339*05b00f60SXin Li                return;
1340*05b00f60SXin Li            }
1341*05b00f60SXin Li            ND_PRINT("User_challenge (");
1342*05b00f60SXin Li            len_data = 8;
1343*05b00f60SXin Li            PRINT_HEX(len_data, data);
1344*05b00f60SXin Li            ND_PRINT(") User_resp(");
1345*05b00f60SXin Li            len_data = 8;
1346*05b00f60SXin Li            PRINT_HEX(len_data, data);
1347*05b00f60SXin Li            ND_PRINT(")");
1348*05b00f60SXin Li         break;
1349*05b00f60SXin Li 
1350*05b00f60SXin Li       case ARAP_FEATURES:
1351*05b00f60SXin Li            if (length != 14)
1352*05b00f60SXin Li            {
1353*05b00f60SXin Li                ND_PRINT("ERROR: length %u != 14", length);
1354*05b00f60SXin Li                return;
1355*05b00f60SXin Li            }
1356*05b00f60SXin Li            if (GET_U_1(data))
1357*05b00f60SXin Li               ND_PRINT("User can change password");
1358*05b00f60SXin Li            else
1359*05b00f60SXin Li               ND_PRINT("User cannot change password");
1360*05b00f60SXin Li            data++;
1361*05b00f60SXin Li            ND_PRINT(", Min password length: %u", GET_U_1(data));
1362*05b00f60SXin Li            data++;
1363*05b00f60SXin Li            ND_PRINT(", created at: ");
1364*05b00f60SXin Li            len_data = 4;
1365*05b00f60SXin Li            PRINT_HEX(len_data, data);
1366*05b00f60SXin Li            ND_PRINT(", expires in: ");
1367*05b00f60SXin Li            len_data = 4;
1368*05b00f60SXin Li            PRINT_HEX(len_data, data);
1369*05b00f60SXin Li            ND_PRINT(", Current Time: ");
1370*05b00f60SXin Li            len_data = 4;
1371*05b00f60SXin Li            PRINT_HEX(len_data, data);
1372*05b00f60SXin Li         break;
1373*05b00f60SXin Li 
1374*05b00f60SXin Li       case ARAP_CHALLENGE_RESP:
1375*05b00f60SXin Li            if (length < 8)
1376*05b00f60SXin Li            {
1377*05b00f60SXin Li                ND_PRINT("ERROR: length %u != 8", length);
1378*05b00f60SXin Li                return;
1379*05b00f60SXin Li            }
1380*05b00f60SXin Li            len_data = 8;
1381*05b00f60SXin Li            PRINT_HEX(len_data, data);
1382*05b00f60SXin Li         break;
1383*05b00f60SXin Li 
1384*05b00f60SXin Li       case ERROR_CAUSE:
1385*05b00f60SXin Li            if (length != 4)
1386*05b00f60SXin Li            {
1387*05b00f60SXin Li                ND_PRINT("Error: length %u != 4", length);
1388*05b00f60SXin Li                return;
1389*05b00f60SXin Li            }
1390*05b00f60SXin Li 
1391*05b00f60SXin Li            error_cause_value = GET_BE_U_4(data);
1392*05b00f60SXin Li            ND_PRINT("Error cause %u: %s", error_cause_value, tok2str(errorcausetype, "Error-Cause %u not known", error_cause_value));
1393*05b00f60SXin Li         break;
1394*05b00f60SXin Li    }
1395*05b00f60SXin Li    return;
1396*05b00f60SXin Li }
1397*05b00f60SXin Li 
1398*05b00f60SXin Li static void
radius_attrs_print(netdissect_options * ndo,const u_char * attr,u_int length)1399*05b00f60SXin Li radius_attrs_print(netdissect_options *ndo,
1400*05b00f60SXin Li                    const u_char *attr, u_int length)
1401*05b00f60SXin Li {
1402*05b00f60SXin Li    const struct radius_attr *rad_attr = (const struct radius_attr *)attr;
1403*05b00f60SXin Li    const char *attr_string;
1404*05b00f60SXin Li    uint8_t type, len;
1405*05b00f60SXin Li 
1406*05b00f60SXin Li    while (length > 0)
1407*05b00f60SXin Li    {
1408*05b00f60SXin Li      if (length < 2)
1409*05b00f60SXin Li         goto trunc;
1410*05b00f60SXin Li      ND_TCHECK_SIZE(rad_attr);
1411*05b00f60SXin Li 
1412*05b00f60SXin Li      type = GET_U_1(rad_attr->type);
1413*05b00f60SXin Li      len = GET_U_1(rad_attr->len);
1414*05b00f60SXin Li      if (type != 0 && type < TAM_SIZE(attr_type))
1415*05b00f60SXin Li 	attr_string = attr_type[type].name;
1416*05b00f60SXin Li      else
1417*05b00f60SXin Li 	attr_string = "Unknown";
1418*05b00f60SXin Li 
1419*05b00f60SXin Li      ND_PRINT("\n\t  %s Attribute (%u), length: %u",
1420*05b00f60SXin Li                attr_string,
1421*05b00f60SXin Li                type,
1422*05b00f60SXin Li                len);
1423*05b00f60SXin Li      if (len < 2)
1424*05b00f60SXin Li      {
1425*05b00f60SXin Li        ND_PRINT(" (bogus, must be >= 2)");
1426*05b00f60SXin Li        return;
1427*05b00f60SXin Li      }
1428*05b00f60SXin Li      if (len > length)
1429*05b00f60SXin Li      {
1430*05b00f60SXin Li         ND_PRINT(" (bogus, goes past end of packet)");
1431*05b00f60SXin Li         return;
1432*05b00f60SXin Li      }
1433*05b00f60SXin Li      ND_PRINT(", Value: ");
1434*05b00f60SXin Li 
1435*05b00f60SXin Li      if (type < TAM_SIZE(attr_type))
1436*05b00f60SXin Li      {
1437*05b00f60SXin Li          if (len > 2)
1438*05b00f60SXin Li          {
1439*05b00f60SXin Li              if ( attr_type[type].print_func )
1440*05b00f60SXin Li                  (*attr_type[type].print_func)(
1441*05b00f60SXin Li                      ndo, ((const u_char *)(rad_attr+1)),
1442*05b00f60SXin Li                      len - 2, type);
1443*05b00f60SXin Li          }
1444*05b00f60SXin Li      }
1445*05b00f60SXin Li      /* do we also want to see a hex dump ? */
1446*05b00f60SXin Li      if (ndo->ndo_vflag> 1)
1447*05b00f60SXin Li          print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t    ", (len)-2);
1448*05b00f60SXin Li 
1449*05b00f60SXin Li      length-=(len);
1450*05b00f60SXin Li      rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+len);
1451*05b00f60SXin Li    }
1452*05b00f60SXin Li    return;
1453*05b00f60SXin Li 
1454*05b00f60SXin Li trunc:
1455*05b00f60SXin Li    nd_print_trunc(ndo);
1456*05b00f60SXin Li }
1457*05b00f60SXin Li 
1458*05b00f60SXin Li void
radius_print(netdissect_options * ndo,const u_char * dat,u_int length)1459*05b00f60SXin Li radius_print(netdissect_options *ndo,
1460*05b00f60SXin Li              const u_char *dat, u_int length)
1461*05b00f60SXin Li {
1462*05b00f60SXin Li    const struct radius_hdr *rad;
1463*05b00f60SXin Li    u_int len, auth_idx;
1464*05b00f60SXin Li 
1465*05b00f60SXin Li    ndo->ndo_protocol = "radius";
1466*05b00f60SXin Li    ND_TCHECK_LEN(dat, MIN_RADIUS_LEN);
1467*05b00f60SXin Li    rad = (const struct radius_hdr *)dat;
1468*05b00f60SXin Li    len = GET_BE_U_2(rad->len);
1469*05b00f60SXin Li 
1470*05b00f60SXin Li    if (len < MIN_RADIUS_LEN)
1471*05b00f60SXin Li    {
1472*05b00f60SXin Li 	  nd_print_trunc(ndo);
1473*05b00f60SXin Li 	  return;
1474*05b00f60SXin Li    }
1475*05b00f60SXin Li 
1476*05b00f60SXin Li    if (len > length)
1477*05b00f60SXin Li 	  len = length;
1478*05b00f60SXin Li 
1479*05b00f60SXin Li    if (ndo->ndo_vflag < 1) {
1480*05b00f60SXin Li        ND_PRINT("RADIUS, %s (%u), id: 0x%02x length: %u",
1481*05b00f60SXin Li               tok2str(radius_command_values,"Unknown Command",GET_U_1(rad->code)),
1482*05b00f60SXin Li               GET_U_1(rad->code),
1483*05b00f60SXin Li               GET_U_1(rad->id),
1484*05b00f60SXin Li               len);
1485*05b00f60SXin Li        return;
1486*05b00f60SXin Li    }
1487*05b00f60SXin Li    else {
1488*05b00f60SXin Li        ND_PRINT("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
1489*05b00f60SXin Li               len,
1490*05b00f60SXin Li               tok2str(radius_command_values,"Unknown Command",GET_U_1(rad->code)),
1491*05b00f60SXin Li               GET_U_1(rad->code),
1492*05b00f60SXin Li               GET_U_1(rad->id));
1493*05b00f60SXin Li 
1494*05b00f60SXin Li        for(auth_idx=0; auth_idx < 16; auth_idx++)
1495*05b00f60SXin Li             ND_PRINT("%02x", rad->auth[auth_idx]);
1496*05b00f60SXin Li    }
1497*05b00f60SXin Li 
1498*05b00f60SXin Li    if (len > MIN_RADIUS_LEN)
1499*05b00f60SXin Li       radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN);
1500*05b00f60SXin Li    return;
1501*05b00f60SXin Li 
1502*05b00f60SXin Li trunc:
1503*05b00f60SXin Li    nd_print_trunc(ndo);
1504*05b00f60SXin Li }
1505