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 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 static int 835 ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * types) 836 { 837 uint8_t data[5]; 838 uint8_t authtype = 0; 839 char * p; 840 struct lan_param * lp; 841 842 if (level == NULL || types == NULL) 843 return -1; 844 845 lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE); 846 if (lp == NULL) 847 return -1; 848 if (lp->data == NULL) 849 return -1; 850 851 lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x", 852 lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]); 853 854 memset(data, 0, 5); 855 memcpy(data, lp->data, 5); 856 857 p = types; 858 while (p) { 859 if (strncasecmp(p, "none", 4) == 0) 860 authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE; 861 else if (strncasecmp(p, "md2", 3) == 0) 862 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2; 863 else if (strncasecmp(p, "md5", 3) == 0) 864 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5; 865 else if ((strncasecmp(p, "password", 8) == 0) || 866 (strncasecmp(p, "key", 3) == 0)) 867 authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY; 868 else if (strncasecmp(p, "oem", 3) == 0) 869 authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM; 870 else 871 lprintf(LOG_WARNING, "Invalid authentication type: %s", p); 872 p = strchr(p, ','); 873 if (p) 874 p++; 875 } 876 877 p = level; 878 while (p) { 879 if (strncasecmp(p, "callback", 8) == 0) 880 data[0] = authtype; 881 else if (strncasecmp(p, "user", 4) == 0) 882 data[1] = authtype; 883 else if (strncasecmp(p, "operator", 8) == 0) 884 data[2] = authtype; 885 else if (strncasecmp(p, "admin", 5) == 0) 886 data[3] = authtype; 887 else 888 lprintf(LOG_WARNING, "Invalid authentication level: %s", p); 889 p = strchr(p, ','); 890 if (p) 891 p++; 892 } 893 894 if (verbose > 1) 895 printbuf(data, 5, "authtype data"); 896 897 return set_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE, data, 5); 898 } 899 900 static int 901 ipmi_lan_set_password(struct ipmi_intf * intf, 902 uint8_t userid, uint8_t * password) 903 { 904 struct ipmi_rs * rsp; 905 struct ipmi_rq req; 906 uint8_t data[18]; 907 908 memset(&data, 0, sizeof(data)); 909 data[0] = userid & 0x3f;/* user ID */ 910 data[1] = 0x02; /* set password */ 911 912 if (password != NULL) 913 memcpy(data+2, password, __min(strlen((const char *)password), 16)); 914 915 memset(&req, 0, sizeof(req)); 916 req.msg.netfn = IPMI_NETFN_APP; 917 req.msg.cmd = 0x47; 918 req.msg.data = data; 919 req.msg.data_len = 18; 920 921 rsp = intf->sendrecv(intf, &req); 922 if (rsp == NULL) { 923 lprintf(LOG_ERR, "Unable to Set LAN Password for user %d", userid); 924 return -1; 925 } 926 if (rsp->ccode > 0) { 927 lprintf(LOG_ERR, "Set LAN Password for user %d failed: %s", 928 userid, val2str(rsp->ccode, completion_code_vals)); 929 return -1; 930 } 931 932 /* adjust our session password 933 * or we will no longer be able to communicate with BMC 934 */ 935 ipmi_intf_session_set_password(intf, (char *)password); 936 printf("Password %s for user %d\n", 937 (password == NULL) ? "cleared" : "set", userid); 938 939 return 0; 940 } 941 942 static int 943 ipmi_set_alert_enable(struct ipmi_intf * intf, uint8_t channel, uint8_t enable) 944 { 945 struct ipmi_rs * rsp; 946 struct ipmi_rq req; 947 uint8_t rqdata[3]; 948 949 memset(&req, 0, sizeof(req)); 950 951 /* update non-volatile access */ 952 rqdata[0] = channel; 953 rqdata[1] = 0x40; 954 955 req.msg.netfn = IPMI_NETFN_APP; 956 req.msg.cmd = 0x41; 957 req.msg.data = rqdata; 958 req.msg.data_len = 2; 959 960 rsp = intf->sendrecv(intf, &req); 961 if (rsp == NULL) { 962 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 963 return -1; 964 } 965 if (rsp->ccode > 0) { 966 lprintf(LOG_ERR, "Get Channel Access for channel %d failed: %s", 967 channel, val2str(rsp->ccode, completion_code_vals)); 968 return -1; 969 } 970 971 /* SAVE TO NVRAM */ 972 memset(rqdata, 0, 3); 973 rqdata[0] = channel & 0xf; 974 rqdata[1] = rsp->data[0]; 975 if (enable != 0) 976 rqdata[1] &= ~0x20; 977 else 978 rqdata[1] |= 0x20; 979 rqdata[1] |= 0x40; 980 rqdata[2] = 0; 981 982 req.msg.cmd = 0x40; 983 req.msg.data_len = 3; 984 985 rsp = intf->sendrecv(intf, &req); 986 if (rsp == NULL) { 987 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 988 return -1; 989 } 990 if (rsp->ccode > 0) { 991 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 992 channel, val2str(rsp->ccode, completion_code_vals)); 993 return -1; 994 } 995 996 /* SAVE TO CURRENT */ 997 rqdata[1] &= 0xc0; 998 rqdata[1] |= 0x80; 999 1000 rsp = intf->sendrecv(intf, &req); 1001 if (rsp == NULL) { 1002 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1003 return -1; 1004 } 1005 if (rsp->ccode > 0) { 1006 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1007 channel, val2str(rsp->ccode, completion_code_vals)); 1008 return -1; 1009 } 1010 1011 return 0; 1012 } 1013 1014 static int 1015 ipmi_set_channel_access(struct ipmi_intf * intf, uint8_t channel, uint8_t enable) 1016 { 1017 struct ipmi_rs * rsp; 1018 struct ipmi_rq req; 1019 uint8_t rqdata[3]; 1020 uint8_t byteEnable; 1021 1022 memset(&req, 0, sizeof(req)); 1023 1024 /* RETREIVE VALUE IN NVRAM */ 1025 req.msg.netfn = IPMI_NETFN_APP; 1026 req.msg.cmd = 0x41; /* Get Channel Access Command */ 1027 req.msg.data = rqdata; 1028 req.msg.data_len = 2; 1029 1030 memset(rqdata, 0, 2); 1031 rqdata[0] = channel & 0xf; 1032 rqdata[1] = 0x40; /* retreive NV */ 1033 1034 rsp = intf->sendrecv(intf, &req); 1035 if (rsp == NULL) { 1036 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 1037 return -1; 1038 } else if (rsp->ccode > 0) { 1039 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1040 channel, val2str(rsp->ccode, completion_code_vals)); 1041 return -1; 1042 } else { 1043 byteEnable = *(rsp->data + 0); 1044 } 1045 1046 /* SAVE TO NVRAM */ 1047 memset(&req, 0, sizeof(req)); 1048 1049 req.msg.netfn = IPMI_NETFN_APP; 1050 req.msg.cmd = 0x40; /* Set Channel Access Command */ 1051 req.msg.data = rqdata; 1052 req.msg.data_len = 3; 1053 1054 memset(rqdata, 0, 3); 1055 rqdata[0] = channel & 0xf; 1056 rqdata[1] = 0x40 | (byteEnable & 0x38); /* use previously set values */ 1057 if (enable != 0) 1058 rqdata[1] |= 0x2; /* set always available if enable is set */ 1059 rqdata[2] = 0x44; /* set channel privilege limit to ADMIN */ 1060 1061 rsp = intf->sendrecv(intf, &req); 1062 if (rsp == NULL) { 1063 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1064 return -1; 1065 } else if (rsp->ccode > 0) { 1066 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1067 channel, val2str(rsp->ccode, completion_code_vals)); 1068 return -1; 1069 } 1070 1071 /* RETREIVE VALUE IN NVRAM */ 1072 req.msg.netfn = IPMI_NETFN_APP; 1073 req.msg.cmd = 0x41; /* Get Channel Access Command */ 1074 req.msg.data = rqdata; 1075 req.msg.data_len = 2; 1076 1077 memset(rqdata, 0, 2); 1078 rqdata[0] = channel & 0xf; 1079 rqdata[1] = 0x80; /* retreive NV */ 1080 1081 rsp = intf->sendrecv(intf, &req); 1082 if (rsp == NULL) { 1083 lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel); 1084 return -1; 1085 } else if (rsp->ccode > 0) { 1086 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1087 channel, val2str(rsp->ccode, completion_code_vals)); 1088 return -1; 1089 } else { 1090 byteEnable = *(rsp->data + 0); 1091 } 1092 1093 /* SAVE TO CURRENT */ 1094 memset(&req, 0, sizeof(req)); 1095 1096 req.msg.netfn = IPMI_NETFN_APP; 1097 req.msg.cmd = 0x40; /* Set Channel Access Command */ 1098 req.msg.data = rqdata; 1099 req.msg.data_len = 3; 1100 1101 memset(rqdata, 0, 3); 1102 rqdata[0] = channel & 0xf; 1103 rqdata[1] = 0x80 | (byteEnable & 0x38); /* use previously set values */ 1104 if (enable != 0) 1105 rqdata[1] |= 0x2; /* set always available if enable is set */ 1106 rqdata[2] = 0x84; /* set channel privilege limit to ADMIN */ 1107 1108 rsp = intf->sendrecv(intf, &req); 1109 if (rsp == NULL) { 1110 lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel); 1111 return -1; 1112 } else if (rsp->ccode > 0) { 1113 lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s", 1114 channel, val2str(rsp->ccode, completion_code_vals)); 1115 return -1; 1116 } 1117 1118 /* can't send close session if access off so abort instead */ 1119 if (enable == 0) 1120 intf->abort = 1; 1121 1122 return 0; 1123 } 1124 1125 static int 1126 ipmi_set_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid) 1127 { 1128 struct ipmi_rs * rsp; 1129 struct ipmi_rq req; 1130 uint8_t rqdata[4]; 1131 1132 memset(rqdata, 0, 4); 1133 rqdata[0] = 0x90 | (channel & 0xf); 1134 rqdata[1] = userid & 0x3f; 1135 rqdata[2] = 0x4; 1136 rqdata[3] = 0; 1137 1138 memset(&req, 0, sizeof(req)); 1139 req.msg.netfn = IPMI_NETFN_APP; 1140 req.msg.cmd = 0x43; 1141 req.msg.data = rqdata; 1142 req.msg.data_len = 4; 1143 1144 rsp = intf->sendrecv(intf, &req); 1145 if (rsp == NULL) { 1146 lprintf(LOG_ERR, "Unable to Set User Access for channel %d", channel); 1147 return -1; 1148 } 1149 if (rsp->ccode > 0) { 1150 lprintf(LOG_ERR, "Set User Access for channel %d failed: %s", 1151 channel, val2str(rsp->ccode, completion_code_vals)); 1152 return -1; 1153 } 1154 1155 return 0; 1156 } 1157 1158 static int 1159 get_cmdline_macaddr(char * arg, uint8_t * buf) 1160 { 1161 uint32_t m1, m2, m3, m4, m5, m6; 1162 if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x", 1163 &m1, &m2, &m3, &m4, &m5, &m6) != 6) { 1164 lprintf(LOG_ERR, "Invalid MAC address: %s", arg); 1165 return -1; 1166 } 1167 buf[0] = (uint8_t)m1; 1168 buf[1] = (uint8_t)m2; 1169 buf[2] = (uint8_t)m3; 1170 buf[3] = (uint8_t)m4; 1171 buf[4] = (uint8_t)m5; 1172 buf[5] = (uint8_t)m6; 1173 return 0; 1174 } 1175 1176 1177 static int 1178 get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf) 1179 { 1180 int i, ret = 0; 1181 1182 if (strlen(arg) != 15) 1183 { 1184 lprintf(LOG_ERR, "Invalid privilege specification length: %d", 1185 strlen(arg)); 1186 return -1; 1187 } 1188 1189 /* 1190 * The first byte is reserved (0). The rest of the buffer is setup 1191 * so that each nibble holds the maximum privilege level available for 1192 * that cipher suite number. The number of nibbles (15) matches the number 1193 * of fixed cipher suite IDs. This command documentation mentions 16 IDs 1194 * but table 22-19 shows that there are only 15 (0-14). 1195 * 1196 * data 1 - reserved 1197 * data 2 - maximum priv level for first (LSN) and second (MSN) ciphers 1198 * data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers 1199 * data 9 - maximum priv level for 15th (LSN) cipher. 1200 */ 1201 bzero(buf, 9); 1202 1203 for (i = 0; i < 15; ++i) 1204 { 1205 unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN; 1206 1207 switch (arg[i]) 1208 { 1209 case 'X': 1210 priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */ 1211 break; 1212 case 'c': 1213 priv_level = IPMI_SESSION_PRIV_CALLBACK; /* 1 */ 1214 break; 1215 case 'u': 1216 priv_level = IPMI_SESSION_PRIV_USER; /* 2 */ 1217 break; 1218 case 'o': 1219 priv_level = IPMI_SESSION_PRIV_OPERATOR; /* 3 */ 1220 break; 1221 case 'a': 1222 priv_level = IPMI_SESSION_PRIV_ADMIN; /* 4 */ 1223 break; 1224 case 'O': 1225 priv_level = IPMI_SESSION_PRIV_OEM; /* 5 */ 1226 break; 1227 default: 1228 lprintf(LOG_ERR, "Invalid privilege specification char: %c", 1229 arg[i]); 1230 ret = -1; 1231 break; 1232 } 1233 1234 if (ret != 0) 1235 break; 1236 else 1237 { 1238 if ((i + 1) % 2) 1239 { 1240 // Odd number cipher suites will be in the LSN 1241 buf[1 + (i / 2)] += priv_level; 1242 } 1243 else 1244 { 1245 // Even number cipher suites will be in the MSN 1246 buf[1 + (i / 2)] += (priv_level << 4); 1247 } 1248 } 1249 } 1250 1251 return ret; 1252 } 1253 1254 1255 static int 1256 get_cmdline_ipaddr(char * arg, uint8_t * buf) 1257 { 1258 uint32_t ip1, ip2, ip3, ip4; 1259 if (sscanf(arg, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) { 1260 lprintf(LOG_ERR, "Invalid IP address: %s", arg); 1261 return -1; 1262 } 1263 buf[0] = (uint8_t)ip1; 1264 buf[1] = (uint8_t)ip2; 1265 buf[2] = (uint8_t)ip3; 1266 buf[3] = (uint8_t)ip4; 1267 return 0; 1268 } 1269 1270 static void ipmi_lan_set_usage(void) 1271 { 1272 lprintf(LOG_NOTICE, "\nusage: lan set <channel> <command> <parameter>\n"); 1273 lprintf(LOG_NOTICE, "LAN set command/parameter options:"); 1274 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set channel IP address"); 1275 lprintf(LOG_NOTICE, " netmask <x.x.x.x> Set channel IP netmask"); 1276 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set channel MAC address"); 1277 lprintf(LOG_NOTICE, " defgw ipaddr <x.x.x.x> Set default gateway IP address"); 1278 lprintf(LOG_NOTICE, " defgw macaddr <x:x:x:x:x:x> Set default gateway MAC address"); 1279 lprintf(LOG_NOTICE, " bakgw ipaddr <x.x.x.x> Set backup gateway IP address"); 1280 lprintf(LOG_NOTICE, " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address"); 1281 lprintf(LOG_NOTICE, " password <password> Set session password for this channel"); 1282 lprintf(LOG_NOTICE, " snmp <community string> Set SNMP public community string"); 1283 lprintf(LOG_NOTICE, " user Enable default user for this channel"); 1284 lprintf(LOG_NOTICE, " access <on|off> Enable or disable access to this channel"); 1285 lprintf(LOG_NOTICE, " alert <on|off> Enable or disable PEF alerting for this channel"); 1286 lprintf(LOG_NOTICE, " arp respond <on|off> Enable or disable BMC ARP responding"); 1287 lprintf(LOG_NOTICE, " arp generate <on|off> Enable or disable BMC gratuitous ARP generation"); 1288 lprintf(LOG_NOTICE, " arp interval <seconds> Set gratuitous ARP generation interval"); 1289 lprintf(LOG_NOTICE, " vlan id <off|<id>> Disable or enable VLAN and set ID (1-4094)"); 1290 lprintf(LOG_NOTICE, " vlan priority <priority> Set vlan priority (0-7)"); 1291 lprintf(LOG_NOTICE, " auth <level> <type,..> Set channel authentication types"); 1292 lprintf(LOG_NOTICE, " level = CALLBACK, USER, OPERATOR, ADMIN"); 1293 lprintf(LOG_NOTICE, " type = NONE, MD2, MD5, PASSWORD, OEM"); 1294 lprintf(LOG_NOTICE, " ipsrc <source> Set IP Address source"); 1295 lprintf(LOG_NOTICE, " none = unspecified source"); 1296 lprintf(LOG_NOTICE, " static = address manually configured to be static"); 1297 lprintf(LOG_NOTICE, " dhcp = address obtained by BMC running DHCP"); 1298 lprintf(LOG_NOTICE, " bios = address loaded by BIOS or system software"); 1299 lprintf(LOG_NOTICE, " cipher_privs XXXXXXXXXXXXXXX Set RMCP+ cipher suite privilege levels"); 1300 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1301 lprintf(LOG_NOTICE, " c = CALLBACK"); 1302 lprintf(LOG_NOTICE, " u = USER"); 1303 lprintf(LOG_NOTICE, " o = OPERATOR"); 1304 lprintf(LOG_NOTICE, " a = ADMIN"); 1305 lprintf(LOG_NOTICE, " O = OEM\n"); 1306 } 1307 1308 static void 1309 ipmi_lan_set_vlan_usage(void) 1310 { 1311 lprintf(LOG_NOTICE, 1312 "lan set <channel> vlan id <id>\n" 1313 "lan set <channel> vlan id off\n" 1314 "lan set <channel> vlan priority <priority>\n"); 1315 } 1316 1317 static int 1318 ipmi_lan_set_vlan_id(struct ipmi_intf * intf, uint8_t chan, char *string) 1319 { 1320 uint8_t data[2]; 1321 int rc; 1322 1323 if (string == NULL) { 1324 data[0] = 0; 1325 data[1] = 0; 1326 } 1327 else { 1328 int id = 0; 1329 if (str2int(string, &id) != 0) { 1330 lprintf(LOG_ERR, "Given VLAN ID '%s' is invalid.", string); 1331 return (-1); 1332 } 1333 1334 if (id < 1 || id > 4094) { 1335 lprintf(LOG_NOTICE, "vlan id must be between 1 and 4094."); 1336 return -1; 1337 } 1338 else { 1339 data[0] = (uint8_t)id; 1340 data[1] = (uint8_t)(id >> 8) | 0x80; 1341 } 1342 } 1343 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_ID, data, 2); 1344 return rc; 1345 } 1346 1347 static int 1348 ipmi_lan_set_vlan_priority(struct ipmi_intf * intf, uint8_t chan, char *string) 1349 { 1350 uint8_t data; 1351 int rc; 1352 int priority = 0; 1353 if (str2int(string, &priority) != 0) { 1354 lprintf(LOG_ERR, "Given VLAN priority '%s' is invalid.", string); 1355 return (-1); 1356 } 1357 1358 if (priority < 0 || priority > 7) { 1359 lprintf(LOG_NOTICE, "vlan priority must be between 0 and 7."); 1360 return -1; 1361 } 1362 data = (uint8_t)priority; 1363 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY, &data, 1); 1364 return rc; 1365 } 1366 1367 static int 1368 ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) 1369 { 1370 uint8_t data[32]; 1371 uint8_t chan; 1372 int rc = 0; 1373 1374 if (argc < 2) { 1375 ipmi_lan_set_usage(); 1376 return (-1); 1377 } 1378 1379 if (strncmp(argv[0], "help", 4) == 0 || 1380 strncmp(argv[1], "help", 4) == 0) { 1381 ipmi_lan_set_usage(); 1382 return 0; 1383 } 1384 1385 if (str2uchar(argv[0], &chan) != 0) { 1386 lprintf(LOG_ERR, "Invalid channel: %s", argv[0]); 1387 return (-1); 1388 } 1389 1390 /* find type of channel and only accept 802.3 LAN */ 1391 if (!is_lan_channel(intf, chan)) { 1392 lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan); 1393 ipmi_lan_set_usage(); 1394 return -1; 1395 } 1396 1397 memset(&data, 0, sizeof(data)); 1398 1399 /* set user access */ 1400 if (strncmp(argv[1], "user", 4) == 0) { 1401 rc = ipmi_set_user_access(intf, chan, 1); 1402 } 1403 /* set channel access mode */ 1404 else if (strncmp(argv[1], "access", 6) == 0) { 1405 if (argc < 3) { 1406 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1407 return (-1); 1408 } 1409 else if (strncmp(argv[2], "help", 4) == 0) { 1410 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1411 return 0; 1412 } 1413 else if (strncmp(argv[2], "on", 2) == 0) { 1414 rc = ipmi_set_channel_access(intf, chan, 1); 1415 } 1416 else if (strncmp(argv[2], "off", 3) == 0) { 1417 rc = ipmi_set_channel_access(intf, chan, 0); 1418 } 1419 else { 1420 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1421 return (-1); 1422 } 1423 } 1424 /* set ARP control */ 1425 else if (strncmp(argv[1], "arp", 3) == 0) { 1426 if (argc < 3) { 1427 lprintf(LOG_NOTICE, 1428 "lan set <channel> arp respond <on|off>\n" 1429 "lan set <channel> arp generate <on|off>\n" 1430 "lan set <channel> arp interval <seconds>\n\n" 1431 "example: lan set 7 arp gratuitous off\n"); 1432 return (-1); 1433 } 1434 else if (strncmp(argv[2], "help", 4) == 0) { 1435 lprintf(LOG_NOTICE, 1436 "lan set <channel> arp respond <on|off>\n" 1437 "lan set <channel> arp generate <on|off>\n" 1438 "lan set <channel> arp interval <seconds>\n\n" 1439 "example: lan set 7 arp gratuitous off\n"); 1440 return 0; 1441 } 1442 else if (strncmp(argv[2], "interval", 8) == 0) { 1443 uint8_t interval = 0; 1444 if (str2uchar(argv[3], &interval) != 0) { 1445 lprintf(LOG_ERR, "Given ARP interval '%s' is invalid.", argv[3]); 1446 return (-1); 1447 } 1448 rc = lan_set_arp_interval(intf, chan, interval); 1449 } 1450 else if (strncmp(argv[2], "generate", 8) == 0) { 1451 if (argc < 4) { 1452 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1453 return (-1); 1454 } 1455 else if (strncmp(argv[3], "on", 2) == 0) 1456 rc = lan_set_arp_generate(intf, chan, 1); 1457 else if (strncmp(argv[3], "off", 3) == 0) 1458 rc = lan_set_arp_generate(intf, chan, 0); 1459 else { 1460 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1461 return (-1); 1462 } 1463 } 1464 else if (strncmp(argv[2], "respond", 7) == 0) { 1465 if (argc < 4) { 1466 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1467 return (-1); 1468 } 1469 else if (strncmp(argv[3], "on", 2) == 0) 1470 rc = lan_set_arp_respond(intf, chan, 1); 1471 else if (strncmp(argv[3], "off", 3) == 0) 1472 rc = lan_set_arp_respond(intf, chan, 0); 1473 else { 1474 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1475 return (-1); 1476 } 1477 } 1478 else { 1479 lprintf(LOG_NOTICE, 1480 "lan set <channel> arp respond <on|off>\n" 1481 "lan set <channel> arp generate <on|off>\n" 1482 "lan set <channel> arp interval <seconds>\n"); 1483 return (-1); 1484 } 1485 } 1486 /* set authentication types */ 1487 else if (strncmp(argv[1], "auth", 4) == 0) { 1488 if (argc < 3) { 1489 lprintf(LOG_NOTICE, 1490 "lan set <channel> auth <level> <type,type,...>\n" 1491 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1492 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1493 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1494 return (-1); 1495 } 1496 else if (strncmp(argv[2], "help", 4) == 0) { 1497 lprintf(LOG_NOTICE, 1498 "lan set <channel> auth <level> <type,type,...>\n" 1499 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1500 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1501 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1502 return 0; 1503 } else { 1504 rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]); 1505 } 1506 } 1507 /* ip address source */ 1508 else if (strncmp(argv[1], "ipsrc", 5) == 0) { 1509 if (argc < 3) { 1510 lprintf(LOG_NOTICE, 1511 "lan set <channel> ipsrc <source>\n" 1512 " none = unspecified\n" 1513 " static = static address (manually configured)\n" 1514 " dhcp = address obtained by BMC running DHCP\n" 1515 " bios = address loaded by BIOS or system software\n"); 1516 return (-1); 1517 } 1518 else if (strncmp(argv[2], "help", 4) == 0) { 1519 lprintf(LOG_NOTICE, 1520 "lan set <channel> ipsrc <source>\n" 1521 " none = unspecified\n" 1522 " static = static address (manually configured)\n" 1523 " dhcp = address obtained by BMC running DHCP\n" 1524 " bios = address loaded by BIOS or system software\n"); 1525 return 0; 1526 } 1527 else if (strncmp(argv[2], "none", 4) == 0) 1528 data[0] = 0; 1529 else if (strncmp(argv[2], "static", 5) == 0) 1530 data[0] = 1; 1531 else if (strncmp(argv[2], "dhcp", 4) == 0) 1532 data[0] = 2; 1533 else if (strncmp(argv[2], "bios", 4) == 0) 1534 data[0] = 3; 1535 else { 1536 lprintf(LOG_NOTICE, 1537 "lan set <channel> ipsrc <source>\n" 1538 " none = unspecified\n" 1539 " static = static address (manually configured)\n" 1540 " dhcp = address obtained by BMC running DHCP\n" 1541 " bios = address loaded by BIOS or system software\n"); 1542 return -1; 1543 } 1544 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC, data, 1); 1545 } 1546 /* session password 1547 * not strictly a lan setting, but its used for lan connections */ 1548 else if (strncmp(argv[1], "password", 8) == 0) { 1549 rc = ipmi_lan_set_password(intf, 1, (uint8_t *)argv[2]); 1550 } 1551 /* snmp community string */ 1552 else if (strncmp(argv[1], "snmp", 4) == 0) { 1553 if (argc < 3) { 1554 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1555 return (-1); 1556 } 1557 else if (strncmp(argv[2], "help", 4) == 0) { 1558 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1559 return 0; 1560 } else { 1561 memcpy(data, argv[2], __min(strlen(argv[2]), 18)); 1562 printf("Setting LAN %s to %s\n", 1563 ipmi_lan_params[IPMI_LANP_SNMP_STRING].desc, data); 1564 rc = set_lan_param(intf, chan, IPMI_LANP_SNMP_STRING, data, 18); 1565 } 1566 } 1567 /* ip address */ 1568 else if (strncmp(argv[1], "ipaddr", 6) == 0) { 1569 if(argc != 3) 1570 { 1571 ipmi_lan_set_usage(); 1572 return -1; 1573 } 1574 rc = get_cmdline_ipaddr(argv[2], data); 1575 if (rc == 0) { 1576 printf("Setting LAN %s to %d.%d.%d.%d\n", 1577 ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, 1578 data[0], data[1], data[2], data[3]); 1579 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); 1580 } 1581 } 1582 /* network mask */ 1583 else if (strncmp(argv[1], "netmask", 7) == 0) { 1584 if(argc != 3) 1585 { 1586 ipmi_lan_set_usage(); 1587 return -1; 1588 } 1589 rc = get_cmdline_ipaddr(argv[2], data); 1590 if (rc == 0) { 1591 printf("Setting LAN %s to %d.%d.%d.%d\n", 1592 ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, 1593 data[0], data[1], data[2], data[3]); 1594 rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); 1595 } 1596 } 1597 /* mac address */ 1598 else if (strncmp(argv[1], "macaddr", 7) == 0) { 1599 if(argc != 3) 1600 { 1601 ipmi_lan_set_usage(); 1602 return -1; 1603 } 1604 rc = get_cmdline_macaddr(argv[2], data); 1605 if (rc == 0) { 1606 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1607 ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, 1608 data[0], data[1], data[2], data[3], data[4], data[5]); 1609 rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); 1610 } 1611 } 1612 /* default gateway settings */ 1613 else if (strncmp(argv[1], "defgw", 5) == 0) { 1614 if (argc < 4) { 1615 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1616 return (-1); 1617 } 1618 else if (strncmp(argv[2], "help", 4) == 0) { 1619 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1620 return 0; 1621 } 1622 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1623 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1624 printf("Setting LAN %s to %d.%d.%d.%d\n", 1625 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_IP].desc, 1626 data[0], data[1], data[2], data[3]); 1627 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4); 1628 } 1629 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1630 (get_cmdline_macaddr(argv[3], data) == 0)) { 1631 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1632 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc, 1633 data[0], data[1], data[2], data[3], data[4], data[5]); 1634 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6); 1635 } 1636 else { 1637 ipmi_lan_set_usage(); 1638 return -1; 1639 } 1640 } 1641 /* backup gateway settings */ 1642 else if (strncmp(argv[1], "bakgw", 5) == 0) { 1643 if (argc < 4) { 1644 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1645 return (-1); 1646 } 1647 else if (strncmp(argv[2], "help", 4) == 0) { 1648 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1649 return 0; 1650 } 1651 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1652 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1653 printf("Setting LAN %s to %d.%d.%d.%d\n", 1654 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_IP].desc, 1655 data[0], data[1], data[2], data[3]); 1656 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4); 1657 } 1658 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1659 (get_cmdline_macaddr(argv[3], data) == 0)) { 1660 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1661 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc, 1662 data[0], data[1], data[2], data[3], data[4], data[5]); 1663 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6); 1664 } 1665 else { 1666 ipmi_lan_set_usage(); 1667 return -1; 1668 } 1669 } 1670 else if (strncasecmp(argv[1], "vlan", 4) == 0) { 1671 if (argc < 4) { 1672 ipmi_lan_set_vlan_usage(); 1673 return (-1); 1674 } 1675 else if (strncmp(argv[2], "help", 4) == 0) { 1676 ipmi_lan_set_vlan_usage(); 1677 return 0; 1678 } 1679 else if (strncasecmp(argv[2], "id", 2) == 0) { 1680 if (strncasecmp(argv[3], "off", 3) == 0) { 1681 ipmi_lan_set_vlan_id(intf, chan, NULL); 1682 } 1683 else { 1684 ipmi_lan_set_vlan_id(intf, chan, argv[3]); 1685 } 1686 } 1687 else if (strncasecmp(argv[2], "priority", 8) == 0) { 1688 ipmi_lan_set_vlan_priority(intf, chan, argv[3]); 1689 } 1690 else { 1691 ipmi_lan_set_vlan_usage(); 1692 return (-1); 1693 } 1694 } 1695 /* set PEF alerting on or off */ 1696 else if (strncasecmp(argv[1], "alert", 5) == 0) { 1697 if (argc < 3) { 1698 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1699 return (-1); 1700 } 1701 else if (strncasecmp(argv[2], "on", 2) == 0 || 1702 strncasecmp(argv[2], "enable", 6) == 0) { 1703 printf("Enabling PEF alerts for LAN channel %d\n", chan); 1704 rc = ipmi_set_alert_enable(intf, chan, 1); 1705 } 1706 else if (strncasecmp(argv[2], "off", 3) == 0 || 1707 strncasecmp(argv[2], "disable", 7) == 0) { 1708 printf("Disabling PEF alerts for LAN channel %d\n", chan); 1709 rc = ipmi_set_alert_enable(intf, chan, 0); 1710 } 1711 else { 1712 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1713 return 0; 1714 } 1715 } 1716 /* RMCP+ cipher suite privilege levels */ 1717 else if (strncmp(argv[1], "cipher_privs", 12) == 0) 1718 { 1719 if (argc != 3) { 1720 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1721 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1722 lprintf(LOG_NOTICE, " c = CALLBACK"); 1723 lprintf(LOG_NOTICE, " u = USER"); 1724 lprintf(LOG_NOTICE, " o = OPERATOR"); 1725 lprintf(LOG_NOTICE, " a = ADMIN"); 1726 lprintf(LOG_NOTICE, " O = OEM\n"); 1727 return (-1); 1728 } 1729 else if ((strncmp(argv[2], "help", 4) == 0) || 1730 get_cmdline_cipher_suite_priv_data(argv[2], data)) 1731 { 1732 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1733 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1734 lprintf(LOG_NOTICE, " c = CALLBACK"); 1735 lprintf(LOG_NOTICE, " u = USER"); 1736 lprintf(LOG_NOTICE, " o = OPERATOR"); 1737 lprintf(LOG_NOTICE, " a = ADMIN"); 1738 lprintf(LOG_NOTICE, " O = OEM\n"); 1739 return 0; 1740 } 1741 else 1742 { 1743 rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9); 1744 } 1745 } 1746 else { 1747 ipmi_lan_set_usage(); 1748 return (-1); 1749 } 1750 1751 return rc; 1752 } 1753 1754 1755 static int 1756 is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1757 { 1758 struct lan_param * p; 1759 1760 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1761 if (p == NULL) 1762 return 0; 1763 if (p->data == NULL) 1764 return 0; 1765 1766 if (alert <= (p->data[0] & 0xf)) 1767 return 1; 1768 else 1769 return 0; 1770 } 1771 1772 static int 1773 ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1774 { 1775 # define PTYPE_LEN 4 1776 # define PADDR_LEN 13 1777 struct lan_param *lp_ptr = NULL; 1778 int isack = 0; 1779 uint8_t ptype[PTYPE_LEN]; 1780 uint8_t paddr[PADDR_LEN]; 1781 1782 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert); 1783 if (lp_ptr == NULL || lp_ptr->data == NULL 1784 || lp_ptr->data_len < PTYPE_LEN) { 1785 return (-1); 1786 } 1787 memcpy(ptype, lp_ptr->data, PTYPE_LEN); 1788 1789 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert); 1790 if (lp_ptr == NULL || lp_ptr->data == NULL 1791 || lp_ptr->data_len < PADDR_LEN) { 1792 return (-1); 1793 } 1794 memcpy(paddr, lp_ptr->data, PADDR_LEN); 1795 1796 printf("%-24s: %d\n", "Alert Destination", 1797 ptype[0]); 1798 1799 if (ptype[1] & 0x80) { 1800 isack = 1; 1801 } 1802 printf("%-24s: %s\n", "Alert Acknowledge", 1803 isack ? "Acknowledged" : "Unacknowledged"); 1804 1805 printf("%-24s: ", "Destination Type"); 1806 switch (ptype[1] & 0x7) { 1807 case 0: 1808 printf("PET Trap\n"); 1809 break; 1810 case 6: 1811 printf("OEM 1\n"); 1812 break; 1813 case 7: 1814 printf("OEM 2\n"); 1815 break; 1816 default: 1817 printf("Unknown\n"); 1818 break; 1819 } 1820 1821 printf("%-24s: %d\n", 1822 isack ? "Acknowledge Timeout" : "Retry Interval", 1823 ptype[2]); 1824 1825 printf("%-24s: %d\n", "Number of Retries", 1826 ptype[3] & 0x7); 1827 1828 if ((paddr[1] & 0xf0) != 0) { 1829 /* unknown address format */ 1830 printf("\n"); 1831 return 0; 1832 } 1833 1834 printf("%-24s: %s\n", "Alert Gateway", 1835 (paddr[2] & 1) ? "Backup" : "Default"); 1836 1837 printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address", 1838 paddr[3], paddr[4], paddr[5], paddr[6]); 1839 1840 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address", 1841 paddr[7], paddr[8], paddr[9], 1842 paddr[10], paddr[11], paddr[12]); 1843 1844 printf("\n"); 1845 return 0; 1846 } 1847 1848 static int 1849 ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel) 1850 { 1851 int j, ndest; 1852 struct lan_param * p; 1853 1854 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1855 if (p == NULL) 1856 return -1; 1857 if (p->data == NULL) 1858 return -1; 1859 ndest = p->data[0] & 0xf; 1860 1861 for (j=0; j<=ndest; j++) { 1862 ipmi_lan_alert_print(intf, channel, j); 1863 } 1864 1865 return 0; 1866 } 1867 1868 static void 1869 ipmi_lan_alert_print_usage(void) 1870 { 1871 lprintf(LOG_NOTICE, "\nusage: lan alert print [channel number] [alert destination]\n"); 1872 lprintf(LOG_NOTICE, "Default will print all alerts for the first found LAN channel"); 1873 } 1874 1875 static void 1876 ipmi_lan_alert_set_usage(void) 1877 { 1878 lprintf(LOG_NOTICE, "\nusage: lan alert set <channel number> <alert destination> <command> <parameter>\n"); 1879 lprintf(LOG_NOTICE, " Command/parameter options:\n"); 1880 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set alert IP address"); 1881 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set alert MAC address"); 1882 lprintf(LOG_NOTICE, " gateway <default|backup> Set channel gateway to use for alerts"); 1883 lprintf(LOG_NOTICE, " ack <on|off> Set Alert Acknowledge on or off"); 1884 lprintf(LOG_NOTICE, " type <pet|oem1|oem2> Set destination type as PET or OEM"); 1885 lprintf(LOG_NOTICE, " time <seconds> Set ack timeout or unack retry interval"); 1886 lprintf(LOG_NOTICE, " retry <number> Set number of alert retries"); 1887 lprintf(LOG_NOTICE, ""); 1888 } 1889 1890 static int 1891 ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert, 1892 int argc, char ** argv) 1893 { 1894 struct lan_param * p; 1895 uint8_t data[32], temp[32]; 1896 int rc = 0; 1897 1898 if (argc < 2) { 1899 ipmi_lan_alert_set_usage(); 1900 return (-1); 1901 } 1902 1903 if (strncmp(argv[0], "help", 4) == 0 || 1904 strncmp(argv[1], "help", 4) == 0) { 1905 ipmi_lan_alert_set_usage(); 1906 return 0; 1907 } 1908 1909 memset(data, 0, sizeof(data)); 1910 memset(temp, 0, sizeof(temp)); 1911 1912 /* alert destination ip address */ 1913 if (strncasecmp(argv[0], "ipaddr", 6) == 0 && 1914 (get_cmdline_ipaddr(argv[1], temp) == 0)) { 1915 /* get current parameter */ 1916 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1917 if (p == NULL) { 1918 return (-1); 1919 } 1920 memcpy(data, p->data, p->data_len); 1921 /* set new ipaddr */ 1922 memcpy(data+3, temp, 4); 1923 printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert, 1924 data[3], data[4], data[5], data[6]); 1925 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1926 } 1927 /* alert destination mac address */ 1928 else if (strncasecmp(argv[0], "macaddr", 7) == 0 && 1929 (get_cmdline_macaddr(argv[1], temp) == 0)) { 1930 /* get current parameter */ 1931 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1932 if (p == NULL) { 1933 return (-1); 1934 } 1935 memcpy(data, p->data, p->data_len); 1936 /* set new macaddr */ 1937 memcpy(data+7, temp, 6); 1938 printf("Setting LAN Alert %d MAC Address to " 1939 "%02x:%02x:%02x:%02x:%02x:%02x\n", alert, 1940 data[7], data[8], data[9], data[10], data[11], data[12]); 1941 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1942 } 1943 /* alert destination gateway selector */ 1944 else if (strncasecmp(argv[0], "gateway", 7) == 0) { 1945 /* get current parameter */ 1946 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1947 if (p == NULL) { 1948 return (-1); 1949 } 1950 memcpy(data, p->data, p->data_len); 1951 1952 if (strncasecmp(argv[1], "def", 3) == 0 || 1953 strncasecmp(argv[1], "default", 7) == 0) { 1954 printf("Setting LAN Alert %d to use Default Gateway\n", alert); 1955 data[2] = 0; 1956 } 1957 else if (strncasecmp(argv[1], "bak", 3) == 0 || 1958 strncasecmp(argv[1], "backup", 6) == 0) { 1959 printf("Setting LAN Alert %d to use Backup Gateway\n", alert); 1960 data[2] = 1; 1961 } 1962 else { 1963 ipmi_lan_alert_set_usage(); 1964 return -1; 1965 } 1966 1967 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1968 } 1969 /* alert acknowledgement */ 1970 else if (strncasecmp(argv[0], "ack", 3) == 0) { 1971 /* get current parameter */ 1972 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 1973 if (p == NULL) { 1974 return (-1); 1975 } 1976 memcpy(data, p->data, p->data_len); 1977 1978 if (strncasecmp(argv[1], "on", 2) == 0 || 1979 strncasecmp(argv[1], "yes", 3) == 0) { 1980 printf("Setting LAN Alert %d to Acknowledged\n", alert); 1981 data[1] |= 0x80; 1982 } 1983 else if (strncasecmp(argv[1], "off", 3) == 0 || 1984 strncasecmp(argv[1], "no", 2) == 0) { 1985 printf("Setting LAN Alert %d to Unacknowledged\n", alert); 1986 data[1] &= ~0x80; 1987 } 1988 else { 1989 ipmi_lan_alert_set_usage(); 1990 return -1; 1991 } 1992 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 1993 } 1994 /* alert destination type */ 1995 else if (strncasecmp(argv[0], "type", 4) == 0) { 1996 /* get current parameter */ 1997 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 1998 if (p == NULL) { 1999 return (-1); 2000 } 2001 memcpy(data, p->data, p->data_len); 2002 2003 if (strncasecmp(argv[1], "pet", 3) == 0) { 2004 printf("Setting LAN Alert %d destination to PET Trap\n", alert); 2005 data[1] &= ~0x07; 2006 } 2007 else if (strncasecmp(argv[1], "oem1", 4) == 0) { 2008 printf("Setting LAN Alert %d destination to OEM 1\n", alert); 2009 data[1] &= ~0x07; 2010 data[1] |= 0x06; 2011 } 2012 else if (strncasecmp(argv[1], "oem2", 4) == 0) { 2013 printf("Setting LAN Alert %d destination to OEM 2\n", alert); 2014 data[1] |= 0x07; 2015 } 2016 else { 2017 ipmi_lan_alert_set_usage(); 2018 return -1; 2019 } 2020 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2021 } 2022 /* alert acknowledge timeout or retry interval */ 2023 else if (strncasecmp(argv[0], "time", 4) == 0) { 2024 /* get current parameter */ 2025 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2026 if (p == NULL) { 2027 return (-1); 2028 } 2029 memcpy(data, p->data, p->data_len); 2030 2031 if (str2uchar(argv[1], &data[2]) != 0) { 2032 lprintf(LOG_ERR, "Invalid time: %s", argv[1]); 2033 return (-1); 2034 } 2035 printf("Setting LAN Alert %d timeout/retry to %d seconds\n", alert, data[2]); 2036 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2037 } 2038 /* number of retries */ 2039 else if (strncasecmp(argv[0], "retry", 5) == 0) { 2040 /* get current parameter */ 2041 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2042 if (p == NULL) { 2043 return (-1); 2044 } 2045 memcpy(data, p->data, p->data_len); 2046 2047 if (str2uchar(argv[1], &data[3]) != 0) { 2048 lprintf(LOG_ERR, "Invalid retry: %s", argv[1]); 2049 return (-1); 2050 } 2051 data[3] = data[3] & 0x7; 2052 printf("Setting LAN Alert %d number of retries to %d\n", alert, data[3]); 2053 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2054 } 2055 else { 2056 ipmi_lan_alert_set_usage(); 2057 return -1; 2058 } 2059 2060 return rc; 2061 } 2062 2063 static int 2064 ipmi_lan_alert(struct ipmi_intf * intf, int argc, char ** argv) 2065 { 2066 uint8_t alert; 2067 uint8_t channel = 1; 2068 2069 if (argc < 1) { 2070 ipmi_lan_alert_print_usage(); 2071 ipmi_lan_alert_set_usage(); 2072 return (-1); 2073 } 2074 else if (strncasecmp(argv[0], "help", 4) == 0) { 2075 ipmi_lan_alert_print_usage(); 2076 ipmi_lan_alert_set_usage(); 2077 return 0; 2078 } 2079 2080 /* alert print [channel] [alert] */ 2081 if (strncasecmp(argv[0], "print", 5) == 0) { 2082 if (argc < 2) { 2083 channel = find_lan_channel(intf, 1); 2084 if (!is_lan_channel(intf, channel)) { 2085 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2086 return -1; 2087 } 2088 return ipmi_lan_alert_print_all(intf, channel); 2089 } 2090 2091 if (strncasecmp(argv[1], "help", 4) == 0) { 2092 ipmi_lan_alert_print_usage(); 2093 return 0; 2094 } 2095 2096 if (str2uchar(argv[1], &channel) != 0) { 2097 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2098 return (-1); 2099 } 2100 if (!is_lan_channel(intf, channel)) { 2101 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2102 return -1; 2103 } 2104 2105 if (argc < 3) 2106 return ipmi_lan_alert_print_all(intf, channel); 2107 2108 if (str2uchar(argv[2], &alert) != 0) { 2109 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2110 return (-1); 2111 } 2112 if (is_alert_destination(intf, channel, alert) == 0) { 2113 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2114 return -1; 2115 } 2116 return ipmi_lan_alert_print(intf, channel, alert); 2117 } 2118 2119 /* alert set <channel> <alert> [option] */ 2120 if (strncasecmp(argv[0], "set", 3) == 0) { 2121 if (argc < 5) { 2122 ipmi_lan_alert_set_usage(); 2123 return (-1); 2124 } 2125 else if (strncasecmp(argv[1], "help", 4) == 0) { 2126 ipmi_lan_alert_set_usage(); 2127 return 0; 2128 } 2129 2130 if (str2uchar(argv[1], &channel) != 0) { 2131 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2132 return (-1); 2133 } 2134 if (!is_lan_channel(intf, channel)) { 2135 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2136 return -1; 2137 } 2138 2139 if (str2uchar(argv[2], &alert) != 0) { 2140 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2141 return (-1); 2142 } 2143 if (is_alert_destination(intf, channel, alert) == 0) { 2144 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2145 return -1; 2146 } 2147 2148 return ipmi_lan_alert_set(intf, channel, alert, argc-3, &(argv[3])); 2149 } 2150 2151 return 0; 2152 } 2153 2154 2155 static int 2156 ipmi_lan_stats_get(struct ipmi_intf * intf, uint8_t chan) 2157 { 2158 int rc = 0; 2159 struct ipmi_rs * rsp; 2160 struct ipmi_rq req; 2161 uint8_t msg_data[2]; 2162 uint16_t statsTemp; 2163 2164 if (!is_lan_channel(intf, chan)) { 2165 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2166 return -1; 2167 } 2168 2169 /* From here, we are ready to get the stats */ 2170 2171 msg_data[0] = chan; 2172 msg_data[1] = 0; /* Don't clear */ 2173 2174 memset(&req, 0, sizeof(req)); 2175 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2176 req.msg.cmd = IPMI_LAN_GET_STAT; 2177 req.msg.data = msg_data; 2178 req.msg.data_len = 2; 2179 2180 rsp = intf->sendrecv(intf, &req); 2181 if (rsp == NULL) { 2182 lprintf(LOG_ERR, "Get LAN Stats command failed"); 2183 return (-1); 2184 } 2185 2186 if (rsp->ccode > 0) { 2187 lprintf(LOG_ERR, "Get LAN Stats command failed: %s", 2188 val2str(rsp->ccode, completion_code_vals)); 2189 return (-1); 2190 } 2191 2192 if (verbose > 1) { 2193 uint8_t counter; 2194 printf("--- Rx Stats ---\n"); 2195 for (counter=0; counter<18; counter+=2) { 2196 printf("%02X", *(rsp->data + counter)); 2197 printf(" %02X - ", *(rsp->data + counter+1)); 2198 } 2199 printf("\n"); 2200 } 2201 2202 statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1)); 2203 printf("IP Rx Packet : %d\n", statsTemp); 2204 2205 statsTemp = ((*(rsp->data + 2)) << 8) | (*(rsp->data + 3)); 2206 printf("IP Rx Header Errors : %u\n", statsTemp); 2207 2208 statsTemp = ((*(rsp->data + 4)) << 8) | (*(rsp->data + 5)); 2209 printf("IP Rx Address Errors : %u\n", statsTemp); 2210 2211 statsTemp = ((*(rsp->data + 6)) << 8) | (*(rsp->data + 7)); 2212 printf("IP Rx Fragmented : %u\n", statsTemp); 2213 2214 statsTemp = ((*(rsp->data + 8)) << 8) | (*(rsp->data + 9)); 2215 printf("IP Tx Packet : %u\n", statsTemp); 2216 2217 statsTemp = ((*(rsp->data +10)) << 8) | (*(rsp->data +11)); 2218 printf("UDP Rx Packet : %u\n", statsTemp); 2219 2220 statsTemp = ((*(rsp->data + 12)) << 8) | (*(rsp->data + 13)); 2221 printf("RMCP Rx Valid : %u\n", statsTemp); 2222 2223 statsTemp = ((*(rsp->data + 14)) << 8) | (*(rsp->data + 15)); 2224 printf("UDP Proxy Packet Received : %u\n", statsTemp); 2225 2226 statsTemp = ((*(rsp->data + 16)) << 8) | (*(rsp->data + 17)); 2227 printf("UDP Proxy Packet Dropped : %u\n", statsTemp); 2228 2229 return rc; 2230 } 2231 2232 2233 static int 2234 ipmi_lan_stats_clear(struct ipmi_intf * intf, uint8_t chan) 2235 { 2236 int rc = 0; 2237 struct ipmi_rs * rsp; 2238 struct ipmi_rq req; 2239 uint8_t msg_data[2]; 2240 2241 if (!is_lan_channel(intf, chan)) { 2242 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2243 return -1; 2244 } 2245 2246 /* From here, we are ready to get the stats */ 2247 msg_data[0] = chan; 2248 msg_data[1] = 1; /* Clear */ 2249 2250 memset(&req, 0, sizeof(req)); 2251 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2252 req.msg.cmd = IPMI_LAN_GET_STAT; 2253 req.msg.data = msg_data; 2254 req.msg.data_len = 2; 2255 2256 rsp = intf->sendrecv(intf, &req); 2257 if (rsp == NULL) { 2258 lprintf(LOG_INFO, "Get LAN Stats command failed"); 2259 return (-1); 2260 } 2261 2262 if (rsp->ccode > 0) { 2263 lprintf(LOG_INFO, "Get LAN Stats command failed: %s", 2264 val2str(rsp->ccode, completion_code_vals)); 2265 return (-1); 2266 } 2267 2268 return rc; 2269 } 2270 2271 2272 /* 2273 * print_lan_usage 2274 */ 2275 static void 2276 print_lan_usage(void) 2277 { 2278 lprintf(LOG_NOTICE, "LAN Commands:"); 2279 lprintf(LOG_NOTICE, " print [<channel number>]"); 2280 lprintf(LOG_NOTICE, " set <channel number> <command> <parameter>"); 2281 lprintf(LOG_NOTICE, " alert print <channel number> <alert destination>"); 2282 lprintf(LOG_NOTICE, " alert set <channel number> <alert destination> <command> <parameter>"); 2283 lprintf(LOG_NOTICE, " stats get [<channel number>]"); 2284 lprintf(LOG_NOTICE, " stats clear [<channel number>]"); 2285 } 2286 2287 2288 int 2289 ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv) 2290 { 2291 int rc = 0; 2292 uint8_t chan = 0; 2293 2294 if (argc == 0) { 2295 print_lan_usage(); 2296 return (-1); 2297 } else if (strncmp(argv[0], "help", 4) == 0) { 2298 print_lan_usage(); 2299 return 0; 2300 } 2301 2302 chan = find_lan_channel(intf, 1); 2303 2304 if (strncmp(argv[0], "printconf", 9) == 0 || 2305 strncmp(argv[0], "print", 5) == 0) 2306 { 2307 if (argc > 2) { 2308 print_lan_usage(); 2309 return (-1); 2310 } else if (argc == 2) { 2311 if (str2uchar(argv[1], &chan) != 0) { 2312 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2313 return (-1); 2314 } 2315 } 2316 if (!is_lan_channel(intf, chan)) { 2317 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2318 return (-1); 2319 } 2320 rc = ipmi_lan_print(intf, chan); 2321 } else if (strncmp(argv[0], "set", 3) == 0) { 2322 rc = ipmi_lan_set(intf, argc-1, &(argv[1])); 2323 } else if (strncmp(argv[0], "alert", 5) == 0) { 2324 rc = ipmi_lan_alert(intf, argc-1, &(argv[1])); 2325 } else if (strncmp(argv[0], "stats", 5) == 0) { 2326 if (argc < 2) { 2327 print_lan_usage(); 2328 return (-1); 2329 } else if (argc == 3) { 2330 if (str2uchar(argv[2], &chan) != 0) { 2331 lprintf(LOG_ERR, "Invalid channel: %s", argv[2]); 2332 return (-1); 2333 } 2334 } 2335 if (!is_lan_channel(intf, chan)) { 2336 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2337 return (-1); 2338 } 2339 if (strncmp(argv[1], "get", 3) == 0) { 2340 rc = ipmi_lan_stats_get(intf, chan); 2341 } else if (strncmp(argv[1], "clear", 5) == 0) { 2342 rc = ipmi_lan_stats_clear(intf, chan); 2343 } else { 2344 print_lan_usage(); 2345 return (-1); 2346 } 2347 } else { 2348 lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]); 2349 return (-1); 2350 } 2351 return rc; 2352 } 2353