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