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