1 /* 2 * Copyright (c) 2005 International Business Machines, Inc. All Rights Reserved. 3 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * Redistribution of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * Redistribution in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * Neither the name of Sun Microsystems, Inc. or the names of 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * This software is provided "AS IS," without a warranty of any kind. 21 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 24 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 25 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 26 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 27 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 28 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 29 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 30 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 31 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 #include <stdlib.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <time.h> 38 39 #include <ipmitool/helper.h> 40 #include <ipmitool/log.h> 41 #include <ipmitool/bswap.h> 42 #include <ipmitool/ipmi.h> 43 #include <ipmitool/ipmi_intf.h> 44 #include <ipmitool/ipmi_firewall.h> 45 #include <ipmitool/ipmi_strings.h> 46 47 static void 48 printf_firewall_usage(void) 49 { 50 lprintf(LOG_NOTICE, 51 "Firmware Firewall Commands:"); 52 lprintf(LOG_NOTICE, 53 "\tinfo [channel H] [lun L]"); 54 lprintf(LOG_NOTICE, 55 "\tinfo [channel H] [lun L [netfn N [command C [subfn S]]]]"); 56 lprintf(LOG_NOTICE, 57 "\tenable [channel H] [lun L [netfn N [command C [subfn S]]]]"); 58 lprintf(LOG_NOTICE, 59 "\tdisable [channel H] [lun L [netfn N [command C [subfn S]]]] [force])"); 60 lprintf(LOG_NOTICE, 61 "\treset [channel H]"); 62 lprintf(LOG_NOTICE, 63 "\t\twhere H is a Channel, L is a LUN, N is a NetFn,"); 64 lprintf(LOG_NOTICE, 65 "\t\tC is a Command and S is a Sub-Function"); 66 } 67 68 void 69 printf_firewall_info_usage(void) 70 { 71 lprintf(LOG_NOTICE, 72 "info [channel H]"); 73 lprintf(LOG_NOTICE, 74 "\tList all of the firewall information for all LUNs, NetFns"); 75 lprintf(LOG_NOTICE, 76 "\tand Commands, This is a long list and is not very human readable."); 77 lprintf(LOG_NOTICE, 78 "info [channel H] lun L"); 79 lprintf(LOG_NOTICE, 80 "\tThis also prints a long list that is not very human readable."); 81 lprintf(LOG_NOTICE, 82 "info [channel H] lun L netfn N"); 83 lprintf(LOG_NOTICE, 84 "\tThis prints out information for a single LUN/NetFn pair."); 85 lprintf(LOG_NOTICE, 86 "\tThat is not really very usable, but at least it is short."); 87 lprintf(LOG_NOTICE, 88 "info [channel H] lun L netfn N command C"); 89 lprintf(LOG_NOTICE, 90 "\tThis is the one you want -- it prints out detailed human"); 91 lprintf(LOG_NOTICE, 92 "\treadable information. It shows the support, configurable, and"); 93 lprintf(LOG_NOTICE, 94 "\tenabled bits for the Command C on LUN/NetFn pair L,N and the"); 95 lprintf(LOG_NOTICE, 96 "\tsame information about each of its Sub-functions."); 97 } 98 99 // print n bytes of bit field bf (if invert, print ~bf) 100 static void print_bitfield(const unsigned char * bf, int n, int invert, int loglevel) { 101 int i = 0; 102 if (loglevel < 0) { 103 while (i<n) { 104 printf("%02x", (unsigned char) (invert?~bf[i]:bf[i])); 105 if (++i % 4 == 0) 106 printf(" "); 107 } 108 printf("\n"); 109 } else { 110 while (i<n) { 111 lprintf(loglevel, "%02x", (unsigned char) (invert?~bf[i]:bf[i])); 112 if (++i % 4 == 0) 113 lprintf(loglevel, " "); 114 } 115 lprintf(loglevel, "\n"); 116 } 117 118 } 119 120 static int 121 ipmi_firewall_parse_args(int argc, char ** argv, struct ipmi_function_params * p) 122 { 123 int i; 124 uint8_t conv_err = 0; 125 126 if (!p) { 127 lprintf(LOG_ERR, "ipmi_firewall_parse_args: p is NULL"); 128 return -1; 129 } 130 for (i=0; i<argc; i++) { 131 if (strncmp(argv[i], "channel", 7) == 0 && (++i < argc)) { 132 uint8_t channel_tmp = 0; 133 if (is_ipmi_channel_num(argv[i], &channel_tmp) != 0) { 134 conv_err = 1; 135 break; 136 } else { 137 p->channel = channel_tmp; 138 } 139 } 140 else if (strncmp(argv[i], "lun", 3) == 0 && (++i < argc)) { 141 if (str2int(argv[i], &(p->lun)) != 0) { 142 lprintf(LOG_ERR, "Given lun '%s' is invalid.", argv[i]); 143 conv_err = 1; 144 break; 145 } 146 } 147 else if (strncmp(argv[i], "force", 5) == 0) { 148 p->force = 1; 149 } 150 else if (strncmp(argv[i], "netfn", 5) == 0 && (++i < argc)) { 151 if (str2int(argv[i], &(p->netfn)) != 0) { 152 lprintf(LOG_ERR, "Given netfn '%s' is invalid.", argv[i]); 153 conv_err = 1; 154 break; 155 } 156 } 157 else if (strncmp(argv[i], "command", 7) == 0 && (++i < argc)) { 158 if (str2int(argv[i], &(p->command)) != 0) { 159 lprintf(LOG_ERR, "Given command '%s' is invalid.", argv[i]); 160 conv_err = 1; 161 break; 162 } 163 } 164 else if (strncmp(argv[i], "subfn", 5) == 0 && (++i < argc)) { 165 if (str2int(argv[i], &(p->subfn)) != 0) { 166 lprintf(LOG_ERR, "Given subfn '%s' is invalid.", argv[i]); 167 conv_err = 1; 168 break; 169 } 170 } 171 } 172 if (conv_err != 0) { 173 return (-1); 174 } 175 if (p->subfn >= MAX_SUBFN) { 176 lprintf(LOG_ERR, "subfn is out of range (0-%d)", MAX_SUBFN-1); 177 return -1; 178 } 179 if (p->command >= MAX_COMMAND) { 180 lprintf(LOG_ERR, "command is out of range (0-%d)", MAX_COMMAND-1); 181 return -1; 182 } 183 if (p->netfn >= MAX_NETFN) { 184 lprintf(LOG_ERR, "netfn is out of range (0-%d)", MAX_NETFN-1); 185 return -1; 186 } 187 if (p->lun >= MAX_LUN) { 188 lprintf(LOG_ERR, "lun is out of range (0-%d)", MAX_LUN-1); 189 return -1; 190 } 191 if (p->netfn >= 0 && p->lun < 0) { 192 lprintf(LOG_ERR, "if netfn is set, so must be lun"); 193 return -1; 194 } 195 if (p->command >= 0 && p->netfn < 0) { 196 lprintf(LOG_ERR, "if command is set, so must be netfn"); 197 return -1; 198 } 199 if (p->subfn >= 0 && p->command < 0) { 200 lprintf(LOG_ERR, "if subfn is set, so must be command"); 201 return -1; 202 } 203 return 0; 204 } 205 206 /* _get_netfn_suport 207 * 208 * @intf: ipmi interface 209 * @channel: ipmi channel 210 * @lun: a pointer to a 4 byte field 211 * @netfn: a pointer to a 128-bit bitfield (16 bytes) 212 * 213 * returns 0 on success and fills in the bitfield for 214 * the 32 netfn * 4 LUN pairs that support commands 215 * returns -1 on error 216 */ 217 static int 218 _get_netfn_support(struct ipmi_intf * intf, int channel, unsigned char * lun, unsigned char * netfn) 219 { 220 struct ipmi_rs * rsp; 221 struct ipmi_rq req; 222 unsigned char * d, rqdata; 223 unsigned int l; 224 225 if (!lun || !netfn) { 226 lprintf(LOG_ERR, "_get_netfn_suport: lun or netfn is NULL"); 227 return -1; 228 } 229 230 memset(&req, 0, sizeof(req)); 231 req.msg.netfn = IPMI_NETFN_APP; 232 req.msg.cmd = BMC_GET_NETFN_SUPPORT; 233 rqdata = (unsigned char) channel; 234 req.msg.data = &rqdata; 235 req.msg.data_len = 1; 236 237 rsp = intf->sendrecv(intf, &req); 238 if (rsp == NULL) { 239 lprintf(LOG_ERR, "Get NetFn Support command failed"); 240 return -1; 241 } 242 if (rsp->ccode > 0) { 243 lprintf(LOG_ERR, "Get NetFn Support command failed: %s", 244 val2str(rsp->ccode, completion_code_vals)); 245 return -1; 246 } 247 248 d = rsp->data; 249 for (l=0; l<4; l++) { 250 lun[l] = (*d)>>(2*l) & 0x3; 251 } 252 d++; 253 254 memcpy(netfn, d, 16); 255 256 return 0; 257 } 258 259 /* _get_command_suport 260 * 261 * @intf: ipmi interface 262 * @p: a pointer to a struct ipmi_function_params 263 * @lnfn: a pointer to a struct lun_netfn_support 264 * 265 * returns 0 on success and fills in lnfn according to the request in p 266 * returns -1 on error 267 */ 268 static int 269 _get_command_support(struct ipmi_intf * intf, 270 struct ipmi_function_params * p, struct lun_netfn_support * lnfn) 271 { 272 struct ipmi_rs * rsp; 273 struct ipmi_rq req; 274 unsigned char * d, rqdata[3]; 275 unsigned int c; 276 277 if (!p || !lnfn) { 278 lprintf(LOG_ERR, "_get_netfn_suport: p or lnfn is NULL"); 279 return -1; 280 } 281 282 memset(&req, 0, sizeof(req)); 283 req.msg.netfn = IPMI_NETFN_APP; 284 req.msg.cmd = BMC_GET_COMMAND_SUPPORT; 285 rqdata[0] = (unsigned char) p->channel; 286 rqdata[1] = p->netfn; 287 rqdata[2] = p->lun; 288 req.msg.data = rqdata; 289 req.msg.data_len = 3; 290 291 rsp = intf->sendrecv(intf, &req); 292 if (rsp == NULL) { 293 lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn); 294 return -1; 295 } 296 if (rsp->ccode > 0) { 297 lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=0) command failed: %s", 298 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 299 return -1; 300 } 301 302 d = rsp->data; 303 for (c=0; c<128; c++) { 304 if (!(d[c>>3] & (1<<(c%8)))) 305 lnfn->command[c].support |= BIT_AVAILABLE; 306 } 307 memcpy(lnfn->command_mask, d, MAX_COMMAND_BYTES/2); 308 309 memset(&req, 0, sizeof(req)); 310 req.msg.netfn = IPMI_NETFN_APP; 311 req.msg.cmd = BMC_GET_COMMAND_SUPPORT; 312 rqdata[0] = (unsigned char) p->channel; 313 rqdata[1] = 0x40 | p->netfn; 314 rqdata[2] = p->lun; 315 req.msg.data = rqdata; 316 req.msg.data_len = 3; 317 318 rsp = intf->sendrecv(intf, &req); 319 if (rsp == NULL) { 320 lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn); 321 return -1; 322 } 323 if (rsp->ccode > 0) { 324 lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=1) command failed: %s", 325 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 326 return -1; 327 } 328 329 d = rsp->data; 330 for (c=0; c<128; c++) { 331 if (!(d[c>>3] & (1<<(c%8)))) 332 lnfn->command[128+c].support |= BIT_AVAILABLE; 333 } 334 memcpy(lnfn->command_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2); 335 return 0; 336 } 337 338 /* _get_command_configurable 339 * 340 * @intf: ipmi interface 341 * @p: a pointer to a struct ipmi_function_params 342 * @lnfn: a pointer to a struct lun_netfn_support 343 * 344 * returns 0 on success and fills in lnfn according to the request in p 345 * returns -1 on error 346 */ 347 static int 348 _get_command_configurable(struct ipmi_intf * intf, 349 struct ipmi_function_params * p, struct lun_netfn_support * lnfn) 350 { 351 struct ipmi_rs * rsp; 352 struct ipmi_rq req; 353 unsigned char * d, rqdata[3]; 354 unsigned int c; 355 356 if (!p || !lnfn) { 357 lprintf(LOG_ERR, "_get_command_configurable: p or lnfn is NULL"); 358 return -1; 359 } 360 361 memset(&req, 0, sizeof(req)); 362 req.msg.netfn = IPMI_NETFN_APP; 363 req.msg.cmd = BMC_GET_CONFIGURABLE_COMMANDS; 364 rqdata[0] = (unsigned char) p->channel; 365 rqdata[1] = p->netfn; 366 rqdata[2] = p->lun; 367 req.msg.data = rqdata; 368 req.msg.data_len = 3; 369 370 rsp = intf->sendrecv(intf, &req); 371 if (rsp == NULL) { 372 lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn); 373 return -1; 374 } 375 if (rsp->ccode > 0) { 376 lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=0) command failed: %s", 377 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 378 return -1; 379 } 380 381 d = rsp->data; 382 for (c=0; c<128; c++) { 383 if (d[c>>3] & (1<<(c%8))) 384 lnfn->command[c].support |= BIT_CONFIGURABLE; 385 } 386 memcpy(lnfn->config_mask, d, MAX_COMMAND_BYTES/2); 387 388 memset(&req, 0, sizeof(req)); 389 req.msg.netfn = IPMI_NETFN_APP; 390 req.msg.cmd = BMC_GET_CONFIGURABLE_COMMANDS; 391 rqdata[0] = (unsigned char) p->channel; 392 rqdata[1] = 0x40 | p->netfn; 393 rqdata[2] = p->lun; 394 req.msg.data = rqdata; 395 req.msg.data_len = 3; 396 397 rsp = intf->sendrecv(intf, &req); 398 if (rsp == NULL) { 399 lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn); 400 return -1; 401 } 402 if (rsp->ccode > 0) { 403 lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=1) command failed: %s", 404 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 405 return -1; 406 } 407 408 d = rsp->data; 409 for (c=0; c<128; c++) { 410 if (d[c>>3] & (1<<(c%8))) 411 lnfn->command[128+c].support |= BIT_CONFIGURABLE; 412 } 413 memcpy(lnfn->config_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2); 414 return 0; 415 } 416 417 /* _get_command_enables 418 * 419 * @intf: ipmi interface 420 * @p: a pointer to a struct ipmi_function_params 421 * @lnfn: a pointer to a struct lun_netfn_support 422 * 423 * returns 0 on success and fills in lnfn according to the request in p 424 * returns -1 on error 425 */ 426 static int 427 _get_command_enables(struct ipmi_intf * intf, 428 struct ipmi_function_params * p, struct lun_netfn_support * lnfn) 429 { 430 struct ipmi_rs * rsp; 431 struct ipmi_rq req; 432 unsigned char * d, rqdata[3]; 433 unsigned int c; 434 435 if (!p || !lnfn) { 436 lprintf(LOG_ERR, "_get_command_enables: p or lnfn is NULL"); 437 return -1; 438 } 439 440 memset(&req, 0, sizeof(req)); 441 req.msg.netfn = IPMI_NETFN_APP; 442 req.msg.cmd = BMC_GET_COMMAND_ENABLES; 443 rqdata[0] = (unsigned char) p->channel; 444 rqdata[1] = p->netfn; 445 rqdata[2] = p->lun; 446 req.msg.data = rqdata; 447 req.msg.data_len = 3; 448 449 rsp = intf->sendrecv(intf, &req); 450 if (rsp == NULL) { 451 lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn); 452 return -1; 453 } 454 if (rsp->ccode > 0) { 455 lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=0) command failed: %s", 456 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 457 return -1; 458 } 459 460 d = rsp->data; 461 for (c=0; c<128; c++) { 462 if (d[c>>3] & (1<<(c%8))) 463 lnfn->command[c].support |= BIT_ENABLED; 464 } 465 memcpy(lnfn->enable_mask, d, MAX_COMMAND_BYTES/2); 466 467 memset(&req, 0, sizeof(req)); 468 req.msg.netfn = IPMI_NETFN_APP; 469 req.msg.cmd = BMC_GET_COMMAND_ENABLES; 470 rqdata[0] = (unsigned char) p->channel; 471 rqdata[1] = 0x40 | p->netfn; 472 rqdata[2] = p->lun; 473 req.msg.data = rqdata; 474 req.msg.data_len = 3; 475 476 rsp = intf->sendrecv(intf, &req); 477 if (rsp == NULL) { 478 lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn); 479 return -1; 480 } 481 if (rsp->ccode > 0) { 482 lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=1) command failed: %s", 483 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 484 return -1; 485 } 486 487 d = rsp->data; 488 for (c=0; c<128; c++) { 489 if (d[c>>3] & (1<<(c%8))) 490 lnfn->command[128+c].support |= BIT_ENABLED; 491 } 492 memcpy(lnfn->enable_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2); 493 return 0; 494 } 495 496 /* _set_command_enables 497 * 498 * @intf: ipmi interface 499 * @p: a pointer to a struct ipmi_function_params 500 * @lnfn: a pointer to a struct lun_netfn_support that contains current info 501 * @enable: a pointer to a 32 byte bitfield that contains the desired enable state 502 * @gun: here is a gun to shoot yourself in the foot. If this is true 503 * you are allowed to disable this command 504 * 505 * returns 0 on success 506 * returns -1 on error 507 */ 508 static int 509 _set_command_enables(struct ipmi_intf * intf, 510 struct ipmi_function_params * p, struct lun_netfn_support * lnfn, 511 unsigned char * enable, int gun) 512 { 513 struct ipmi_rs * rsp; 514 struct ipmi_rq req; 515 unsigned char rqdata[19]; 516 unsigned int c; 517 518 if (!p || !lnfn) { 519 lprintf(LOG_ERR, "_set_command_enables: p or lnfn is NULL"); 520 return -1; 521 } 522 523 lprintf(LOG_INFO, "support: "); 524 print_bitfield(lnfn->command_mask, MAX_COMMAND_BYTES, 1, LOG_INFO); 525 lprintf(LOG_INFO, "configurable: "); 526 print_bitfield(lnfn->config_mask, MAX_COMMAND_BYTES, 0, LOG_INFO); 527 lprintf(LOG_INFO, "enabled: "); 528 print_bitfield(lnfn->enable_mask, MAX_COMMAND_BYTES, 0, LOG_INFO); 529 lprintf(LOG_INFO, "enable mask before: "); 530 print_bitfield(enable, MAX_COMMAND_BYTES, 0, LOG_INFO); 531 532 // mask off the appropriate bits (if not configurable, set enable bit 533 // must be the same as the current enable bit) 534 for (c=0; c<(MAX_COMMAND_BYTES); c++) { 535 enable[c] = (lnfn->config_mask[c] & enable[c]) | 536 (~lnfn->config_mask[c] & lnfn->enable_mask[c]); 537 } 538 539 // take the gun out of their hand if they are not supposed to have it 540 if (!gun) { 541 enable[SET_COMMAND_ENABLE_BYTE] = 542 (lnfn->config_mask[SET_COMMAND_ENABLE_BYTE] 543 & SET_COMMAND_ENABLE_BIT) | 544 (~lnfn->config_mask[SET_COMMAND_ENABLE_BYTE] 545 & lnfn->enable_mask[SET_COMMAND_ENABLE_BYTE]); 546 } 547 lprintf(LOG_INFO, "enable mask after: "); 548 print_bitfield(enable, MAX_COMMAND_BYTES, 0, LOG_INFO); 549 550 memset(&req, 0, sizeof(req)); 551 req.msg.netfn = IPMI_NETFN_APP; 552 req.msg.cmd = BMC_SET_COMMAND_ENABLES; 553 rqdata[0] = (unsigned char) p->channel; 554 rqdata[1] = p->netfn; 555 rqdata[2] = p->lun; 556 memcpy(&rqdata[3], enable, MAX_COMMAND_BYTES/2); 557 req.msg.data = rqdata; 558 req.msg.data_len = 19; 559 560 rsp = intf->sendrecv(intf, &req); 561 if (rsp == NULL) { 562 lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn); 563 return -1; 564 } 565 if (rsp->ccode > 0) { 566 lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=0) command failed: %s", 567 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 568 return -1; 569 } 570 571 memset(&req, 0, sizeof(req)); 572 req.msg.netfn = IPMI_NETFN_APP; 573 req.msg.cmd = BMC_SET_COMMAND_ENABLES; 574 rqdata[0] = (unsigned char) p->channel; 575 rqdata[1] = 0x40 | p->netfn; 576 rqdata[2] = p->lun; 577 memcpy(&rqdata[3], enable+MAX_COMMAND_BYTES/2, MAX_COMMAND_BYTES/2); 578 req.msg.data = rqdata; 579 req.msg.data_len = 19; 580 581 rsp = intf->sendrecv(intf, &req); 582 if (rsp == NULL) { 583 lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn); 584 return -1; 585 } 586 if (rsp->ccode > 0) { 587 lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=1) command failed: %s", 588 p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals)); 589 return -1; 590 } 591 592 return 0; 593 } 594 595 /* _get_subfn_support 596 * 597 * @intf: ipmi interface 598 * @p: a pointer to a struct ipmi_function_params 599 * @cmd: a pointer to a struct command_support 600 * 601 * returns 0 on success and fills in cmd according to the request in p 602 * returns -1 on error 603 */ 604 static int 605 _get_subfn_support(struct ipmi_intf * intf, 606 struct ipmi_function_params * p, struct command_support * cmd) 607 { 608 struct ipmi_rs * rsp; 609 struct ipmi_rq req; 610 unsigned char rqdata[4]; 611 612 if (!p || !cmd) { 613 lprintf(LOG_ERR, "_get_subfn_support: p or cmd is NULL"); 614 return -1; 615 } 616 617 memset(&req, 0, sizeof(req)); 618 req.msg.netfn = IPMI_NETFN_APP; 619 req.msg.cmd = BMC_GET_COMMAND_SUBFUNCTION_SUPPORT; 620 rqdata[0] = (unsigned char) p->channel; 621 rqdata[1] = p->netfn; 622 rqdata[2] = p->lun; 623 rqdata[3] = p->command; 624 req.msg.data = rqdata; 625 req.msg.data_len = 4; 626 627 rsp = intf->sendrecv(intf, &req); 628 if (rsp == NULL) { 629 lprintf(LOG_ERR, "Get Command Sub-function Support (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command); 630 return -1; 631 } 632 if (rsp->ccode > 0) { 633 lprintf(LOG_ERR, "Get Command Sub-function Support (LUN=%d, NetFn=%d, command=%d) command failed: %s", 634 p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals)); 635 return -1; 636 } 637 638 memcpy(cmd->subfn_support, rsp->data, sizeof(cmd->subfn_support)); 639 return 0; 640 } 641 642 /* _get_subfn_configurable 643 * 644 * @intf: ipmi interface 645 * @p: a pointer to a struct ipmi_function_params 646 * @cmd: a pointer to a struct command_support 647 * 648 * returns 0 on success and fills in cmd according to the request in p 649 * returns -1 on error 650 */ 651 static int 652 _get_subfn_configurable(struct ipmi_intf * intf, 653 struct ipmi_function_params * p, struct command_support * cmd) 654 { 655 struct ipmi_rs * rsp; 656 struct ipmi_rq req; 657 unsigned char rqdata[4]; 658 659 if (!p || !cmd) { 660 lprintf(LOG_ERR, "_get_subfn_configurable: p or cmd is NULL"); 661 return -1; 662 } 663 664 memset(&req, 0, sizeof(req)); 665 req.msg.netfn = IPMI_NETFN_APP; 666 req.msg.cmd = BMC_GET_CONFIGURABLE_COMMAND_SUBFUNCTIONS; 667 rqdata[0] = (unsigned char) p->channel; 668 rqdata[1] = p->netfn; 669 rqdata[2] = p->lun; 670 rqdata[3] = p->command; 671 req.msg.data = rqdata; 672 req.msg.data_len = 4; 673 674 rsp = intf->sendrecv(intf, &req); 675 if (rsp == NULL) { 676 lprintf(LOG_ERR, "Get Configurable Command Sub-function (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command); 677 return -1; 678 } 679 if (rsp->ccode > 0) { 680 lprintf(LOG_ERR, "Get Configurable Command Sub-function (LUN=%d, NetFn=%d, command=%d) command failed: %s", 681 p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals)); 682 return -1; 683 } 684 685 memcpy(cmd->subfn_config, rsp->data, sizeof(cmd->subfn_config)); 686 return 0; 687 } 688 689 /* _get_subfn_enables 690 * 691 * @intf: ipmi interface 692 * @p: a pointer to a struct ipmi_function_params 693 * @cmd: a pointer to a struct command_support 694 * 695 * returns 0 on success and fills in cmd according to the request in p 696 * returns -1 on error 697 */ 698 static int 699 _get_subfn_enables(struct ipmi_intf * intf, 700 struct ipmi_function_params * p, struct command_support * cmd) 701 { 702 struct ipmi_rs * rsp; 703 struct ipmi_rq req; 704 unsigned char rqdata[4]; 705 706 if (!p || !cmd) { 707 lprintf(LOG_ERR, "_get_subfn_enables: p or cmd is NULL"); 708 return -1; 709 } 710 711 memset(&req, 0, sizeof(req)); 712 req.msg.netfn = IPMI_NETFN_APP; 713 req.msg.cmd = BMC_GET_COMMAND_SUBFUNCTION_ENABLES; 714 rqdata[0] = (unsigned char) p->channel; 715 rqdata[1] = p->netfn; 716 rqdata[2] = p->lun; 717 rqdata[3] = p->command; 718 req.msg.data = rqdata; 719 req.msg.data_len = 4; 720 721 rsp = intf->sendrecv(intf, &req); 722 if (rsp == NULL) { 723 lprintf(LOG_ERR, "Get Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command); 724 return -1; 725 } 726 if (rsp->ccode > 0) { 727 lprintf(LOG_ERR, "Get Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed: %s", 728 p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals)); 729 return -1; 730 } 731 732 memcpy(cmd->subfn_enable, rsp->data, sizeof(cmd->subfn_enable)); 733 return 0; 734 } 735 736 /* _set_subfn_enables 737 * 738 * @intf: ipmi interface 739 * @p: a pointer to a struct ipmi_function_params 740 * @cmd: a pointer to a struct command_support 741 * @enable: a pointer to a 4 byte bitfield that contains the desired enable state 742 * 743 * returns 0 on success (and modifies enable to be the bits it actually set) 744 * returns -1 on error 745 */ 746 static int 747 _set_subfn_enables(struct ipmi_intf * intf, 748 struct ipmi_function_params * p, struct command_support * cmd, 749 unsigned char * enable) 750 { 751 struct ipmi_rs * rsp; 752 struct ipmi_rq req; 753 unsigned char rqdata[8]; 754 unsigned int c; 755 756 if (!p || !cmd) { 757 lprintf(LOG_ERR, "_set_subfn_enables: p or cmd is NULL"); 758 return -1; 759 } 760 761 lprintf(LOG_INFO, "support: "); 762 print_bitfield(cmd->subfn_support, MAX_SUBFN_BYTES, 1, LOG_INFO); 763 lprintf(LOG_INFO, "configurable: "); 764 print_bitfield(cmd->subfn_config, MAX_SUBFN_BYTES, 0, LOG_INFO); 765 lprintf(LOG_INFO, "enabled: "); 766 print_bitfield(cmd->subfn_enable, MAX_SUBFN_BYTES, 0, LOG_INFO); 767 lprintf(LOG_INFO, "enable mask before: "); 768 print_bitfield(enable, MAX_SUBFN_BYTES, 0, LOG_INFO); 769 // mask off the appropriate bits (if not configurable, set enable bit 770 // must be the same as the current enable bit) 771 for (c=0; c<sizeof(cmd->subfn_enable); c++) { 772 enable[c] = (cmd->subfn_config[c] & enable[c]) | 773 (~cmd->subfn_config[c] & cmd->subfn_enable[c]); 774 } 775 lprintf(LOG_INFO, "enable mask after: "); 776 print_bitfield(enable, MAX_SUBFN_BYTES, 0, LOG_INFO); 777 778 memset(&req, 0, sizeof(req)); 779 req.msg.netfn = IPMI_NETFN_APP; 780 req.msg.cmd = BMC_SET_COMMAND_SUBFUNCTION_ENABLES; 781 rqdata[0] = (unsigned char) p->channel; 782 rqdata[1] = p->netfn; 783 rqdata[2] = p->lun; 784 rqdata[3] = p->command; 785 memcpy(&rqdata[4], enable, MAX_SUBFN_BYTES); 786 req.msg.data = rqdata; 787 req.msg.data_len = 8; 788 789 rsp = intf->sendrecv(intf, &req); 790 if (rsp == NULL) { 791 lprintf(LOG_ERR, "Set Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command); 792 return -1; 793 } 794 if (rsp->ccode > 0) { 795 lprintf(LOG_ERR, "Set Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed: %s", 796 p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals)); 797 return -1; 798 } 799 800 return 0; 801 } 802 803 /* _gather_info 804 * 805 * @intf: ipmi interface 806 * @p: a pointer to a struct ipmi_function_params 807 * @bmc: a pointer to a struct bmc_fn_support 808 * @enable: a pointer to a 4 byte bitfield that contains the desired enable state 809 * 810 * returns 0 on success and fills in bmc according to request p 811 * returns -1 on error 812 */ 813 static int _gather_info(struct ipmi_intf * intf, struct ipmi_function_params * p, struct bmc_fn_support * bmc) 814 { 815 int ret, l, n; 816 unsigned char lun[MAX_LUN], netfn[16]; 817 818 ret = _get_netfn_support(intf, p->channel, lun, netfn); 819 if (!ret) { 820 for (l=0; l<MAX_LUN; l++) { 821 if (p->lun >= 0 && p->lun != l) 822 continue; 823 bmc->lun[l].support = lun[l]; 824 if (lun[l]) { 825 for (n=0; n<MAX_NETFN_PAIR; n++) { 826 int offset = l*MAX_NETFN_PAIR+n; 827 bmc->lun[l].netfn[n].support = 828 !!(netfn[offset>>3] & (1<<(offset%8))); 829 } 830 } 831 } 832 } 833 if (p->netfn >= 0) { 834 if (!((p->lun < 0 || bmc->lun[p->lun].support) && 835 (p->netfn < 0 || bmc->lun[p->lun].netfn[p->netfn>>1].support))) { 836 lprintf(LOG_ERR, "LUN or LUN/NetFn pair %d,%d not supported", p->lun, p->netfn); 837 return 0; 838 } 839 ret = _get_command_support(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1])); 840 ret |= _get_command_configurable(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1])); 841 ret |= _get_command_enables(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1])); 842 if (!ret && p->command >= 0) { 843 ret = _get_subfn_support(intf, p, 844 &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command])); 845 ret |= _get_subfn_configurable(intf, p, 846 &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command])); 847 ret |= _get_subfn_enables(intf, p, 848 &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command])); 849 } 850 } 851 else if (p->lun >= 0) { 852 l = p->lun; 853 if (bmc->lun[l].support) { 854 for (n=0; n<MAX_NETFN_PAIR; n++) { 855 p->netfn = n*2; 856 if (bmc->lun[l].netfn[n].support) { 857 ret = _get_command_support(intf, p, &(bmc->lun[l].netfn[n])); 858 ret |= _get_command_configurable(intf, p, &(bmc->lun[l].netfn[n])); 859 ret |= _get_command_enables(intf, p, &(bmc->lun[l].netfn[n])); 860 } 861 if (ret) 862 bmc->lun[l].netfn[n].support = 0; 863 } 864 } 865 p->netfn = -1; 866 } else { 867 for (l=0; l<4; l++) { 868 p->lun = l; 869 if (bmc->lun[l].support) { 870 for (n=0; n<MAX_NETFN_PAIR; n++) { 871 p->netfn = n*2; 872 if (bmc->lun[l].netfn[n].support) { 873 ret = _get_command_support(intf, p, &(bmc->lun[l].netfn[n])); 874 ret |= _get_command_configurable(intf, p, &(bmc->lun[l].netfn[n])); 875 ret |= _get_command_enables(intf, p, &(bmc->lun[l].netfn[n])); 876 } 877 if (ret) 878 bmc->lun[l].netfn[n].support = 0; 879 } 880 } 881 } 882 p->lun = -1; 883 p->netfn = -1; 884 } 885 886 return 0; 887 } 888 889 /* ipmi_firewall_info - print out info for firewall functions 890 * 891 * @intf: ipmi inteface 892 * @argc: argument count 893 * @argv: argument list 894 * 895 * returns 0 on success 896 * returns -1 on error 897 */ 898 static int 899 ipmi_firewall_info(struct ipmi_intf * intf, int argc, char ** argv) 900 { 901 int ret = 0; 902 struct ipmi_function_params p = {0xe, -1, -1, -1, -1}; 903 struct bmc_fn_support * bmc_fn_support; 904 unsigned int l, n, c; 905 906 if ((argc > 0 && strncmp(argv[0], "help", 4) == 0) || ipmi_firewall_parse_args(argc, argv, &p) < 0) 907 { 908 printf_firewall_info_usage(); 909 return 0; 910 } 911 912 bmc_fn_support = malloc(sizeof(struct bmc_fn_support)); 913 if (!bmc_fn_support) { 914 lprintf(LOG_ERR, "malloc struct bmc_fn_support failed"); 915 return -1; 916 } 917 918 ret = _gather_info(intf, &p, bmc_fn_support); 919 920 if (p.command >= 0) { 921 struct command_support * cmd; 922 if (!((p.lun < 0 || bmc_fn_support->lun[p.lun].support) && 923 (p.netfn < 0 || bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].support) && 924 bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].command[p.command].support)) 925 { 926 lprintf(LOG_ERR, "Command 0x%02x not supported on LUN/NetFn pair %02x,%02x", 927 p.command, p.lun, p.netfn); 928 free(bmc_fn_support); 929 bmc_fn_support = NULL; 930 return 0; 931 } 932 cmd = 933 &bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].command[p.command]; 934 c = cmd->support; 935 printf("(A)vailable, (C)onfigurable, (E)nabled: | A | C | E |\n"); 936 printf("-----------------------------------------------------\n"); 937 printf("LUN %01d, NetFn 0x%02x, Command 0x%02x: | %c | %c | %c |\n", 938 p.lun, p.netfn, p.command, 939 (c & BIT_AVAILABLE) ? 'X' : ' ', 940 (c & BIT_CONFIGURABLE) ? 'X' : ' ', 941 (c & BIT_ENABLED) ? 'X': ' '); 942 943 for (n=0; n<MAX_SUBFN; n++) { 944 printf("sub-function 0x%02x: | %c | %c | %c |\n", n, 945 (!bit_test(cmd->subfn_support, n)) ? 'X' : ' ', 946 (bit_test(cmd->subfn_config, n)) ? 'X' : ' ', 947 (bit_test(cmd->subfn_enable, n)) ? 'X' : ' '); 948 } 949 } 950 else if (p.netfn >= 0) { 951 if (!((p.lun < 0 || bmc_fn_support->lun[p.lun].support) && 952 (bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].support))) 953 { 954 lprintf(LOG_ERR, "LUN or LUN/NetFn pair %02x,%02x not supported", 955 p.lun, p.netfn); 956 free(bmc_fn_support); 957 bmc_fn_support = NULL; 958 return 0; 959 } 960 n = p.netfn >> 1; 961 l = p.lun; 962 printf("Commands on LUN 0x%02x, NetFn 0x%02x\n", p.lun, p.netfn); 963 printf("support: "); 964 print_bitfield(bmc_fn_support->lun[l].netfn[n].command_mask, 965 MAX_COMMAND_BYTES, 1, -1); 966 printf("configurable: "); 967 print_bitfield(bmc_fn_support->lun[l].netfn[n].config_mask, 968 MAX_COMMAND_BYTES, 0, -1); 969 printf("enabled: "); 970 print_bitfield(bmc_fn_support->lun[l].netfn[n].enable_mask, 971 MAX_COMMAND_BYTES, 0, -1); 972 } 973 else { 974 for (l=0; l<4; l++) { 975 p.lun = l; 976 if (bmc_fn_support->lun[l].support) { 977 for (n=0; n<MAX_NETFN_PAIR; n++) { 978 p.netfn = n*2; 979 if (bmc_fn_support->lun[l].netfn[n].support) { 980 printf("%02x,%02x support: ", p.lun, p.netfn); 981 print_bitfield(bmc_fn_support->lun[l].netfn[n].command_mask, 982 MAX_COMMAND_BYTES, 1, -1); 983 printf("%02x,%02x configurable: ", p.lun, p.netfn); 984 print_bitfield(bmc_fn_support->lun[l].netfn[n].config_mask, 985 MAX_COMMAND_BYTES, 0, -1); 986 printf("%02x,%02x enabled: ", p.lun, p.netfn); 987 print_bitfield(bmc_fn_support->lun[l].netfn[n].enable_mask, 988 MAX_COMMAND_BYTES, 0, -1); 989 } 990 } 991 } 992 } 993 p.lun = -1; 994 p.netfn = -1; 995 } 996 997 free(bmc_fn_support); 998 bmc_fn_support = NULL; 999 return ret; 1000 } 1001 1002 /* ipmi_firewall_enable_disable - enable/disable BMC functions 1003 * 1004 * @intf: ipmi inteface 1005 * @enable: whether to enable or disable 1006 * @argc: argument count 1007 * @argv: argument list 1008 * 1009 * returns 0 on success 1010 * returns -1 on error 1011 */ 1012 static int 1013 ipmi_firewall_enable_disable(struct ipmi_intf * intf, int enable, int argc, char ** argv) 1014 { 1015 struct ipmi_function_params p = {0xe, -1, -1, -1, -1}; 1016 struct bmc_fn_support * bmc_fn_support; 1017 int ret; 1018 unsigned int l, n, c; 1019 unsigned char enables[MAX_COMMAND_BYTES]; 1020 1021 if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { 1022 char * s1 = enable?"en":"dis"; 1023 char * s2 = enable?"":" [force]"; 1024 printf("%sable [channel H] lun L netfn N%s\n", s1, s2); 1025 printf("\t%sable all commands on this LUN/NetFn pair\n", s1); 1026 printf("%sable [channel H] lun L netfn N command C%s\n", s1, s2); 1027 printf("\t%sable Command C and all its Sub-functions for this LUN/NetFn pair\n", s1); 1028 printf("%sable [channel H] lun L netfn N command C subfn S\n", s1); 1029 printf("\t%sable Sub-function S for Command C for this LUN/NetFn pair\n", s1); 1030 if (!enable) { 1031 printf("* force will allow you to disable the \"Command Set Enable\" command\n"); 1032 printf("\tthereby letting you shoot yourself in the foot\n"); 1033 printf("\tthis is only recommended for advanced users\n"); 1034 } 1035 return 0; 1036 } 1037 if (ipmi_firewall_parse_args(argc, argv, &p) < 0) 1038 return -1; 1039 1040 bmc_fn_support = malloc(sizeof(struct bmc_fn_support)); 1041 if (!bmc_fn_support) { 1042 lprintf(LOG_ERR, "malloc struct bmc_fn_support failed"); 1043 return -1; 1044 } 1045 1046 ret = _gather_info(intf, &p, bmc_fn_support); 1047 if (ret < 0) { 1048 free(bmc_fn_support); 1049 bmc_fn_support = NULL; 1050 return ret; 1051 } 1052 1053 l = p.lun; 1054 n = p.netfn>>1; 1055 c = p.command; 1056 if (p.subfn >= 0) { 1057 // firewall (en|dis)able [channel c] lun l netfn n command m subfn s 1058 // (en|dis)able this sub-function for this commnad on this lun/netfn pair 1059 memcpy(enables, 1060 bmc_fn_support->lun[l].netfn[n].command[c].subfn_enable, 1061 MAX_SUBFN_BYTES); 1062 bit_set(enables, p.subfn, enable); 1063 ret = _set_subfn_enables(intf, &p, 1064 &bmc_fn_support->lun[l].netfn[n].command[c], enables); 1065 1066 } else if (p.command >= 0) { 1067 // firewall (en|dis)able [channel c] lun l netfn n command m 1068 // (en|dis)able all subfn and command for this commnad on this lun/netfn pair 1069 memset(enables, enable?0xff:0, MAX_SUBFN_BYTES); 1070 ret = _set_subfn_enables(intf, &p, 1071 &bmc_fn_support->lun[l].netfn[n].command[c], enables); 1072 memcpy(enables, 1073 &bmc_fn_support->lun[l].netfn[n].enable_mask, sizeof(enables)); 1074 bit_set(enables, p.command, enable); 1075 ret |= _set_command_enables(intf, &p, 1076 &bmc_fn_support->lun[l].netfn[n], enables, p.force); 1077 } else if (p.netfn >= 0) { 1078 // firewall (en|dis)able [channel c] lun l netfn n 1079 // (en|dis)able all commnads on this lun/netfn pair 1080 memset(enables, enable?0xff:0, sizeof(enables)); 1081 ret = _set_command_enables(intf, &p, 1082 &bmc_fn_support->lun[l].netfn[n], enables, p.force); 1083 /* 1084 } else if (p.lun >= 0) { 1085 // firewall (en|dis)able [channel c] lun l 1086 // (en|dis)able all commnads on all netfn pairs for this lun 1087 */ 1088 } 1089 free(bmc_fn_support); 1090 bmc_fn_support = NULL; 1091 return ret; 1092 } 1093 1094 /* ipmi_firewall_reset - reset firmware firewall to enable everything 1095 * 1096 * @intf: ipmi inteface 1097 * @argc: argument count 1098 * @argv: argument list 1099 * 1100 * returns 0 on success 1101 * returns -1 on error 1102 */ 1103 static int 1104 ipmi_firewall_reset(struct ipmi_intf * intf, int argc, char ** argv) 1105 { 1106 struct ipmi_function_params p = {0xe, -1, -1, -1, -1}; 1107 struct bmc_fn_support * bmc_fn_support; 1108 int ret; 1109 unsigned int l, n, c; 1110 unsigned char enables[MAX_COMMAND_BYTES]; 1111 1112 if (argc < 1) { 1113 lprintf(LOG_ERR, "Not enough parameters given."); 1114 printf_firewall_usage(); 1115 return (-1); 1116 } else if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 1117 printf_firewall_usage(); 1118 return 0; 1119 } 1120 if (ipmi_firewall_parse_args(argc, argv, &p) < 0) 1121 return -1; 1122 1123 bmc_fn_support = malloc(sizeof(struct bmc_fn_support)); 1124 if (!bmc_fn_support) { 1125 lprintf(LOG_ERR, "malloc struct bmc_fn_support failed"); 1126 return -1; 1127 } 1128 1129 ret = _gather_info(intf, &p, bmc_fn_support); 1130 if (ret < 0) { 1131 free(bmc_fn_support); 1132 bmc_fn_support = NULL; 1133 return ret; 1134 } 1135 1136 for (l=0; l<MAX_LUN; l++) { 1137 p.lun = l; 1138 for (n=0; n<MAX_NETFN; n+=2) { 1139 p.netfn = n; 1140 for (c=0; c<MAX_COMMAND; c++) { 1141 p.command = c; 1142 printf("reset lun %d, netfn %d, command %d, subfn\n", l, n, c); 1143 memset(enables, 0xff, MAX_SUBFN_BYTES); 1144 ret = _set_subfn_enables(intf, &p, 1145 &bmc_fn_support->lun[l].netfn[n].command[c], enables); 1146 } 1147 printf("reset lun %d, netfn %d, command\n", l, n); 1148 memset(enables, 0xff, sizeof(enables)); 1149 ret = _set_command_enables(intf, &p, 1150 &bmc_fn_support->lun[l].netfn[n], enables, 0); 1151 } 1152 } 1153 1154 free(bmc_fn_support); 1155 bmc_fn_support = NULL; 1156 return ret; 1157 } 1158 1159 1160 /* ipmi_firewall_main - top-level handler for firmware firewall functions 1161 * 1162 * @intf: ipmi interface 1163 * @argc: number of arguments 1164 * @argv: argument list 1165 * 1166 * returns 0 on success 1167 * returns -1 on error 1168 */ 1169 int 1170 ipmi_firewall_main(struct ipmi_intf * intf, int argc, char ** argv) 1171 { 1172 int rc = 0; 1173 1174 if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { 1175 printf_firewall_usage(); 1176 } 1177 else if (strncmp(argv[0], "info", 4) == 0) { 1178 rc = ipmi_firewall_info(intf, argc-1, &(argv[1])); 1179 } 1180 else if (strncmp(argv[0], "enable", 6) == 0) { 1181 rc = ipmi_firewall_enable_disable(intf, 1, argc-1, &(argv[1])); 1182 } 1183 else if (strncmp(argv[0], "disable", 7) == 0) { 1184 rc = ipmi_firewall_enable_disable(intf, 0, argc-1, &(argv[1])); 1185 } 1186 else if (strncmp(argv[0], "reset", 5) == 0) { 1187 rc = ipmi_firewall_reset(intf, argc-1, &(argv[1])); 1188 } 1189 else { 1190 printf_firewall_usage(); 1191 } 1192 1193 return rc; 1194 } 1195