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 { 500 ND_PRINT((ndo, "%s", tstr)); 501 return; 502 } 503 if (*data && (*data <=0x1F) ) 504 ND_PRINT((ndo, "Tag[%u] ", *data)); 505 else 506 ND_PRINT((ndo, "Tag[Unused] ")); 507 data++; 508 length--; 509 ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data))); 510 data+=2; 511 length-=2; 512 break; 513 case TUNNEL_CLIENT_END: 514 case TUNNEL_SERVER_END: 515 case TUNNEL_PRIV_GROUP: 516 case TUNNEL_ASSIGN_ID: 517 case TUNNEL_CLIENT_AUTH: 518 case TUNNEL_SERVER_AUTH: 519 if (*data <= 0x1F) 520 { 521 if (length < 1) 522 { 523 ND_PRINT((ndo, "%s", tstr)); 524 return; 525 } 526 if (*data) 527 ND_PRINT((ndo, "Tag[%u] ", *data)); 528 else 529 ND_PRINT((ndo, "Tag[Unused] ")); 530 data++; 531 length--; 532 } 533 break; 534 case EGRESS_VLAN_NAME: 535 ND_PRINT((ndo, "%s (0x%02x) ", 536 tok2str(rfc4675_tagged,"Unknown tag",*data), 537 *data)); 538 data++; 539 length--; 540 break; 541 } 542 543 for (i=0; *data && i < length ; i++, data++) 544 ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); 545 546 return; 547 548 trunc: 549 ND_PRINT((ndo, "%s", tstr)); 550 } 551 552 /* 553 * print vendor specific attributes 554 */ 555 static void 556 print_vendor_attr(netdissect_options *ndo, 557 register const u_char *data, u_int length, u_short attr_code _U_) 558 { 559 u_int idx; 560 u_int vendor_id; 561 u_int vendor_type; 562 u_int vendor_length; 563 564 if (length < 4) 565 goto trunc; 566 ND_TCHECK2(*data, 4); 567 vendor_id = EXTRACT_32BITS(data); 568 data+=4; 569 length-=4; 570 571 ND_PRINT((ndo, "Vendor: %s (%u)", 572 tok2str(smi_values,"Unknown",vendor_id), 573 vendor_id)); 574 575 while (length >= 2) { 576 ND_TCHECK2(*data, 2); 577 578 vendor_type = *(data); 579 vendor_length = *(data+1); 580 581 if (vendor_length < 2) 582 { 583 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", 584 vendor_type, 585 vendor_length)); 586 return; 587 } 588 if (vendor_length > length) 589 { 590 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", 591 vendor_type, 592 vendor_length)); 593 return; 594 } 595 data+=2; 596 vendor_length-=2; 597 length-=2; 598 ND_TCHECK2(*data, vendor_length); 599 600 ND_PRINT((ndo, "\n\t Vendor Attribute: %u, Length: %u, Value: ", 601 vendor_type, 602 vendor_length)); 603 for (idx = 0; idx < vendor_length ; idx++, data++) 604 ND_PRINT((ndo, "%c", (*data < 32 || *data > 126) ? '.' : *data)); 605 length-=vendor_length; 606 } 607 return; 608 609 trunc: 610 ND_PRINT((ndo, "%s", tstr)); 611 } 612 613 /******************************/ 614 /* Print an attribute numeric */ 615 /* value pointed by 'data' */ 616 /* and 'length' size. */ 617 /******************************/ 618 /* Returns nothing. */ 619 /******************************/ 620 static void 621 print_attr_num(netdissect_options *ndo, 622 register const u_char *data, u_int length, u_short attr_code) 623 { 624 uint32_t timeout; 625 626 if (length != 4) 627 { 628 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 629 return; 630 } 631 632 ND_TCHECK2(data[0],4); 633 /* This attribute has standard values */ 634 if (attr_type[attr_code].siz_subtypes) 635 { 636 static const char **table; 637 uint32_t data_value; 638 table = attr_type[attr_code].subtypes; 639 640 if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) 641 { 642 if (!*data) 643 ND_PRINT((ndo, "Tag[Unused] ")); 644 else 645 ND_PRINT((ndo, "Tag[%d] ", *data)); 646 data++; 647 data_value = EXTRACT_24BITS(data); 648 } 649 else 650 { 651 data_value = EXTRACT_32BITS(data); 652 } 653 if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 + 654 attr_type[attr_code].first_subtype) && 655 data_value >= attr_type[attr_code].first_subtype ) 656 ND_PRINT((ndo, "%s", table[data_value])); 657 else 658 ND_PRINT((ndo, "#%u", data_value)); 659 } 660 else 661 { 662 switch(attr_code) /* Be aware of special cases... */ 663 { 664 case FRM_IPX: 665 if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) 666 ND_PRINT((ndo, "NAS Select")); 667 else 668 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 669 break; 670 671 case SESSION_TIMEOUT: 672 case IDLE_TIMEOUT: 673 case ACCT_DELAY: 674 case ACCT_SESSION_TIME: 675 case ACCT_INT_INTERVAL: 676 timeout = EXTRACT_32BITS( data); 677 if ( timeout < 60 ) 678 ND_PRINT((ndo, "%02d secs", timeout)); 679 else 680 { 681 if ( timeout < 3600 ) 682 ND_PRINT((ndo, "%02d:%02d min", 683 timeout / 60, timeout % 60)); 684 else 685 ND_PRINT((ndo, "%02d:%02d:%02d hours", 686 timeout / 3600, (timeout % 3600) / 60, 687 timeout % 60)); 688 } 689 break; 690 691 case FRM_ATALK_LINK: 692 if (EXTRACT_32BITS(data) ) 693 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 694 else 695 ND_PRINT((ndo, "Unnumbered")); 696 break; 697 698 case FRM_ATALK_NETWORK: 699 if (EXTRACT_32BITS(data) ) 700 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 701 else 702 ND_PRINT((ndo, "NAS assigned")); 703 break; 704 705 case TUNNEL_PREFERENCE: 706 if (*data) 707 ND_PRINT((ndo, "Tag[%d] ", *data)); 708 else 709 ND_PRINT((ndo, "Tag[Unused] ")); 710 data++; 711 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); 712 break; 713 714 case EGRESS_VLAN_ID: 715 ND_PRINT((ndo, "%s (0x%02x) ", 716 tok2str(rfc4675_tagged,"Unknown tag",*data), 717 *data)); 718 data++; 719 ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); 720 break; 721 722 default: 723 ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); 724 break; 725 726 } /* switch */ 727 728 } /* if-else */ 729 730 return; 731 732 trunc: 733 ND_PRINT((ndo, "%s", tstr)); 734 } 735 736 /*****************************/ 737 /* Print an attribute IPv4 */ 738 /* address value pointed by */ 739 /* 'data' and 'length' size. */ 740 /*****************************/ 741 /* Returns nothing. */ 742 /*****************************/ 743 static void 744 print_attr_address(netdissect_options *ndo, 745 register const u_char *data, u_int length, u_short attr_code) 746 { 747 if (length != 4) 748 { 749 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 750 return; 751 } 752 753 ND_TCHECK2(data[0],4); 754 755 switch(attr_code) 756 { 757 case FRM_IPADDR: 758 case LOG_IPHOST: 759 if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) 760 ND_PRINT((ndo, "User Selected")); 761 else 762 if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) 763 ND_PRINT((ndo, "NAS Select")); 764 else 765 ND_PRINT((ndo, "%s",ipaddr_string(ndo, data))); 766 break; 767 768 default: 769 ND_PRINT((ndo, "%s", ipaddr_string(ndo, data))); 770 break; 771 } 772 773 return; 774 775 trunc: 776 ND_PRINT((ndo, "%s", tstr)); 777 } 778 779 /*************************************/ 780 /* Print an attribute of 'secs since */ 781 /* January 1, 1970 00:00 UTC' value */ 782 /* pointed by 'data' and 'length' */ 783 /* size. */ 784 /*************************************/ 785 /* Returns nothing. */ 786 /*************************************/ 787 static void 788 print_attr_time(netdissect_options *ndo, 789 register const u_char *data, u_int length, u_short attr_code _U_) 790 { 791 time_t attr_time; 792 char string[26]; 793 794 if (length != 4) 795 { 796 ND_PRINT((ndo, "ERROR: length %u != 4", length)); 797 return; 798 } 799 800 ND_TCHECK2(data[0],4); 801 802 attr_time = EXTRACT_32BITS(data); 803 strlcpy(string, ctime(&attr_time), sizeof(string)); 804 /* Get rid of the newline */ 805 string[24] = '\0'; 806 ND_PRINT((ndo, "%.24s", string)); 807 return; 808 809 trunc: 810 ND_PRINT((ndo, "%s", tstr)); 811 } 812 813 /***********************************/ 814 /* Print an attribute of 'strange' */ 815 /* data format pointed by 'data' */ 816 /* and 'length' size. */ 817 /***********************************/ 818 /* Returns nothing. */ 819 /***********************************/ 820 static void 821 print_attr_strange(netdissect_options *ndo, 822 register const u_char *data, u_int length, u_short attr_code) 823 { 824 u_short len_data; 825 826 switch(attr_code) 827 { 828 case ARAP_PASS: 829 if (length != 16) 830 { 831 ND_PRINT((ndo, "ERROR: length %u != 16", length)); 832 return; 833 } 834 ND_PRINT((ndo, "User_challenge (")); 835 ND_TCHECK2(data[0],8); 836 len_data = 8; 837 PRINT_HEX(len_data, data); 838 ND_PRINT((ndo, ") User_resp(")); 839 ND_TCHECK2(data[0],8); 840 len_data = 8; 841 PRINT_HEX(len_data, data); 842 ND_PRINT((ndo, ")")); 843 break; 844 845 case ARAP_FEATURES: 846 if (length != 14) 847 { 848 ND_PRINT((ndo, "ERROR: length %u != 14", length)); 849 return; 850 } 851 ND_TCHECK2(data[0],1); 852 if (*data) 853 ND_PRINT((ndo, "User can change password")); 854 else 855 ND_PRINT((ndo, "User cannot change password")); 856 data++; 857 ND_TCHECK2(data[0],1); 858 ND_PRINT((ndo, ", Min password length: %d", *data)); 859 data++; 860 ND_PRINT((ndo, ", created at: ")); 861 ND_TCHECK2(data[0],4); 862 len_data = 4; 863 PRINT_HEX(len_data, data); 864 ND_PRINT((ndo, ", expires in: ")); 865 ND_TCHECK2(data[0],4); 866 len_data = 4; 867 PRINT_HEX(len_data, data); 868 ND_PRINT((ndo, ", Current Time: ")); 869 ND_TCHECK2(data[0],4); 870 len_data = 4; 871 PRINT_HEX(len_data, data); 872 break; 873 874 case ARAP_CHALLENGE_RESP: 875 if (length < 8) 876 { 877 ND_PRINT((ndo, "ERROR: length %u != 8", length)); 878 return; 879 } 880 ND_TCHECK2(data[0],8); 881 len_data = 8; 882 PRINT_HEX(len_data, data); 883 break; 884 } 885 return; 886 887 trunc: 888 ND_PRINT((ndo, "%s", tstr)); 889 } 890 891 static void 892 radius_attrs_print(netdissect_options *ndo, 893 register const u_char *attr, u_int length) 894 { 895 register const struct radius_attr *rad_attr = (const struct radius_attr *)attr; 896 const char *attr_string; 897 898 while (length > 0) 899 { 900 if (length < 2) 901 goto trunc; 902 ND_TCHECK(*rad_attr); 903 904 if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type)) 905 attr_string = attr_type[rad_attr->type].name; 906 else 907 attr_string = "Unknown"; 908 if (rad_attr->len < 2) 909 { 910 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)", 911 attr_string, 912 rad_attr->type, 913 rad_attr->len)); 914 return; 915 } 916 if (rad_attr->len > length) 917 { 918 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)", 919 attr_string, 920 rad_attr->type, 921 rad_attr->len)); 922 return; 923 } 924 ND_PRINT((ndo, "\n\t %s Attribute (%u), length: %u, Value: ", 925 attr_string, 926 rad_attr->type, 927 rad_attr->len)); 928 929 if (rad_attr->type < TAM_SIZE(attr_type)) 930 { 931 if (rad_attr->len > 2) 932 { 933 if ( attr_type[rad_attr->type].print_func ) 934 (*attr_type[rad_attr->type].print_func)( 935 ndo, ((const u_char *)(rad_attr+1)), 936 rad_attr->len - 2, rad_attr->type); 937 } 938 } 939 /* do we also want to see a hex dump ? */ 940 if (ndo->ndo_vflag> 1) 941 print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2); 942 943 length-=(rad_attr->len); 944 rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len); 945 } 946 return; 947 948 trunc: 949 ND_PRINT((ndo, "%s", tstr)); 950 } 951 952 void 953 radius_print(netdissect_options *ndo, 954 const u_char *dat, u_int length) 955 { 956 register const struct radius_hdr *rad; 957 u_int len, auth_idx; 958 959 ND_TCHECK2(*dat, MIN_RADIUS_LEN); 960 rad = (const struct radius_hdr *)dat; 961 len = EXTRACT_16BITS(&rad->len); 962 963 if (len < MIN_RADIUS_LEN) 964 { 965 ND_PRINT((ndo, "%s", tstr)); 966 return; 967 } 968 969 if (len > length) 970 len = length; 971 972 if (ndo->ndo_vflag < 1) { 973 ND_PRINT((ndo, "RADIUS, %s (%u), id: 0x%02x length: %u", 974 tok2str(radius_command_values,"Unknown Command",rad->code), 975 rad->code, 976 rad->id, 977 len)); 978 return; 979 } 980 else { 981 ND_PRINT((ndo, "RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", 982 len, 983 tok2str(radius_command_values,"Unknown Command",rad->code), 984 rad->code, 985 rad->id)); 986 987 for(auth_idx=0; auth_idx < 16; auth_idx++) 988 ND_PRINT((ndo, "%02x", rad->auth[auth_idx])); 989 } 990 991 if (len > MIN_RADIUS_LEN) 992 radius_attrs_print(ndo, dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN); 993 return; 994 995 trunc: 996 ND_PRINT((ndo, "%s", tstr)); 997 } 998