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