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