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