xref: /openbmc/ipmitool/lib/ipmi_lanp.c (revision 89e9e634)
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