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
printf_firewall_usage(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
printf_firewall_info_usage(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)
print_bitfield(const unsigned char * bf,int n,int invert,int loglevel)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
ipmi_firewall_parse_args(int argc,char ** argv,struct ipmi_function_params * p)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
_get_netfn_support(struct ipmi_intf * intf,int channel,unsigned char * lun,unsigned char * netfn)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
_get_command_support(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)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
_get_command_configurable(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)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
_get_command_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)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
_set_command_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn,unsigned char * enable,int gun)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
_get_subfn_support(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)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
_get_subfn_configurable(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)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
_get_subfn_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)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
_set_subfn_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd,unsigned char * enable)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 */
_gather_info(struct ipmi_intf * intf,struct ipmi_function_params * p,struct bmc_fn_support * bmc)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
ipmi_firewall_info(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_firewall_enable_disable(struct ipmi_intf * intf,int enable,int argc,char ** argv)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
ipmi_firewall_reset(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_firewall_main(struct ipmi_intf * intf,int argc,char ** argv)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