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 memset(buf, 0, 9); 1202 for (i = 0; i < 15; ++i) 1203 { 1204 unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN; 1205 1206 switch (arg[i]) 1207 { 1208 case 'X': 1209 priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */ 1210 break; 1211 case 'c': 1212 priv_level = IPMI_SESSION_PRIV_CALLBACK; /* 1 */ 1213 break; 1214 case 'u': 1215 priv_level = IPMI_SESSION_PRIV_USER; /* 2 */ 1216 break; 1217 case 'o': 1218 priv_level = IPMI_SESSION_PRIV_OPERATOR; /* 3 */ 1219 break; 1220 case 'a': 1221 priv_level = IPMI_SESSION_PRIV_ADMIN; /* 4 */ 1222 break; 1223 case 'O': 1224 priv_level = IPMI_SESSION_PRIV_OEM; /* 5 */ 1225 break; 1226 default: 1227 lprintf(LOG_ERR, "Invalid privilege specification char: %c", 1228 arg[i]); 1229 ret = -1; 1230 break; 1231 } 1232 1233 if (ret != 0) 1234 break; 1235 else 1236 { 1237 if ((i + 1) % 2) 1238 { 1239 // Odd number cipher suites will be in the LSN 1240 buf[1 + (i / 2)] += priv_level; 1241 } 1242 else 1243 { 1244 // Even number cipher suites will be in the MSN 1245 buf[1 + (i / 2)] += (priv_level << 4); 1246 } 1247 } 1248 } 1249 1250 return ret; 1251 } 1252 1253 1254 static int 1255 get_cmdline_ipaddr(char * arg, uint8_t * buf) 1256 { 1257 uint32_t ip1, ip2, ip3, ip4; 1258 if (sscanf(arg, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) { 1259 lprintf(LOG_ERR, "Invalid IP address: %s", arg); 1260 return -1; 1261 } 1262 buf[0] = (uint8_t)ip1; 1263 buf[1] = (uint8_t)ip2; 1264 buf[2] = (uint8_t)ip3; 1265 buf[3] = (uint8_t)ip4; 1266 return 0; 1267 } 1268 1269 static void ipmi_lan_set_usage(void) 1270 { 1271 lprintf(LOG_NOTICE, "\nusage: lan set <channel> <command> <parameter>\n"); 1272 lprintf(LOG_NOTICE, "LAN set command/parameter options:"); 1273 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set channel IP address"); 1274 lprintf(LOG_NOTICE, " netmask <x.x.x.x> Set channel IP netmask"); 1275 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set channel MAC address"); 1276 lprintf(LOG_NOTICE, " defgw ipaddr <x.x.x.x> Set default gateway IP address"); 1277 lprintf(LOG_NOTICE, " defgw macaddr <x:x:x:x:x:x> Set default gateway MAC address"); 1278 lprintf(LOG_NOTICE, " bakgw ipaddr <x.x.x.x> Set backup gateway IP address"); 1279 lprintf(LOG_NOTICE, " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address"); 1280 lprintf(LOG_NOTICE, " password <password> Set session password for this channel"); 1281 lprintf(LOG_NOTICE, " snmp <community string> Set SNMP public community string"); 1282 lprintf(LOG_NOTICE, " user Enable default user for this channel"); 1283 lprintf(LOG_NOTICE, " access <on|off> Enable or disable access to this channel"); 1284 lprintf(LOG_NOTICE, " alert <on|off> Enable or disable PEF alerting for this channel"); 1285 lprintf(LOG_NOTICE, " arp respond <on|off> Enable or disable BMC ARP responding"); 1286 lprintf(LOG_NOTICE, " arp generate <on|off> Enable or disable BMC gratuitous ARP generation"); 1287 lprintf(LOG_NOTICE, " arp interval <seconds> Set gratuitous ARP generation interval"); 1288 lprintf(LOG_NOTICE, " vlan id <off|<id>> Disable or enable VLAN and set ID (1-4094)"); 1289 lprintf(LOG_NOTICE, " vlan priority <priority> Set vlan priority (0-7)"); 1290 lprintf(LOG_NOTICE, " auth <level> <type,..> Set channel authentication types"); 1291 lprintf(LOG_NOTICE, " level = CALLBACK, USER, OPERATOR, ADMIN"); 1292 lprintf(LOG_NOTICE, " type = NONE, MD2, MD5, PASSWORD, OEM"); 1293 lprintf(LOG_NOTICE, " ipsrc <source> Set IP Address source"); 1294 lprintf(LOG_NOTICE, " none = unspecified source"); 1295 lprintf(LOG_NOTICE, " static = address manually configured to be static"); 1296 lprintf(LOG_NOTICE, " dhcp = address obtained by BMC running DHCP"); 1297 lprintf(LOG_NOTICE, " bios = address loaded by BIOS or system software"); 1298 lprintf(LOG_NOTICE, " cipher_privs XXXXXXXXXXXXXXX Set RMCP+ cipher suite privilege levels"); 1299 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1300 lprintf(LOG_NOTICE, " c = CALLBACK"); 1301 lprintf(LOG_NOTICE, " u = USER"); 1302 lprintf(LOG_NOTICE, " o = OPERATOR"); 1303 lprintf(LOG_NOTICE, " a = ADMIN"); 1304 lprintf(LOG_NOTICE, " O = OEM\n"); 1305 } 1306 1307 static void 1308 ipmi_lan_set_vlan_usage(void) 1309 { 1310 lprintf(LOG_NOTICE, 1311 "lan set <channel> vlan id <id>\n" 1312 "lan set <channel> vlan id off\n" 1313 "lan set <channel> vlan priority <priority>\n"); 1314 } 1315 1316 static int 1317 ipmi_lan_set_vlan_id(struct ipmi_intf * intf, uint8_t chan, char *string) 1318 { 1319 uint8_t data[2]; 1320 int rc; 1321 1322 if (string == NULL) { 1323 data[0] = 0; 1324 data[1] = 0; 1325 } 1326 else { 1327 int id = 0; 1328 if (str2int(string, &id) != 0) { 1329 lprintf(LOG_ERR, "Given VLAN ID '%s' is invalid.", string); 1330 return (-1); 1331 } 1332 1333 if (id < 1 || id > 4094) { 1334 lprintf(LOG_NOTICE, "vlan id must be between 1 and 4094."); 1335 return -1; 1336 } 1337 else { 1338 data[0] = (uint8_t)id; 1339 data[1] = (uint8_t)(id >> 8) | 0x80; 1340 } 1341 } 1342 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_ID, data, 2); 1343 return rc; 1344 } 1345 1346 static int 1347 ipmi_lan_set_vlan_priority(struct ipmi_intf * intf, uint8_t chan, char *string) 1348 { 1349 uint8_t data; 1350 int rc; 1351 int priority = 0; 1352 if (str2int(string, &priority) != 0) { 1353 lprintf(LOG_ERR, "Given VLAN priority '%s' is invalid.", string); 1354 return (-1); 1355 } 1356 1357 if (priority < 0 || priority > 7) { 1358 lprintf(LOG_NOTICE, "vlan priority must be between 0 and 7."); 1359 return -1; 1360 } 1361 data = (uint8_t)priority; 1362 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY, &data, 1); 1363 return rc; 1364 } 1365 1366 static int 1367 ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) 1368 { 1369 uint8_t data[32]; 1370 uint8_t chan; 1371 int rc = 0; 1372 1373 if (argc < 2) { 1374 ipmi_lan_set_usage(); 1375 return (-1); 1376 } 1377 1378 if (strncmp(argv[0], "help", 4) == 0 || 1379 strncmp(argv[1], "help", 4) == 0) { 1380 ipmi_lan_set_usage(); 1381 return 0; 1382 } 1383 1384 if (str2uchar(argv[0], &chan) != 0) { 1385 lprintf(LOG_ERR, "Invalid channel: %s", argv[0]); 1386 return (-1); 1387 } 1388 1389 /* find type of channel and only accept 802.3 LAN */ 1390 if (!is_lan_channel(intf, chan)) { 1391 lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan); 1392 ipmi_lan_set_usage(); 1393 return -1; 1394 } 1395 1396 memset(&data, 0, sizeof(data)); 1397 1398 /* set user access */ 1399 if (strncmp(argv[1], "user", 4) == 0) { 1400 rc = ipmi_set_user_access(intf, chan, 1); 1401 } 1402 /* set channel access mode */ 1403 else if (strncmp(argv[1], "access", 6) == 0) { 1404 if (argc < 3) { 1405 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1406 return (-1); 1407 } 1408 else if (strncmp(argv[2], "help", 4) == 0) { 1409 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1410 return 0; 1411 } 1412 else if (strncmp(argv[2], "on", 2) == 0) { 1413 rc = ipmi_set_channel_access(intf, chan, 1); 1414 } 1415 else if (strncmp(argv[2], "off", 3) == 0) { 1416 rc = ipmi_set_channel_access(intf, chan, 0); 1417 } 1418 else { 1419 lprintf(LOG_NOTICE, "lan set access <on|off>"); 1420 return (-1); 1421 } 1422 } 1423 /* set ARP control */ 1424 else if (strncmp(argv[1], "arp", 3) == 0) { 1425 if (argc < 3) { 1426 lprintf(LOG_NOTICE, 1427 "lan set <channel> arp respond <on|off>\n" 1428 "lan set <channel> arp generate <on|off>\n" 1429 "lan set <channel> arp interval <seconds>\n\n" 1430 "example: lan set 7 arp gratuitous off\n"); 1431 return (-1); 1432 } 1433 else if (strncmp(argv[2], "help", 4) == 0) { 1434 lprintf(LOG_NOTICE, 1435 "lan set <channel> arp respond <on|off>\n" 1436 "lan set <channel> arp generate <on|off>\n" 1437 "lan set <channel> arp interval <seconds>\n\n" 1438 "example: lan set 7 arp gratuitous off\n"); 1439 return 0; 1440 } 1441 else if (strncmp(argv[2], "interval", 8) == 0) { 1442 uint8_t interval = 0; 1443 if (str2uchar(argv[3], &interval) != 0) { 1444 lprintf(LOG_ERR, "Given ARP interval '%s' is invalid.", argv[3]); 1445 return (-1); 1446 } 1447 rc = lan_set_arp_interval(intf, chan, interval); 1448 } 1449 else if (strncmp(argv[2], "generate", 8) == 0) { 1450 if (argc < 4) { 1451 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1452 return (-1); 1453 } 1454 else if (strncmp(argv[3], "on", 2) == 0) 1455 rc = lan_set_arp_generate(intf, chan, 1); 1456 else if (strncmp(argv[3], "off", 3) == 0) 1457 rc = lan_set_arp_generate(intf, chan, 0); 1458 else { 1459 lprintf(LOG_NOTICE, "lan set <channel> arp generate <on|off>"); 1460 return (-1); 1461 } 1462 } 1463 else if (strncmp(argv[2], "respond", 7) == 0) { 1464 if (argc < 4) { 1465 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1466 return (-1); 1467 } 1468 else if (strncmp(argv[3], "on", 2) == 0) 1469 rc = lan_set_arp_respond(intf, chan, 1); 1470 else if (strncmp(argv[3], "off", 3) == 0) 1471 rc = lan_set_arp_respond(intf, chan, 0); 1472 else { 1473 lprintf(LOG_NOTICE, "lan set <channel> arp respond <on|off>"); 1474 return (-1); 1475 } 1476 } 1477 else { 1478 lprintf(LOG_NOTICE, 1479 "lan set <channel> arp respond <on|off>\n" 1480 "lan set <channel> arp generate <on|off>\n" 1481 "lan set <channel> arp interval <seconds>\n"); 1482 return (-1); 1483 } 1484 } 1485 /* set authentication types */ 1486 else if (strncmp(argv[1], "auth", 4) == 0) { 1487 if (argc < 3) { 1488 lprintf(LOG_NOTICE, 1489 "lan set <channel> auth <level> <type,type,...>\n" 1490 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1491 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1492 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1493 return (-1); 1494 } 1495 else if (strncmp(argv[2], "help", 4) == 0) { 1496 lprintf(LOG_NOTICE, 1497 "lan set <channel> auth <level> <type,type,...>\n" 1498 " level = CALLBACK, USER, OPERATOR, ADMIN\n" 1499 " types = NONE, MD2, MD5, PASSWORD, OEM\n" 1500 "example: lan set 7 auth ADMIN PASSWORD,MD5\n"); 1501 return 0; 1502 } else { 1503 rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]); 1504 } 1505 } 1506 /* ip address source */ 1507 else if (strncmp(argv[1], "ipsrc", 5) == 0) { 1508 if (argc < 3) { 1509 lprintf(LOG_NOTICE, 1510 "lan set <channel> ipsrc <source>\n" 1511 " none = unspecified\n" 1512 " static = static address (manually configured)\n" 1513 " dhcp = address obtained by BMC running DHCP\n" 1514 " bios = address loaded by BIOS or system software\n"); 1515 return (-1); 1516 } 1517 else if (strncmp(argv[2], "help", 4) == 0) { 1518 lprintf(LOG_NOTICE, 1519 "lan set <channel> ipsrc <source>\n" 1520 " none = unspecified\n" 1521 " static = static address (manually configured)\n" 1522 " dhcp = address obtained by BMC running DHCP\n" 1523 " bios = address loaded by BIOS or system software\n"); 1524 return 0; 1525 } 1526 else if (strncmp(argv[2], "none", 4) == 0) 1527 data[0] = 0; 1528 else if (strncmp(argv[2], "static", 5) == 0) 1529 data[0] = 1; 1530 else if (strncmp(argv[2], "dhcp", 4) == 0) 1531 data[0] = 2; 1532 else if (strncmp(argv[2], "bios", 4) == 0) 1533 data[0] = 3; 1534 else { 1535 lprintf(LOG_NOTICE, 1536 "lan set <channel> ipsrc <source>\n" 1537 " none = unspecified\n" 1538 " static = static address (manually configured)\n" 1539 " dhcp = address obtained by BMC running DHCP\n" 1540 " bios = address loaded by BIOS or system software\n"); 1541 return -1; 1542 } 1543 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC, data, 1); 1544 } 1545 /* session password 1546 * not strictly a lan setting, but its used for lan connections */ 1547 else if (strncmp(argv[1], "password", 8) == 0) { 1548 rc = ipmi_lan_set_password(intf, 1, (uint8_t *)argv[2]); 1549 } 1550 /* snmp community string */ 1551 else if (strncmp(argv[1], "snmp", 4) == 0) { 1552 if (argc < 3) { 1553 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1554 return (-1); 1555 } 1556 else if (strncmp(argv[2], "help", 4) == 0) { 1557 lprintf(LOG_NOTICE, "lan set <channel> snmp <community string>"); 1558 return 0; 1559 } else { 1560 memcpy(data, argv[2], __min(strlen(argv[2]), 18)); 1561 printf("Setting LAN %s to %s\n", 1562 ipmi_lan_params[IPMI_LANP_SNMP_STRING].desc, data); 1563 rc = set_lan_param(intf, chan, IPMI_LANP_SNMP_STRING, data, 18); 1564 } 1565 } 1566 /* ip address */ 1567 else if (strncmp(argv[1], "ipaddr", 6) == 0) { 1568 if(argc != 3) 1569 { 1570 ipmi_lan_set_usage(); 1571 return -1; 1572 } 1573 rc = get_cmdline_ipaddr(argv[2], data); 1574 if (rc == 0) { 1575 printf("Setting LAN %s to %d.%d.%d.%d\n", 1576 ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, 1577 data[0], data[1], data[2], data[3]); 1578 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); 1579 } 1580 } 1581 /* network mask */ 1582 else if (strncmp(argv[1], "netmask", 7) == 0) { 1583 if(argc != 3) 1584 { 1585 ipmi_lan_set_usage(); 1586 return -1; 1587 } 1588 rc = get_cmdline_ipaddr(argv[2], data); 1589 if (rc == 0) { 1590 printf("Setting LAN %s to %d.%d.%d.%d\n", 1591 ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, 1592 data[0], data[1], data[2], data[3]); 1593 rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); 1594 } 1595 } 1596 /* mac address */ 1597 else if (strncmp(argv[1], "macaddr", 7) == 0) { 1598 if(argc != 3) 1599 { 1600 ipmi_lan_set_usage(); 1601 return -1; 1602 } 1603 rc = get_cmdline_macaddr(argv[2], data); 1604 if (rc == 0) { 1605 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1606 ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, 1607 data[0], data[1], data[2], data[3], data[4], data[5]); 1608 rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); 1609 } 1610 } 1611 /* default gateway settings */ 1612 else if (strncmp(argv[1], "defgw", 5) == 0) { 1613 if (argc < 4) { 1614 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1615 return (-1); 1616 } 1617 else if (strncmp(argv[2], "help", 4) == 0) { 1618 lprintf(LOG_NOTICE, "LAN set default gateway Commands: ipaddr, macaddr"); 1619 return 0; 1620 } 1621 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1622 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1623 printf("Setting LAN %s to %d.%d.%d.%d\n", 1624 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_IP].desc, 1625 data[0], data[1], data[2], data[3]); 1626 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4); 1627 } 1628 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1629 (get_cmdline_macaddr(argv[3], data) == 0)) { 1630 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1631 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc, 1632 data[0], data[1], data[2], data[3], data[4], data[5]); 1633 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6); 1634 } 1635 else { 1636 ipmi_lan_set_usage(); 1637 return -1; 1638 } 1639 } 1640 /* backup gateway settings */ 1641 else if (strncmp(argv[1], "bakgw", 5) == 0) { 1642 if (argc < 4) { 1643 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1644 return (-1); 1645 } 1646 else if (strncmp(argv[2], "help", 4) == 0) { 1647 lprintf(LOG_NOTICE, "LAN set backup gateway commands: ipaddr, macaddr"); 1648 return 0; 1649 } 1650 else if ((strncmp(argv[2], "ipaddr", 5) == 0) && 1651 (get_cmdline_ipaddr(argv[3], data) == 0)) { 1652 printf("Setting LAN %s to %d.%d.%d.%d\n", 1653 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_IP].desc, 1654 data[0], data[1], data[2], data[3]); 1655 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4); 1656 } 1657 else if ((strncmp(argv[2], "macaddr", 7) == 0) && 1658 (get_cmdline_macaddr(argv[3], data) == 0)) { 1659 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", 1660 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc, 1661 data[0], data[1], data[2], data[3], data[4], data[5]); 1662 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6); 1663 } 1664 else { 1665 ipmi_lan_set_usage(); 1666 return -1; 1667 } 1668 } 1669 else if (strncasecmp(argv[1], "vlan", 4) == 0) { 1670 if (argc < 4) { 1671 ipmi_lan_set_vlan_usage(); 1672 return (-1); 1673 } 1674 else if (strncmp(argv[2], "help", 4) == 0) { 1675 ipmi_lan_set_vlan_usage(); 1676 return 0; 1677 } 1678 else if (strncasecmp(argv[2], "id", 2) == 0) { 1679 if (strncasecmp(argv[3], "off", 3) == 0) { 1680 ipmi_lan_set_vlan_id(intf, chan, NULL); 1681 } 1682 else { 1683 ipmi_lan_set_vlan_id(intf, chan, argv[3]); 1684 } 1685 } 1686 else if (strncasecmp(argv[2], "priority", 8) == 0) { 1687 ipmi_lan_set_vlan_priority(intf, chan, argv[3]); 1688 } 1689 else { 1690 ipmi_lan_set_vlan_usage(); 1691 return (-1); 1692 } 1693 } 1694 /* set PEF alerting on or off */ 1695 else if (strncasecmp(argv[1], "alert", 5) == 0) { 1696 if (argc < 3) { 1697 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1698 return (-1); 1699 } 1700 else if (strncasecmp(argv[2], "on", 2) == 0 || 1701 strncasecmp(argv[2], "enable", 6) == 0) { 1702 printf("Enabling PEF alerts for LAN channel %d\n", chan); 1703 rc = ipmi_set_alert_enable(intf, chan, 1); 1704 } 1705 else if (strncasecmp(argv[2], "off", 3) == 0 || 1706 strncasecmp(argv[2], "disable", 7) == 0) { 1707 printf("Disabling PEF alerts for LAN channel %d\n", chan); 1708 rc = ipmi_set_alert_enable(intf, chan, 0); 1709 } 1710 else { 1711 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'"); 1712 return 0; 1713 } 1714 } 1715 /* RMCP+ cipher suite privilege levels */ 1716 else if (strncmp(argv[1], "cipher_privs", 12) == 0) 1717 { 1718 if (argc != 3) { 1719 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1720 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1721 lprintf(LOG_NOTICE, " c = CALLBACK"); 1722 lprintf(LOG_NOTICE, " u = USER"); 1723 lprintf(LOG_NOTICE, " o = OPERATOR"); 1724 lprintf(LOG_NOTICE, " a = ADMIN"); 1725 lprintf(LOG_NOTICE, " O = OEM\n"); 1726 return (-1); 1727 } 1728 else if ((strncmp(argv[2], "help", 4) == 0) || 1729 get_cmdline_cipher_suite_priv_data(argv[2], data)) 1730 { 1731 lprintf(LOG_NOTICE, "lan set <channel> cipher_privs XXXXXXXXXXXXXXX"); 1732 lprintf(LOG_NOTICE, " X = Cipher Suite Unused"); 1733 lprintf(LOG_NOTICE, " c = CALLBACK"); 1734 lprintf(LOG_NOTICE, " u = USER"); 1735 lprintf(LOG_NOTICE, " o = OPERATOR"); 1736 lprintf(LOG_NOTICE, " a = ADMIN"); 1737 lprintf(LOG_NOTICE, " O = OEM\n"); 1738 return 0; 1739 } 1740 else 1741 { 1742 rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9); 1743 } 1744 } 1745 else { 1746 ipmi_lan_set_usage(); 1747 return (-1); 1748 } 1749 1750 return rc; 1751 } 1752 1753 1754 static int 1755 is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1756 { 1757 struct lan_param * p; 1758 1759 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1760 if (p == NULL) 1761 return 0; 1762 if (p->data == NULL) 1763 return 0; 1764 1765 if (alert <= (p->data[0] & 0xf)) 1766 return 1; 1767 else 1768 return 0; 1769 } 1770 1771 static int 1772 ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) 1773 { 1774 # define PTYPE_LEN 4 1775 # define PADDR_LEN 13 1776 struct lan_param *lp_ptr = NULL; 1777 int isack = 0; 1778 uint8_t ptype[PTYPE_LEN]; 1779 uint8_t paddr[PADDR_LEN]; 1780 1781 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert); 1782 if (lp_ptr == NULL || lp_ptr->data == NULL 1783 || lp_ptr->data_len < PTYPE_LEN) { 1784 return (-1); 1785 } 1786 memcpy(ptype, lp_ptr->data, PTYPE_LEN); 1787 1788 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert); 1789 if (lp_ptr == NULL || lp_ptr->data == NULL 1790 || lp_ptr->data_len < PADDR_LEN) { 1791 return (-1); 1792 } 1793 memcpy(paddr, lp_ptr->data, PADDR_LEN); 1794 1795 printf("%-24s: %d\n", "Alert Destination", 1796 ptype[0]); 1797 1798 if (ptype[1] & 0x80) { 1799 isack = 1; 1800 } 1801 printf("%-24s: %s\n", "Alert Acknowledge", 1802 isack ? "Acknowledged" : "Unacknowledged"); 1803 1804 printf("%-24s: ", "Destination Type"); 1805 switch (ptype[1] & 0x7) { 1806 case 0: 1807 printf("PET Trap\n"); 1808 break; 1809 case 6: 1810 printf("OEM 1\n"); 1811 break; 1812 case 7: 1813 printf("OEM 2\n"); 1814 break; 1815 default: 1816 printf("Unknown\n"); 1817 break; 1818 } 1819 1820 printf("%-24s: %d\n", 1821 isack ? "Acknowledge Timeout" : "Retry Interval", 1822 ptype[2]); 1823 1824 printf("%-24s: %d\n", "Number of Retries", 1825 ptype[3] & 0x7); 1826 1827 if ((paddr[1] & 0xf0) != 0) { 1828 /* unknown address format */ 1829 printf("\n"); 1830 return 0; 1831 } 1832 1833 printf("%-24s: %s\n", "Alert Gateway", 1834 (paddr[2] & 1) ? "Backup" : "Default"); 1835 1836 printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address", 1837 paddr[3], paddr[4], paddr[5], paddr[6]); 1838 1839 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address", 1840 paddr[7], paddr[8], paddr[9], 1841 paddr[10], paddr[11], paddr[12]); 1842 1843 printf("\n"); 1844 return 0; 1845 } 1846 1847 static int 1848 ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel) 1849 { 1850 int j, ndest; 1851 struct lan_param * p; 1852 1853 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); 1854 if (p == NULL) 1855 return -1; 1856 if (p->data == NULL) 1857 return -1; 1858 ndest = p->data[0] & 0xf; 1859 1860 for (j=0; j<=ndest; j++) { 1861 ipmi_lan_alert_print(intf, channel, j); 1862 } 1863 1864 return 0; 1865 } 1866 1867 static void 1868 ipmi_lan_alert_print_usage(void) 1869 { 1870 lprintf(LOG_NOTICE, "\nusage: lan alert print [channel number] [alert destination]\n"); 1871 lprintf(LOG_NOTICE, "Default will print all alerts for the first found LAN channel"); 1872 } 1873 1874 static void 1875 ipmi_lan_alert_set_usage(void) 1876 { 1877 lprintf(LOG_NOTICE, "\nusage: lan alert set <channel number> <alert destination> <command> <parameter>\n"); 1878 lprintf(LOG_NOTICE, " Command/parameter options:\n"); 1879 lprintf(LOG_NOTICE, " ipaddr <x.x.x.x> Set alert IP address"); 1880 lprintf(LOG_NOTICE, " macaddr <x:x:x:x:x:x> Set alert MAC address"); 1881 lprintf(LOG_NOTICE, " gateway <default|backup> Set channel gateway to use for alerts"); 1882 lprintf(LOG_NOTICE, " ack <on|off> Set Alert Acknowledge on or off"); 1883 lprintf(LOG_NOTICE, " type <pet|oem1|oem2> Set destination type as PET or OEM"); 1884 lprintf(LOG_NOTICE, " time <seconds> Set ack timeout or unack retry interval"); 1885 lprintf(LOG_NOTICE, " retry <number> Set number of alert retries"); 1886 lprintf(LOG_NOTICE, ""); 1887 } 1888 1889 static int 1890 ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert, 1891 int argc, char ** argv) 1892 { 1893 struct lan_param * p; 1894 uint8_t data[32], temp[32]; 1895 int rc = 0; 1896 1897 if (argc < 2) { 1898 ipmi_lan_alert_set_usage(); 1899 return (-1); 1900 } 1901 1902 if (strncmp(argv[0], "help", 4) == 0 || 1903 strncmp(argv[1], "help", 4) == 0) { 1904 ipmi_lan_alert_set_usage(); 1905 return 0; 1906 } 1907 1908 memset(data, 0, sizeof(data)); 1909 memset(temp, 0, sizeof(temp)); 1910 1911 /* alert destination ip address */ 1912 if (strncasecmp(argv[0], "ipaddr", 6) == 0 && 1913 (get_cmdline_ipaddr(argv[1], temp) == 0)) { 1914 /* get current parameter */ 1915 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1916 if (p == NULL) { 1917 return (-1); 1918 } 1919 memcpy(data, p->data, p->data_len); 1920 /* set new ipaddr */ 1921 memcpy(data+3, temp, 4); 1922 printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert, 1923 data[3], data[4], data[5], data[6]); 1924 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1925 } 1926 /* alert destination mac address */ 1927 else if (strncasecmp(argv[0], "macaddr", 7) == 0 && 1928 (get_cmdline_macaddr(argv[1], temp) == 0)) { 1929 /* get current parameter */ 1930 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1931 if (p == NULL) { 1932 return (-1); 1933 } 1934 memcpy(data, p->data, p->data_len); 1935 /* set new macaddr */ 1936 memcpy(data+7, temp, 6); 1937 printf("Setting LAN Alert %d MAC Address to " 1938 "%02x:%02x:%02x:%02x:%02x:%02x\n", alert, 1939 data[7], data[8], data[9], data[10], data[11], data[12]); 1940 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1941 } 1942 /* alert destination gateway selector */ 1943 else if (strncasecmp(argv[0], "gateway", 7) == 0) { 1944 /* get current parameter */ 1945 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert); 1946 if (p == NULL) { 1947 return (-1); 1948 } 1949 memcpy(data, p->data, p->data_len); 1950 1951 if (strncasecmp(argv[1], "def", 3) == 0 || 1952 strncasecmp(argv[1], "default", 7) == 0) { 1953 printf("Setting LAN Alert %d to use Default Gateway\n", alert); 1954 data[2] = 0; 1955 } 1956 else if (strncasecmp(argv[1], "bak", 3) == 0 || 1957 strncasecmp(argv[1], "backup", 6) == 0) { 1958 printf("Setting LAN Alert %d to use Backup Gateway\n", alert); 1959 data[2] = 1; 1960 } 1961 else { 1962 ipmi_lan_alert_set_usage(); 1963 return -1; 1964 } 1965 1966 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len); 1967 } 1968 /* alert acknowledgement */ 1969 else if (strncasecmp(argv[0], "ack", 3) == 0) { 1970 /* get current parameter */ 1971 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 1972 if (p == NULL) { 1973 return (-1); 1974 } 1975 memcpy(data, p->data, p->data_len); 1976 1977 if (strncasecmp(argv[1], "on", 2) == 0 || 1978 strncasecmp(argv[1], "yes", 3) == 0) { 1979 printf("Setting LAN Alert %d to Acknowledged\n", alert); 1980 data[1] |= 0x80; 1981 } 1982 else if (strncasecmp(argv[1], "off", 3) == 0 || 1983 strncasecmp(argv[1], "no", 2) == 0) { 1984 printf("Setting LAN Alert %d to Unacknowledged\n", alert); 1985 data[1] &= ~0x80; 1986 } 1987 else { 1988 ipmi_lan_alert_set_usage(); 1989 return -1; 1990 } 1991 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 1992 } 1993 /* alert destination type */ 1994 else if (strncasecmp(argv[0], "type", 4) == 0) { 1995 /* get current parameter */ 1996 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 1997 if (p == NULL) { 1998 return (-1); 1999 } 2000 memcpy(data, p->data, p->data_len); 2001 2002 if (strncasecmp(argv[1], "pet", 3) == 0) { 2003 printf("Setting LAN Alert %d destination to PET Trap\n", alert); 2004 data[1] &= ~0x07; 2005 } 2006 else if (strncasecmp(argv[1], "oem1", 4) == 0) { 2007 printf("Setting LAN Alert %d destination to OEM 1\n", alert); 2008 data[1] &= ~0x07; 2009 data[1] |= 0x06; 2010 } 2011 else if (strncasecmp(argv[1], "oem2", 4) == 0) { 2012 printf("Setting LAN Alert %d destination to OEM 2\n", alert); 2013 data[1] |= 0x07; 2014 } 2015 else { 2016 ipmi_lan_alert_set_usage(); 2017 return -1; 2018 } 2019 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2020 } 2021 /* alert acknowledge timeout or retry interval */ 2022 else if (strncasecmp(argv[0], "time", 4) == 0) { 2023 /* get current parameter */ 2024 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2025 if (p == NULL) { 2026 return (-1); 2027 } 2028 memcpy(data, p->data, p->data_len); 2029 2030 if (str2uchar(argv[1], &data[2]) != 0) { 2031 lprintf(LOG_ERR, "Invalid time: %s", argv[1]); 2032 return (-1); 2033 } 2034 printf("Setting LAN Alert %d timeout/retry to %d seconds\n", alert, data[2]); 2035 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2036 } 2037 /* number of retries */ 2038 else if (strncasecmp(argv[0], "retry", 5) == 0) { 2039 /* get current parameter */ 2040 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert); 2041 if (p == NULL) { 2042 return (-1); 2043 } 2044 memcpy(data, p->data, p->data_len); 2045 2046 if (str2uchar(argv[1], &data[3]) != 0) { 2047 lprintf(LOG_ERR, "Invalid retry: %s", argv[1]); 2048 return (-1); 2049 } 2050 data[3] = data[3] & 0x7; 2051 printf("Setting LAN Alert %d number of retries to %d\n", alert, data[3]); 2052 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len); 2053 } 2054 else { 2055 ipmi_lan_alert_set_usage(); 2056 return -1; 2057 } 2058 2059 return rc; 2060 } 2061 2062 static int 2063 ipmi_lan_alert(struct ipmi_intf * intf, int argc, char ** argv) 2064 { 2065 uint8_t alert; 2066 uint8_t channel = 1; 2067 2068 if (argc < 1) { 2069 ipmi_lan_alert_print_usage(); 2070 ipmi_lan_alert_set_usage(); 2071 return (-1); 2072 } 2073 else if (strncasecmp(argv[0], "help", 4) == 0) { 2074 ipmi_lan_alert_print_usage(); 2075 ipmi_lan_alert_set_usage(); 2076 return 0; 2077 } 2078 2079 /* alert print [channel] [alert] */ 2080 if (strncasecmp(argv[0], "print", 5) == 0) { 2081 if (argc < 2) { 2082 channel = find_lan_channel(intf, 1); 2083 if (!is_lan_channel(intf, channel)) { 2084 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2085 return -1; 2086 } 2087 return ipmi_lan_alert_print_all(intf, channel); 2088 } 2089 2090 if (strncasecmp(argv[1], "help", 4) == 0) { 2091 ipmi_lan_alert_print_usage(); 2092 return 0; 2093 } 2094 2095 if (str2uchar(argv[1], &channel) != 0) { 2096 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2097 return (-1); 2098 } 2099 if (!is_lan_channel(intf, channel)) { 2100 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2101 return -1; 2102 } 2103 2104 if (argc < 3) 2105 return ipmi_lan_alert_print_all(intf, channel); 2106 2107 if (str2uchar(argv[2], &alert) != 0) { 2108 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2109 return (-1); 2110 } 2111 if (is_alert_destination(intf, channel, alert) == 0) { 2112 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2113 return -1; 2114 } 2115 return ipmi_lan_alert_print(intf, channel, alert); 2116 } 2117 2118 /* alert set <channel> <alert> [option] */ 2119 if (strncasecmp(argv[0], "set", 3) == 0) { 2120 if (argc < 5) { 2121 ipmi_lan_alert_set_usage(); 2122 return (-1); 2123 } 2124 else if (strncasecmp(argv[1], "help", 4) == 0) { 2125 ipmi_lan_alert_set_usage(); 2126 return 0; 2127 } 2128 2129 if (str2uchar(argv[1], &channel) != 0) { 2130 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2131 return (-1); 2132 } 2133 if (!is_lan_channel(intf, channel)) { 2134 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel); 2135 return -1; 2136 } 2137 2138 if (str2uchar(argv[2], &alert) != 0) { 2139 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]); 2140 return (-1); 2141 } 2142 if (is_alert_destination(intf, channel, alert) == 0) { 2143 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert); 2144 return -1; 2145 } 2146 2147 return ipmi_lan_alert_set(intf, channel, alert, argc-3, &(argv[3])); 2148 } 2149 2150 return 0; 2151 } 2152 2153 2154 static int 2155 ipmi_lan_stats_get(struct ipmi_intf * intf, uint8_t chan) 2156 { 2157 int rc = 0; 2158 struct ipmi_rs * rsp; 2159 struct ipmi_rq req; 2160 uint8_t msg_data[2]; 2161 uint16_t statsTemp; 2162 2163 if (!is_lan_channel(intf, chan)) { 2164 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2165 return -1; 2166 } 2167 2168 /* From here, we are ready to get the stats */ 2169 2170 msg_data[0] = chan; 2171 msg_data[1] = 0; /* Don't clear */ 2172 2173 memset(&req, 0, sizeof(req)); 2174 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2175 req.msg.cmd = IPMI_LAN_GET_STAT; 2176 req.msg.data = msg_data; 2177 req.msg.data_len = 2; 2178 2179 rsp = intf->sendrecv(intf, &req); 2180 if (rsp == NULL) { 2181 lprintf(LOG_ERR, "Get LAN Stats command failed"); 2182 return (-1); 2183 } 2184 2185 if (rsp->ccode > 0) { 2186 lprintf(LOG_ERR, "Get LAN Stats command failed: %s", 2187 val2str(rsp->ccode, completion_code_vals)); 2188 return (-1); 2189 } 2190 2191 if (verbose > 1) { 2192 uint8_t counter; 2193 printf("--- Rx Stats ---\n"); 2194 for (counter=0; counter<18; counter+=2) { 2195 printf("%02X", *(rsp->data + counter)); 2196 printf(" %02X - ", *(rsp->data + counter+1)); 2197 } 2198 printf("\n"); 2199 } 2200 2201 statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1)); 2202 printf("IP Rx Packet : %d\n", statsTemp); 2203 2204 statsTemp = ((*(rsp->data + 2)) << 8) | (*(rsp->data + 3)); 2205 printf("IP Rx Header Errors : %u\n", statsTemp); 2206 2207 statsTemp = ((*(rsp->data + 4)) << 8) | (*(rsp->data + 5)); 2208 printf("IP Rx Address Errors : %u\n", statsTemp); 2209 2210 statsTemp = ((*(rsp->data + 6)) << 8) | (*(rsp->data + 7)); 2211 printf("IP Rx Fragmented : %u\n", statsTemp); 2212 2213 statsTemp = ((*(rsp->data + 8)) << 8) | (*(rsp->data + 9)); 2214 printf("IP Tx Packet : %u\n", statsTemp); 2215 2216 statsTemp = ((*(rsp->data +10)) << 8) | (*(rsp->data +11)); 2217 printf("UDP Rx Packet : %u\n", statsTemp); 2218 2219 statsTemp = ((*(rsp->data + 12)) << 8) | (*(rsp->data + 13)); 2220 printf("RMCP Rx Valid : %u\n", statsTemp); 2221 2222 statsTemp = ((*(rsp->data + 14)) << 8) | (*(rsp->data + 15)); 2223 printf("UDP Proxy Packet Received : %u\n", statsTemp); 2224 2225 statsTemp = ((*(rsp->data + 16)) << 8) | (*(rsp->data + 17)); 2226 printf("UDP Proxy Packet Dropped : %u\n", statsTemp); 2227 2228 return rc; 2229 } 2230 2231 2232 static int 2233 ipmi_lan_stats_clear(struct ipmi_intf * intf, uint8_t chan) 2234 { 2235 int rc = 0; 2236 struct ipmi_rs * rsp; 2237 struct ipmi_rq req; 2238 uint8_t msg_data[2]; 2239 2240 if (!is_lan_channel(intf, chan)) { 2241 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); 2242 return -1; 2243 } 2244 2245 /* From here, we are ready to get the stats */ 2246 msg_data[0] = chan; 2247 msg_data[1] = 1; /* Clear */ 2248 2249 memset(&req, 0, sizeof(req)); 2250 req.msg.netfn = IPMI_NETFN_TRANSPORT; 2251 req.msg.cmd = IPMI_LAN_GET_STAT; 2252 req.msg.data = msg_data; 2253 req.msg.data_len = 2; 2254 2255 rsp = intf->sendrecv(intf, &req); 2256 if (rsp == NULL) { 2257 lprintf(LOG_INFO, "Get LAN Stats command failed"); 2258 return (-1); 2259 } 2260 2261 if (rsp->ccode > 0) { 2262 lprintf(LOG_INFO, "Get LAN Stats command failed: %s", 2263 val2str(rsp->ccode, completion_code_vals)); 2264 return (-1); 2265 } 2266 2267 return rc; 2268 } 2269 2270 2271 /* 2272 * print_lan_usage 2273 */ 2274 static void 2275 print_lan_usage(void) 2276 { 2277 lprintf(LOG_NOTICE, "LAN Commands:"); 2278 lprintf(LOG_NOTICE, " print [<channel number>]"); 2279 lprintf(LOG_NOTICE, " set <channel number> <command> <parameter>"); 2280 lprintf(LOG_NOTICE, " alert print <channel number> <alert destination>"); 2281 lprintf(LOG_NOTICE, " alert set <channel number> <alert destination> <command> <parameter>"); 2282 lprintf(LOG_NOTICE, " stats get [<channel number>]"); 2283 lprintf(LOG_NOTICE, " stats clear [<channel number>]"); 2284 } 2285 2286 2287 int 2288 ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv) 2289 { 2290 int rc = 0; 2291 uint8_t chan = 0; 2292 2293 if (argc == 0) { 2294 print_lan_usage(); 2295 return (-1); 2296 } else if (strncmp(argv[0], "help", 4) == 0) { 2297 print_lan_usage(); 2298 return 0; 2299 } 2300 2301 chan = find_lan_channel(intf, 1); 2302 2303 if (strncmp(argv[0], "printconf", 9) == 0 || 2304 strncmp(argv[0], "print", 5) == 0) 2305 { 2306 if (argc > 2) { 2307 print_lan_usage(); 2308 return (-1); 2309 } else if (argc == 2) { 2310 if (str2uchar(argv[1], &chan) != 0) { 2311 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); 2312 return (-1); 2313 } 2314 } 2315 if (!is_lan_channel(intf, chan)) { 2316 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2317 return (-1); 2318 } 2319 rc = ipmi_lan_print(intf, chan); 2320 } else if (strncmp(argv[0], "set", 3) == 0) { 2321 rc = ipmi_lan_set(intf, argc-1, &(argv[1])); 2322 } else if (strncmp(argv[0], "alert", 5) == 0) { 2323 rc = ipmi_lan_alert(intf, argc-1, &(argv[1])); 2324 } else if (strncmp(argv[0], "stats", 5) == 0) { 2325 if (argc < 2) { 2326 print_lan_usage(); 2327 return (-1); 2328 } else if (argc == 3) { 2329 if (str2uchar(argv[2], &chan) != 0) { 2330 lprintf(LOG_ERR, "Invalid channel: %s", argv[2]); 2331 return (-1); 2332 } 2333 } 2334 if (!is_lan_channel(intf, chan)) { 2335 lprintf(LOG_ERR, "Invalid channel: %d", chan); 2336 return (-1); 2337 } 2338 if (strncmp(argv[1], "get", 3) == 0) { 2339 rc = ipmi_lan_stats_get(intf, chan); 2340 } else if (strncmp(argv[1], "clear", 5) == 0) { 2341 rc = ipmi_lan_stats_clear(intf, chan); 2342 } else { 2343 print_lan_usage(); 2344 return (-1); 2345 } 2346 } else { 2347 lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]); 2348 return (-1); 2349 } 2350 return rc; 2351 } 2352