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
is_lan_channel(struct ipmi_intf * intf,uint8_t chan)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
find_lan_channel(struct ipmi_intf * intf,uint8_t start)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 *
get_lan_param_select(struct ipmi_intf * intf,uint8_t chan,int param,int select)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 *
get_lan_param(struct ipmi_intf * intf,uint8_t chan,int 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
set_lan_param_wait(struct ipmi_intf * intf,uint8_t chan,int param,uint8_t * data,int len)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
__set_lan_param(struct ipmi_intf * intf,uint8_t chan,int param,uint8_t * data,int len,int wait)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
ipmi_lanp_lock_state(struct ipmi_intf * intf,uint8_t chan)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
ipmi_lanp_lock(struct ipmi_intf * intf,uint8_t chan)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
ipmi_lanp_unlock(struct ipmi_intf * intf,uint8_t chan)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
set_lan_param(struct ipmi_intf * intf,uint8_t chan,int param,uint8_t * data,int len)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
set_lan_param_nowait(struct ipmi_intf * intf,uint8_t chan,int param,uint8_t * data,int len)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
lan_set_arp_interval(struct ipmi_intf * intf,uint8_t chan,uint8_t ival)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
lan_set_arp_generate(struct ipmi_intf * intf,uint8_t chan,uint8_t ctl)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
lan_set_arp_respond(struct ipmi_intf * intf,uint8_t chan,uint8_t ctl)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 */
priv_level_to_char(unsigned char priv_level)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
ipmi_lan_print(struct ipmi_intf * intf,uint8_t chan)577 ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
578 {
579 struct lan_param * p;
580
581 if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) {
582 lprintf(LOG_ERR, "Invalid Channel %d", chan);
583 return -1;
584 }
585
586 /* find type of channel and only accept 802.3 LAN */
587 if (!is_lan_channel(intf, chan)) {
588 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan);
589 return -1;
590 }
591
592 p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS);
593 if (p == NULL)
594 return -1;
595 if (p->data != NULL) {
596 printf("%-24s: ", p->desc);
597 p->data[0] &= 3;
598 switch (p->data[0]) {
599 case 0:
600 printf("Set Complete\n");
601 break;
602 case 1:
603 printf("Set In Progress\n");
604 break;
605 case 2:
606 printf("Commit Write\n");
607 break;
608 case 3:
609 printf("Reserved\n");
610 break;
611 default:
612 printf("Unknown\n");
613 }
614 }
615
616 p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE);
617 if (p == NULL)
618 return -1;
619 if (p->data != NULL) {
620 printf("%-24s: %s%s%s%s%s\n", p->desc,
621 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
622 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
623 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
624 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
625 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
626 }
627
628 p = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE);
629 if (p == NULL)
630 return -1;
631 if (p->data != NULL) {
632 printf("%-24s: Callback : %s%s%s%s%s\n", p->desc,
633 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
634 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
635 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
636 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
637 (p->data[0] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
638 printf("%-24s: User : %s%s%s%s%s\n", "",
639 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
640 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
641 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
642 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
643 (p->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
644 printf("%-24s: Operator : %s%s%s%s%s\n", "",
645 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
646 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
647 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
648 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
649 (p->data[2] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
650 printf("%-24s: Admin : %s%s%s%s%s\n", "",
651 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
652 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
653 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
654 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
655 (p->data[3] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
656 printf("%-24s: OEM : %s%s%s%s%s\n", "",
657 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
658 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
659 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
660 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
661 (p->data[4] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
662 }
663
664 p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC);
665 if (p == NULL)
666 return -1;
667 if (p->data != NULL) {
668 printf("%-24s: ", p->desc);
669 p->data[0] &= 0xf;
670 switch (p->data[0]) {
671 case 0:
672 printf("Unspecified\n");
673 break;
674 case 1:
675 printf("Static Address\n");
676 break;
677 case 2:
678 printf("DHCP Address\n");
679 break;
680 case 3:
681 printf("BIOS Assigned Address\n");
682 break;
683 default:
684 printf("Other\n");
685 break;
686 }
687 }
688
689 p = get_lan_param(intf, chan, IPMI_LANP_IP_ADDR);
690 if (p == NULL)
691 return -1;
692 if (p->data != NULL)
693 printf("%-24s: %d.%d.%d.%d\n", p->desc,
694 p->data[0], p->data[1], p->data[2], p->data[3]);
695
696 p = get_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK);
697 if (p == NULL)
698 return -1;
699 if (p->data != NULL)
700 printf("%-24s: %d.%d.%d.%d\n", p->desc,
701 p->data[0], p->data[1], p->data[2], p->data[3]);
702
703 p = get_lan_param(intf, chan, IPMI_LANP_MAC_ADDR);
704 if (p == NULL)
705 return -1;
706 if (p->data != NULL)
707 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
708 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
709
710 p = get_lan_param(intf, chan, IPMI_LANP_SNMP_STRING);
711 if (p == NULL)
712 return -1;
713 if (p->data != NULL)
714 printf("%-24s: %s\n", p->desc, p->data);
715
716 p = get_lan_param(intf, chan, IPMI_LANP_IP_HEADER);
717 if (p == NULL)
718 return -1;
719 if (p->data != NULL)
720 printf("%-24s: TTL=0x%02x Flags=0x%02x Precedence=0x%02x TOS=0x%02x\n",
721 p->desc, p->data[0], p->data[1] & 0xe0, p->data[2] & 0xe0, p->data[2] & 0x1e);
722
723 p = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
724 if (p == NULL)
725 return -1;
726 if (p->data != NULL)
727 printf("%-24s: ARP Responses %sabled, Gratuitous ARP %sabled\n", p->desc,
728 (p->data[0] & 2) ? "En" : "Dis", (p->data[0] & 1) ? "En" : "Dis");
729
730 p = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP);
731 if (p == NULL)
732 return -1;
733 if (p->data != NULL)
734 printf("%-24s: %.1f seconds\n", p->desc, (float)((p->data[0] + 1) / 2));
735
736 p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP);
737 if (p == NULL)
738 return -1;
739 if (p->data != NULL)
740 printf("%-24s: %d.%d.%d.%d\n", p->desc,
741 p->data[0], p->data[1], p->data[2], p->data[3]);
742
743 p = get_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC);
744 if (p == NULL)
745 return -1;
746 if (p->data != NULL)
747 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
748 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
749
750 p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP);
751 if (p == NULL)
752 return -1;
753 if (p->data != NULL)
754 printf("%-24s: %d.%d.%d.%d\n", p->desc,
755 p->data[0], p->data[1], p->data[2], p->data[3]);
756
757 p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC);
758 if (p == NULL)
759 return -1;
760 if (p->data != NULL)
761 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
762 p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
763
764 p = get_lan_param(intf, chan, IPMI_LANP_VLAN_ID);
765 if (p != NULL && p->data != NULL) {
766 int id = ((p->data[1] & 0x0f) << 8) + p->data[0];
767 if (p->data[1] & 0x80)
768 printf("%-24s: %d\n", p->desc, id);
769 else
770 printf("%-24s: Disabled\n", p->desc);
771 }
772
773 p = get_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY);
774 if (p != NULL && p->data != NULL)
775 printf("%-24s: %d\n", p->desc, p->data[0] & 0x07);
776
777 /* Determine supported Cipher Suites -- Requires two calls */
778 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHER_SUPPORT);
779 if (p == NULL)
780 return -1;
781 else if (p->data != NULL)
782 {
783 unsigned char cipher_suite_count = p->data[0];
784 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHERS);
785 if (p == NULL)
786 return -1;
787
788 printf("%-24s: ", p->desc);
789
790 /* Now we're dangerous. There are only 15 fixed cipher
791 suite IDs, but the spec allows for 16 in the return data.*/
792 if ((p->data != NULL) && (p->data_len <= 17))
793 {
794 unsigned int i;
795 for (i = 0; (i < 16) && (i < cipher_suite_count); ++i)
796 {
797 printf("%s%d",
798 (i > 0? ",": ""),
799 p->data[i + 1]);
800 }
801 printf("\n");
802 }
803 else
804 {
805 printf("None\n");
806 }
807 }
808
809 /* RMCP+ Messaging Cipher Suite Privilege Levels */
810 /* These are the privilege levels for the 15 fixed cipher suites */
811 p = get_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS);
812 if (p == NULL)
813 return -1;
814 if ((p->data != NULL) && (p->data_len == 9))
815 {
816 printf("%-24s: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", p->desc,
817 priv_level_to_char(p->data[1] & 0x0F),
818 priv_level_to_char(p->data[1] >> 4),
819 priv_level_to_char(p->data[2] & 0x0F),
820 priv_level_to_char(p->data[2] >> 4),
821 priv_level_to_char(p->data[3] & 0x0F),
822 priv_level_to_char(p->data[3] >> 4),
823 priv_level_to_char(p->data[4] & 0x0F),
824 priv_level_to_char(p->data[4] >> 4),
825 priv_level_to_char(p->data[5] & 0x0F),
826 priv_level_to_char(p->data[5] >> 4),
827 priv_level_to_char(p->data[6] & 0x0F),
828 priv_level_to_char(p->data[6] >> 4),
829 priv_level_to_char(p->data[7] & 0x0F),
830 priv_level_to_char(p->data[7] >> 4),
831 priv_level_to_char(p->data[8] & 0x0F));
832
833 /* Now print a legend */
834 printf("%-24s: %s\n", "", " X=Cipher Suite Unused");
835 printf("%-24s: %s\n", "", " c=CALLBACK");
836 printf("%-24s: %s\n", "", " u=USER");
837 printf("%-24s: %s\n", "", " o=OPERATOR");
838 printf("%-24s: %s\n", "", " a=ADMIN");
839 printf("%-24s: %s\n", "", " O=OEM");
840 }
841 else
842 printf("%-24s: Not Available\n", p->desc);
843
844 /* Bad Password Threshold */
845 p = get_lan_param(intf, chan, IPMI_LANP_BAD_PASS_THRESH);
846 if (p == NULL)
847 return -1;
848 if ((p->data != NULL) && (p->data_len == 6)) {
849 int tmp;
850
851 printf("%-24s: %d\n", p->desc, p->data[1]);
852 printf("%-24s: %s\n", "Invalid password disable",
853 p->data[0] & 1 ? "yes" : "no" );
854 tmp = p->data[2] + (p->data[3] << 8);
855 printf("%-24s: %d\n", "Attempt Count Reset Int.", tmp * 10);
856 tmp = p->data[4] + (p->data[5] << 8);
857 printf("%-24s: %d\n", "User Lockout Interval", tmp * 10);
858 } else {
859 printf("%-24s: Not Available\n", p->desc);
860 }
861
862 return 0;
863 }
864
865 /* Configure Authentication Types */
866 /* TODO - probably some code duplication going on ??? */
867 static int
ipmi_lan_set_auth(struct ipmi_intf * intf,uint8_t chan,char * level,char * types)868 ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * types)
869 {
870 uint8_t data[5];
871 uint8_t authtype = 0;
872 char * p;
873 struct lan_param * lp;
874
875 if (level == NULL || types == NULL)
876 return -1;
877
878 lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE);
879 if (lp == NULL)
880 return -1;
881 if (lp->data == NULL)
882 return -1;
883
884 lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x",
885 lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]);
886
887 memset(data, 0, 5);
888 memcpy(data, lp->data, 5);
889
890 p = types;
891 while (p) {
892 if (strncasecmp(p, "none", 4) == 0)
893 authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE;
894 else if (strncasecmp(p, "md2", 3) == 0)
895 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2;
896 else if (strncasecmp(p, "md5", 3) == 0)
897 authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5;
898 else if ((strncasecmp(p, "password", 8) == 0) ||
899 (strncasecmp(p, "key", 3) == 0))
900 authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY;
901 else if (strncasecmp(p, "oem", 3) == 0)
902 authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM;
903 else
904 lprintf(LOG_WARNING, "Invalid authentication type: %s", p);
905 p = strchr(p, ',');
906 if (p)
907 p++;
908 }
909
910 p = level;
911 while (p) {
912 if (strncasecmp(p, "callback", 8) == 0)
913 data[0] = authtype;
914 else if (strncasecmp(p, "user", 4) == 0)
915 data[1] = authtype;
916 else if (strncasecmp(p, "operator", 8) == 0)
917 data[2] = authtype;
918 else if (strncasecmp(p, "admin", 5) == 0)
919 data[3] = authtype;
920 else
921 lprintf(LOG_WARNING, "Invalid authentication level: %s", p);
922 p = strchr(p, ',');
923 if (p)
924 p++;
925 }
926
927 if (verbose > 1)
928 printbuf(data, 5, "authtype data");
929
930 return set_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE, data, 5);
931 }
932
933 static int
ipmi_lan_set_password(struct ipmi_intf * intf,uint8_t user_id,const char * password)934 ipmi_lan_set_password(struct ipmi_intf *intf,
935 uint8_t user_id, const char *password)
936 {
937 int ccode = 0;
938 ccode = _ipmi_set_user_password(intf, user_id,
939 IPMI_PASSWORD_SET_PASSWORD, password, 0);
940 if (eval_ccode(ccode) != 0) {
941 lprintf(LOG_ERR, "Unable to Set LAN Password for user %d",
942 user_id);
943 return (-1);
944 }
945 /* adjust our session password
946 * or we will no longer be able to communicate with BMC
947 */
948 ipmi_intf_session_set_password(intf, (char *)password);
949 printf("Password %s for user %d\n",
950 (password == NULL) ? "cleared" : "set", user_id);
951
952 return 0;
953 }
954
955 /* ipmi_set_alert_enable - enable/disable PEF alerting for given channel.
956 *
957 * @channel - IPMI channel
958 * @enable - whether to enable/disable PEF alerting for given channel
959 *
960 * returns - 0 on success, (-1) on error.
961 */
962 static int
ipmi_set_alert_enable(struct ipmi_intf * intf,uint8_t channel,uint8_t enable)963 ipmi_set_alert_enable(struct ipmi_intf *intf, uint8_t channel, uint8_t enable)
964 {
965 struct channel_access_t channel_access;
966 int ccode = 0;
967 memset(&channel_access, 0, sizeof(channel_access));
968 channel_access.channel = channel;
969 ccode = _ipmi_get_channel_access(intf, &channel_access, 0);
970 if (eval_ccode(ccode) != 0) {
971 lprintf(LOG_ERR,
972 "Unable to Get Channel Access(non-volatile) for channel %d",
973 channel);
974 return (-1);
975 }
976 if (enable != 0) {
977 channel_access.alerting = 1;
978 } else {
979 channel_access.alerting = 0;
980 }
981 /* non-volatile */
982 ccode = _ipmi_set_channel_access(intf, channel_access, 1, 0);
983 if (eval_ccode(ccode) != 0) {
984 lprintf(LOG_ERR,
985 "Unable to Set Channel Access(non-volatile) for channel %d",
986 channel);
987 return (-1);
988 }
989 /* volatile */
990 ccode = _ipmi_set_channel_access(intf, channel_access, 2, 0);
991 if (eval_ccode(ccode) != 0) {
992 lprintf(LOG_ERR,
993 "Unable to Set Channel Access(volatile) for channel %d",
994 channel);
995 return (-1);
996 }
997 printf("PEF alerts for channel %d %s.\n",
998 channel,
999 (enable) ? "enabled" : "disabled");
1000 return 0;
1001 }
1002
1003 /* ipmi_set_channel_access - enable/disable IPMI messaging for given channel and
1004 * set Privilege Level to Administrator.
1005 *
1006 * @channel - IPMI channel
1007 * @enable - whether to enable/disable IPMI messaging for given channel.
1008 *
1009 * returns - 0 on success, (-1) on error
1010 */
1011 static int
ipmi_set_channel_access(struct ipmi_intf * intf,uint8_t channel,uint8_t enable)1012 ipmi_set_channel_access(struct ipmi_intf *intf, uint8_t channel,
1013 uint8_t enable)
1014 {
1015 struct channel_access_t channel_access;
1016 int ccode = 0;
1017 memset(&channel_access, 0, sizeof(channel_access));
1018 channel_access.channel = channel;
1019 /* Get Non-Volatile Channel Access first */
1020 ccode = _ipmi_get_channel_access(intf, &channel_access, 0);
1021 if (eval_ccode(ccode) != 0) {
1022 lprintf(LOG_ERR,
1023 "Unable to Get Channel Access(non-volatile) for channel %d",
1024 channel);
1025 return (-1);
1026 }
1027
1028 if (enable != 0) {
1029 channel_access.access_mode = 2;
1030 } else {
1031 channel_access.access_mode = 0;
1032 }
1033 channel_access.privilege_limit = 0x04;
1034 ccode = _ipmi_set_channel_access(intf, channel_access, 1, 1);
1035 if (eval_ccode(ccode) != 0) {
1036 lprintf(LOG_ERR,
1037 "Unable to Set Channel Access(non-volatile) for channel %d",
1038 channel);
1039 return (-1);
1040 }
1041
1042 memset(&channel_access, 0, sizeof(channel_access));
1043 channel_access.channel = channel;
1044 /* Get Volatile Channel Access */
1045 ccode = _ipmi_get_channel_access(intf, &channel_access, 1);
1046 if (eval_ccode(ccode) != 0) {
1047 lprintf(LOG_ERR,
1048 "Unable to Get Channel Access(volatile) for channel %d",
1049 channel);
1050 return (-1);
1051 }
1052
1053 if (enable != 0) {
1054 channel_access.access_mode = 2;
1055 } else {
1056 channel_access.access_mode = 0;
1057 }
1058 channel_access.privilege_limit = 0x04;
1059 ccode = _ipmi_set_channel_access(intf, channel_access, 2, 2);
1060 if (eval_ccode(ccode) != 0) {
1061 lprintf(LOG_ERR,
1062 "Unable to Set Channel Access(volatile) for channel %d",
1063 channel);
1064 return (-1);
1065 }
1066
1067 /* can't send close session if access off so abort instead */
1068 if (enable == 0) {
1069 intf->abort = 1;
1070 }
1071 printf("Set Channel Access for channel %d was successful.\n",
1072 channel);
1073 return 0;
1074 }
1075
1076 /* ipmi_set_user_access - set admin access for given user and channel.
1077 *
1078 * @intf - IPMI interface
1079 * @channel - IPMI channel
1080 * @user_id - IPMI User ID
1081 *
1082 * returns - 0 on success, (-1) on error.
1083 */
1084 static int
ipmi_set_user_access(struct ipmi_intf * intf,uint8_t channel,uint8_t user_id)1085 ipmi_set_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id)
1086 {
1087 struct user_access_t user_access;
1088 int ccode = 0;
1089 memset(&user_access, 0, sizeof(user_access));
1090 user_access.channel = channel;
1091 user_access.user_id = user_id;
1092 user_access.privilege_limit = 0x04;
1093
1094 ccode = _ipmi_set_user_access(intf, &user_access, 1);
1095 if (eval_ccode(ccode) != 0) {
1096 lprintf(LOG_ERR, "Set User Access for channel %d failed",
1097 channel);
1098 return (-1);
1099 } else {
1100 printf("Set User Access for channel %d was successful.",
1101 channel);
1102 return 0;
1103 }
1104 }
1105
1106 /* get_cmdline_macaddr - parse-out MAC address from given string and store it
1107 * into buffer.
1108 *
1109 * @arg: string to be parsed.
1110 * @buf: buffer of 6 to hold parsed MAC address.
1111 *
1112 * returns zero on success, (-1) on error and error message is printed-out.
1113 */
1114 static int
get_cmdline_macaddr(char * arg,uint8_t * buf)1115 get_cmdline_macaddr(char *arg, uint8_t *buf)
1116 {
1117 uint32_t m1 = 0;
1118 uint32_t m2 = 0;
1119 uint32_t m3 = 0;
1120 uint32_t m4 = 0;
1121 uint32_t m5 = 0;
1122 uint32_t m6 = 0;
1123 if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
1124 &m1, &m2, &m3, &m4, &m5, &m6) != 6) {
1125 lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
1126 return -1;
1127 }
1128 if (m1 > UINT8_MAX || m2 > UINT8_MAX
1129 || m3 > UINT8_MAX || m4 > UINT8_MAX
1130 || m5 > UINT8_MAX || m6 > UINT8_MAX) {
1131 lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
1132 return -1;
1133 }
1134 buf[0] = (uint8_t)m1;
1135 buf[1] = (uint8_t)m2;
1136 buf[2] = (uint8_t)m3;
1137 buf[3] = (uint8_t)m4;
1138 buf[4] = (uint8_t)m5;
1139 buf[5] = (uint8_t)m6;
1140 return 0;
1141 }
1142
1143
1144 static int
get_cmdline_cipher_suite_priv_data(char * arg,uint8_t * buf)1145 get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
1146 {
1147 int i, ret = 0;
1148
1149 if (strlen(arg) != 15)
1150 {
1151 lprintf(LOG_ERR, "Invalid privilege specification length: %d",
1152 strlen(arg));
1153 return -1;
1154 }
1155
1156 /*
1157 * The first byte is reserved (0). The rest of the buffer is setup
1158 * so that each nibble holds the maximum privilege level available for
1159 * that cipher suite number. The number of nibbles (15) matches the number
1160 * of fixed cipher suite IDs. This command documentation mentions 16 IDs
1161 * but table 22-19 shows that there are only 15 (0-14).
1162 *
1163 * data 1 - reserved
1164 * data 2 - maximum priv level for first (LSN) and second (MSN) ciphers
1165 * data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers
1166 * data 9 - maximum priv level for 15th (LSN) cipher.
1167 */
1168 memset(buf, 0, 9);
1169 for (i = 0; i < 15; ++i)
1170 {
1171 unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN;
1172
1173 switch (arg[i])
1174 {
1175 case 'X':
1176 priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */
1177 break;
1178 case 'c':
1179 priv_level = IPMI_SESSION_PRIV_CALLBACK; /* 1 */
1180 break;
1181 case 'u':
1182 priv_level = IPMI_SESSION_PRIV_USER; /* 2 */
1183 break;
1184 case 'o':
1185 priv_level = IPMI_SESSION_PRIV_OPERATOR; /* 3 */
1186 break;
1187 case 'a':
1188 priv_level = IPMI_SESSION_PRIV_ADMIN; /* 4 */
1189 break;
1190 case 'O':
1191 priv_level = IPMI_SESSION_PRIV_OEM; /* 5 */
1192 break;
1193 default:
1194 lprintf(LOG_ERR, "Invalid privilege specification char: %c",
1195 arg[i]);
1196 ret = -1;
1197 break;
1198 }
1199
1200 if (ret != 0)
1201 break;
1202 else
1203 {
1204 if ((i + 1) % 2)
1205 {
1206 // Odd number cipher suites will be in the LSN
1207 buf[1 + (i / 2)] += priv_level;
1208 }
1209 else
1210 {
1211 // Even number cipher suites will be in the MSN
1212 buf[1 + (i / 2)] += (priv_level << 4);
1213 }
1214 }
1215 }
1216
1217 return ret;
1218 }
1219
1220
1221 static int
get_cmdline_ipaddr(char * arg,uint8_t * buf)1222 get_cmdline_ipaddr(char * arg, uint8_t * buf)
1223 {
1224 uint32_t ip1, ip2, ip3, ip4;
1225 if (sscanf(arg,
1226 "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
1227 &ip1, &ip2, &ip3, &ip4) != 4) {
1228 lprintf(LOG_ERR, "Invalid IP address: %s", arg);
1229 return (-1);
1230 }
1231 if (ip1 > UINT8_MAX || ip2 > UINT8_MAX
1232 || ip3 > UINT8_MAX || ip4 > UINT8_MAX) {
1233 lprintf(LOG_ERR, "Invalid IP address: %s", arg);
1234 return (-1);
1235 }
1236 buf[0] = (uint8_t)ip1;
1237 buf[1] = (uint8_t)ip2;
1238 buf[2] = (uint8_t)ip3;
1239 buf[3] = (uint8_t)ip4;
1240 return 0;
1241 }
1242
1243 static int
ipmi_lan_set_vlan_id(struct ipmi_intf * intf,uint8_t chan,char * string)1244 ipmi_lan_set_vlan_id(struct ipmi_intf *intf, uint8_t chan, char *string)
1245 {
1246 uint8_t data[2];
1247 int rc;
1248
1249 if (string == NULL) {
1250 data[0] = 0;
1251 data[1] = 0;
1252 }
1253 else {
1254 int id = 0;
1255 if (str2int(string, &id) != 0) {
1256 lprintf(LOG_ERR, "Given VLAN ID '%s' is invalid.", string);
1257 return (-1);
1258 }
1259
1260 if (id < 1 || id > 4094) {
1261 lprintf(LOG_NOTICE, "VLAN ID must be between 1 and 4094.");
1262 return (-1);
1263 }
1264 else {
1265 data[0] = (uint8_t)id;
1266 data[1] = (uint8_t)(id >> 8) | 0x80;
1267 }
1268 }
1269 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_ID, data, 2);
1270 return rc;
1271 }
1272
1273 static int
ipmi_lan_set_vlan_priority(struct ipmi_intf * intf,uint8_t chan,char * string)1274 ipmi_lan_set_vlan_priority(struct ipmi_intf *intf, uint8_t chan, char *string)
1275 {
1276 uint8_t data;
1277 int rc;
1278 int priority = 0;
1279 if (str2int(string, &priority) != 0) {
1280 lprintf(LOG_ERR, "Given VLAN priority '%s' is invalid.", string);
1281 return (-1);
1282 }
1283
1284 if (priority < 0 || priority > 7) {
1285 lprintf(LOG_NOTICE, "VLAN priority must be between 0 and 7.");
1286 return (-1);
1287 }
1288 data = (uint8_t)priority;
1289 rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY, &data, 1);
1290 return rc;
1291 }
1292
1293 static void
print_lan_set_bad_pass_thresh_usage(void)1294 print_lan_set_bad_pass_thresh_usage(void)
1295 {
1296 lprintf(LOG_NOTICE,
1297 "lan set <chanel> bad_pass_thresh <thresh_num> <1|0> <reset_interval> <lockout_interval>\n"
1298 " <thresh_num> Bad Pasword Threshold number.\n"
1299 " <1|0> 1 = generate a Session Audit sensor event.\n"
1300 " 0 = do not generate an event.\n"
1301 " <reset_interval> Attempt Count Reset Interval. In tens of seconds.\n"
1302 " <lockount_interval> User Lockout Interval. In tens of seconds.");
1303 }
1304
1305 /* get_cmdline_bad_pass_thresh - parse-out bad password threshold from given
1306 * string and store it into buffer.
1307 *
1308 * @arg: string to be parsed.
1309 * @buf: buffer of 6 to hold parsed Bad Password Threshold.
1310 *
1311 * returns zero on success, (-1) on error.
1312 */
1313 static int
get_cmdline_bad_pass_thresh(char * argv[],uint8_t * buf)1314 get_cmdline_bad_pass_thresh(char *argv[], uint8_t *buf)
1315 {
1316 uint16_t reset, lockout;
1317
1318 if (str2uchar(argv[0], &buf[1])) {
1319 return -1;
1320 }
1321
1322 if (str2uchar(argv[1], &buf[0]) || buf[0] > 1) {
1323 return -1;
1324 }
1325
1326 if (str2ushort(argv[2], &reset)) {
1327 return -1;
1328 }
1329
1330 if (str2ushort(argv[3], &lockout)) {
1331 return -1;
1332 }
1333
1334 /* store parsed data */
1335 buf[2] = reset & 0xFF;
1336 buf[3] = reset >> 8;
1337 buf[4] = lockout & 0xFF;
1338 buf[5] = lockout >> 8;
1339 return 0;
1340 }
1341
1342 static int
ipmi_lan_set(struct ipmi_intf * intf,int argc,char ** argv)1343 ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
1344 {
1345 uint8_t data[32];
1346 uint8_t chan;
1347 int rc = 0;
1348
1349 if (argc < 2) {
1350 print_lan_set_usage();
1351 return (-1);
1352 }
1353
1354 if (strncmp(argv[0], "help", 4) == 0 ||
1355 strncmp(argv[1], "help", 4) == 0) {
1356 print_lan_set_usage();
1357 return 0;
1358 }
1359
1360 if (str2uchar(argv[0], &chan) != 0) {
1361 lprintf(LOG_ERR, "Invalid channel: %s", argv[0]);
1362 return (-1);
1363 }
1364
1365 /* find type of channel and only accept 802.3 LAN */
1366 if (!is_lan_channel(intf, chan)) {
1367 lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan);
1368 print_lan_set_usage();
1369 return -1;
1370 }
1371
1372 memset(&data, 0, sizeof(data));
1373
1374 /* set user access */
1375 if (strncmp(argv[1], "user", 4) == 0) {
1376 rc = ipmi_set_user_access(intf, chan, 1);
1377 }
1378 /* set channel access mode */
1379 else if (strncmp(argv[1], "access", 6) == 0) {
1380 if (argc < 3) {
1381 print_lan_set_access_usage();
1382 return (-1);
1383 }
1384 else if (strncmp(argv[2], "help", 4) == 0) {
1385 print_lan_set_access_usage();
1386 return 0;
1387 }
1388 else if (strncmp(argv[2], "on", 2) == 0) {
1389 rc = ipmi_set_channel_access(intf, chan, 1);
1390 }
1391 else if (strncmp(argv[2], "off", 3) == 0) {
1392 rc = ipmi_set_channel_access(intf, chan, 0);
1393 }
1394 else {
1395 print_lan_set_access_usage();
1396 return (-1);
1397 }
1398 }
1399 /* set ARP control */
1400 else if (strncmp(argv[1], "arp", 3) == 0) {
1401 if (argc < 3) {
1402 print_lan_set_arp_usage();
1403 return (-1);
1404 }
1405 else if (strncmp(argv[2], "help", 4) == 0) {
1406 print_lan_set_arp_usage();
1407 }
1408 else if (strncmp(argv[2], "interval", 8) == 0) {
1409 uint8_t interval = 0;
1410 if (str2uchar(argv[3], &interval) != 0) {
1411 lprintf(LOG_ERR, "Given ARP interval '%s' is invalid.", argv[3]);
1412 return (-1);
1413 }
1414 rc = lan_set_arp_interval(intf, chan, interval);
1415 }
1416 else if (strncmp(argv[2], "generate", 8) == 0) {
1417 if (argc < 4) {
1418 print_lan_set_arp_usage();
1419 return (-1);
1420 }
1421 else if (strncmp(argv[3], "on", 2) == 0)
1422 rc = lan_set_arp_generate(intf, chan, 1);
1423 else if (strncmp(argv[3], "off", 3) == 0)
1424 rc = lan_set_arp_generate(intf, chan, 0);
1425 else {
1426 print_lan_set_arp_usage();
1427 return (-1);
1428 }
1429 }
1430 else if (strncmp(argv[2], "respond", 7) == 0) {
1431 if (argc < 4) {
1432 print_lan_set_arp_usage();
1433 return (-1);
1434 }
1435 else if (strncmp(argv[3], "on", 2) == 0)
1436 rc = lan_set_arp_respond(intf, chan, 1);
1437 else if (strncmp(argv[3], "off", 3) == 0)
1438 rc = lan_set_arp_respond(intf, chan, 0);
1439 else {
1440 print_lan_set_arp_usage();
1441 return (-1);
1442 }
1443 }
1444 else {
1445 print_lan_set_arp_usage();
1446 }
1447 }
1448 /* set authentication types */
1449 else if (strncmp(argv[1], "auth", 4) == 0) {
1450 if (argc < 3) {
1451 print_lan_set_auth_usage();
1452 return (-1);
1453 }
1454 else if (strncmp(argv[2], "help", 4) == 0) {
1455 print_lan_set_auth_usage();
1456 return 0;
1457 } else {
1458 rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]);
1459 }
1460 }
1461 /* ip address source */
1462 else if (strncmp(argv[1], "ipsrc", 5) == 0) {
1463 if (argc < 3) {
1464 print_lan_set_ipsrc_usage();
1465 return (-1);
1466 }
1467 else if (strncmp(argv[2], "help", 4) == 0) {
1468 print_lan_set_ipsrc_usage();
1469 return 0;
1470 }
1471 else if (strncmp(argv[2], "none", 4) == 0)
1472 data[0] = 0;
1473 else if (strncmp(argv[2], "static", 5) == 0)
1474 data[0] = 1;
1475 else if (strncmp(argv[2], "dhcp", 4) == 0)
1476 data[0] = 2;
1477 else if (strncmp(argv[2], "bios", 4) == 0)
1478 data[0] = 3;
1479 else {
1480 print_lan_set_ipsrc_usage();
1481 return -1;
1482 }
1483 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC, data, 1);
1484 }
1485 /* session password
1486 * not strictly a lan setting, but its used for lan connections */
1487 else if (strncmp(argv[1], "password", 8) == 0) {
1488 rc = ipmi_lan_set_password(intf, 1, argv[2]);
1489 }
1490 /* snmp community string */
1491 else if (strncmp(argv[1], "snmp", 4) == 0) {
1492 if (argc < 3) {
1493 print_lan_set_snmp_usage();
1494 return (-1);
1495 }
1496 else if (strncmp(argv[2], "help", 4) == 0) {
1497 print_lan_set_snmp_usage();
1498 return 0;
1499 } else {
1500 memcpy(data, argv[2], __min(strlen(argv[2]), 18));
1501 printf("Setting LAN %s to %s\n",
1502 ipmi_lan_params[IPMI_LANP_SNMP_STRING].desc, data);
1503 rc = set_lan_param(intf, chan, IPMI_LANP_SNMP_STRING, data, 18);
1504 }
1505 }
1506 /* ip address */
1507 else if (strncmp(argv[1], "ipaddr", 6) == 0) {
1508 if(argc != 3)
1509 {
1510 print_lan_set_usage();
1511 return -1;
1512 }
1513 rc = get_cmdline_ipaddr(argv[2], data);
1514 if (rc == 0) {
1515 printf("Setting LAN %s to %d.%d.%d.%d\n",
1516 ipmi_lan_params[IPMI_LANP_IP_ADDR].desc,
1517 data[0], data[1], data[2], data[3]);
1518 rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4);
1519 }
1520 }
1521 /* network mask */
1522 else if (strncmp(argv[1], "netmask", 7) == 0) {
1523 if(argc != 3)
1524 {
1525 print_lan_set_usage();
1526 return -1;
1527 }
1528 rc = get_cmdline_ipaddr(argv[2], data);
1529 if (rc == 0) {
1530 printf("Setting LAN %s to %d.%d.%d.%d\n",
1531 ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc,
1532 data[0], data[1], data[2], data[3]);
1533 rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4);
1534 }
1535 }
1536 /* mac address */
1537 else if (strncmp(argv[1], "macaddr", 7) == 0) {
1538 if(argc != 3)
1539 {
1540 print_lan_set_usage();
1541 return -1;
1542 }
1543 rc = get_cmdline_macaddr(argv[2], data);
1544 if (rc == 0) {
1545 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1546 ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc,
1547 data[0], data[1], data[2], data[3], data[4], data[5]);
1548 rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6);
1549 }
1550 }
1551 /* default gateway settings */
1552 else if (strncmp(argv[1], "defgw", 5) == 0) {
1553 if (argc < 4) {
1554 print_lan_set_defgw_usage();
1555 return (-1);
1556 }
1557 else if (strncmp(argv[2], "help", 4) == 0) {
1558 print_lan_set_defgw_usage();
1559 return 0;
1560 }
1561 else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
1562 (get_cmdline_ipaddr(argv[3], data) == 0)) {
1563 printf("Setting LAN %s to %d.%d.%d.%d\n",
1564 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_IP].desc,
1565 data[0], data[1], data[2], data[3]);
1566 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4);
1567 }
1568 else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
1569 (get_cmdline_macaddr(argv[3], data) == 0)) {
1570 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1571 ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc,
1572 data[0], data[1], data[2], data[3], data[4], data[5]);
1573 rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6);
1574 }
1575 else {
1576 print_lan_set_usage();
1577 return -1;
1578 }
1579 }
1580 /* backup gateway settings */
1581 else if (strncmp(argv[1], "bakgw", 5) == 0) {
1582 if (argc < 4) {
1583 print_lan_set_bakgw_usage();
1584 return (-1);
1585 }
1586 else if (strncmp(argv[2], "help", 4) == 0) {
1587 print_lan_set_bakgw_usage();
1588 return 0;
1589 }
1590 else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
1591 (get_cmdline_ipaddr(argv[3], data) == 0)) {
1592 printf("Setting LAN %s to %d.%d.%d.%d\n",
1593 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_IP].desc,
1594 data[0], data[1], data[2], data[3]);
1595 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4);
1596 }
1597 else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
1598 (get_cmdline_macaddr(argv[3], data) == 0)) {
1599 printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1600 ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc,
1601 data[0], data[1], data[2], data[3], data[4], data[5]);
1602 rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6);
1603 }
1604 else {
1605 print_lan_set_usage();
1606 return -1;
1607 }
1608 }
1609 else if (strncasecmp(argv[1], "vlan", 4) == 0) {
1610 if (argc < 4) {
1611 print_lan_set_vlan_usage();
1612 return (-1);
1613 }
1614 else if (strncmp(argv[2], "help", 4) == 0) {
1615 print_lan_set_vlan_usage();
1616 return 0;
1617 }
1618 else if (strncasecmp(argv[2], "id", 2) == 0) {
1619 if (strncasecmp(argv[3], "off", 3) == 0) {
1620 ipmi_lan_set_vlan_id(intf, chan, NULL);
1621 }
1622 else {
1623 ipmi_lan_set_vlan_id(intf, chan, argv[3]);
1624 }
1625 }
1626 else if (strncasecmp(argv[2], "priority", 8) == 0) {
1627 ipmi_lan_set_vlan_priority(intf, chan, argv[3]);
1628 }
1629 else {
1630 print_lan_set_vlan_usage();
1631 return (-1);
1632 }
1633 }
1634 /* set PEF alerting on or off */
1635 else if (strncasecmp(argv[1], "alert", 5) == 0) {
1636 if (argc < 3) {
1637 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'");
1638 return (-1);
1639 }
1640 else if (strncasecmp(argv[2], "on", 2) == 0 ||
1641 strncasecmp(argv[2], "enable", 6) == 0) {
1642 printf("Enabling PEF alerts for LAN channel %d\n", chan);
1643 rc = ipmi_set_alert_enable(intf, chan, 1);
1644 }
1645 else if (strncasecmp(argv[2], "off", 3) == 0 ||
1646 strncasecmp(argv[2], "disable", 7) == 0) {
1647 printf("Disabling PEF alerts for LAN channel %d\n", chan);
1648 rc = ipmi_set_alert_enable(intf, chan, 0);
1649 }
1650 else {
1651 lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'");
1652 return 0;
1653 }
1654 }
1655 /* RMCP+ cipher suite privilege levels */
1656 else if (strncmp(argv[1], "cipher_privs", 12) == 0)
1657 {
1658 if (argc != 3) {
1659 print_lan_set_cipher_privs_usage();
1660 return (-1);
1661 }
1662 else if ((strncmp(argv[2], "help", 4) == 0) ||
1663 get_cmdline_cipher_suite_priv_data(argv[2], data))
1664 {
1665 print_lan_set_cipher_privs_usage();
1666 return 0;
1667 }
1668 else
1669 {
1670 rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9);
1671 }
1672 }
1673 else if (strncmp(argv[1], "bad_pass_thresh", 15) == 0)
1674 {
1675 if (argc == 3 && strncmp(argv[2], "help", 4) == 0) {
1676 print_lan_set_bad_pass_thresh_usage();
1677 return 0;
1678 }
1679 if (argc < 6 || get_cmdline_bad_pass_thresh(&argv[2], data)) {
1680 print_lan_set_bad_pass_thresh_usage();
1681 return (-1);
1682 }
1683 rc = set_lan_param(intf, chan, IPMI_LANP_BAD_PASS_THRESH, data, 6);
1684 }
1685 else {
1686 print_lan_set_usage();
1687 return (-1);
1688 }
1689
1690 return rc;
1691 }
1692
1693
1694 static int
is_alert_destination(struct ipmi_intf * intf,uint8_t channel,uint8_t alert)1695 is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert)
1696 {
1697 struct lan_param * p;
1698
1699 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST);
1700 if (p == NULL)
1701 return 0;
1702 if (p->data == NULL)
1703 return 0;
1704
1705 if (alert <= (p->data[0] & 0xf))
1706 return 1;
1707 else
1708 return 0;
1709 }
1710
1711 static int
ipmi_lan_alert_print(struct ipmi_intf * intf,uint8_t channel,uint8_t alert)1712 ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert)
1713 {
1714 # define PTYPE_LEN 4
1715 # define PADDR_LEN 13
1716 struct lan_param *lp_ptr = NULL;
1717 int isack = 0;
1718 uint8_t ptype[PTYPE_LEN];
1719 uint8_t paddr[PADDR_LEN];
1720
1721 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert);
1722 if (lp_ptr == NULL || lp_ptr->data == NULL
1723 || lp_ptr->data_len < PTYPE_LEN) {
1724 return (-1);
1725 }
1726 memcpy(ptype, lp_ptr->data, PTYPE_LEN);
1727
1728 lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert);
1729 if (lp_ptr == NULL || lp_ptr->data == NULL
1730 || lp_ptr->data_len < PADDR_LEN) {
1731 return (-1);
1732 }
1733 memcpy(paddr, lp_ptr->data, PADDR_LEN);
1734
1735 printf("%-24s: %d\n", "Alert Destination",
1736 ptype[0]);
1737
1738 if (ptype[1] & 0x80) {
1739 isack = 1;
1740 }
1741 printf("%-24s: %s\n", "Alert Acknowledge",
1742 isack ? "Acknowledged" : "Unacknowledged");
1743
1744 printf("%-24s: ", "Destination Type");
1745 switch (ptype[1] & 0x7) {
1746 case 0:
1747 printf("PET Trap\n");
1748 break;
1749 case 6:
1750 printf("OEM 1\n");
1751 break;
1752 case 7:
1753 printf("OEM 2\n");
1754 break;
1755 default:
1756 printf("Unknown\n");
1757 break;
1758 }
1759
1760 printf("%-24s: %d\n",
1761 isack ? "Acknowledge Timeout" : "Retry Interval",
1762 ptype[2]);
1763
1764 printf("%-24s: %d\n", "Number of Retries",
1765 ptype[3] & 0x7);
1766
1767 if ((paddr[1] & 0xf0) != 0) {
1768 /* unknown address format */
1769 printf("\n");
1770 return 0;
1771 }
1772
1773 printf("%-24s: %s\n", "Alert Gateway",
1774 (paddr[2] & 1) ? "Backup" : "Default");
1775
1776 printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address",
1777 paddr[3], paddr[4], paddr[5], paddr[6]);
1778
1779 printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address",
1780 paddr[7], paddr[8], paddr[9],
1781 paddr[10], paddr[11], paddr[12]);
1782
1783 printf("\n");
1784 return 0;
1785 }
1786
1787 static int
ipmi_lan_alert_print_all(struct ipmi_intf * intf,uint8_t channel)1788 ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel)
1789 {
1790 int j, ndest;
1791 struct lan_param * p;
1792
1793 p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST);
1794 if (p == NULL)
1795 return -1;
1796 if (p->data == NULL)
1797 return -1;
1798 ndest = p->data[0] & 0xf;
1799
1800 for (j=0; j<=ndest; j++) {
1801 ipmi_lan_alert_print(intf, channel, j);
1802 }
1803
1804 return 0;
1805 }
1806
1807 static int
ipmi_lan_alert_set(struct ipmi_intf * intf,uint8_t chan,uint8_t alert,int argc,char ** argv)1808 ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
1809 int argc, char ** argv)
1810 {
1811 struct lan_param * p;
1812 uint8_t data[32], temp[32];
1813 int rc = 0;
1814
1815 if (argc < 2) {
1816 print_lan_alert_set_usage();
1817 return (-1);
1818 }
1819
1820 if (strncmp(argv[0], "help", 4) == 0 ||
1821 strncmp(argv[1], "help", 4) == 0) {
1822 print_lan_alert_set_usage();
1823 return 0;
1824 }
1825
1826 memset(data, 0, sizeof(data));
1827 memset(temp, 0, sizeof(temp));
1828
1829 /* alert destination ip address */
1830 if (strncasecmp(argv[0], "ipaddr", 6) == 0 &&
1831 (get_cmdline_ipaddr(argv[1], temp) == 0)) {
1832 /* get current parameter */
1833 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1834 if (p == NULL) {
1835 return (-1);
1836 }
1837 memcpy(data, p->data, p->data_len);
1838 /* set new ipaddr */
1839 memcpy(data+3, temp, 4);
1840 printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert,
1841 data[3], data[4], data[5], data[6]);
1842 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1843 }
1844 /* alert destination mac address */
1845 else if (strncasecmp(argv[0], "macaddr", 7) == 0 &&
1846 (get_cmdline_macaddr(argv[1], temp) == 0)) {
1847 /* get current parameter */
1848 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1849 if (p == NULL) {
1850 return (-1);
1851 }
1852 memcpy(data, p->data, p->data_len);
1853 /* set new macaddr */
1854 memcpy(data+7, temp, 6);
1855 printf("Setting LAN Alert %d MAC Address to "
1856 "%02x:%02x:%02x:%02x:%02x:%02x\n", alert,
1857 data[7], data[8], data[9], data[10], data[11], data[12]);
1858 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1859 }
1860 /* alert destination gateway selector */
1861 else if (strncasecmp(argv[0], "gateway", 7) == 0) {
1862 /* get current parameter */
1863 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1864 if (p == NULL) {
1865 return (-1);
1866 }
1867 memcpy(data, p->data, p->data_len);
1868
1869 if (strncasecmp(argv[1], "def", 3) == 0 ||
1870 strncasecmp(argv[1], "default", 7) == 0) {
1871 printf("Setting LAN Alert %d to use Default Gateway\n", alert);
1872 data[2] = 0;
1873 }
1874 else if (strncasecmp(argv[1], "bak", 3) == 0 ||
1875 strncasecmp(argv[1], "backup", 6) == 0) {
1876 printf("Setting LAN Alert %d to use Backup Gateway\n", alert);
1877 data[2] = 1;
1878 }
1879 else {
1880 print_lan_alert_set_usage();
1881 return -1;
1882 }
1883
1884 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1885 }
1886 /* alert acknowledgement */
1887 else if (strncasecmp(argv[0], "ack", 3) == 0) {
1888 /* get current parameter */
1889 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1890 if (p == NULL) {
1891 return (-1);
1892 }
1893 memcpy(data, p->data, p->data_len);
1894
1895 if (strncasecmp(argv[1], "on", 2) == 0 ||
1896 strncasecmp(argv[1], "yes", 3) == 0) {
1897 printf("Setting LAN Alert %d to Acknowledged\n", alert);
1898 data[1] |= 0x80;
1899 }
1900 else if (strncasecmp(argv[1], "off", 3) == 0 ||
1901 strncasecmp(argv[1], "no", 2) == 0) {
1902 printf("Setting LAN Alert %d to Unacknowledged\n", alert);
1903 data[1] &= ~0x80;
1904 }
1905 else {
1906 print_lan_alert_set_usage();
1907 return -1;
1908 }
1909 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1910 }
1911 /* alert destination type */
1912 else if (strncasecmp(argv[0], "type", 4) == 0) {
1913 /* get current parameter */
1914 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1915 if (p == NULL) {
1916 return (-1);
1917 }
1918 memcpy(data, p->data, p->data_len);
1919
1920 if (strncasecmp(argv[1], "pet", 3) == 0) {
1921 printf("Setting LAN Alert %d destination to PET Trap\n", alert);
1922 data[1] &= ~0x07;
1923 }
1924 else if (strncasecmp(argv[1], "oem1", 4) == 0) {
1925 printf("Setting LAN Alert %d destination to OEM 1\n", alert);
1926 data[1] &= ~0x07;
1927 data[1] |= 0x06;
1928 }
1929 else if (strncasecmp(argv[1], "oem2", 4) == 0) {
1930 printf("Setting LAN Alert %d destination to OEM 2\n", alert);
1931 data[1] |= 0x07;
1932 }
1933 else {
1934 print_lan_alert_set_usage();
1935 return -1;
1936 }
1937 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1938 }
1939 /* alert acknowledge timeout or retry interval */
1940 else if (strncasecmp(argv[0], "time", 4) == 0) {
1941 /* get current parameter */
1942 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1943 if (p == NULL) {
1944 return (-1);
1945 }
1946 memcpy(data, p->data, p->data_len);
1947
1948 if (str2uchar(argv[1], &data[2]) != 0) {
1949 lprintf(LOG_ERR, "Invalid time: %s", argv[1]);
1950 return (-1);
1951 }
1952 printf("Setting LAN Alert %d timeout/retry to %d seconds\n", alert, data[2]);
1953 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1954 }
1955 /* number of retries */
1956 else if (strncasecmp(argv[0], "retry", 5) == 0) {
1957 /* get current parameter */
1958 p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1959 if (p == NULL) {
1960 return (-1);
1961 }
1962 memcpy(data, p->data, p->data_len);
1963
1964 if (str2uchar(argv[1], &data[3]) != 0) {
1965 lprintf(LOG_ERR, "Invalid retry: %s", argv[1]);
1966 return (-1);
1967 }
1968 data[3] = data[3] & 0x7;
1969 printf("Setting LAN Alert %d number of retries to %d\n", alert, data[3]);
1970 rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1971 }
1972 else {
1973 print_lan_alert_set_usage();
1974 return -1;
1975 }
1976
1977 return rc;
1978 }
1979
1980 static int
ipmi_lan_alert(struct ipmi_intf * intf,int argc,char ** argv)1981 ipmi_lan_alert(struct ipmi_intf * intf, int argc, char ** argv)
1982 {
1983 uint8_t alert;
1984 uint8_t channel = 1;
1985
1986 if (argc < 1) {
1987 print_lan_alert_print_usage();
1988 print_lan_alert_set_usage();
1989 return (-1);
1990 }
1991 else if (strncasecmp(argv[0], "help", 4) == 0) {
1992 print_lan_alert_print_usage();
1993 print_lan_alert_set_usage();
1994 return 0;
1995 }
1996
1997 /* alert print [channel] [alert] */
1998 if (strncasecmp(argv[0], "print", 5) == 0) {
1999 if (argc < 2) {
2000 channel = find_lan_channel(intf, 1);
2001 if (!is_lan_channel(intf, channel)) {
2002 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2003 return -1;
2004 }
2005 return ipmi_lan_alert_print_all(intf, channel);
2006 }
2007
2008 if (strncasecmp(argv[1], "help", 4) == 0) {
2009 print_lan_alert_print_usage();
2010 return 0;
2011 }
2012
2013 if (str2uchar(argv[1], &channel) != 0) {
2014 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2015 return (-1);
2016 }
2017 if (!is_lan_channel(intf, channel)) {
2018 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2019 return -1;
2020 }
2021
2022 if (argc < 3)
2023 return ipmi_lan_alert_print_all(intf, channel);
2024
2025 if (str2uchar(argv[2], &alert) != 0) {
2026 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]);
2027 return (-1);
2028 }
2029 if (is_alert_destination(intf, channel, alert) == 0) {
2030 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert);
2031 return -1;
2032 }
2033 return ipmi_lan_alert_print(intf, channel, alert);
2034 }
2035
2036 /* alert set <channel> <alert> [option] */
2037 if (strncasecmp(argv[0], "set", 3) == 0) {
2038 if (argc < 5) {
2039 print_lan_alert_set_usage();
2040 return (-1);
2041 }
2042 else if (strncasecmp(argv[1], "help", 4) == 0) {
2043 print_lan_alert_set_usage();
2044 return 0;
2045 }
2046
2047 if (str2uchar(argv[1], &channel) != 0) {
2048 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2049 return (-1);
2050 }
2051 if (!is_lan_channel(intf, channel)) {
2052 lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2053 return -1;
2054 }
2055
2056 if (str2uchar(argv[2], &alert) != 0) {
2057 lprintf(LOG_ERR, "Invalid alert: %s", argv[2]);
2058 return (-1);
2059 }
2060 if (is_alert_destination(intf, channel, alert) == 0) {
2061 lprintf(LOG_ERR, "Alert %d is not a valid destination", alert);
2062 return -1;
2063 }
2064
2065 return ipmi_lan_alert_set(intf, channel, alert, argc-3, &(argv[3]));
2066 }
2067
2068 return 0;
2069 }
2070
2071
2072 static int
ipmi_lan_stats_get(struct ipmi_intf * intf,uint8_t chan)2073 ipmi_lan_stats_get(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 uint16_t statsTemp;
2080
2081 if (!is_lan_channel(intf, chan)) {
2082 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan);
2083 return -1;
2084 }
2085
2086 /* From here, we are ready to get the stats */
2087
2088 msg_data[0] = chan;
2089 msg_data[1] = 0; /* Don't clear */
2090
2091 memset(&req, 0, sizeof(req));
2092 req.msg.netfn = IPMI_NETFN_TRANSPORT;
2093 req.msg.cmd = IPMI_LAN_GET_STAT;
2094 req.msg.data = msg_data;
2095 req.msg.data_len = 2;
2096
2097 rsp = intf->sendrecv(intf, &req);
2098 if (rsp == NULL) {
2099 lprintf(LOG_ERR, "Get LAN Stats command failed");
2100 return (-1);
2101 }
2102
2103 if (rsp->ccode > 0) {
2104 lprintf(LOG_ERR, "Get LAN Stats command failed: %s",
2105 val2str(rsp->ccode, completion_code_vals));
2106 return (-1);
2107 }
2108
2109 if (verbose > 1) {
2110 uint8_t counter;
2111 printf("--- Rx Stats ---\n");
2112 for (counter=0; counter<18; counter+=2) {
2113 printf("%02X", *(rsp->data + counter));
2114 printf(" %02X - ", *(rsp->data + counter+1));
2115 }
2116 printf("\n");
2117 }
2118
2119 statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1));
2120 printf("IP Rx Packet : %d\n", statsTemp);
2121
2122 statsTemp = ((*(rsp->data + 2)) << 8) | (*(rsp->data + 3));
2123 printf("IP Rx Header Errors : %u\n", statsTemp);
2124
2125 statsTemp = ((*(rsp->data + 4)) << 8) | (*(rsp->data + 5));
2126 printf("IP Rx Address Errors : %u\n", statsTemp);
2127
2128 statsTemp = ((*(rsp->data + 6)) << 8) | (*(rsp->data + 7));
2129 printf("IP Rx Fragmented : %u\n", statsTemp);
2130
2131 statsTemp = ((*(rsp->data + 8)) << 8) | (*(rsp->data + 9));
2132 printf("IP Tx Packet : %u\n", statsTemp);
2133
2134 statsTemp = ((*(rsp->data +10)) << 8) | (*(rsp->data +11));
2135 printf("UDP Rx Packet : %u\n", statsTemp);
2136
2137 statsTemp = ((*(rsp->data + 12)) << 8) | (*(rsp->data + 13));
2138 printf("RMCP Rx Valid : %u\n", statsTemp);
2139
2140 statsTemp = ((*(rsp->data + 14)) << 8) | (*(rsp->data + 15));
2141 printf("UDP Proxy Packet Received : %u\n", statsTemp);
2142
2143 statsTemp = ((*(rsp->data + 16)) << 8) | (*(rsp->data + 17));
2144 printf("UDP Proxy Packet Dropped : %u\n", statsTemp);
2145
2146 return rc;
2147 }
2148
2149
2150 static int
ipmi_lan_stats_clear(struct ipmi_intf * intf,uint8_t chan)2151 ipmi_lan_stats_clear(struct ipmi_intf * intf, uint8_t chan)
2152 {
2153 int rc = 0;
2154 struct ipmi_rs * rsp;
2155 struct ipmi_rq req;
2156 uint8_t msg_data[2];
2157
2158 if (!is_lan_channel(intf, chan)) {
2159 lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan);
2160 return -1;
2161 }
2162
2163 /* From here, we are ready to get the stats */
2164 msg_data[0] = chan;
2165 msg_data[1] = 1; /* Clear */
2166
2167 memset(&req, 0, sizeof(req));
2168 req.msg.netfn = IPMI_NETFN_TRANSPORT;
2169 req.msg.cmd = IPMI_LAN_GET_STAT;
2170 req.msg.data = msg_data;
2171 req.msg.data_len = 2;
2172
2173 rsp = intf->sendrecv(intf, &req);
2174 if (rsp == NULL) {
2175 lprintf(LOG_INFO, "Get LAN Stats command failed");
2176 return (-1);
2177 }
2178
2179 if (rsp->ccode > 0) {
2180 lprintf(LOG_INFO, "Get LAN Stats command failed: %s",
2181 val2str(rsp->ccode, completion_code_vals));
2182 return (-1);
2183 }
2184
2185 return rc;
2186 }
2187
2188 static void
print_lan_alert_print_usage(void)2189 print_lan_alert_print_usage(void)
2190 {
2191 lprintf(LOG_NOTICE,
2192 "");
2193 lprintf(LOG_NOTICE,
2194 "usage: lan alert print [channel number] [alert destination]");
2195 lprintf(LOG_NOTICE,
2196 "");
2197 lprintf(LOG_NOTICE,
2198 "Default will print all alerts for the first found LAN channel");
2199 }
2200
2201 static void
print_lan_alert_set_usage(void)2202 print_lan_alert_set_usage(void)
2203 {
2204 lprintf(LOG_NOTICE,
2205 "");
2206 lprintf(LOG_NOTICE,
2207 "usage: lan alert set <channel number> <alert destination> <command> <parameter>");
2208 lprintf(LOG_NOTICE,
2209 "");
2210 lprintf(LOG_NOTICE,
2211 " Command/parameter options:");
2212 lprintf(LOG_NOTICE,
2213 "");
2214 lprintf(LOG_NOTICE,
2215 " ipaddr <x.x.x.x> Set alert IP address");
2216 lprintf(LOG_NOTICE,
2217 " macaddr <x:x:x:x:x:x> Set alert MAC address");
2218 lprintf(LOG_NOTICE,
2219 " gateway <default|backup> Set channel gateway to use for alerts");
2220 lprintf(LOG_NOTICE,
2221 " ack <on|off> Set Alert Acknowledge on or off");
2222 lprintf(LOG_NOTICE,
2223 " type <pet|oem1|oem2> Set destination type as PET or OEM");
2224 lprintf(LOG_NOTICE,
2225 " time <seconds> Set ack timeout or unack retry interval");
2226 lprintf(LOG_NOTICE,
2227 " retry <number> Set number of alert retries");
2228 lprintf(LOG_NOTICE,
2229 "");
2230 }
2231
2232 static void
print_lan_set_usage(void)2233 print_lan_set_usage(void)
2234 {
2235 lprintf(LOG_NOTICE,
2236 "");
2237 lprintf(LOG_NOTICE,
2238 "usage: lan set <channel> <command> <parameter>");
2239 lprintf(LOG_NOTICE,
2240 "");
2241 lprintf(LOG_NOTICE,
2242 "LAN set command/parameter options:");
2243 lprintf(LOG_NOTICE,
2244 " ipaddr <x.x.x.x> Set channel IP address");
2245 lprintf(LOG_NOTICE,
2246 " netmask <x.x.x.x> Set channel IP netmask");
2247 lprintf(LOG_NOTICE,
2248 " macaddr <x:x:x:x:x:x> Set channel MAC address");
2249 lprintf(LOG_NOTICE,
2250 " defgw ipaddr <x.x.x.x> Set default gateway IP address");
2251 lprintf(LOG_NOTICE,
2252 " defgw macaddr <x:x:x:x:x:x> Set default gateway MAC address");
2253 lprintf(LOG_NOTICE,
2254 " bakgw ipaddr <x.x.x.x> Set backup gateway IP address");
2255 lprintf(LOG_NOTICE,
2256 " bakgw macaddr <x:x:x:x:x:x> Set backup gateway MAC address");
2257 lprintf(LOG_NOTICE,
2258 " password <password> Set session password for this channel");
2259 lprintf(LOG_NOTICE,
2260 " snmp <community string> Set SNMP public community string");
2261 lprintf(LOG_NOTICE,
2262 " user Enable default user for this channel");
2263 lprintf(LOG_NOTICE,
2264 " access <on|off> Enable or disable access to this channel");
2265 lprintf(LOG_NOTICE,
2266 " alert <on|off> Enable or disable PEF alerting for this channel");
2267 lprintf(LOG_NOTICE,
2268 " arp respond <on|off> Enable or disable BMC ARP responding");
2269 lprintf(LOG_NOTICE,
2270 " arp generate <on|off> Enable or disable BMC gratuitous ARP generation");
2271 lprintf(LOG_NOTICE,
2272 " arp interval <seconds> Set gratuitous ARP generation interval");
2273 lprintf(LOG_NOTICE,
2274 " vlan id <off|<id>> Disable or enable VLAN and set ID (1-4094)");
2275 lprintf(LOG_NOTICE,
2276 " vlan priority <priority> Set vlan priority (0-7)");
2277 lprintf(LOG_NOTICE,
2278 " auth <level> <type,..> Set channel authentication types");
2279 lprintf(LOG_NOTICE,
2280 " level = CALLBACK, USER, OPERATOR, ADMIN");
2281 lprintf(LOG_NOTICE,
2282 " type = NONE, MD2, MD5, PASSWORD, OEM");
2283 lprintf(LOG_NOTICE,
2284 " ipsrc <source> Set IP Address source");
2285 lprintf(LOG_NOTICE,
2286 " none = unspecified source");
2287 lprintf(LOG_NOTICE,
2288 " static = address manually configured to be static");
2289 lprintf(LOG_NOTICE,
2290 " dhcp = address obtained by BMC running DHCP");
2291 lprintf(LOG_NOTICE,
2292 " bios = address loaded by BIOS or system software");
2293 lprintf(LOG_NOTICE,
2294 " cipher_privs XXXXXXXXXXXXXXX Set RMCP+ cipher suite privilege levels");
2295 lprintf(LOG_NOTICE,
2296 " X = Cipher Suite Unused");
2297 lprintf(LOG_NOTICE,
2298 " c = CALLBACK");
2299 lprintf(LOG_NOTICE,
2300 " u = USER");
2301 lprintf(LOG_NOTICE,
2302 " o = OPERATOR");
2303 lprintf(LOG_NOTICE,
2304 " a = ADMIN");
2305 lprintf(LOG_NOTICE,
2306 " O = OEM");
2307 lprintf(LOG_NOTICE,
2308 "");
2309 lprintf(LOG_NOTICE,
2310 " bad_pass_thresh <thresh_num> <1|0> <reset_interval> <lockout_interval>\n"
2311 " Set bad password threshold");
2312 }
2313
2314 static void
print_lan_set_access_usage(void)2315 print_lan_set_access_usage(void)
2316 {
2317 lprintf(LOG_NOTICE,
2318 "lan set access <on|off>");
2319 }
2320
2321 static void
print_lan_set_arp_usage(void)2322 print_lan_set_arp_usage(void)
2323 {
2324 lprintf(LOG_NOTICE,
2325 "lan set <channel> arp respond <on|off>");
2326 lprintf(LOG_NOTICE,
2327 "lan set <channel> arp generate <on|off>");
2328 lprintf(LOG_NOTICE,
2329 "lan set <channel> arp interval <seconds>");
2330 lprintf(LOG_NOTICE,
2331 "");
2332 lprintf(LOG_NOTICE,
2333 "example: lan set 7 arp gratuitous off");
2334 }
2335
2336 static void
print_lan_set_auth_usage(void)2337 print_lan_set_auth_usage(void)
2338 {
2339 lprintf(LOG_NOTICE,
2340 "lan set <channel> auth <level> <type,type,...>");
2341 lprintf(LOG_NOTICE,
2342 " level = CALLBACK, USER, OPERATOR, ADMIN");
2343 lprintf(LOG_NOTICE,
2344 " types = NONE, MD2, MD5, PASSWORD, OEM");
2345 lprintf(LOG_NOTICE,
2346 "example: lan set 7 auth ADMIN PASSWORD,MD5");
2347 }
2348
2349 static void
print_lan_set_bakgw_usage(void)2350 print_lan_set_bakgw_usage(void)
2351 {
2352 lprintf(LOG_NOTICE,
2353 "LAN set backup gateway commands: ipaddr, macaddr");
2354 }
2355
2356 static void
print_lan_set_cipher_privs_usage(void)2357 print_lan_set_cipher_privs_usage(void)
2358 {
2359 lprintf(LOG_NOTICE,
2360 "lan set <channel> cipher_privs XXXXXXXXXXXXXXX");
2361 lprintf(LOG_NOTICE,
2362 " X = Cipher Suite Unused");
2363 lprintf(LOG_NOTICE,
2364 " c = CALLBACK");
2365 lprintf(LOG_NOTICE,
2366 " u = USER");
2367 lprintf(LOG_NOTICE,
2368 " o = OPERATOR");
2369 lprintf(LOG_NOTICE,
2370 " a = ADMIN");
2371 lprintf(LOG_NOTICE,
2372 " O = OEM");
2373 lprintf(LOG_NOTICE,
2374 "");
2375 }
2376
2377 static void
print_lan_set_defgw_usage(void)2378 print_lan_set_defgw_usage(void)
2379 {
2380 lprintf(LOG_NOTICE,
2381 "LAN set default gateway Commands: ipaddr, macaddr");
2382 }
2383
2384 static void
print_lan_set_ipsrc_usage(void)2385 print_lan_set_ipsrc_usage(void)
2386 {
2387 lprintf(LOG_NOTICE,
2388 "lan set <channel> ipsrc <source>");
2389 lprintf(LOG_NOTICE,
2390 " none = unspecified");
2391 lprintf(LOG_NOTICE,
2392 " static = static address (manually configured)");
2393 lprintf(LOG_NOTICE,
2394 " dhcp = address obtained by BMC running DHCP");
2395 lprintf(LOG_NOTICE,
2396 " bios = address loaded by BIOS or system software");
2397 }
2398
2399 static void
print_lan_set_snmp_usage(void)2400 print_lan_set_snmp_usage(void)
2401 {
2402 lprintf(LOG_NOTICE,
2403 "lan set <channel> snmp <community string>");
2404 }
2405
2406 static void
print_lan_set_vlan_usage(void)2407 print_lan_set_vlan_usage(void)
2408 {
2409 lprintf(LOG_NOTICE,
2410 "lan set <channel> vlan id <id>");
2411 lprintf(LOG_NOTICE,
2412 "lan set <channel> vlan id off");
2413 lprintf(LOG_NOTICE,
2414 "lan set <channel> vlan priority <priority>");
2415 }
2416
2417 /*
2418 * print_lan_usage
2419 */
2420 static void
print_lan_usage(void)2421 print_lan_usage(void)
2422 {
2423 lprintf(LOG_NOTICE,
2424 "LAN Commands:");
2425 lprintf(LOG_NOTICE,
2426 " print [<channel number>]");
2427 lprintf(LOG_NOTICE,
2428 " set <channel number> <command> <parameter>");
2429 lprintf(LOG_NOTICE,
2430 " alert print <channel number> <alert destination>");
2431 lprintf(LOG_NOTICE,
2432 " alert set <channel number> <alert destination> <command> <parameter>");
2433 lprintf(LOG_NOTICE,
2434 " stats get [<channel number>]");
2435 lprintf(LOG_NOTICE,
2436 " stats clear [<channel number>]");
2437 }
2438
2439
2440 int
ipmi_lanp_main(struct ipmi_intf * intf,int argc,char ** argv)2441 ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
2442 {
2443 int rc = 0;
2444 uint8_t chan = 0;
2445
2446 if (argc == 0) {
2447 print_lan_usage();
2448 return (-1);
2449 } else if (strncmp(argv[0], "help", 4) == 0) {
2450 print_lan_usage();
2451 return 0;
2452 }
2453
2454 chan = find_lan_channel(intf, 1);
2455
2456 if (strncmp(argv[0], "printconf", 9) == 0 ||
2457 strncmp(argv[0], "print", 5) == 0)
2458 {
2459 if (argc > 2) {
2460 print_lan_usage();
2461 return (-1);
2462 } else if (argc == 2) {
2463 if (str2uchar(argv[1], &chan) != 0) {
2464 lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2465 return (-1);
2466 }
2467 } else {
2468 chan = find_lan_channel(intf, 1);
2469 }
2470 if (!is_lan_channel(intf, chan)) {
2471 lprintf(LOG_ERR, "Invalid channel: %d", chan);
2472 return (-1);
2473 }
2474 rc = ipmi_lan_print(intf, chan);
2475 } else if (strncmp(argv[0], "set", 3) == 0) {
2476 rc = ipmi_lan_set(intf, argc-1, &(argv[1]));
2477 } else if (strncmp(argv[0], "alert", 5) == 0) {
2478 rc = ipmi_lan_alert(intf, argc-1, &(argv[1]));
2479 } else if (strncmp(argv[0], "stats", 5) == 0) {
2480 if (argc < 2) {
2481 print_lan_usage();
2482 return (-1);
2483 } else if (argc == 3) {
2484 if (str2uchar(argv[2], &chan) != 0) {
2485 lprintf(LOG_ERR, "Invalid channel: %s", argv[2]);
2486 return (-1);
2487 }
2488 } else {
2489 chan = find_lan_channel(intf, 1);
2490 }
2491 if (!is_lan_channel(intf, chan)) {
2492 lprintf(LOG_ERR, "Invalid channel: %d", chan);
2493 return (-1);
2494 }
2495 if (strncmp(argv[1], "get", 3) == 0) {
2496 rc = ipmi_lan_stats_get(intf, chan);
2497 } else if (strncmp(argv[1], "clear", 5) == 0) {
2498 rc = ipmi_lan_stats_clear(intf, chan);
2499 } else {
2500 print_lan_usage();
2501 return (-1);
2502 }
2503 } else {
2504 lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]);
2505 return (-1);
2506 }
2507 return rc;
2508 }
2509