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