1 /* 2 * Copyright (c) 2003 Sun Microsystems, Inc. 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 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #include <stdlib.h> 34 #include <stdio.h> 35 #include <string.h> 36 #include <strings.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <netinet/in.h> 40 #include <arpa/inet.h> 41 #include <errno.h> 42 #include <unistd.h> 43 #include <signal.h> 44 #include <setjmp.h> 45 #include <netdb.h> 46 #include <limits.h> 47 48 #include <ipmitool/ipmi.h> 49 #include <ipmitool/log.h> 50 #include <ipmitool/ipmi_intf.h> 51 #include <ipmitool/helper.h> 52 #include <ipmitool/ipmi_constants.h> 53 #include <ipmitool/ipmi_strings.h> 54 #include <ipmitool/ipmi_lanp.h> 55 #include <ipmitool/ipmi_channel.h> 56 57 extern int verbose; 58 59 /* is_lan_channel - Check if channel is LAN medium 60 * 61 * return 1 if channel is LAN 62 * return 0 if channel is not LAN 63 * 64 * @intf: ipmi interface handle 65 * @chan: channel number to check 66 */ 67 static int 68 is_lan_channel(struct ipmi_intf * intf, uint8_t chan) 69 { 70 uint8_t medium; 71 72 if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) 73 return 0; 74 75 medium = ipmi_get_channel_medium(intf, chan); 76 77 if (medium == IPMI_CHANNEL_MEDIUM_LAN || 78 medium == IPMI_CHANNEL_MEDIUM_LAN_OTHER) 79 return 1; 80 81 return 0; 82 } 83 84 /* find_lan_channel - Find first channel that is LAN 85 * 86 * return channel number if successful 87 * return 0 if no lan channel found, which is not a valid LAN channel 88 * 89 * @intf: ipmi interface handle 90 * @start: channel number to start searching from 91 */ 92 static uint8_t 93 find_lan_channel(struct ipmi_intf * intf, uint8_t start) 94 { 95 uint8_t chan = 0; 96 97 for (chan = start; chan < IPMI_CHANNEL_NUMBER_MAX; chan++) { 98 if (is_lan_channel(intf, chan)) { 99 return chan; 100 } 101 } 102 return 0; 103 } 104 105 /* get_lan_param_select - Query BMC for LAN parameter data 106 * 107 * return pointer to lan_param if successful 108 * if parameter not supported then 109 * return pointer to lan_param with 110 * lan_param->data == NULL and lan_param->data_len == 0 111 * return NULL on error 112 * 113 * @intf: ipmi interface handle 114 * @chan: ipmi channel 115 * @param: lan parameter id 116 * @select: lan parameter set selector 117 */ 118 static struct lan_param * 119 get_lan_param_select(struct ipmi_intf * intf, uint8_t chan, int param, int select) 120 { 121 struct lan_param * p = NULL; 122 struct ipmi_rs * rsp; 123 struct ipmi_rq req; 124 int i = 0; 125 uint8_t msg_data[4]; 126 127 for (i = 0; ipmi_lan_params[i].cmd != (-1); i++) { 128 if (ipmi_lan_params[i].cmd == param) { 129 p = &ipmi_lan_params[i]; 130 break; 131 } 132 } 133 134 if (p == NULL) { 135 lprintf(LOG_INFO, "Get LAN Parameter failed: Unknown parameter."); 136 return NULL; 137 } 138 139 msg_data[0] = chan; 140 msg_data[1] = p->cmd; 141 msg_data[2] = select; 142 msg_data[3] = 0; 143 144 memset(&req, 0, sizeof(req)); 145 req.msg.netfn = IPMI_NETFN_TRANSPORT; 146 req.msg.cmd = IPMI_LAN_GET_CONFIG; 147 req.msg.data = msg_data; 148 req.msg.data_len = 4; 149 150 rsp = intf->sendrecv(intf, &req); 151 if (rsp == NULL) { 152 lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed", p->desc); 153 return NULL; 154 } 155 156 switch (rsp->ccode) 157 { 158 case 0x00: /* successful */ 159 break; 160 161 case 0x80: /* parameter not supported */ 162 case 0xc9: /* parameter out of range */ 163 case 0xcc: /* invalid data field in request */ 164 165 /* these completion codes usually mean parameter not supported */ 166 lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed: %s", 167 p->desc, val2str(rsp->ccode, completion_code_vals)); 168 p->data = NULL; 169 p->data_len = 0; 170 return p; 171 172 default: 173 174 /* other completion codes are treated as error */ 175 lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed: %s", 176 p->desc, val2str(rsp->ccode, completion_code_vals)); 177 return NULL; 178 } 179 180 p->data = rsp->data + 1; 181 p->data_len = rsp->data_len - 1; 182 183 return p; 184 } 185 186 /* get_lan_param - Query BMC for LAN parameter data 187 * 188 * return pointer to lan_param if successful 189 * if parameter not supported then 190 * return pointer to lan_param with 191 * lan_param->data == NULL and lan_param->data_len == 0 192 * return NULL on error 193 * 194 * @intf: ipmi interface handle 195 * @chan: ipmi channel 196 * @param: lan parameter id 197 */ 198 static struct lan_param * 199 get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) 200 { 201 return get_lan_param_select(intf, chan, param, 0); 202 } 203 204 /* set_lan_param_wait - Wait for Set LAN Parameter command to complete 205 * 206 * On some systems this can take unusually long so we wait for the write 207 * to take effect and verify that the data was written successfully 208 * before continuing or retrying. 209 * 210 * returns 0 on success 211 * returns -1 on error 212 * 213 * @intf: ipmi interface handle 214 * @chan: ipmi channel 215 * @param: lan parameter id 216 * @data: lan parameter data 217 * @len: length of lan parameter data 218 */ 219 static int 220 set_lan_param_wait(struct ipmi_intf * intf, uint8_t chan, 221 int param, uint8_t * data, int len) 222 { 223 struct lan_param * p; 224 int retry = 10; /* 10 retries */ 225 226 lprintf(LOG_DEBUG, "Waiting for Set LAN Parameter to complete..."); 227 if (verbose > 1) 228 printbuf(data, len, "SET DATA"); 229 230 for (;;) { 231 p = get_lan_param(intf, chan, param); 232 if (p == NULL) { 233 sleep(IPMI_LANP_TIMEOUT); 234 if (retry-- == 0) 235 return -1; 236 continue; 237 } 238 if (verbose > 1) 239 printbuf(p->data, p->data_len, "READ DATA"); 240 if (p->data_len != len) { 241 sleep(IPMI_LANP_TIMEOUT); 242 if (retry-- == 0) { 243 lprintf(LOG_WARNING, "Mismatched data lengths: %d != %d", 244 p->data_len, len); 245 return -1; 246 } 247 continue; 248 } 249 if (memcmp(data, p->data, len) != 0) { 250 sleep(IPMI_LANP_TIMEOUT); 251 if (retry-- == 0) { 252 lprintf(LOG_WARNING, "LAN Parameter Data does not match! " 253 "Write may have failed."); 254 return -1; 255 } 256 continue; 257 } 258 break; 259 } 260 return 0; 261 } 262 263 /* __set_lan_param - Write LAN Parameter data to BMC 264 * 265 * This function does the actual work of writing the LAN parameter 266 * to the BMC and calls set_lan_param_wait() if requested. 267 * 268 * returns 0 on success 269 * returns -1 on error 270 * 271 * @intf: ipmi interface handle 272 * @chan: ipmi channel 273 * @param: lan parameter id 274 * @data: lan parameter data 275 * @len: length of lan parameter data 276 * @wait: whether to wait for write completion 277 */ 278 static int 279 __set_lan_param(struct ipmi_intf * intf, uint8_t chan, 280 int param, uint8_t * data, int len, int wait) 281 { 282 struct ipmi_rs * rsp; 283 struct ipmi_rq req; 284 uint8_t msg_data[32]; 285 286 if (param < 0) 287 return -1; 288 289 msg_data[0] = chan; 290 msg_data[1] = param; 291 292 memcpy(&msg_data[2], data, len); 293 memset(&req, 0, sizeof(req)); 294 req.msg.netfn = IPMI_NETFN_TRANSPORT; 295 req.msg.cmd = IPMI_LAN_SET_CONFIG; 296 req.msg.data = msg_data; 297 req.msg.data_len = len+2; 298 299 rsp = intf->sendrecv(intf, &req); 300 if (rsp == NULL) { 301 lprintf(LOG_ERR, "Set LAN Parameter failed"); 302 return -1; 303 } 304 if ((rsp->ccode > 0) && (wait != 0)) { 305 lprintf(LOG_DEBUG, "Warning: Set LAN Parameter failed: %s", 306 val2str(rsp->ccode, completion_code_vals)); 307 if (rsp->ccode == 0xcc) { 308 /* retry hack for invalid data field ccode */ 309 int retry = 10; /* 10 retries */ 310 lprintf(LOG_DEBUG, "Retrying..."); 311 for (;;) { 312 if (retry-- == 0) 313 break; 314 sleep(IPMI_LANP_TIMEOUT); 315 rsp = intf->sendrecv(intf, &req); 316 if (rsp == NULL) 317 continue; 318 if (rsp->ccode > 0) 319 continue; 320 return set_lan_param_wait(intf, chan, param, data, len); 321 } 322 } 323 else if (rsp->ccode != 0xff) { 324 /* let 0xff ccode continue */ 325 return -1; 326 } 327 } 328 329 if (wait == 0) 330 return 0; 331 return set_lan_param_wait(intf, chan, param, data, len); 332 } 333 334 /* ipmi_lanp_lock_state - Retrieve set-in-progress status 335 * 336 * returns one of: 337 * IPMI_LANP_WRITE_UNLOCK 338 * IPMI_LANP_WRITE_LOCK 339 * IPMI_LANP_WRITE_COMMIT 340 * -1 on error/if not supported 341 * 342 * @intf: ipmi interface handle 343 * @chan: ipmi channel 344 */ 345 static int 346 ipmi_lanp_lock_state(struct ipmi_intf * intf, uint8_t chan) 347 { 348 struct lan_param * p; 349 p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS); 350 if (p == NULL) 351 return -1; 352 if (p->data == NULL) 353 return -1; 354 return (p->data[0] & 3); 355 } 356 357 /* ipmi_lanp_lock - Lock set-in-progress bits for our use 358 * 359 * Write to the Set-In-Progress LAN parameter to indicate 360 * to other management software that we are modifying parameters. 361 * 362 * No meaningful return value because this is an optional 363 * requirement in IPMI spec and not found on many BMCs. 364 * 365 * @intf: ipmi interface handle 366 * @chan: ipmi channel 367 */ 368 static void 369 ipmi_lanp_lock(struct ipmi_intf * intf, uint8_t chan) 370 { 371 uint8_t val = IPMI_LANP_WRITE_LOCK; 372 int retry = 3; 373 374 for (;;) { 375 int state = ipmi_lanp_lock_state(intf, chan); 376 if (state == -1) 377 break; 378 if (state == val) 379 break; 380 if (retry-- == 0) 381 break; 382 __set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, 383 &val, 1, 0); 384 } 385 } 386 387 /* ipmi_lanp_unlock - Unlock set-in-progress bits 388 * 389 * Write to the Set-In-Progress LAN parameter, first with 390 * a "commit" instruction and then unlocking it. 391 * 392 * No meaningful return value because this is an optional 393 * requirement in IPMI spec and not found on many BMCs. 394 * 395 * @intf: ipmi interface handle 396 * @chan: ipmi channel 397 */ 398 static void 399 ipmi_lanp_unlock(struct ipmi_intf * intf, uint8_t chan) 400 { 401 uint8_t val = IPMI_LANP_WRITE_COMMIT; 402 int rc; 403 404 rc = __set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0); 405 if (rc < 0) { 406 lprintf(LOG_DEBUG, "LAN Parameter Commit not supported"); 407 } 408 409 val = IPMI_LANP_WRITE_UNLOCK; 410 __set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0); 411 } 412 413 /* set_lan_param - Wrap LAN parameter write with set-in-progress lock 414 * 415 * Returns value from __set_lan_param() 416 * 417 * @intf: ipmi interface handle 418 * @chan: ipmi channel 419 * @param: lan parameter id 420 * @data: lan parameter data 421 * @len: length of lan parameter data 422 */ 423 static int 424 set_lan_param(struct ipmi_intf * intf, uint8_t chan, 425 int param, uint8_t * data, int len) 426 { 427 int rc; 428 ipmi_lanp_lock(intf, chan); 429 rc = __set_lan_param(intf, chan, param, data, len, 1); 430 ipmi_lanp_unlock(intf, chan); 431 return rc; 432 } 433 434 /* set_lan_param_nowait - Wrap LAN parameter write without set-in-progress lock 435 * 436 * Returns value from __set_lan_param() 437 * 438 * @intf: ipmi interface handle 439 * @chan: ipmi channel 440 * @param: lan parameter id 441 * @data: lan parameter data 442 * @len: length of lan parameter data 443 */ 444 static int 445 set_lan_param_nowait(struct ipmi_intf * intf, uint8_t chan, 446 int param, uint8_t * data, int len) 447 { 448 int rc; 449 ipmi_lanp_lock(intf, chan); 450 rc = __set_lan_param(intf, chan, param, data, len, 0); 451 ipmi_lanp_unlock(intf, chan); 452 return rc; 453 } 454 455 static int 456 lan_set_arp_interval(struct ipmi_intf * intf, uint8_t chan, uint8_t ival) 457 { 458 struct lan_param *lp; 459 uint8_t interval = 0; 460 int rc = 0; 461 462 lp = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP); 463 if (lp == NULL) 464 return -1; 465 if (lp->data == NULL) 466 return -1; 467 468 if (ival != 0) { 469 if (((UINT8_MAX - 1) / 2) < ival) { 470 lprintf(LOG_ERR, "Given ARP interval '%u' is too big.", ival); 471 return (-1); 472 } 473 interval = (ival * 2) - 1; 474 rc = set_lan_param(intf, chan, IPMI_LANP_GRAT_ARP, &interval, 1); 475 } else { 476 interval = lp->data[0]; 477 } 478 479 printf("BMC-generated Gratuitous ARP interval: %.1f seconds\n", 480 (float)((interval + 1) / 2)); 481 482 return rc; 483 } 484 485 static int 486 lan_set_arp_generate(struct ipmi_intf * intf, 487 uint8_t chan, uint8_t ctl) 488 { 489 struct lan_param *lp; 490 uint8_t data; 491 492 lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); 493 if (lp == NULL) 494 return -1; 495 if (lp->data == NULL) 496 return -1; 497 data = lp->data[0]; 498 499 /* set arp generate bitflag */ 500 if (ctl == 0) 501 data &= ~0x1; 502 else 503 data |= 0x1; 504 505 printf("%sabling BMC-generated Gratuitous ARPs\n", ctl ? "En" : "Dis"); 506 return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1); 507 } 508 509 static int 510 lan_set_arp_respond(struct ipmi_intf * intf, 511 uint8_t chan, uint8_t ctl) 512 { 513 struct lan_param *lp; 514 uint8_t data; 515 516 lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); 517 if (lp == NULL) 518 return -1; 519 if (lp->data == NULL) 520 return -1; 521 data = lp->data[0]; 522 523 /* set arp response bitflag */ 524 if (ctl == 0) 525 data &= ~0x2; 526 else 527 data |= 0x2; 528 529 printf("%sabling BMC-generated ARP responses\n", ctl ? "En" : "Dis"); 530 return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1); 531 } 532 533 /* TODO - probably move elsewhere */ 534 static char priv_level_to_char(unsigned char priv_level) 535 { 536 char ret = 'X'; 537 538 switch (priv_level) 539 { 540 case IPMI_SESSION_PRIV_CALLBACK: 541 ret = 'c'; 542 break; 543 case IPMI_SESSION_PRIV_USER: 544 ret = 'u'; 545 break; 546 case IPMI_SESSION_PRIV_OPERATOR: 547 ret = 'o'; 548 break; 549 case IPMI_SESSION_PRIV_ADMIN: 550 ret = 'a'; 551 break; 552 case IPMI_SESSION_PRIV_OEM: 553 ret = 'O'; 554 break; 555 } 556 557 return ret; 558 } 559 560 561 static int 562 ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan) 563 { 564 struct lan_param * p; 565 int rc = 0; 566 567 if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) { 568 lprintf(LOG_ERR, "Invalid Channel %d", chan); 569 return -1; 570 } 571 572 /* find type of channel and only accept 802.3 LAN */ 573 if (!is_lan_channel(intf, chan)) { 574 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 575 return -1; 576 } 577 578 p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS); 579 if (p == NULL) 580 return -1; 581 if (p->data != NULL) { 582 printf("%-24s: ", p->desc); 583 p->data[0] &= 3; 584 switch (p->data[0]) { 585 case 0: 586 printf("Set Complete\n"); 587 break; 588 case 1: 589 printf("Set In Progress\n"); 590 break; 591 case 2: 592 printf("Commit Write\n"); 593 break; 594 case 3: 595 printf("Reserved\n"); 596 break; 597 default: 598 printf("Unknown\n"); 599 } 600 } 601 602 p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE); 603 if (p == NULL) 604 return -1; 605 if (p->data != NULL) { 606 printf("%-24s: %s%s%s%s%s\n", p->desc, 607 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 608 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 609 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 610 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 611 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 612 } 613 614 p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE); 615 if (p == NULL) 616 return -1; 617 if (p->data != NULL) { 618 printf("%-24s: Callback : %s%s%s%s%s\n", p->desc, 619 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 620 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 621 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 622 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 623 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 624 printf("%-24s: User : %s%s%s%s%s\n", "", 625 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 626 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 627 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 628 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 629 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 630 printf("%-24s: Operator : %s%s%s%s%s\n", "", 631 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 632 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 633 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 634 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 635 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 636 printf("%-24s: Admin : %s%s%s%s%s\n", "", 637 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 638 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 639 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 640 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 641 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 642 printf("%-24s: OEM : %s%s%s%s%s\n", "", 643 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "", 644 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "", 645 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "", 646 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "", 647 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : ""); 648 } 649 650 p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC); 651 if (p == NULL) 652 return -1; 653 if (p->data != NULL) { 654 printf("%-24s: ", p->desc); 655 p->data[0] &= 0xf; 656 switch (p->data[0]) { 657 case 0: 658 printf("Unspecified\n"); 659 break; 660 case 1: 661 printf("Static Address\n"); 662 break; 663 case 2: 664 printf("DHCP Address\n"); 665 break; 666 case 3: 667 printf("BIOS Assigned Address\n"); 668 break; 669 default: 670 printf("Other\n"); 671 break; 672 } 673 } 674 675 p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR); 676 if (p == NULL) 677 return -1; 678 if (p->data != NULL) 679 printf("%-24s: %d.%d.%d.%d\n", p->desc, 680 p->data[0], p->data[1], p->data[2], p->data[3]); 681 682 p = get_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK); 683 if (p == NULL) 684 return -1; 685 if (p->data != NULL) 686 printf("%-24s: %d.%d.%d.%d\n", p->desc, 687 p->data[0], p->data[1], p->data[2], p->data[3]); 688 689 p = get_lan_param(intf, chan, IPMI_LANP_MAC_ADDR); 690 if (p == NULL) 691 return -1; 692 if (p->data != NULL) 693 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, 694 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); 695 696 p = get_lan_param(intf, chan, IPMI_LANP_SNMP_STRING); 697 if (p == NULL) 698 return -1; 699 if (p->data != NULL) 700 printf("%-24s: %s\n", p->desc, p->data); 701 702 p = get_lan_param(intf, chan, IPMI_LANP_IP_HEADER); 703 if (p == NULL) 704 return -1; 705 if (p->data != NULL) 706 printf("%-24s: TTL=0x%02x Flags=0x%02x Precedence=0x%02x TOS=0x%02x\n", 707 p->desc, p->data[0], p->data[1] & 0xe0, p->data[2] & 0xe0, p->data[2] & 0x1e); 708 709 p = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP); 710 if (p == NULL) 711 return -1; 712 if (p->data != NULL) 713 printf("%-24s: ARP Responses %sabled, Gratuitous ARP %sabled\n", p->desc, 714 (p->data[0] & 2) ? "En" : "Dis", (p->data[0] & 1) ? "En" : "Dis"); 715 716 p = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP); 717 if (p == NULL) 718 return -1; 719 if (p->data != NULL) 720 printf("%-24s: %.1f seconds\n", p->desc, (float)((p->data[0] + 1) / 2)); 721 722 p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP); 723 if (p == NULL) 724 return -1; 725 if (p->data != NULL) 726 printf("%-24s: %d.%d.%d.%d\n", p->desc, 727 p->data[0], p->data[1], p->data[2], p->data[3]); 728 729 p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC); 730 if (p == NULL) 731 return -1; 732 if (p->data != NULL) 733 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, 734 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); 735 736 p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP); 737 if (p == NULL) 738 return -1; 739 if (p->data != NULL) 740 printf("%-24s: %d.%d.%d.%d\n", p->desc, 741 p->data[0], p->data[1], p->data[2], p->data[3]); 742 743 p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC); 744 if (p == NULL) 745 return -1; 746 if (p->data != NULL) 747 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, 748 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); 749 750 p = get_lan_param(intf, chan, IPMI_LANP_VLAN_ID); 751 if (p != NULL && p->data != NULL) { 752 int id = ((p->data[1] & 0x0f) << 8) + p->data[0]; 753 if (p->data[1] & 0x80) 754 printf("%-24s: %d\n", p->desc, id); 755 else 756 printf("%-24s: Disabled\n", p->desc); 757 } 758 759 p = get_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY); 760 if (p != NULL && p->data != NULL) 761 printf("%-24s: %d\n", p->desc, p->data[0] & 0x07); 762 763 /* Determine supported Cipher Suites -- Requires two calls */ 764 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHER_SUPPORT); 765 if (p == NULL) 766 return -1; 767 else if (p->data != NULL) 768 { 769 unsigned char cipher_suite_count = p->data[0]; 770 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHERS); 771 if (p == NULL) 772 return -1; 773 774 printf("%-24s: ", p->desc); 775 776 /* Now we're dangerous. There are only 15 fixed cipher 777 suite IDs, but the spec allows for 16 in the return data.*/ 778 if ((p->data != NULL) && (p->data_len <= 17)) 779 { 780 unsigned int i; 781 for (i = 0; (i < 16) && (i < cipher_suite_count); ++i) 782 { 783 printf("%s%d", 784 (i > 0? ",": ""), 785 p->data[i + 1]); 786 } 787 printf("\n"); 788 } 789 else 790 { 791 printf("None\n"); 792 } 793 } 794 795 /* RMCP+ Messaging Cipher Suite Privilege Levels */ 796 /* These are the privilege levels for the 15 fixed cipher suites */ 797 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS); 798 if (p == NULL) 799 return -1; 800 if ((p->data != NULL) && (p->data_len == 9)) 801 { 802 printf("%-24s: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", p->desc, 803 priv_level_to_char(p->data[1] & 0x0F), 804 priv_level_to_char(p->data[1] >> 4), 805 priv_level_to_char(p->data[2] & 0x0F), 806 priv_level_to_char(p->data[2] >> 4), 807 priv_level_to_char(p->data[3] & 0x0F), 808 priv_level_to_char(p->data[3] >> 4), 809 priv_level_to_char(p->data[4] & 0x0F), 810 priv_level_to_char(p->data[4] >> 4), 811 priv_level_to_char(p->data[5] & 0x0F), 812 priv_level_to_char(p->data[5] >> 4), 813 priv_level_to_char(p->data[6] & 0x0F), 814 priv_level_to_char(p->data[6] >> 4), 815 priv_level_to_char(p->data[7] & 0x0F), 816 priv_level_to_char(p->data[7] >> 4), 817 priv_level_to_char(p->data[8] & 0x0F)); 818 819 /* Now print a legend */ 820 printf("%-24s: %s\n", "", " X=Cipher Suite Unused"); 821 printf("%-24s: %s\n", "", " c=CALLBACK"); 822 printf("%-24s: %s\n", "", " u=USER"); 823 printf("%-24s: %s\n", "", " o=OPERATOR"); 824 printf("%-24s: %s\n", "", " a=ADMIN"); 825 printf("%-24s: %s\n", "", " O=OEM"); 826 } 827 else 828 printf("%-24s: Not Available\n", p->desc); 829 830 return rc; 831 } 832 833 /* Configure Authentication Types */ 834 /* TODO - probably some code duplication going on ??? */ 835 static int 836 ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * types) 837 { 838 uint8_t data[5]; 839 uint8_t authtype = 0; 840 char * p; 841 struct lan_param * lp; 842 843 if (level == NULL || types == NULL) 844 return -1; 845 846 lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE); 847 if (lp == NULL) 848 return -1; 849 if (lp->data == NULL) 850 return -1; 851 852 lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x", 853 lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]); 854 855 memset(data, 0, 5); 856 memcpy(data, lp->data, 5); 857 858 p = types; 859 while (p) { 860 if (strncasecmp(p, "none", 4) == 0) 861 authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE; 862 else if (strncasecmp(p, "md2", 3) == 0) 863 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2; 864 else if (strncasecmp(p, "md5", 3) == 0) 865 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5; 866 else if ((strncasecmp(p, "password", 8) == 0) || 867 (strncasecmp(p, "key", 3) == 0)) 868 authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY; 869 else if (strncasecmp(p, "oem", 3) == 0) 870 authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM; 871 else 872 lprintf(LOG_WARNING, "Invalid authentication type: %s", p); 873 p = strchr(p, ','); 874 if (p) 875 p++; 876 } 877 878 p = level; 879 while (p) { 880 if (strncasecmp(p, "callback", 8) == 0) 881 data[0] = authtype; 882 else if (strncasecmp(p, "user", 4) == 0) 883 data[1] = authtype; 884 else if (strncasecmp(p, "operator", 8) == 0) 885 data[2] = authtype; 886 else if (strncasecmp(p, "admin", 5) == 0) 887 data[3] = authtype; 888 else 889 lprintf(LOG_WARNING, "Invalid authentication level: %s", p); 890 p = strchr(p, ','); 891 if (p) 892 p++; 893 } 894 895 if (verbose > 1) 896 printbuf(data, 5, "authtype data"); 897 898 return set_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE, data, 5); 899 } 900 901 /* TODO - we already have set user password in ipmi_user! */ 902 static int 903 ipmi_lan_set_password(struct ipmi_intf * intf, 904 uint8_t userid, uint8_t * password) 905 { 906 struct ipmi_rs * rsp; 907 struct ipmi_rq req; 908 uint8_t data[18]; 909 910 memset(&data, 0, sizeof(data)); 911 data[0] = userid & 0x3f;/* user ID */ 912 data[1] = 0x02; /* set password */ 913 914 if (password != NULL) 915 memcpy(data+2, password, __min(strlen((const char *)password), 16)); 916 917 memset(&req, 0, sizeof(req)); 918 req.msg.netfn = IPMI_NETFN_APP; 919 req.msg.cmd = 0x47; 920 req.msg.data = data; 921 req.msg.data_len = 18; 922 923 rsp = intf->sendrecv(intf, &req); 924 if (rsp == NULL) { 925 lprintf(LOG_ERR, "Unable to Set LAN Password for user %d", userid); 926 return -1; 927 } 928 if (rsp->ccode > 0) { 929 lprintf(LOG_ERR, "Set LAN Password for user %d failed: %s", 930 userid, val2str(rsp->ccode, completion_code_vals)); 931 return -1; 932 } 933 934 /* adjust our session password 935 * or we will no longer be able to communicate with BMC 936 */ 937 ipmi_intf_session_set_password(intf, (char *)password); 938 printf("Password %s for user %d\n", 939 (password == NULL) ? "cleared" : "set", userid); 940 941 return 0; 942 } 943 944 static int 945 ipmi_set_alert_enable(struct ipmi_intf * intf, uint8_t channel, uint8_t enable) 946 { 947 struct ipmi_rs * rsp; 948 struct ipmi_rq req; 949 uint8_t rqdata[3]; 950 951 memset(&req, 0, sizeof(req)); 952 953 /* update non-volatile access */ 954 rqdata[0] = channel; 955 rqdata[1] = 0x40; 956 957 req.msg.netfn = IPMI_NETFN_APP; 958 req.msg.cmd = 0x41; /* Get Channel Access ??? */ 959 req.msg.data = rqdata; 960 req.msg.data_len = 2; 961 962 rsp = intf->sendrecv(intf, &req); 963 if (rsp == NULL) { 964 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 965 return -1; 966 } 967 if (rsp->ccode > 0) { 968 lprintf(LOG_ERR, "Get Channel Access for channel %d failed: %s", 969 channel, val2str(rsp->ccode, completion_code_vals)); 970 return -1; 971 } 972 973 /* SAVE TO NVRAM */ 974 memset(rqdata, 0, 3); 975 rqdata[0] = channel & 0xf; 976 rqdata[1] = rsp->data[0]; 977 if (enable != 0) 978 rqdata[1] &= ~0x20; 979 else 980 rqdata[1] |= 0x20; 981 rqdata[1] |= 0x40; 982 rqdata[2] = 0; 983 984 req.msg.cmd = 0x40; /* Set Channel Access ??? */ 985 req.msg.data_len = 3; 986 987 rsp = intf->sendrecv(intf, &req); 988 if (rsp == NULL) { 989 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 990 return -1; 991 } 992 if (rsp->ccode > 0) { 993 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 994 channel, val2str(rsp->ccode, completion_code_vals)); 995 return -1; 996 } 997 998 /* SAVE TO CURRENT */ 999 rqdata[1] &= 0xc0; 1000 rqdata[1] |= 0x80; 1001 1002 rsp = intf->sendrecv(intf, &req); 1003 if (rsp == NULL) { 1004 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1005 return -1; 1006 } 1007 if (rsp->ccode > 0) { 1008 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1009 channel, val2str(rsp->ccode, completion_code_vals)); 1010 return -1; 1011 } 1012 1013 return 0; 1014 } 1015 1016 /* TODO - we already have functions for this elsewere!!! */ 1017 static int 1018 ipmi_set_channel_access(struct ipmi_intf * intf, uint8_t channel, uint8_t enable) 1019 { 1020 struct ipmi_rs * rsp; 1021 struct ipmi_rq req; 1022 uint8_t rqdata[3]; 1023 uint8_t byteEnable; 1024 1025 memset(&req, 0, sizeof(req)); 1026 1027 /* RETREIVE VALUE IN NVRAM */ 1028 req.msg.netfn = IPMI_NETFN_APP; 1029 req.msg.cmd = 0x41; /* Get Channel Access Command */ 1030 req.msg.data = rqdata; 1031 req.msg.data_len = 2; 1032 1033 memset(rqdata, 0, 2); 1034 rqdata[0] = channel & 0xf; 1035 rqdata[1] = 0x40; /* retreive NV */ 1036 1037 rsp = intf->sendrecv(intf, &req); 1038 if (rsp == NULL) { 1039 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 1040 return -1; 1041 } else if (rsp->ccode > 0) { 1042 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1043 channel, val2str(rsp->ccode, completion_code_vals)); 1044 return -1; 1045 } else { 1046 byteEnable = *(rsp->data + 0); 1047 } 1048 1049 /* SAVE TO NVRAM */ 1050 memset(&req, 0, sizeof(req)); 1051 1052 req.msg.netfn = IPMI_NETFN_APP; 1053 req.msg.cmd = 0x40; /* Set Channel Access Command */ 1054 req.msg.data = rqdata; 1055 req.msg.data_len = 3; 1056 1057 memset(rqdata, 0, 3); 1058 rqdata[0] = channel & 0xf; 1059 rqdata[1] = 0x40 | (byteEnable & 0x38); /* use previously set values */ 1060 if (enable != 0) 1061 rqdata[1] |= 0x2; /* set always available if enable is set */ 1062 rqdata[2] = 0x44; /* set channel privilege limit to ADMIN */ 1063 1064 rsp = intf->sendrecv(intf, &req); 1065 if (rsp == NULL) { 1066 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1067 return -1; 1068 } else if (rsp->ccode > 0) { 1069 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1070 channel, val2str(rsp->ccode, completion_code_vals)); 1071 return -1; 1072 } 1073 1074 /* RETREIVE VALUE IN NVRAM */ 1075 req.msg.netfn = IPMI_NETFN_APP; 1076 req.msg.cmd = 0x41; /* Get Channel Access Command */ 1077 req.msg.data = rqdata; 1078 req.msg.data_len = 2; 1079 1080 memset(rqdata, 0, 2); 1081 rqdata[0] = channel & 0xf; 1082 rqdata[1] = 0x80; /* retreive NV */ 1083 1084 rsp = intf->sendrecv(intf, &req); 1085 if (rsp == NULL) { 1086 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 1087 return -1; 1088 } else if (rsp->ccode > 0) { 1089 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1090 channel, val2str(rsp->ccode, completion_code_vals)); 1091 return -1; 1092 } else { 1093 byteEnable = *(rsp->data + 0); 1094 } 1095 1096 /* SAVE TO CURRENT */ 1097 memset(&req, 0, sizeof(req)); 1098 1099 req.msg.netfn = IPMI_NETFN_APP; 1100 req.msg.cmd = 0x40; /* Set Channel Access Command */ 1101 req.msg.data = rqdata; 1102 req.msg.data_len = 3; 1103 1104 memset(rqdata, 0, 3); 1105 rqdata[0] = channel & 0xf; 1106 rqdata[1] = 0x80 | (byteEnable & 0x38); /* use previously set values */ 1107 if (enable != 0) 1108 rqdata[1] |= 0x2; /* set always available if enable is set */ 1109 rqdata[2] = 0x84; /* set channel privilege limit to ADMIN */ 1110 1111 rsp = intf->sendrecv(intf, &req); 1112 if (rsp == NULL) { 1113 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1114 return -1; 1115 } else if (rsp->ccode > 0) { 1116 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1117 channel, val2str(rsp->ccode, completion_code_vals)); 1118 return -1; 1119 } 1120 1121 /* can't send close session if access off so abort instead */ 1122 if (enable == 0) 1123 intf->abort = 1; 1124 1125 return 0; 1126 } 1127 1128 /* TODO - we already have functions for this elsewhere!!! */ 1129 static int 1130 ipmi_set_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid) 1131 { 1132 struct ipmi_rs * rsp; 1133 struct ipmi_rq req; 1134 uint8_t rqdata[4]; 1135 1136 memset(rqdata, 0, 4); 1137 rqdata[0] = 0x90 | (channel & 0xf); 1138 rqdata[1] = userid & 0x3f; 1139 rqdata[2] = 0x4; 1140 rqdata[3] = 0; 1141 1142 memset(&req, 0, sizeof(req)); 1143 req.msg.netfn = IPMI_NETFN_APP; 1144 req.msg.cmd = 0x43; 1145 req.msg.data = rqdata; 1146 req.msg.data_len = 4; 1147 1148 rsp = intf->sendrecv(intf, &req); 1149 if (rsp == NULL) { 1150 lprintf(LOG_ERR, "Unable to Set User Access for channel %d", channel); 1151 return -1; 1152 } 1153 if (rsp->ccode > 0) { 1154 lprintf(LOG_ERR, "Set User Access for channel %d failed: %s", 1155 channel, val2str(rsp->ccode, completion_code_vals)); 1156 return -1; 1157 } 1158 1159 return 0; 1160 } 1161 1162 static int 1163 get_cmdline_macaddr(char * arg, uint8_t * buf) 1164 { 1165 uint32_t m1, m2, m3, m4, m5, m6; 1166 if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x", 1167 &m1, &m2, &m3, &m4, &m5, &m6) != 6) { 1168 lprintf(LOG_ERR, "Invalid MAC address: %s", arg); 1169 return -1; 1170 } 1171 /* TODO - UINT8_MAX check */ 1172 buf[0] = (uint8_t)m1; 1173 buf[1] = (uint8_t)m2; 1174 buf[2] = (uint8_t)m3; 1175 buf[3] = (uint8_t)m4; 1176 buf[4] = (uint8_t)m5; 1177 buf[5] = (uint8_t)m6; 1178 return 0; 1179 } 1180 1181 1182 static int 1183 get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf) 1184 { 1185 int i, ret = 0; 1186 1187 if (strlen(arg) != 15) 1188 { 1189 lprintf(LOG_ERR, "Invalid privilege specification length: %d", 1190 strlen(arg)); 1191 return -1; 1192 } 1193 1194 /* 1195 * The first byte is reserved (0). The rest of the buffer is setup 1196 * so that each nibble holds the maximum privilege level available for 1197 * that cipher suite number. The number of nibbles (15) matches the number 1198 * of fixed cipher suite IDs. This command documentation mentions 16 IDs 1199 * but table 22-19 shows that there are only 15 (0-14). 1200 * 1201 * data 1 - reserved 1202 * data 2 - maximum priv level for first (LSN) and second (MSN) ciphers 1203 * data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers 1204 * data 9 - maximum priv level for 15th (LSN) cipher. 1205 */ 1206 memset(buf, 0, 9); 1207 for (i = 0; i < 15; ++i) 1208 { 1209 unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN; 1210 1211 switch (arg[i]) 1212 { 1213 case 'X': 1214 priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */ 1215 break; 1216 case 'c': 1217 priv_level = IPMI_SESSION_PRIV_CALLBACK; /* 1 */ 1218 break; 1219 case 'u': 1220 priv_level = IPMI_SESSION_PRIV_USER; /* 2 */ 1221 break; 1222 case 'o': 1223 priv_level = IPMI_SESSION_PRIV_OPERATOR; /* 3 */ 1224 break; 1225 case 'a': 1226 priv_level = IPMI_SESSION_PRIV_ADMIN; /* 4 */ 1227 break; 1228 case 'O': 1229 priv_level = IPMI_SESSION_PRIV_OEM; /* 5 */ 1230 break; 1231 default: 1232 lprintf(LOG_ERR, "Invalid privilege specification char: %c", 1233 arg[i]); 1234 ret = -1; 1235 break; 1236 } 1237 1238 if (ret != 0) 1239 break; 1240 else 1241 { 1242 if ((i + 1) % 2) 1243 { 1244 // Odd number cipher suites will be in the LSN 1245 buf[1 + (i / 2)] += priv_level; 1246 } 1247 else 1248 { 1249 // Even number cipher suites will be in the MSN 1250 buf[1 + (i / 2)] += (priv_level << 4); 1251 } 1252 } 1253 } 1254 1255 return ret; 1256 } 1257 1258 1259 static int 1260 get_cmdline_ipaddr(char * arg, uint8_t * buf) 1261 { 1262 uint32_t ip1, ip2, ip3, ip4; 1263 if (sscanf(arg, 1264 "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32, 1265 &ip1, &ip2, &ip3, &ip4) != 4) { 1266 lprintf(LOG_ERR, "Invalid IP address: %s", arg); 1267 return (-1); 1268 } 1269 if (ip1 > UINT8_MAX || ip2 > UINT8_MAX 1270 || ip3 > UINT8_MAX || ip4 > UINT8_MAX) { 1271 lprintf(LOG_ERR, "Invalid IP address: %s", arg); 1272 return (-1); 1273 } 1274 buf[0] = (uint8_t)ip1; 1275 buf[1] = (uint8_t)ip2; 1276 buf[2] = (uint8_t)ip3; 1277 buf[3] = (uint8_t)ip4; 1278 return 0; 1279 } 1280 1281 static void ipmi_lan_set_usage(void) 1282 { 1283 lprintf(LOG_NOTICE, "\nusage: lan set <channel> <command> <parameter>\n"); 1284 lprintf(LOG_NOTICE, "LAN set command/parameter options:"); 1285 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set channel IP address"); 1286 lprintf(LOG_NOTICE, " netmask <x.x.x.x> Set channel IP netmask"); 1287 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set channel MAC address"); 1288 lprintf(LOG_NOTICE, " defgw ipaddr <x.x.x.x> Set default gateway IP address"); 1289 lprintf(LOG_NOTICE, " defgw macaddr <x:x:x:x:x:x> Set default gateway MAC address"); 1290 lprintf(LOG_NOTICE, " bakgw ipaddr <x.x.x.x> Set backup gateway IP address"); 1291 lprintf(LOG_NOTICE, " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address"); 1292 lprintf(LOG_NOTICE, " password <password> Set session password for this channel"); 1293 lprintf(LOG_NOTICE, " snmp <community string> Set SNMP public community string"); 1294 lprintf(LOG_NOTICE, " user Enable default user for this channel"); 1295 lprintf(LOG_NOTICE, " access <on|off> Enable or disable access to this channel"); 1296 lprintf(LOG_NOTICE, " alert <on|off> Enable or disable PEF alerting for this channel"); 1297 lprintf(LOG_NOTICE, " arp respond <on|off> Enable or disable BMC ARP responding"); 1298 lprintf(LOG_NOTICE, " arp generate <on|off> Enable or disable BMC gratuitous ARP generation"); 1299 lprintf(LOG_NOTICE, " arp interval <seconds> Set gratuitous ARP generation interval"); 1300 lprintf(LOG_NOTICE, " vlan id <off|<id>> Disable or enable VLAN and set ID (1-4094)"); 1301 lprintf(LOG_NOTICE, " vlan priority <priority> Set vlan priority (0-7)"); 1302 lprintf(LOG_NOTICE, " auth <level> <type,..> Set channel authentication types"); 1303 lprintf(LOG_NOTICE, " level = CALLBACK, USER, OPERATOR, ADMIN"); 1304 lprintf(LOG_NOTICE, " type = NONE, MD2, MD5, PASSWORD, OEM"); 1305 lprintf(LOG_NOTICE, " ipsrc <source> Set IP Address source"); 1306 lprintf(LOG_NOTICE, " none = unspecified source"); 1307 lprintf(LOG_NOTICE, " static = address manually configured to be static"); 1308 lprintf(LOG_NOTICE, " dhcp = address obtained by BMC running DHCP"); 1309 lprintf(LOG_NOTICE, " bios = address loaded by BIOS or system software"); 1310 lprintf(LOG_NOTICE, " cipher_privs XXXXXXXXXXXXXXX Set RMCP+ cipher suite privilege levels"); 1311 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1312 lprintf(LOG_NOTICE, " c = CALLBACK"); 1313 lprintf(LOG_NOTICE, " u = USER"); 1314 lprintf(LOG_NOTICE, " o = OPERATOR"); 1315 lprintf(LOG_NOTICE, " a = ADMIN"); 1316 lprintf(LOG_NOTICE, " O = OEM\n"); 1317 } 1318 1319 static void 1320 ipmi_lan_set_vlan_usage(void) 1321 { 1322 lprintf(LOG_NOTICE, 1323 "lan set <channel> vlan id <id>\n" 1324 "lan set <channel> vlan id off\n" 1325 "lan set <channel> vlan priority <priority>\n"); 1326 } 1327 1328 /* TODO - formatting, vlan->VLAN */ 1329 static int 1330 ipmi_lan_set_vlan_id(struct ipmi_intf * intf, uint8_t chan, char *string) 1331 { 1332 uint8_t data[2]; 1333 int rc; 1334 1335 if (string == NULL) { 1336 data[0] = 0; 1337 data[1] = 0; 1338 } 1339 else { 1340 int id = 0; 1341 if (str2int(string, &id) != 0) { 1342 lprintf(LOG_ERR, "Given VLAN ID '%s' is invalid.", string); 1343 return (-1); 1344 } 1345 1346 if (id < 1 || id > 4094) { 1347 lprintf(LOG_NOTICE, "vlan id must be between 1 and 4094."); 1348 return -1; 1349 } 1350 else { 1351 data[0] = (uint8_t)id; 1352 data[1] = (uint8_t)(id >> 8) | 0x80; 1353 } 1354 } 1355 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_ID, data, 2); 1356 return rc; 1357 } 1358 1359 /* TODO - formatting, vlan->VLAN */ 1360 static int 1361 ipmi_lan_set_vlan_priority(struct ipmi_intf * intf, uint8_t chan, char *string) 1362 { 1363 uint8_t data; 1364 int rc; 1365 int priority = 0; 1366 if (str2int(string, &priority) != 0) { 1367 lprintf(LOG_ERR, "Given VLAN priority '%s' is invalid.", string); 1368 return (-1); 1369 } 1370 1371 if (priority < 0 || priority > 7) { 1372 lprintf(LOG_NOTICE, "vlan priority must be between 0 and 7."); 1373 return -1; 1374 } 1375 data = (uint8_t)priority; 1376 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY, &data, 1); 1377 return rc; 1378 } 1379 1380 static int 1381 ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) 1382 { 1383 uint8_t data[32]; 1384 uint8_t chan; 1385 int rc = 0; 1386 1387 if (argc < 2) { 1388 ipmi_lan_set_usage(); 1389 return (-1); 1390 } 1391 1392 if (strncmp(argv[0], "help", 4) == 0 || 1393 strncmp(argv[1], "help", 4) == 0) { 1394 ipmi_lan_set_usage(); 1395 return 0; 1396 } 1397 1398 if (str2uchar(argv[0], &chan) != 0) { 1399 lprintf(LOG_ERR, "Invalid channel: %s", argv[0]); 1400 return (-1); 1401 } 1402 1403 /* find type of channel and only accept 802.3 LAN */ 1404 if (!is_lan_channel(intf, chan)) { 1405 lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan); 1406 ipmi_lan_set_usage(); 1407 return -1; 1408 } 1409 1410 memset(&data, 0, sizeof(data)); 1411 1412 /* set user access */ 1413 if (strncmp(argv[1], "user", 4) == 0) { 1414 rc = ipmi_set_user_access(intf, chan, 1); 1415 } 1416 /* set channel access mode */ 1417 else if (strncmp(argv[1], "access", 6) == 0) { 1418 if (argc < 3) { 1419 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1420 return (-1); 1421 } 1422 else if (strncmp(argv[2], "help", 4) == 0) { 1423 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1424 return 0; 1425 } 1426 else if (strncmp(argv[2], "on", 2) == 0) { 1427 rc = ipmi_set_channel_access(intf, chan, 1); 1428 } 1429 else if (strncmp(argv[2], "off", 3) == 0) { 1430 rc = ipmi_set_channel_access(intf, chan, 0); 1431 } 1432 else { 1433 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1434 return (-1); 1435 } 1436 } 1437 /* set ARP control */ 1438 else if (strncmp(argv[1], "arp", 3) == 0) { 1439 if (argc < 3) { 1440 lprintf(LOG_NOTICE, 1441 "lan set <channel> arp respond <on|off>\n" 1442 "lan set <channel> arp generate <on|off>\n" 1443 "lan set <channel> arp interval <seconds>\n\n" 1444 "example: lan set 7 arp gratuitous off\n"); 1445 return (-1); 1446 } 1447 else if (strncmp(argv[2], "help", 4) == 0) { 1448 lprintf(LOG_NOTICE, 1449 "lan set <channel> arp respond <on|off>\n" 1450 "lan set <channel> arp generate <on|off>\n" 1451 "lan set <channel> arp interval <seconds>\n\n" 1452 "example: lan set 7 arp gratuitous off\n"); 1453 return 0; 1454 } 1455 else if (strncmp(argv[2], "interval", 8) == 0) { 1456 uint8_t interval = 0; 1457 if (str2uchar(argv[3], &interval) != 0) { 1458 lprintf(LOG_ERR, "Given ARP interval '%s' is invalid.", argv[3]); 1459 return (-1); 1460 } 1461 rc = lan_set_arp_interval(intf, chan, interval); 1462 } 1463 else if (strncmp(argv[2], "generate", 8) == 0) { 1464 if (argc < 4) { 1465 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1466 return (-1); 1467 } 1468 else if (strncmp(argv[3], "on", 2) == 0) 1469 rc = lan_set_arp_generate(intf, chan, 1); 1470 else if (strncmp(argv[3], "off", 3) == 0) 1471 rc = lan_set_arp_generate(intf, chan, 0); 1472 else { 1473 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1474 return (-1); 1475 } 1476 } 1477 else if (strncmp(argv[2], "respond", 7) == 0) { 1478 if (argc < 4) { 1479 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1480 return (-1); 1481 } 1482 else if (strncmp(argv[3], "on", 2) == 0) 1483 rc = lan_set_arp_respond(intf, chan, 1); 1484 else if (strncmp(argv[3], "off", 3) == 0) 1485 rc = lan_set_arp_respond(intf, chan, 0); 1486 else { 1487 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1488 return (-1); 1489 } 1490 } 1491 else { 1492 lprintf(LOG_NOTICE, 1493 "lan set <channel> arp respond <on|off>\n" 1494 "lan set <channel> arp generate <on|off>\n" 1495 "lan set <channel> arp interval <seconds>\n"); 1496 return (-1); 1497 } 1498 } 1499 /* set authentication types */ 1500 else if (strncmp(argv[1], "auth", 4) == 0) { 1501 if (argc < 3) { 1502 lprintf(LOG_NOTICE, 1503 "lan set <channel> auth <level> <type,type,...>\n" 1504 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1505 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1506 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1507 return (-1); 1508 } 1509 else if (strncmp(argv[2], "help", 4) == 0) { 1510 lprintf(LOG_NOTICE, 1511 "lan set <channel> auth <level> <type,type,...>\n" 1512 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1513 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1514 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1515 return 0; 1516 } else { 1517 rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]); 1518 } 1519 } 1520 /* ip address source */ 1521 else if (strncmp(argv[1], "ipsrc", 5) == 0) { 1522 if (argc < 3) { 1523 lprintf(LOG_NOTICE, 1524 "lan set <channel> ipsrc <source>\n" 1525 " none = unspecified\n" 1526 " static = static address (manually configured)\n" 1527 " dhcp = address obtained by BMC running DHCP\n" 1528 " bios = address loaded by BIOS or system software\n"); 1529 return (-1); 1530 } 1531 else if (strncmp(argv[2], "help", 4) == 0) { 1532 lprintf(LOG_NOTICE, 1533 "lan set <channel> ipsrc <source>\n" 1534 " none = unspecified\n" 1535 " static = static address (manually configured)\n" 1536 " dhcp = address obtained by BMC running DHCP\n" 1537 " bios = address loaded by BIOS or system software\n"); 1538 return 0; 1539 } 1540 else if (strncmp(argv[2], "none", 4) == 0) 1541 data[0] = 0; 1542 else if (strncmp(argv[2], "static", 5) == 0) 1543 data[0] = 1; 1544 else if (strncmp(argv[2], "dhcp", 4) == 0) 1545 data[0] = 2; 1546 else if (strncmp(argv[2], "bios", 4) == 0) 1547 data[0] = 3; 1548 else { 1549 lprintf(LOG_NOTICE, 1550 "lan set <channel> ipsrc <source>\n" 1551 " none = unspecified\n" 1552 " static = static address (manually configured)\n" 1553 " dhcp = address obtained by BMC running DHCP\n" 1554 " bios = address loaded by BIOS or system software\n"); 1555 return -1; 1556 } 1557 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC, data, 1); 1558 } 1559 /* session password 1560 * not strictly a lan setting, but its used for lan connections */ 1561 else if (strncmp(argv[1], "password", 8) == 0) { 1562 rc = ipmi_lan_set_password(intf, 1, (uint8_t *)argv[2]); 1563 } 1564 /* snmp community string */ 1565 else if (strncmp(argv[1], "snmp", 4) == 0) { 1566 if (argc < 3) { 1567 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1568 return (-1); 1569 } 1570 else if (strncmp(argv[2], "help", 4) == 0) { 1571 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1572 return 0; 1573 } else { 1574 memcpy(data, argv[2], __min(strlen(argv[2]), 18)); 1575 printf("Setting LAN %s to %s\n", 1576 ipmi_lan_params[IPMI_LANP_SNMP_STRING].desc, data); 1577 rc = set_lan_param(intf, chan, IPMI_LANP_SNMP_STRING, data, 18); 1578 } 1579 } 1580 /* ip address */ 1581 else if (strncmp(argv[1], "ipaddr", 6) == 0) { 1582 if(argc != 3) 1583 { 1584 ipmi_lan_set_usage(); 1585 return -1; 1586 } 1587 rc = get_cmdline_ipaddr(argv[2], data); 1588 if (rc == 0) { 1589 printf("Setting LAN %s to %d.%d.%d.%d\n", 1590 ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, 1591 data[0], data[1], data[2], data[3]); 1592 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); 1593 } 1594 } 1595 /* network mask */ 1596 else if (strncmp(argv[1], "netmask", 7) == 0) { 1597 if(argc != 3) 1598 { 1599 ipmi_lan_set_usage(); 1600 return -1; 1601 } 1602 rc = get_cmdline_ipaddr(argv[2], data); 1603 if (rc == 0) { 1604 printf("Setting LAN %s to %d.%d.%d.%d\n", 1605 ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, 1606 data[0], data[1], data[2], data[3]); 1607 rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); 1608 } 1609 } 1610 /* mac address */ 1611 else if (strncmp(argv[1], "macaddr", 7) == 0) { 1612 if(argc != 3) 1613 { 1614 ipmi_lan_set_usage(); 1615 return -1; 1616 } 1617 rc = get_cmdline_macaddr(argv[2], data); 1618 if (rc == 0) { 1619 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1620 ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, 1621 data[0], data[1], data[2], data[3], data[4], data[5]); 1622 rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); 1623 } 1624 } 1625 /* default gateway settings */ 1626 else if (strncmp(argv[1], "defgw", 5) == 0) { 1627 if (argc < 4) { 1628 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1629 return (-1); 1630 } 1631 else if (strncmp(argv[2], "help", 4) == 0) { 1632 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1633 return 0; 1634 } 1635 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1636 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1637 printf("Setting LAN %s to %d.%d.%d.%d\n", 1638 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_IP].desc, 1639 data[0], data[1], data[2], data[3]); 1640 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4); 1641 } 1642 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1643 (get_cmdline_macaddr(argv[3], data) == 0)) { 1644 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1645 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc, 1646 data[0], data[1], data[2], data[3], data[4], data[5]); 1647 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6); 1648 } 1649 else { 1650 ipmi_lan_set_usage(); 1651 return -1; 1652 } 1653 } 1654 /* backup gateway settings */ 1655 else if (strncmp(argv[1], "bakgw", 5) == 0) { 1656 if (argc < 4) { 1657 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1658 return (-1); 1659 } 1660 else if (strncmp(argv[2], "help", 4) == 0) { 1661 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1662 return 0; 1663 } 1664 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1665 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1666 printf("Setting LAN %s to %d.%d.%d.%d\n", 1667 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_IP].desc, 1668 data[0], data[1], data[2], data[3]); 1669 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4); 1670 } 1671 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1672 (get_cmdline_macaddr(argv[3], data) == 0)) { 1673 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1674 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc, 1675 data[0], data[1], data[2], data[3], data[4], data[5]); 1676 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6); 1677 } 1678 else { 1679 ipmi_lan_set_usage(); 1680 return -1; 1681 } 1682 } 1683 else if (strncasecmp(argv[1], "vlan", 4) == 0) { 1684 if (argc < 4) { 1685 ipmi_lan_set_vlan_usage(); 1686 return (-1); 1687 } 1688 else if (strncmp(argv[2], "help", 4) == 0) { 1689 ipmi_lan_set_vlan_usage(); 1690 return 0; 1691 } 1692 else if (strncasecmp(argv[2], "id", 2) == 0) { 1693 if (strncasecmp(argv[3], "off", 3) == 0) { 1694 ipmi_lan_set_vlan_id(intf, chan, NULL); 1695 } 1696 else { 1697 ipmi_lan_set_vlan_id(intf, chan, argv[3]); 1698 } 1699 } 1700 else if (strncasecmp(argv[2], "priority", 8) == 0) { 1701 ipmi_lan_set_vlan_priority(intf, chan, argv[3]); 1702 } 1703 else { 1704 ipmi_lan_set_vlan_usage(); 1705 return (-1); 1706 } 1707 } 1708 /* set PEF alerting on or off */ 1709 else if (strncasecmp(argv[1], "alert", 5) == 0) { 1710 if (argc < 3) { 1711 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1712 return (-1); 1713 } 1714 else if (strncasecmp(argv[2], "on", 2) == 0 || 1715 strncasecmp(argv[2], "enable", 6) == 0) { 1716 printf("Enabling PEF alerts for LAN channel %d\n", chan); 1717 rc = ipmi_set_alert_enable(intf, chan, 1); 1718 } 1719 else if (strncasecmp(argv[2], "off", 3) == 0 || 1720 strncasecmp(argv[2], "disable", 7) == 0) { 1721 printf("Disabling PEF alerts for LAN channel %d\n", chan); 1722 rc = ipmi_set_alert_enable(intf, chan, 0); 1723 } 1724 else { 1725 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1726 return 0; 1727 } 1728 } 1729 /* RMCP+ cipher suite privilege levels */ 1730 else if (strncmp(argv[1], "cipher_privs", 12) == 0) 1731 { 1732 if (argc != 3) { 1733 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1734 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1735 lprintf(LOG_NOTICE, " c = CALLBACK"); 1736 lprintf(LOG_NOTICE, " u = USER"); 1737 lprintf(LOG_NOTICE, " o = OPERATOR"); 1738 lprintf(LOG_NOTICE, " a = ADMIN"); 1739 lprintf(LOG_NOTICE, " O = OEM\n"); 1740 return (-1); 1741 } 1742 else if ((strncmp(argv[2], "help", 4) == 0) || 1743 get_cmdline_cipher_suite_priv_data(argv[2], data)) 1744 { 1745 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1746 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1747 lprintf(LOG_NOTICE, " c = CALLBACK"); 1748 lprintf(LOG_NOTICE, " u = USER"); 1749 lprintf(LOG_NOTICE, " o = OPERATOR"); 1750 lprintf(LOG_NOTICE, " a = ADMIN"); 1751 lprintf(LOG_NOTICE, " O = OEM\n"); 1752 return 0; 1753 } 1754 else 1755 { 1756 rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9); 1757 } 1758 } 1759 else { 1760 ipmi_lan_set_usage(); 1761 return (-1); 1762 } 1763 1764 return rc; 1765 } 1766 1767 1768 static int 1769 is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1770 { 1771 struct lan_param * p; 1772 1773 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1774 if (p == NULL) 1775 return 0; 1776 if (p->data == NULL) 1777 return 0; 1778 1779 if (alert <= (p->data[0] & 0xf)) 1780 return 1; 1781 else 1782 return 0; 1783 } 1784 1785 static int 1786 ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1787 { 1788 # define PTYPE_LEN 4 1789 # define PADDR_LEN 13 1790 struct lan_param *lp_ptr = NULL; 1791 int isack = 0; 1792 uint8_t ptype[PTYPE_LEN]; 1793 uint8_t paddr[PADDR_LEN]; 1794 1795 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert); 1796 if (lp_ptr == NULL || lp_ptr->data == NULL 1797 || lp_ptr->data_len < PTYPE_LEN) { 1798 return (-1); 1799 } 1800 memcpy(ptype, lp_ptr->data, PTYPE_LEN); 1801 1802 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert); 1803 if (lp_ptr == NULL || lp_ptr->data == NULL 1804 || lp_ptr->data_len < PADDR_LEN) { 1805 return (-1); 1806 } 1807 memcpy(paddr, lp_ptr->data, PADDR_LEN); 1808 1809 printf("%-24s: %d\n", "Alert Destination", 1810 ptype[0]); 1811 1812 if (ptype[1] & 0x80) { 1813 isack = 1; 1814 } 1815 printf("%-24s: %s\n", "Alert Acknowledge", 1816 isack ? "Acknowledged" : "Unacknowledged"); 1817 1818 printf("%-24s: ", "Destination Type"); 1819 switch (ptype[1] & 0x7) { 1820 case 0: 1821 printf("PET Trap\n"); 1822 break; 1823 case 6: 1824 printf("OEM 1\n"); 1825 break; 1826 case 7: 1827 printf("OEM 2\n"); 1828 break; 1829 default: 1830 printf("Unknown\n"); 1831 break; 1832 } 1833 1834 printf("%-24s: %d\n", 1835 isack ? "Acknowledge Timeout" : "Retry Interval", 1836 ptype[2]); 1837 1838 printf("%-24s: %d\n", "Number of Retries", 1839 ptype[3] & 0x7); 1840 1841 if ((paddr[1] & 0xf0) != 0) { 1842 /* unknown address format */ 1843 printf("\n"); 1844 return 0; 1845 } 1846 1847 printf("%-24s: %s\n", "Alert Gateway", 1848 (paddr[2] & 1) ? "Backup" : "Default"); 1849 1850 printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address", 1851 paddr[3], paddr[4], paddr[5], paddr[6]); 1852 1853 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address", 1854 paddr[7], paddr[8], paddr[9], 1855 paddr[10], paddr[11], paddr[12]); 1856 1857 printf("\n"); 1858 return 0; 1859 } 1860 1861 static int 1862 ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel) 1863 { 1864 int j, ndest; 1865 struct lan_param * p; 1866 1867 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1868 if (p == NULL) 1869 return -1; 1870 if (p->data == NULL) 1871 return -1; 1872 ndest = p->data[0] & 0xf; 1873 1874 for (j=0; j<=ndest; j++) { 1875 ipmi_lan_alert_print(intf, channel, j); 1876 } 1877 1878 return 0; 1879 } 1880 1881 static void 1882 ipmi_lan_alert_print_usage(void) 1883 { 1884 lprintf(LOG_NOTICE, "\nusage: lan alert print [channel number] [alert destination]\n"); 1885 lprintf(LOG_NOTICE, "Default will print all alerts for the first found LAN channel"); 1886 } 1887 1888 static void 1889 ipmi_lan_alert_set_usage(void) 1890 { 1891 lprintf(LOG_NOTICE, "\nusage: lan alert set <channel number> <alert destination> <command> <parameter>\n"); 1892 lprintf(LOG_NOTICE, " Command/parameter options:\n"); 1893 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set alert IP address"); 1894 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set alert MAC address"); 1895 lprintf(LOG_NOTICE, " gateway <default|backup> Set channel gateway to use for alerts"); 1896 lprintf(LOG_NOTICE, " ack <on|off> Set Alert Acknowledge on or off"); 1897 lprintf(LOG_NOTICE, " type <pet|oem1|oem2> Set destination type as PET or OEM"); 1898 lprintf(LOG_NOTICE, " time <seconds> Set ack timeout or unack retry interval"); 1899 lprintf(LOG_NOTICE, " retry <number> Set number of alert retries"); 1900 lprintf(LOG_NOTICE, ""); 1901 } 1902 1903 static int 1904 ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert, 1905 int argc, char ** argv) 1906 { 1907 struct lan_param * p; 1908 uint8_t data[32], temp[32]; 1909 int rc = 0; 1910 1911 if (argc < 2) { 1912 ipmi_lan_alert_set_usage(); 1913 return (-1); 1914 } 1915 1916 if (strncmp(argv[0], "help", 4) == 0 || 1917 strncmp(argv[1], "help", 4) == 0) { 1918 ipmi_lan_alert_set_usage(); 1919 return 0; 1920 } 1921 1922 memset(data, 0, sizeof(data)); 1923 memset(temp, 0, sizeof(temp)); 1924 1925 /* alert destination ip address */ 1926 if (strncasecmp(argv[0], "ipaddr", 6) == 0 && 1927 (get_cmdline_ipaddr(argv[1], temp) == 0)) { 1928 /* get current parameter */ 1929 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1930 if (p == NULL) { 1931 return (-1); 1932 } 1933 memcpy(data, p->data, p->data_len); 1934 /* set new ipaddr */ 1935 memcpy(data+3, temp, 4); 1936 printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert, 1937 data[3], data[4], data[5], data[6]); 1938 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1939 } 1940 /* alert destination mac address */ 1941 else if (strncasecmp(argv[0], "macaddr", 7) == 0 && 1942 (get_cmdline_macaddr(argv[1], temp) == 0)) { 1943 /* get current parameter */ 1944 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1945 if (p == NULL) { 1946 return (-1); 1947 } 1948 memcpy(data, p->data, p->data_len); 1949 /* set new macaddr */ 1950 memcpy(data+7, temp, 6); 1951 printf("Setting LAN Alert %d MAC Address to " 1952 "%02x:%02x:%02x:%02x:%02x:%02x\n", alert, 1953 data[7], data[8], data[9], data[10], data[11], data[12]); 1954 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1955 } 1956 /* alert destination gateway selector */ 1957 else if (strncasecmp(argv[0], "gateway", 7) == 0) { 1958 /* get current parameter */ 1959 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1960 if (p == NULL) { 1961 return (-1); 1962 } 1963 memcpy(data, p->data, p->data_len); 1964 1965 if (strncasecmp(argv[1], "def", 3) == 0 || 1966 strncasecmp(argv[1], "default", 7) == 0) { 1967 printf("Setting LAN Alert %d to use Default Gateway\n", alert); 1968 data[2] = 0; 1969 } 1970 else if (strncasecmp(argv[1], "bak", 3) == 0 || 1971 strncasecmp(argv[1], "backup", 6) == 0) { 1972 printf("Setting LAN Alert %d to use Backup Gateway\n", alert); 1973 data[2] = 1; 1974 } 1975 else { 1976 ipmi_lan_alert_set_usage(); 1977 return -1; 1978 } 1979 1980 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1981 } 1982 /* alert acknowledgement */ 1983 else if (strncasecmp(argv[0], "ack", 3) == 0) { 1984 /* get current parameter */ 1985 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 1986 if (p == NULL) { 1987 return (-1); 1988 } 1989 memcpy(data, p->data, p->data_len); 1990 1991 if (strncasecmp(argv[1], "on", 2) == 0 || 1992 strncasecmp(argv[1], "yes", 3) == 0) { 1993 printf("Setting LAN Alert %d to Acknowledged\n", alert); 1994 data[1] |= 0x80; 1995 } 1996 else if (strncasecmp(argv[1], "off", 3) == 0 || 1997 strncasecmp(argv[1], "no", 2) == 0) { 1998 printf("Setting LAN Alert %d to Unacknowledged\n", alert); 1999 data[1] &= ~0x80; 2000 } 2001 else { 2002 ipmi_lan_alert_set_usage(); 2003 return -1; 2004 } 2005 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2006 } 2007 /* alert destination type */ 2008 else if (strncasecmp(argv[0], "type", 4) == 0) { 2009 /* get current parameter */ 2010 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2011 if (p == NULL) { 2012 return (-1); 2013 } 2014 memcpy(data, p->data, p->data_len); 2015 2016 if (strncasecmp(argv[1], "pet", 3) == 0) { 2017 printf("Setting LAN Alert %d destination to PET Trap\n", alert); 2018 data[1] &= ~0x07; 2019 } 2020 else if (strncasecmp(argv[1], "oem1", 4) == 0) { 2021 printf("Setting LAN Alert %d destination to OEM 1\n", alert); 2022 data[1] &= ~0x07; 2023 data[1] |= 0x06; 2024 } 2025 else if (strncasecmp(argv[1], "oem2", 4) == 0) { 2026 printf("Setting LAN Alert %d destination to OEM 2\n", alert); 2027 data[1] |= 0x07; 2028 } 2029 else { 2030 ipmi_lan_alert_set_usage(); 2031 return -1; 2032 } 2033 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2034 } 2035 /* alert acknowledge timeout or retry interval */ 2036 else if (strncasecmp(argv[0], "time", 4) == 0) { 2037 /* get current parameter */ 2038 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2039 if (p == NULL) { 2040 return (-1); 2041 } 2042 memcpy(data, p->data, p->data_len); 2043 2044 if (str2uchar(argv[1], &data[2]) != 0) { 2045 lprintf(LOG_ERR, "Invalid time: %s", argv[1]); 2046 return (-1); 2047 } 2048 printf("Setting LAN Alert %d timeout/retry to %d seconds\n", alert, data[2]); 2049 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2050 } 2051 /* number of retries */ 2052 else if (strncasecmp(argv[0], "retry", 5) == 0) { 2053 /* get current parameter */ 2054 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2055 if (p == NULL) { 2056 return (-1); 2057 } 2058 memcpy(data, p->data, p->data_len); 2059 2060 if (str2uchar(argv[1], &data[3]) != 0) { 2061 lprintf(LOG_ERR, "Invalid retry: %s", argv[1]); 2062 return (-1); 2063 } 2064 data[3] = data[3] & 0x7; 2065 printf("Setting LAN Alert %d number of retries to %d\n", alert, data[3]); 2066 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2067 } 2068 else { 2069 ipmi_lan_alert_set_usage(); 2070 return -1; 2071 } 2072 2073 return rc; 2074 } 2075 2076 static int 2077 ipmi_lan_alert(struct ipmi_intf * intf, int argc, char ** argv) 2078 { 2079 uint8_t alert; 2080 uint8_t channel = 1; 2081 2082 if (argc < 1) { 2083 ipmi_lan_alert_print_usage(); 2084 ipmi_lan_alert_set_usage(); 2085 return (-1); 2086 } 2087 else if (strncasecmp(argv[0], "help", 4) == 0) { 2088 ipmi_lan_alert_print_usage(); 2089 ipmi_lan_alert_set_usage(); 2090 return 0; 2091 } 2092 2093 /* alert print [channel] [alert] */ 2094 if (strncasecmp(argv[0], "print", 5) == 0) { 2095 if (argc < 2) { 2096 channel = find_lan_channel(intf, 1); 2097 if (!is_lan_channel(intf, channel)) { 2098 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2099 return -1; 2100 } 2101 return ipmi_lan_alert_print_all(intf, channel); 2102 } 2103 2104 if (strncasecmp(argv[1], "help", 4) == 0) { 2105 ipmi_lan_alert_print_usage(); 2106 return 0; 2107 } 2108 2109 if (str2uchar(argv[1], &channel) != 0) { 2110 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2111 return (-1); 2112 } 2113 if (!is_lan_channel(intf, channel)) { 2114 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2115 return -1; 2116 } 2117 2118 if (argc < 3) 2119 return ipmi_lan_alert_print_all(intf, channel); 2120 2121 if (str2uchar(argv[2], &alert) != 0) { 2122 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2123 return (-1); 2124 } 2125 if (is_alert_destination(intf, channel, alert) == 0) { 2126 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2127 return -1; 2128 } 2129 return ipmi_lan_alert_print(intf, channel, alert); 2130 } 2131 2132 /* alert set <channel> <alert> [option] */ 2133 if (strncasecmp(argv[0], "set", 3) == 0) { 2134 if (argc < 5) { 2135 ipmi_lan_alert_set_usage(); 2136 return (-1); 2137 } 2138 else if (strncasecmp(argv[1], "help", 4) == 0) { 2139 ipmi_lan_alert_set_usage(); 2140 return 0; 2141 } 2142 2143 if (str2uchar(argv[1], &channel) != 0) { 2144 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2145 return (-1); 2146 } 2147 if (!is_lan_channel(intf, channel)) { 2148 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2149 return -1; 2150 } 2151 2152 if (str2uchar(argv[2], &alert) != 0) { 2153 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2154 return (-1); 2155 } 2156 if (is_alert_destination(intf, channel, alert) == 0) { 2157 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2158 return -1; 2159 } 2160 2161 return ipmi_lan_alert_set(intf, channel, alert, argc-3, &(argv[3])); 2162 } 2163 2164 return 0; 2165 } 2166 2167 2168 static int 2169 ipmi_lan_stats_get(struct ipmi_intf * intf, uint8_t chan) 2170 { 2171 int rc = 0; 2172 struct ipmi_rs * rsp; 2173 struct ipmi_rq req; 2174 uint8_t msg_data[2]; 2175 uint16_t statsTemp; 2176 2177 if (!is_lan_channel(intf, chan)) { 2178 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2179 return -1; 2180 } 2181 2182 /* From here, we are ready to get the stats */ 2183 2184 msg_data[0] = chan; 2185 msg_data[1] = 0; /* Don't clear */ 2186 2187 memset(&req, 0, sizeof(req)); 2188 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2189 req.msg.cmd = IPMI_LAN_GET_STAT; 2190 req.msg.data = msg_data; 2191 req.msg.data_len = 2; 2192 2193 rsp = intf->sendrecv(intf, &req); 2194 if (rsp == NULL) { 2195 lprintf(LOG_ERR, "Get LAN Stats command failed"); 2196 return (-1); 2197 } 2198 2199 if (rsp->ccode > 0) { 2200 lprintf(LOG_ERR, "Get LAN Stats command failed: %s", 2201 val2str(rsp->ccode, completion_code_vals)); 2202 return (-1); 2203 } 2204 2205 if (verbose > 1) { 2206 uint8_t counter; 2207 printf("--- Rx Stats ---\n"); 2208 for (counter=0; counter<18; counter+=2) { 2209 printf("%02X", *(rsp->data + counter)); 2210 printf(" %02X - ", *(rsp->data + counter+1)); 2211 } 2212 printf("\n"); 2213 } 2214 2215 statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1)); 2216 printf("IP Rx Packet : %d\n", statsTemp); 2217 2218 statsTemp = ((*(rsp->data + 2)) << 8) | (*(rsp->data + 3)); 2219 printf("IP Rx Header Errors : %u\n", statsTemp); 2220 2221 statsTemp = ((*(rsp->data + 4)) << 8) | (*(rsp->data + 5)); 2222 printf("IP Rx Address Errors : %u\n", statsTemp); 2223 2224 statsTemp = ((*(rsp->data + 6)) << 8) | (*(rsp->data + 7)); 2225 printf("IP Rx Fragmented : %u\n", statsTemp); 2226 2227 statsTemp = ((*(rsp->data + 8)) << 8) | (*(rsp->data + 9)); 2228 printf("IP Tx Packet : %u\n", statsTemp); 2229 2230 statsTemp = ((*(rsp->data +10)) << 8) | (*(rsp->data +11)); 2231 printf("UDP Rx Packet : %u\n", statsTemp); 2232 2233 statsTemp = ((*(rsp->data + 12)) << 8) | (*(rsp->data + 13)); 2234 printf("RMCP Rx Valid : %u\n", statsTemp); 2235 2236 statsTemp = ((*(rsp->data + 14)) << 8) | (*(rsp->data + 15)); 2237 printf("UDP Proxy Packet Received : %u\n", statsTemp); 2238 2239 statsTemp = ((*(rsp->data + 16)) << 8) | (*(rsp->data + 17)); 2240 printf("UDP Proxy Packet Dropped : %u\n", statsTemp); 2241 2242 return rc; 2243 } 2244 2245 2246 static int 2247 ipmi_lan_stats_clear(struct ipmi_intf * intf, uint8_t chan) 2248 { 2249 int rc = 0; 2250 struct ipmi_rs * rsp; 2251 struct ipmi_rq req; 2252 uint8_t msg_data[2]; 2253 2254 if (!is_lan_channel(intf, chan)) { 2255 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2256 return -1; 2257 } 2258 2259 /* From here, we are ready to get the stats */ 2260 msg_data[0] = chan; 2261 msg_data[1] = 1; /* Clear */ 2262 2263 memset(&req, 0, sizeof(req)); 2264 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2265 req.msg.cmd = IPMI_LAN_GET_STAT; 2266 req.msg.data = msg_data; 2267 req.msg.data_len = 2; 2268 2269 rsp = intf->sendrecv(intf, &req); 2270 if (rsp == NULL) { 2271 lprintf(LOG_INFO, "Get LAN Stats command failed"); 2272 return (-1); 2273 } 2274 2275 if (rsp->ccode > 0) { 2276 lprintf(LOG_INFO, "Get LAN Stats command failed: %s", 2277 val2str(rsp->ccode, completion_code_vals)); 2278 return (-1); 2279 } 2280 2281 return rc; 2282 } 2283 2284 2285 /* 2286 * print_lan_usage 2287 */ 2288 static void 2289 print_lan_usage(void) 2290 { 2291 lprintf(LOG_NOTICE, "LAN Commands:"); 2292 lprintf(LOG_NOTICE, " print [<channel number>]"); 2293 lprintf(LOG_NOTICE, " set <channel number> <command> <parameter>"); 2294 lprintf(LOG_NOTICE, " alert print <channel number> <alert destination>"); 2295 lprintf(LOG_NOTICE, " alert set <channel number> <alert destination> <command> <parameter>"); 2296 lprintf(LOG_NOTICE, " stats get [<channel number>]"); 2297 lprintf(LOG_NOTICE, " stats clear [<channel number>]"); 2298 } 2299 2300 2301 int 2302 ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv) 2303 { 2304 int rc = 0; 2305 uint8_t chan = 0; 2306 2307 if (argc == 0) { 2308 print_lan_usage(); 2309 return (-1); 2310 } else if (strncmp(argv[0], "help", 4) == 0) { 2311 print_lan_usage(); 2312 return 0; 2313 } 2314 2315 chan = find_lan_channel(intf, 1); 2316 2317 if (strncmp(argv[0], "printconf", 9) == 0 || 2318 strncmp(argv[0], "print", 5) == 0) 2319 { 2320 if (argc > 2) { 2321 print_lan_usage(); 2322 return (-1); 2323 } else if (argc == 2) { 2324 if (str2uchar(argv[1], &chan) != 0) { 2325 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2326 return (-1); 2327 } 2328 } 2329 if (!is_lan_channel(intf, chan)) { 2330 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2331 return (-1); 2332 } 2333 rc = ipmi_lan_print(intf, chan); 2334 } else if (strncmp(argv[0], "set", 3) == 0) { 2335 rc = ipmi_lan_set(intf, argc-1, &(argv[1])); 2336 } else if (strncmp(argv[0], "alert", 5) == 0) { 2337 rc = ipmi_lan_alert(intf, argc-1, &(argv[1])); 2338 } else if (strncmp(argv[0], "stats", 5) == 0) { 2339 if (argc < 2) { 2340 print_lan_usage(); 2341 return (-1); 2342 } else if (argc == 3) { 2343 if (str2uchar(argv[2], &chan) != 0) { 2344 lprintf(LOG_ERR, "Invalid channel: %s", argv[2]); 2345 return (-1); 2346 } 2347 } 2348 if (!is_lan_channel(intf, chan)) { 2349 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2350 return (-1); 2351 } 2352 if (strncmp(argv[1], "get", 3) == 0) { 2353 rc = ipmi_lan_stats_get(intf, chan); 2354 } else if (strncmp(argv[1], "clear", 5) == 0) { 2355 rc = ipmi_lan_stats_clear(intf, chan); 2356 } else { 2357 print_lan_usage(); 2358 return (-1); 2359 } 2360 } else { 2361 lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]); 2362 return (-1); 2363 } 2364 return rc; 2365 } 2366