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