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