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