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