print-radius.c revision 1.7
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 * Radius printer routines as specified on: 24 * 25 * RFC 2865: 26 * "Remote Authentication Dial In User Service (RADIUS)" 27 * 28 * RFC 2866: 29 * "RADIUS Accounting" 30 * 31 * RFC 2867: 32 * "RADIUS Accounting Modifications for Tunnel Protocol Support" 33 * 34 * RFC 2868: 35 * "RADIUS Attributes for Tunnel Protocol Support" 36 * 37 * RFC 2869: 38 * "RADIUS Extensions" 39 * 40 * RFC 3580: 41 * "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)" 42 * "Usage Guidelines" 43 * 44 * RFC 4675: 45 * "RADIUS Attributes for Virtual LAN and Priority Support" 46 * 47 * RFC 5176: 48 * "Dynamic Authorization Extensions to RADIUS" 49 * 50 * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15 51 * 52 * TODO: Among other things to print ok MacIntosh and Vendor values 53 */ 54 55#include <sys/cdefs.h> 56#ifndef lint 57__RCSID("$NetBSD: print-radius.c,v 1.7 2017/01/24 23:29:14 christos Exp $"); 58#endif 59 60#ifdef HAVE_CONFIG_H 61#include "config.h" 62#endif 63 64#include <netdissect-stdinc.h> 65 66#include <string.h> 67 68#include "netdissect.h" 69#include "addrtoname.h" 70#include "extract.h" 71#include "oui.h" 72 73static const char tstr[] = " [|radius]"; 74 75#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) ) 76 77#define PRINT_HEX(bytes_len, ptr_data) \ 78 while(bytes_len) \ 79 { \ 80 ND_PRINT((ndo, "%02X", *ptr_data )); \ 81 ptr_data++; \ 82 bytes_len--; \ 83 } 84 85 86/* Radius packet codes */ 87#define RADCMD_ACCESS_REQ 1 /* Access-Request */ 88#define RADCMD_ACCESS_ACC 2 /* Access-Accept */ 89#define RADCMD_ACCESS_REJ 3 /* Access-Reject */ 90#define RADCMD_ACCOUN_REQ 4 /* Accounting-Request */ 91#define RADCMD_ACCOUN_RES 5 /* Accounting-Response */ 92#define RADCMD_ACCESS_CHA 11 /* Access-Challenge */ 93#define RADCMD_STATUS_SER 12 /* Status-Server */ 94#define RADCMD_STATUS_CLI 13 /* Status-Client */ 95#define RADCMD_DISCON_REQ 40 /* Disconnect-Request */ 96#define RADCMD_DISCON_ACK 41 /* Disconnect-ACK */ 97#define RADCMD_DISCON_NAK 42 /* Disconnect-NAK */ 98#define RADCMD_COA_REQ 43 /* CoA-Request */ 99#define RADCMD_COA_ACK 44 /* CoA-ACK */ 100#define RADCMD_COA_NAK 45 /* CoA-NAK */ 101#define RADCMD_RESERVED 255 /* Reserved */ 102 103static const struct tok radius_command_values[] = { 104 { RADCMD_ACCESS_REQ, "Access-Request" }, 105 { RADCMD_ACCESS_ACC, "Access-Accept" }, 106 { RADCMD_ACCESS_REJ, "Access-Reject" }, 107 { RADCMD_ACCOUN_REQ, "Accounting-Request" }, 108 { RADCMD_ACCOUN_RES, "Accounting-Response" }, 109 { RADCMD_ACCESS_CHA, "Access-Challenge" }, 110 { RADCMD_STATUS_SER, "Status-Server" }, 111 { RADCMD_STATUS_CLI, "Status-Client" }, 112 { RADCMD_DISCON_REQ, "Disconnect-Request" }, 113 { RADCMD_DISCON_ACK, "Disconnect-ACK" }, 114 { RADCMD_DISCON_NAK, "Disconnect-NAK" }, 115 { RADCMD_COA_REQ, "CoA-Request" }, 116 { RADCMD_COA_ACK, "CoA-ACK" }, 117 { RADCMD_COA_NAK, "CoA-NAK" }, 118 { RADCMD_RESERVED, "Reserved" }, 119 { 0, NULL} 120}; 121 122/********************************/ 123/* Begin Radius Attribute types */ 124/********************************/ 125#define SERV_TYPE 6 126#define FRM_IPADDR 8 127#define LOG_IPHOST 14 128#define LOG_SERVICE 15 129#define FRM_IPX 23 130#define SESSION_TIMEOUT 27 131#define IDLE_TIMEOUT 28 132#define FRM_ATALK_LINK 37 133#define FRM_ATALK_NETWORK 38 134 135#define ACCT_DELAY 41 136#define ACCT_SESSION_TIME 46 137 138#define EGRESS_VLAN_ID 56 139#define EGRESS_VLAN_NAME 58 140 141#define TUNNEL_TYPE 64 142#define TUNNEL_MEDIUM 65 143#define TUNNEL_CLIENT_END 66 144#define TUNNEL_SERVER_END 67 145#define TUNNEL_PASS 69 146 147#define ARAP_PASS 70 148#define ARAP_FEATURES 71 149 150#define TUNNEL_PRIV_GROUP 81 151#define TUNNEL_ASSIGN_ID 82 152#define TUNNEL_PREFERENCE 83 153 154#define ARAP_CHALLENGE_RESP 84 155#define ACCT_INT_INTERVAL 85 156 157#define TUNNEL_CLIENT_AUTH 90 158#define TUNNEL_SERVER_AUTH 91 159/********************************/ 160/* End Radius Attribute types */ 161/********************************/ 162 163#define RFC4675_TAGGED 0x31 164#define RFC4675_UNTAGGED 0x32 165 166static const struct tok rfc4675_tagged[] = { 167 { RFC4675_TAGGED, "Tagged" }, 168 { RFC4675_UNTAGGED, "Untagged" }, 169 { 0, NULL} 170}; 171 172 173static void print_attr_string(netdissect_options *, register const u_char *, u_int, u_short ); 174static void print_attr_num(netdissect_options *, register const u_char *, u_int, u_short ); 175static void print_vendor_attr(netdissect_options *, register const u_char *, u_int, u_short ); 176static void print_attr_address(netdissect_options *, register const u_char *, u_int, u_short); 177static void print_attr_time(netdissect_options *, register const u_char *, u_int, u_short); 178static void print_attr_strange(netdissect_options *, register const u_char *, u_int, u_short); 179 180 181struct radius_hdr { uint8_t code; /* Radius packet code */ 182 uint8_t id; /* Radius packet id */ 183 uint16_t len; /* Radius total length */ 184 uint8_t auth[16]; /* Authenticator */ 185 }; 186 187#define MIN_RADIUS_LEN 20 188 189struct radius_attr { uint8_t type; /* Attribute type */ 190 uint8_t len; /* Attribute length */ 191 }; 192 193 194/* Service-Type Attribute standard values */ 195static const char *serv_type[]={ NULL, 196 "Login", 197 "Framed", 198 "Callback Login", 199 "Callback Framed", 200 "Outbound", 201 "Administrative", 202 "NAS Prompt", 203 "Authenticate Only", 204 "Callback NAS Prompt", 205 "Call Check", 206 "Callback Administrative", 207 }; 208 209/* Framed-Protocol Attribute standard values */ 210static const char *frm_proto[]={ NULL, 211 "PPP", 212 "SLIP", 213 "ARAP", 214 "Gandalf proprietary", 215 "Xylogics IPX/SLIP", 216 "X.75 Synchronous", 217 }; 218 219/* Framed-Routing Attribute standard values */ 220static const char *frm_routing[]={ "None", 221 "Send", 222 "Listen", 223 "Send&Listen", 224 }; 225 226/* Framed-Compression Attribute standard values */ 227static const char *frm_comp[]={ "None", 228 "VJ TCP/IP", 229 "IPX", 230 "Stac-LZS", 231 }; 232 233/* Login-Service Attribute standard values */ 234static const char *login_serv[]={ "Telnet", 235 "Rlogin", 236 "TCP Clear", 237 "PortMaster(proprietary)", 238 "LAT", 239 "X.25-PAD", 240 "X.25-T3POS", 241 "Unassigned", 242 "TCP Clear Quiet", 243 }; 244 245 246/* Termination-Action Attribute standard values */ 247static const char *term_action[]={ "Default", 248 "RADIUS-Request", 249 }; 250 251/* Ingress-Filters Attribute standard values */ 252static const char *ingress_filters[]={ NULL, 253 "Enabled", 254 "Disabled", 255 }; 256 257/* NAS-Port-Type Attribute standard values */ 258static const char *nas_port_type[]={ "Async", 259 "Sync", 260 "ISDN Sync", 261 "ISDN Async V.120", 262 "ISDN Async V.110", 263 "Virtual", 264 "PIAFS", 265 "HDLC Clear Channel", 266 "X.25", 267 "X.75", 268 "G.3 Fax", 269 "SDSL", 270 "ADSL-CAP", 271 "ADSL-DMT", 272 "ISDN-DSL", 273 "Ethernet", 274 "xDSL", 275 "Cable", 276 "Wireless - Other", 277 "Wireless - IEEE 802.11", 278 }; 279 280/* Acct-Status-Type Accounting Attribute standard values */ 281static const char *acct_status[]={ NULL, 282 "Start", 283 "Stop", 284 "Interim-Update", 285 "Unassigned", 286 "Unassigned", 287 "Unassigned", 288 "Accounting-On", 289 "Accounting-Off", 290 "Tunnel-Start", 291 "Tunnel-Stop", 292 "Tunnel-Reject", 293 "Tunnel-Link-Start", 294 "Tunnel-Link-Stop", 295 "Tunnel-Link-Reject", 296 "Failed", 297 }; 298 299/* Acct-Authentic Accounting Attribute standard values */ 300static const char *acct_auth[]={ NULL, 301 "RADIUS", 302 "Local", 303 "Remote", 304 }; 305 306/* Acct-Terminate-Cause Accounting Attribute standard values */ 307static const char *acct_term[]={ NULL, 308 "User Request", 309 "Lost Carrier", 310 "Lost Service", 311 "Idle Timeout", 312 "Session Timeout", 313 "Admin Reset", 314 "Admin Reboot", 315 "Port Error", 316 "NAS Error", 317 "NAS Request", 318 "NAS Reboot", 319 "Port Unneeded", 320 "Port Preempted", 321 "Port Suspended", 322 "Service Unavailable", 323 "Callback", 324 "User Error", 325 "Host Request", 326 }; 327 328/* Tunnel-Type Attribute standard values */ 329static const char *tunnel_type[]={ NULL, 330 "PPTP", 331 "L2F", 332 "L2TP", 333 "ATMP", 334 "VTP", 335 "AH", 336 "IP-IP", 337 "MIN-IP-IP", 338 "ESP", 339 "GRE", 340 "DVS", 341 "IP-in-IP Tunneling", 342 "VLAN", 343 }; 344 345/* Tunnel-Medium-Type Attribute standard values */ 346static const char *tunnel_medium[]={ NULL, 347 "IPv4", 348 "IPv6", 349 "NSAP", 350 "HDLC", 351 "BBN 1822", 352 "802", 353 "E.163", 354 "E.164", 355 "F.69", 356 "X.121", 357 "IPX", 358 "Appletalk", 359 "Decnet IV", 360 "Banyan Vines", 361 "E.164 with NSAP subaddress", 362 }; 363 364/* ARAP-Zone-Access Attribute standard values */ 365static const char *arap_zone[]={ NULL, 366 "Only access to dfl zone", 367 "Use zone filter inc.", 368 "Not used", 369 "Use zone filter exc.", 370 }; 371 372static const char *prompt[]={ "No Echo", 373 "Echo", 374 }; 375 376 377struct attrtype { const char *name; /* Attribute name */ 378 const char **subtypes; /* Standard Values (if any) */ 379 u_char siz_subtypes; /* Size of total standard values */ 380 u_char first_subtype; /* First standard value is 0 or 1 */ 381 void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short); 382 } attr_type[]= 383 { 384 { NULL, NULL, 0, 0, NULL }, 385 { "User-Name", NULL, 0, 0, print_attr_string }, 386 { "User-Password", NULL, 0, 0, NULL }, 387 { "CHAP-Password", NULL, 0, 0, NULL }, 388 { "NAS-IP-Address", NULL, 0, 0, print_attr_address }, 389 { "NAS-Port", NULL, 0, 0, print_attr_num }, 390 { "Service-Type", serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num }, 391 { "Framed-Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num }, 392 { "Framed-IP-Address", NULL, 0, 0, print_attr_address }, 393 { "Framed-IP-Netmask", NULL, 0, 0, print_attr_address }, 394 { "Framed-Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num }, 395 { "Filter-Id", NULL, 0, 0, print_attr_string }, 396 { "Framed-MTU", NULL, 0, 0, print_attr_num }, 397 { "Framed-Compression", frm_comp, TAM_SIZE(frm_comp), 0, print_attr_num }, 398 { "Login-IP-Host", NULL, 0, 0, print_attr_address }, 399 { "Login-Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num }, 400 { "Login-TCP-Port", NULL, 0, 0, print_attr_num }, 401 { "Unassigned", NULL, 0, 0, NULL }, /*17*/ 402 { "Reply-Message", NULL, 0, 0, print_attr_string }, 403 { "Callback-Number", NULL, 0, 0, print_attr_string }, 404 { "Callback-Id", NULL, 0, 0, print_attr_string }, 405 { "Unassigned", NULL, 0, 0, NULL }, /*21*/ 406 { "Framed-Route", NULL, 0, 0, print_attr_string }, 407 { "Framed-IPX-Network", NULL, 0, 0, print_attr_num }, 408 { "State", NULL, 0, 0, print_attr_string }, 409 { "Class", NULL, 0, 0, print_attr_string }, 410 { "Vendor-Specific", NULL, 0, 0, print_vendor_attr }, 411 { "Session-Timeout", NULL, 0, 0, print_attr_num }, 412 { "Idle-Timeout", NULL, 0, 0, print_attr_num }, 413 { "Termination-Action", term_action, TAM_SIZE(term_action), 0, print_attr_num }, 414 { "Called-Station-Id", NULL, 0, 0, print_attr_string }, 415 { "Calling-Station-Id", NULL, 0, 0, print_attr_string }, 416 { "NAS-Identifier", NULL, 0, 0, print_attr_string }, 417 { "Proxy-State", NULL, 0, 0, print_attr_string }, 418 { "Login-LAT-Service", NULL, 0, 0, print_attr_string }, 419 { "Login-LAT-Node", NULL, 0, 0, print_attr_string }, 420 { "Login-LAT-Group", NULL, 0, 0, print_attr_string }, 421 { "Framed-AppleTalk-Link", NULL, 0, 0, print_attr_num }, 422 { "Framed-AppleTalk-Network", NULL, 0, 0, print_attr_num }, 423 { "Framed-AppleTalk-Zone", NULL, 0, 0, print_attr_string }, 424 { "Acct-Status-Type", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num }, 425 { "Acct-Delay-Time", NULL, 0, 0, print_attr_num }, 426 { "Acct-Input-Octets", NULL, 0, 0, print_attr_num }, 427 { "Acct-Output-Octets", NULL, 0, 0, print_attr_num }, 428 { "Acct-Session-Id", NULL, 0, 0, print_attr_string }, 429 { "Acct-Authentic", acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num }, 430 { "Acct-Session-Time", NULL, 0, 0, print_attr_num }, 431 { "Acct-Input-Packets", NULL, 0, 0, print_attr_num }, 432 { "Acct-Output-Packets", NULL, 0, 0, print_attr_num }, 433 { "Acct-Terminate-Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num }, 434 { "Acct-Multi-Session-Id", NULL, 0, 0, print_attr_string }, 435 { "Acct-Link-Count", NULL, 0, 0, print_attr_num }, 436 { "Acct-Input-Gigawords", NULL, 0, 0, print_attr_num }, 437 { "Acct-Output-Gigawords", NULL, 0, 0, print_attr_num }, 438 { "Unassigned", NULL, 0, 0, NULL }, /*54*/ 439 { "Event-Timestamp", NULL, 0, 0, print_attr_time }, 440 { "Egress-VLANID", NULL, 0, 0, print_attr_num }, 441 { "Ingress-Filters", ingress_filters, TAM_SIZE(ingress_filters)-1, 1, print_attr_num }, 442 { "Egress-VLAN-Name", NULL, 0, 0, print_attr_string }, 443 { "User-Priority-Table", NULL, 0, 0, NULL }, 444 { "CHAP-Challenge", NULL, 0, 0, print_attr_string }, 445 { "NAS-Port-Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num }, 446 { "Port-Limit", NULL, 0, 0, print_attr_num }, 447 { "Login-LAT-Port", NULL, 0, 0, print_attr_string }, /*63*/ 448 { "Tunnel-Type", tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num }, 449 { "Tunnel-Medium-Type", tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num }, 450 { "Tunnel-Client-Endpoint", NULL, 0, 0, print_attr_string }, 451 { "Tunnel-Server-Endpoint", NULL, 0, 0, print_attr_string }, 452 { "Acct-Tunnel-Connection", NULL, 0, 0, print_attr_string }, 453 { "Tunnel-Password", NULL, 0, 0, print_attr_string }, 454 { "ARAP-Password", NULL, 0, 0, print_attr_strange }, 455 { "ARAP-Features", NULL, 0, 0, print_attr_strange }, 456 { "ARAP-Zone-Access", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/ 457 { "ARAP-Security", NULL, 0, 0, print_attr_string }, 458 { "ARAP-Security-Data", NULL, 0, 0, print_attr_string }, 459 { "Password-Retry", NULL, 0, 0, print_attr_num }, 460 { "Prompt", prompt, TAM_SIZE(prompt), 0, print_attr_num }, 461 { "Connect-Info", NULL, 0, 0, print_attr_string }, 462 { "Configuration-Token", NULL, 0, 0, print_attr_string }, 463 { "EAP-Message", NULL, 0, 0, print_attr_string }, 464 { "Message-Authenticator", NULL, 0, 0, print_attr_string }, /*80*/ 465 { "Tunnel-Private-Group-ID", NULL, 0, 0, print_attr_string }, 466 { "Tunnel-Assignment-ID", NULL, 0, 0, print_attr_string }, 467 { "Tunnel-Preference", NULL, 0, 0, print_attr_num }, 468 { "ARAP-Challenge-Response", NULL, 0, 0, print_attr_strange }, 469 { "Acct-Interim-Interval", NULL, 0, 0, print_attr_num }, 470 { "Acct-Tunnel-Packets-Lost", NULL, 0, 0, print_attr_num }, /*86*/ 471 { "NAS-Port-Id", NULL, 0, 0, print_attr_string }, 472 { "Framed-Pool", NULL, 0, 0, print_attr_string }, 473 { "CUI", NULL, 0, 0, print_attr_string }, 474 { "Tunnel-Client-Auth-ID", NULL, 0, 0, print_attr_string }, 475 { "Tunnel-Server-Auth-ID", NULL, 0, 0, print_attr_string }, 476 { "Unassigned", NULL, 0, 0, NULL }, /*92*/ 477 { "Unassigned", NULL, 0, 0, NULL } /*93*/ 478 }; 479 480 481/*****************************/ 482/* Print an attribute string */ 483/* value pointed by 'data' */ 484/* and 'length' size. */ 485/*****************************/ 486/* Returns nothing. */ 487/*****************************/ 488static void 489print_attr_string(netdissect_options *ndo, 490 register const u_char *data, u_int length, u_short attr_code) 491{ 492 register u_int i; 493 494 ND_TCHECK2(data[0],length); 495 496 switch(attr_code) 497 { 498 case TUNNEL_PASS: 499 if (length < 3) 500 { 501 ND_PRINT((ndo, "%s", tstr)); 502 return; 503 } 504 if (*data && (*data <=0x1F) ) 505 ND_PRINT((ndo, "Tag[%u] ", *data)); 506 else 507 ND_PRINT((ndo, "Tag[Unused] ")); 508 data++; 509 length--; 510 ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data))); 511 data+=2; 512 length-=2; 513 break; 514 case TUNNEL_CLIENT_END: 515 case TUNNEL_SERVER_END: 516 case TUNNEL_PRIV_GROUP: 517 case TUNNEL_ASSIGN_ID: 518 case TUNNEL_CLIENT_AUTH: 519 case TUNNEL_SERVER_AUTH: 520 if (*data <= 0x1F) 521 { 522 if (length < 1) 523 { 524 ND_PRINT((ndo, "%s", tstr)); 525 return; 526 } 527 if (*data) 528 ND_PRINT((ndo, "Tag[%u] ", *data)); 529 else 530 ND_PRINT((ndo, "Tag[Unused] ")); 531 data++; 532 length--; 533 } 534 break; 535 case EGRESS_VLAN_NAME: 536 ND_PRINT((ndo, "%s (0x%02x) ", 537 tok2str(rfc4675_tagged,"Unknown tag",*data), 538 *data)); 539 data++; 540 length--; 541 break; 542 } 543 544 for (i=0; *data && i < length ; i++, data++) 545 ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); 546 547 return; 548 549 trunc: 550 ND_PRINT((ndo, "%s", tstr)); 551} 552 553/* 554 * print vendor specific attributes 555 */ 556static void 557print_vendor_attr(netdissect_options *ndo, 558 register const u_char *data, u_int length, u_short attr_code _U_) 559{ 560 u_int idx; 561 u_int vendor_id; 562 u_int vendor_type; 563 u_int vendor_length; 564 565 if (length < 4) 566 goto trunc; 567 ND_TCHECK2(*data, 4); 568 vendor_id = EXTRACT_32BITS(data); 569 data+=4; 570 length-=4; 571 572 ND_PRINT((ndo, "Vendor: %s (%u)", 573 tok2str(smi_values,"Unknown",vendor_id), 574 vendor_id)); 575 576 while (length >= 2) { 577 ND_TCHECK2(*data, 2); 578 579 vendor_type = *(data); 580 vendor_length = *(data+1); 581 582 if (vendor_length < 2) 583 { 584 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", 585 vendor_type, 586 vendor_length)); 587 return; 588 } 589 if (vendor_length > length) 590 { 591 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", 592 vendor_type, 593 vendor_length)); 594 return; 595 } 596 data+=2; 597 vendor_length-=2; 598 length-=2; 599 ND_TCHECK2(*data, vendor_length); 600 601 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u, Value: ", 602 vendor_type, 603 vendor_length)); 604 for (idx = 0; idx < vendor_length ; idx++, data++) 605 ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); 606 length-=vendor_length; 607 } 608 return; 609 610 trunc: 611 ND_PRINT((ndo, "%s", tstr)); 612} 613 614/******************************/ 615/* Print an attribute numeric */ 616/* value pointed by 'data' */ 617/* and 'length' size. */ 618/******************************/ 619/* Returns nothing. */ 620/******************************/ 621static void 622print_attr_num(netdissect_options *ndo, 623 register const u_char *data, u_int length, u_short attr_code) 624{ 625 uint32_t timeout; 626 627 if (length != 4) 628 { 629 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 630 return; 631 } 632 633 ND_TCHECK2(data[0],4); 634 /* This attribute has standard values */ 635 if (attr_type[attr_code].siz_subtypes) 636 { 637 static const char **table; 638 uint32_t data_value; 639 table = attr_type[attr_code].subtypes; 640 641 if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) 642 { 643 if (!*data) 644 ND_PRINT((ndo, "Tag[Unused] ")); 645 else 646 ND_PRINT((ndo, "Tag[%d] ", *data)); 647 data++; 648 data_value = EXTRACT_24BITS(data); 649 } 650 else 651 { 652 data_value = EXTRACT_32BITS(data); 653 } 654 if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 + 655 attr_type[attr_code].first_subtype) && 656 data_value >= attr_type[attr_code].first_subtype ) 657 ND_PRINT((ndo, "%s", table[data_value])); 658 else 659 ND_PRINT((ndo, "#%u", data_value)); 660 } 661 else 662 { 663 switch(attr_code) /* Be aware of special cases... */ 664 { 665 case FRM_IPX: 666 if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) 667 ND_PRINT((ndo, "NAS Select")); 668 else 669 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 670 break; 671 672 case SESSION_TIMEOUT: 673 case IDLE_TIMEOUT: 674 case ACCT_DELAY: 675 case ACCT_SESSION_TIME: 676 case ACCT_INT_INTERVAL: 677 timeout = EXTRACT_32BITS( data); 678 if ( timeout < 60 ) 679 ND_PRINT((ndo, "%02d secs", timeout)); 680 else 681 { 682 if ( timeout < 3600 ) 683 ND_PRINT((ndo, "%02d:%02d min", 684 timeout / 60, timeout % 60)); 685 else 686 ND_PRINT((ndo, "%02d:%02d:%02d hours", 687 timeout / 3600, (timeout % 3600) / 60, 688 timeout % 60)); 689 } 690 break; 691 692 case FRM_ATALK_LINK: 693 if (EXTRACT_32BITS(data) ) 694 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 695 else 696 ND_PRINT((ndo, "Unnumbered")); 697 break; 698 699 case FRM_ATALK_NETWORK: 700 if (EXTRACT_32BITS(data) ) 701 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 702 else 703 ND_PRINT((ndo, "NAS assigned")); 704 break; 705 706 case TUNNEL_PREFERENCE: 707 if (*data) 708 ND_PRINT((ndo, "Tag[%d] ", *data)); 709 else 710 ND_PRINT((ndo, "Tag[Unused] ")); 711 data++; 712 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); 713 break; 714 715 case EGRESS_VLAN_ID: 716 ND_PRINT((ndo, "%s (0x%02x) ", 717 tok2str(rfc4675_tagged,"Unknown tag",*data), 718 *data)); 719 data++; 720 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); 721 break; 722 723 default: 724 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 725 break; 726 727 } /* switch */ 728 729 } /* if-else */ 730 731 return; 732 733 trunc: 734 ND_PRINT((ndo, "%s", tstr)); 735} 736 737/*****************************/ 738/* Print an attribute IPv4 */ 739/* address value pointed by */ 740/* 'data' and 'length' size. */ 741/*****************************/ 742/* Returns nothing. */ 743/*****************************/ 744static void 745print_attr_address(netdissect_options *ndo, 746 register const u_char *data, u_int length, u_short attr_code) 747{ 748 if (length != 4) 749 { 750 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 751 return; 752 } 753 754 ND_TCHECK2(data[0],4); 755 756 switch(attr_code) 757 { 758 case FRM_IPADDR: 759 case LOG_IPHOST: 760 if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) 761 ND_PRINT((ndo, "User Selected")); 762 else 763 if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) 764 ND_PRINT((ndo, "NAS Select")); 765 else 766 ND_PRINT((ndo, "%s",ipaddr_string(ndo, data))); 767 break; 768 769 default: 770 ND_PRINT((ndo, "%s", ipaddr_string(ndo, data))); 771 break; 772 } 773 774 return; 775 776 trunc: 777 ND_PRINT((ndo, "%s", tstr)); 778} 779 780/*************************************/ 781/* Print an attribute of 'secs since */ 782/* January 1, 1970 00:00 UTC' value */ 783/* pointed by 'data' and 'length' */ 784/* size. */ 785/*************************************/ 786/* Returns nothing. */ 787/*************************************/ 788static void 789print_attr_time(netdissect_options *ndo, 790 register const u_char *data, u_int length, u_short attr_code _U_) 791{ 792 time_t attr_time; 793 char string[26]; 794 const char *p; 795 796 if (length != 4) 797 { 798 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 799 return; 800 } 801 802 ND_TCHECK2(data[0],4); 803 804 attr_time = EXTRACT_32BITS(data); 805 if ((p = ctime(&attr_time)) == NULL) 806 p = "?"; 807 strlcpy(string, p, sizeof(string)); 808 /* Get rid of the newline */ 809 string[24] = '\0'; 810 ND_PRINT((ndo, "%.24s", string)); 811 return; 812 813 trunc: 814 ND_PRINT((ndo, "%s", tstr)); 815} 816 817/***********************************/ 818/* Print an attribute of 'strange' */ 819/* data format pointed by 'data' */ 820/* and 'length' size. */ 821/***********************************/ 822/* Returns nothing. */ 823/***********************************/ 824static void 825print_attr_strange(netdissect_options *ndo, 826 register const u_char *data, u_int length, u_short attr_code) 827{ 828 u_short len_data; 829 830 switch(attr_code) 831 { 832 case ARAP_PASS: 833 if (length != 16) 834 { 835 ND_PRINT((ndo, "ERROR: length %u != 16", length)); 836 return; 837 } 838 ND_PRINT((ndo, "User_challenge (")); 839 ND_TCHECK2(data[0],8); 840 len_data = 8; 841 PRINT_HEX(len_data, data); 842 ND_PRINT((ndo, ") User_resp(")); 843 ND_TCHECK2(data[0],8); 844 len_data = 8; 845 PRINT_HEX(len_data, data); 846 ND_PRINT((ndo, ")")); 847 break; 848 849 case ARAP_FEATURES: 850 if (length != 14) 851 { 852 ND_PRINT((ndo, "ERROR: length %u != 14", length)); 853 return; 854 } 855 ND_TCHECK2(data[0],1); 856 if (*data) 857 ND_PRINT((ndo, "User can change password")); 858 else 859 ND_PRINT((ndo, "User cannot change password")); 860 data++; 861 ND_TCHECK2(data[0],1); 862 ND_PRINT((ndo, ", Min password length: %d", *data)); 863 data++; 864 ND_PRINT((ndo, ", created at: ")); 865 ND_TCHECK2(data[0],4); 866 len_data = 4; 867 PRINT_HEX(len_data, data); 868 ND_PRINT((ndo, ", expires in: ")); 869 ND_TCHECK2(data[0],4); 870 len_data = 4; 871 PRINT_HEX(len_data, data); 872 ND_PRINT((ndo, ", Current Time: ")); 873 ND_TCHECK2(data[0],4); 874 len_data = 4; 875 PRINT_HEX(len_data, data); 876 break; 877 878 case ARAP_CHALLENGE_RESP: 879 if (length < 8) 880 { 881 ND_PRINT((ndo, "ERROR: length %u != 8", length)); 882 return; 883 } 884 ND_TCHECK2(data[0],8); 885 len_data = 8; 886 PRINT_HEX(len_data, data); 887 break; 888 } 889 return; 890 891 trunc: 892 ND_PRINT((ndo, "%s", tstr)); 893} 894 895static void 896radius_attrs_print(netdissect_options *ndo, 897 register const u_char *attr, u_int length) 898{ 899 register const struct radius_attr *rad_attr = (const struct radius_attr *)attr; 900 const char *attr_string; 901 902 while (length > 0) 903 { 904 if (length < 2) 905 goto trunc; 906 ND_TCHECK(*rad_attr); 907 908 if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type)) 909 attr_string = attr_type[rad_attr->type].name; 910 else 911 attr_string = "Unknown"; 912 if (rad_attr->len < 2) 913 { 914 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)", 915 attr_string, 916 rad_attr->type, 917 rad_attr->len)); 918 return; 919 } 920 if (rad_attr->len > length) 921 { 922 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)", 923 attr_string, 924 rad_attr->type, 925 rad_attr->len)); 926 return; 927 } 928 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u, Value: ", 929 attr_string, 930 rad_attr->type, 931 rad_attr->len)); 932 933 if (rad_attr->type < TAM_SIZE(attr_type)) 934 { 935 if (rad_attr->len > 2) 936 { 937 if ( attr_type[rad_attr->type].print_func ) 938 (*attr_type[rad_attr->type].print_func)( 939 ndo, ((const u_char *)(rad_attr+1)), 940 rad_attr->len - 2, rad_attr->type); 941 } 942 } 943 /* do we also want to see a hex dump ? */ 944 if (ndo->ndo_vflag> 1) 945 print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2); 946 947 length-=(rad_attr->len); 948 rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len); 949 } 950 return; 951 952trunc: 953 ND_PRINT((ndo, "%s", tstr)); 954} 955 956void 957radius_print(netdissect_options *ndo, 958 const u_char *dat, u_int length) 959{ 960 register const struct radius_hdr *rad; 961 u_int len, auth_idx; 962 963 ND_TCHECK2(*dat, MIN_RADIUS_LEN); 964 rad = (const struct radius_hdr *)dat; 965 len = EXTRACT_16BITS(&rad->len); 966 967 if (len < MIN_RADIUS_LEN) 968 { 969 ND_PRINT((ndo, "%s", tstr)); 970 return; 971 } 972 973 if (len > length) 974 len = length; 975 976 if (ndo->ndo_vflag < 1) { 977 ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u", 978 tok2str(radius_command_values,"Unknown Command",rad->code), 979 rad->code, 980 rad->id, 981 len)); 982 return; 983 } 984 else { 985 ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", 986 len, 987 tok2str(radius_command_values,"Unknown Command",rad->code), 988 rad->code, 989 rad->id)); 990 991 for(auth_idx=0; auth_idx < 16; auth_idx++) 992 ND_PRINT((ndo, "%02x", rad->auth[auth_idx])); 993 } 994 995 if (len > MIN_RADIUS_LEN) 996 radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN); 997 return; 998 999trunc: 1000 ND_PRINT((ndo, "%s", tstr)); 1001} 1002