xref: /openbmc/ipmitool/lib/ipmi_lanp.c (revision 0e99dafa)
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 
57 extern int verbose;
58 
59 static void print_lan_alert_print_usage(void);
60 static void print_lan_alert_set_usage(void);
61 static void print_lan_set_usage(void);
62 static void print_lan_set_access_usage(void);
63 static void print_lan_set_arp_usage(void);
64 static void print_lan_set_auth_usage(void);
65 static void print_lan_set_bakgw_usage(void);
66 static void print_lan_set_cipher_privs_usage(void);
67 static void print_lan_set_defgw_usage(void);
68 static void print_lan_set_ipsrc_usage(void);
69 static void print_lan_set_snmp_usage(void);
70 static void print_lan_set_vlan_usage(void);
71 static void print_lan_usage(void);
72 
73 /* is_lan_channel - Check if channel is LAN medium
74  *
75  * return 1 if channel is LAN
76  * return 0 if channel is not LAN
77  *
78  * @intf:    ipmi interface handle
79  * @chan:    channel number to check
80  */
81 static int
82 is_lan_channel(struct ipmi_intf * intf, uint8_t chan)
83 {
84 	uint8_t medium;
85 
86 	if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX)
87 		return 0;
88 
89 	medium = ipmi_get_channel_medium(intf, chan);
90 
91 	if (medium == IPMI_CHANNEL_MEDIUM_LAN ||
92 	    medium == IPMI_CHANNEL_MEDIUM_LAN_OTHER)
93 		return 1;
94 
95 	return 0;
96 }
97 
98 /* find_lan_channel - Find first channel that is LAN
99  *
100  * return channel number if successful
101  * return 0 if no lan channel found, which is not a valid LAN channel
102  *
103  * @intf:    ipmi interface handle
104  * @start:   channel number to start searching from
105  */
106 static uint8_t
107 find_lan_channel(struct ipmi_intf * intf, uint8_t start)
108 {
109 	uint8_t chan = 0;
110 
111 	for (chan = start; chan < IPMI_CHANNEL_NUMBER_MAX; chan++) {
112 		if (is_lan_channel(intf, chan)) {
113 			return chan;
114 		}
115 	}
116 	return 0;
117 }
118 
119 /* get_lan_param_select - Query BMC for LAN parameter data
120  *
121  * return pointer to lan_param if successful
122  * if parameter not supported then
123  *   return pointer to lan_param with
124  *   lan_param->data == NULL and lan_param->data_len == 0
125  * return NULL on error
126  *
127  * @intf:    ipmi interface handle
128  * @chan:    ipmi channel
129  * @param:   lan parameter id
130  * @select:  lan parameter set selector
131  */
132 static struct lan_param *
133 get_lan_param_select(struct ipmi_intf * intf, uint8_t chan, int param, int select)
134 {
135 	struct lan_param * p = NULL;
136 	struct ipmi_rs * rsp;
137 	struct ipmi_rq req;
138 	int i = 0;
139 	uint8_t msg_data[4];
140 
141 	for (i = 0; ipmi_lan_params[i].cmd != (-1); i++) {
142 		if (ipmi_lan_params[i].cmd == param) {
143 			p = &ipmi_lan_params[i];
144 			break;
145 		}
146 	}
147 
148 	if (p == NULL) {
149 		lprintf(LOG_INFO, "Get LAN Parameter failed: Unknown parameter.");
150 		return NULL;
151 	}
152 
153 	msg_data[0] = chan;
154 	msg_data[1] = p->cmd;
155 	msg_data[2] = select;
156 	msg_data[3] = 0;
157 
158 	memset(&req, 0, sizeof(req));
159 	req.msg.netfn    = IPMI_NETFN_TRANSPORT;
160 	req.msg.cmd      = IPMI_LAN_GET_CONFIG;
161 	req.msg.data     = msg_data;
162 	req.msg.data_len = 4;
163 
164 	rsp = intf->sendrecv(intf, &req);
165 	if (rsp == NULL) {
166 		lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed", p->desc);
167 		return NULL;
168 	}
169 
170 	switch (rsp->ccode)
171 	{
172 	case 0x00: /* successful */
173 		break;
174 
175 	case 0x80: /* parameter not supported */
176 	case 0xc9: /* parameter out of range */
177 	case 0xcc: /* invalid data field in request */
178 
179 		/* these completion codes usually mean parameter not supported */
180 		lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed: %s",
181 			p->desc, val2str(rsp->ccode, completion_code_vals));
182 		p->data = NULL;
183 		p->data_len = 0;
184 		return p;
185 
186 	default:
187 
188 		/* other completion codes are treated as error */
189 		lprintf(LOG_INFO, "Get LAN Parameter '%s' command failed: %s",
190 			p->desc, val2str(rsp->ccode, completion_code_vals));
191 		return NULL;
192 	}
193 
194 	p->data = rsp->data + 1;
195 	p->data_len = rsp->data_len - 1;
196 
197 	return p;
198 }
199 
200 /* get_lan_param - Query BMC for LAN parameter data
201  *
202  * return pointer to lan_param if successful
203  * if parameter not supported then
204  *   return pointer to lan_param with
205  *   lan_param->data == NULL and lan_param->data_len == 0
206  * return NULL on error
207  *
208  * @intf:    ipmi interface handle
209  * @chan:    ipmi channel
210  * @param:   lan parameter id
211  */
212 static struct lan_param *
213 get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param)
214 {
215 	return get_lan_param_select(intf, chan, param, 0);
216 }
217 
218 /* set_lan_param_wait - Wait for Set LAN Parameter command to complete
219  *
220  * On some systems this can take unusually long so we wait for the write
221  * to take effect and verify that the data was written successfully
222  * before continuing or retrying.
223  *
224  * returns 0 on success
225  * returns -1 on error
226  *
227  * @intf:    ipmi interface handle
228  * @chan:    ipmi channel
229  * @param:   lan parameter id
230  * @data:    lan parameter data
231  * @len:     length of lan parameter data
232  */
233 static int
234 set_lan_param_wait(struct ipmi_intf * intf, uint8_t chan,
235 		   int param, uint8_t * data, int len)
236 {
237 	struct lan_param * p;
238 	int retry = 10;		/* 10 retries */
239 
240 	lprintf(LOG_DEBUG, "Waiting for Set LAN Parameter to complete...");
241 	if (verbose > 1)
242 		printbuf(data, len, "SET DATA");
243 
244 	for (;;) {
245 		p = get_lan_param(intf, chan, param);
246 		if (p == NULL) {
247 			sleep(IPMI_LANP_TIMEOUT);
248 			if (retry-- == 0)
249 				return -1;
250 			continue;
251 		}
252 		if (verbose > 1)
253 			printbuf(p->data, p->data_len, "READ DATA");
254 		if (p->data_len != len) {
255 			sleep(IPMI_LANP_TIMEOUT);
256 			if (retry-- == 0) {
257 				lprintf(LOG_WARNING, "Mismatched data lengths: %d != %d",
258 				       p->data_len, len);
259 				return -1;
260 			}
261 			continue;
262 		}
263 		if (memcmp(data, p->data, len) != 0) {
264 			sleep(IPMI_LANP_TIMEOUT);
265 			if (retry-- == 0) {
266 				lprintf(LOG_WARNING, "LAN Parameter Data does not match!  "
267 				       "Write may have failed.");
268 				return -1;
269 			}
270 			continue;
271 		}
272 		break;
273 	}
274 	return 0;
275 }
276 
277 /* __set_lan_param - Write LAN Parameter data to BMC
278  *
279  * This function does the actual work of writing the LAN parameter
280  * to the BMC and calls set_lan_param_wait() if requested.
281  *
282  * returns 0 on success
283  * returns -1 on error
284  *
285  * @intf:    ipmi interface handle
286  * @chan:    ipmi channel
287  * @param:   lan parameter id
288  * @data:    lan parameter data
289  * @len:     length of lan parameter data
290  * @wait:    whether to wait for write completion
291  */
292 static int
293 __set_lan_param(struct ipmi_intf * intf, uint8_t chan,
294 		int param, uint8_t * data, int len, int wait)
295 {
296 	struct ipmi_rs * rsp;
297 	struct ipmi_rq req;
298 	uint8_t msg_data[32];
299 
300 	if (param < 0)
301 		return -1;
302 
303 	msg_data[0] = chan;
304 	msg_data[1] = param;
305 
306 	memcpy(&msg_data[2], data, len);
307 	memset(&req, 0, sizeof(req));
308 	req.msg.netfn = IPMI_NETFN_TRANSPORT;
309 	req.msg.cmd = IPMI_LAN_SET_CONFIG;
310 	req.msg.data = msg_data;
311 	req.msg.data_len = len+2;
312 
313 	rsp = intf->sendrecv(intf, &req);
314 	if (rsp == NULL) {
315 		lprintf(LOG_ERR, "Set LAN Parameter failed");
316 		return -1;
317 	}
318 	if ((rsp->ccode > 0) && (wait != 0)) {
319 		lprintf(LOG_DEBUG, "Warning: Set LAN Parameter failed: %s",
320 			val2str(rsp->ccode, completion_code_vals));
321 		if (rsp->ccode == 0xcc) {
322 			/* retry hack for invalid data field ccode */
323 			int retry = 10;		/* 10 retries */
324 			lprintf(LOG_DEBUG, "Retrying...");
325 			for (;;) {
326 				if (retry-- == 0)
327 					break;
328 				sleep(IPMI_LANP_TIMEOUT);
329 				rsp = intf->sendrecv(intf, &req);
330 				if (rsp == NULL)
331 					continue;
332 				if (rsp->ccode > 0)
333 					continue;
334 				return set_lan_param_wait(intf, chan, param, data, len);
335 			}
336 		}
337 		else if (rsp->ccode != 0xff) {
338 			/* let 0xff ccode continue */
339 			return -1;
340 		}
341 	}
342 
343 	if (wait == 0)
344 		return 0;
345 	return set_lan_param_wait(intf, chan, param, data, len);
346 }
347 
348 /* ipmi_lanp_lock_state - Retrieve set-in-progress status
349  *
350  * returns one of:
351  *  IPMI_LANP_WRITE_UNLOCK
352  *  IPMI_LANP_WRITE_LOCK
353  *  IPMI_LANP_WRITE_COMMIT
354  *  -1 on error/if not supported
355  *
356  * @intf:    ipmi interface handle
357  * @chan:    ipmi channel
358  */
359 static int
360 ipmi_lanp_lock_state(struct ipmi_intf * intf, uint8_t chan)
361 {
362 	struct lan_param * p;
363 	p = get_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS);
364 	if (p == NULL)
365 		return -1;
366 	if (p->data == NULL)
367 		return -1;
368 	return (p->data[0] & 3);
369 }
370 
371 /* ipmi_lanp_lock - Lock set-in-progress bits for our use
372  *
373  * Write to the Set-In-Progress LAN parameter to indicate
374  * to other management software that we are modifying parameters.
375  *
376  * No meaningful return value because this is an optional
377  * requirement in IPMI spec and not found on many BMCs.
378  *
379  * @intf:    ipmi interface handle
380  * @chan:    ipmi channel
381  */
382 static void
383 ipmi_lanp_lock(struct ipmi_intf * intf, uint8_t chan)
384 {
385 	uint8_t val = IPMI_LANP_WRITE_LOCK;
386 	int retry = 3;
387 
388 	for (;;) {
389 		int state = ipmi_lanp_lock_state(intf, chan);
390 		if (state == -1)
391 			break;
392 		if (state == val)
393 			break;
394 		if (retry-- == 0)
395 			break;
396 		__set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS,
397 				&val, 1, 0);
398 	}
399 }
400 
401 /* ipmi_lanp_unlock - Unlock set-in-progress bits
402  *
403  * Write to the Set-In-Progress LAN parameter, first with
404  * a "commit" instruction and then unlocking it.
405  *
406  * No meaningful return value because this is an optional
407  * requirement in IPMI spec and not found on many BMCs.
408  *
409  * @intf:    ipmi interface handle
410  * @chan:    ipmi channel
411  */
412 static void
413 ipmi_lanp_unlock(struct ipmi_intf * intf, uint8_t chan)
414 {
415 	uint8_t val = IPMI_LANP_WRITE_COMMIT;
416 	int rc;
417 
418 	rc = __set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0);
419 	if (rc < 0) {
420 		lprintf(LOG_DEBUG, "LAN Parameter Commit not supported");
421 	}
422 
423 	val = IPMI_LANP_WRITE_UNLOCK;
424 	__set_lan_param(intf, chan, IPMI_LANP_SET_IN_PROGRESS, &val, 1, 0);
425 }
426 
427 /* set_lan_param - Wrap LAN parameter write with set-in-progress lock
428  *
429  * Returns value from __set_lan_param()
430  *
431  * @intf:    ipmi interface handle
432  * @chan:    ipmi channel
433  * @param:   lan parameter id
434  * @data:    lan parameter data
435  * @len:     length of lan parameter data
436  */
437 static int
438 set_lan_param(struct ipmi_intf * intf, uint8_t chan,
439 	      int param, uint8_t * data, int len)
440 {
441 	int rc;
442 	ipmi_lanp_lock(intf, chan);
443 	rc = __set_lan_param(intf, chan, param, data, len, 1);
444 	ipmi_lanp_unlock(intf, chan);
445 	return rc;
446 }
447 
448 /* set_lan_param_nowait - Wrap LAN parameter write without set-in-progress lock
449  *
450  * Returns value from __set_lan_param()
451  *
452  * @intf:    ipmi interface handle
453  * @chan:    ipmi channel
454  * @param:   lan parameter id
455  * @data:    lan parameter data
456  * @len:     length of lan parameter data
457  */
458 static int
459 set_lan_param_nowait(struct ipmi_intf * intf, uint8_t chan,
460 		     int param, uint8_t * data, int len)
461 {
462 	int rc;
463 	ipmi_lanp_lock(intf, chan);
464 	rc = __set_lan_param(intf, chan, param, data, len, 0);
465 	ipmi_lanp_unlock(intf, chan);
466 	return rc;
467 }
468 
469 static int
470 lan_set_arp_interval(struct ipmi_intf * intf, uint8_t chan, uint8_t ival)
471 {
472 	struct lan_param *lp;
473 	uint8_t interval = 0;
474 	int rc = 0;
475 
476 	lp = get_lan_param(intf, chan, IPMI_LANP_GRAT_ARP);
477 	if (lp == NULL)
478 		return -1;
479 	if (lp->data == NULL)
480 		return -1;
481 
482 	if (ival != 0) {
483 		if (((UINT8_MAX - 1) / 2) < ival) {
484 			lprintf(LOG_ERR, "Given ARP interval '%u' is too big.", ival);
485 			return (-1);
486 		}
487 		interval = (ival * 2) - 1;
488 		rc = set_lan_param(intf, chan, IPMI_LANP_GRAT_ARP, &interval, 1);
489 	} else {
490 		interval = lp->data[0];
491 	}
492 
493 	printf("BMC-generated Gratuitous ARP interval:  %.1f seconds\n",
494 	       (float)((interval + 1) / 2));
495 
496 	return rc;
497 }
498 
499 static int
500 lan_set_arp_generate(struct ipmi_intf * intf,
501 		     uint8_t chan, uint8_t ctl)
502 {
503 	struct lan_param *lp;
504 	uint8_t data;
505 
506 	lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
507 	if (lp == NULL)
508 		return -1;
509 	if (lp->data == NULL)
510 		return -1;
511 	data = lp->data[0];
512 
513 	/* set arp generate bitflag */
514 	if (ctl == 0)
515 		data &= ~0x1;
516 	else
517 		data |= 0x1;
518 
519 	printf("%sabling BMC-generated Gratuitous ARPs\n", ctl ? "En" : "Dis");
520 	return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1);
521 }
522 
523 static int
524 lan_set_arp_respond(struct ipmi_intf * intf,
525 		    uint8_t chan, uint8_t ctl)
526 {
527 	struct lan_param *lp;
528 	uint8_t data;
529 
530 	lp = get_lan_param(intf, chan, IPMI_LANP_BMC_ARP);
531 	if (lp == NULL)
532 		return -1;
533 	if (lp->data == NULL)
534 		return -1;
535 	data = lp->data[0];
536 
537 	/* set arp response bitflag */
538 	if (ctl == 0)
539 		data &= ~0x2;
540 	else
541 		data |= 0x2;
542 
543 	printf("%sabling BMC-generated ARP responses\n", ctl ? "En" : "Dis");
544 	return set_lan_param(intf, chan, IPMI_LANP_BMC_ARP, &data, 1);
545 }
546 
547 /* TODO - probably move elsewhere */
548 static char priv_level_to_char(unsigned char priv_level)
549 {
550 	char ret = 'X';
551 
552 	switch (priv_level)
553 	{
554 	case IPMI_SESSION_PRIV_CALLBACK:
555 		ret = 'c';
556 		break;
557 	case IPMI_SESSION_PRIV_USER:
558 		ret = 'u';
559 		break;
560 	case IPMI_SESSION_PRIV_OPERATOR:
561 		ret = 'o';
562 		break;
563 	case IPMI_SESSION_PRIV_ADMIN:
564 		ret = 'a';
565 		break;
566 	case IPMI_SESSION_PRIV_OEM:
567 		ret = 'O';
568 		break;
569 	}
570 
571  	return ret;
572 }
573 
574 
575 static int
576 ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
577 {
578 	struct lan_param * p;
579 	int rc = 0;
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 	return rc;
845 }
846 
847 /* Configure Authentication Types */
848 /* TODO - probably some code duplication going on ??? */
849 static int
850 ipmi_lan_set_auth(struct ipmi_intf * intf, uint8_t chan, char * level, char * types)
851 {
852 	uint8_t data[5];
853 	uint8_t authtype = 0;
854 	char * p;
855 	struct lan_param * lp;
856 
857 	if (level == NULL || types == NULL)
858 		return -1;
859 
860 	lp = get_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE);
861 	if (lp == NULL)
862 		return -1;
863 	if (lp->data == NULL)
864 		return -1;
865 
866 	lprintf(LOG_DEBUG, "%-24s: callback=0x%02x user=0x%02x operator=0x%02x admin=0x%02x oem=0x%02x",
867 		lp->desc, lp->data[0], lp->data[1], lp->data[2], lp->data[3], lp->data[4]);
868 
869 	memset(data, 0, 5);
870 	memcpy(data, lp->data, 5);
871 
872 	p = types;
873 	while (p) {
874 		if (strncasecmp(p, "none", 4) == 0)
875 			authtype |= 1 << IPMI_SESSION_AUTHTYPE_NONE;
876 		else if (strncasecmp(p, "md2", 3) == 0)
877 			authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD2;
878 		else if (strncasecmp(p, "md5", 3) == 0)
879 			authtype |= 1 << IPMI_SESSION_AUTHTYPE_MD5;
880 		else if ((strncasecmp(p, "password", 8) == 0) ||
881 			 (strncasecmp(p, "key", 3) == 0))
882 			authtype |= 1 << IPMI_SESSION_AUTHTYPE_KEY;
883 		else if (strncasecmp(p, "oem", 3) == 0)
884 			authtype |= 1 << IPMI_SESSION_AUTHTYPE_OEM;
885 		else
886 			lprintf(LOG_WARNING, "Invalid authentication type: %s", p);
887 		p = strchr(p, ',');
888 		if (p)
889 			p++;
890 	}
891 
892 	p = level;
893 	while (p) {
894 		if (strncasecmp(p, "callback", 8) == 0)
895 			data[0] = authtype;
896 		else if (strncasecmp(p, "user", 4) == 0)
897 			data[1] = authtype;
898 		else if (strncasecmp(p, "operator", 8) == 0)
899 			data[2] = authtype;
900 		else if (strncasecmp(p, "admin", 5) == 0)
901 			data[3] = authtype;
902 		else
903 			lprintf(LOG_WARNING, "Invalid authentication level: %s", p);
904 		p = strchr(p, ',');
905 		if (p)
906 			p++;
907 	}
908 
909 	if (verbose > 1)
910 		printbuf(data, 5, "authtype data");
911 
912 	return set_lan_param(intf, chan, IPMI_LANP_AUTH_TYPE_ENABLE, data, 5);
913 }
914 
915 /* TODO - we already have set user password in ipmi_user! */
916 static int
917 ipmi_lan_set_password(struct ipmi_intf * intf,
918 	uint8_t userid, uint8_t * password)
919 {
920 	struct ipmi_rs * rsp;
921 	struct ipmi_rq req;
922 	uint8_t data[18];
923 
924 	memset(&data, 0, sizeof(data));
925 	data[0] = userid & 0x3f;/* user ID */
926 	data[1] = 0x02;		/* set password */
927 
928 	if (password != NULL)
929 		memcpy(data+2, password, __min(strlen((const char *)password), 16));
930 
931 	memset(&req, 0, sizeof(req));
932 	req.msg.netfn = IPMI_NETFN_APP;
933 	req.msg.cmd = 0x47;
934 	req.msg.data = data;
935 	req.msg.data_len = 18;
936 
937 	rsp = intf->sendrecv(intf, &req);
938 	if (rsp == NULL) {
939 		lprintf(LOG_ERR, "Unable to Set LAN Password for user %d", userid);
940 		return -1;
941 	}
942 	if (rsp->ccode > 0) {
943 		lprintf(LOG_ERR, "Set LAN Password for user %d failed: %s",
944 			userid, val2str(rsp->ccode, completion_code_vals));
945 		return -1;
946 	}
947 
948 	/* adjust our session password
949 	 * or we will no longer be able to communicate with BMC
950 	 */
951 	ipmi_intf_session_set_password(intf, (char *)password);
952 	printf("Password %s for user %d\n",
953 	       (password == NULL) ? "cleared" : "set", userid);
954 
955 	return 0;
956 }
957 
958 static int
959 ipmi_set_alert_enable(struct ipmi_intf * intf, uint8_t channel, uint8_t enable)
960 {
961 	struct ipmi_rs * rsp;
962 	struct ipmi_rq req;
963 	uint8_t rqdata[3];
964 
965 	memset(&req, 0, sizeof(req));
966 
967 	/* update non-volatile access */
968 	rqdata[0] = channel;
969 	rqdata[1] = 0x40;
970 
971 	req.msg.netfn = IPMI_NETFN_APP;
972 	req.msg.cmd = 0x41; /* Get Channel Access ??? */
973 	req.msg.data = rqdata;
974 	req.msg.data_len = 2;
975 
976 	rsp = intf->sendrecv(intf, &req);
977 	if (rsp == NULL) {
978 		lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel);
979 		return -1;
980 	}
981 	if (rsp->ccode > 0) {
982 		lprintf(LOG_ERR, "Get Channel Access for channel %d failed: %s",
983 			channel, val2str(rsp->ccode, completion_code_vals));
984 		return -1;
985 	}
986 
987 	/* SAVE TO NVRAM */
988 	memset(rqdata, 0, 3);
989 	rqdata[0] = channel & 0xf;
990 	rqdata[1] = rsp->data[0];
991 	if (enable != 0)
992 		rqdata[1] &= ~0x20;
993 	else
994 		rqdata[1] |= 0x20;
995 	rqdata[1] |= 0x40;
996 	rqdata[2] = 0;
997 
998 	req.msg.cmd = 0x40; /* Set Channel Access ??? */
999 	req.msg.data_len = 3;
1000 
1001 	rsp = intf->sendrecv(intf, &req);
1002 	if (rsp == NULL) {
1003 		lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
1004 		return -1;
1005 	}
1006 	if (rsp->ccode > 0) {
1007 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1008 			channel, val2str(rsp->ccode, completion_code_vals));
1009 		return -1;
1010 	}
1011 
1012 	/* SAVE TO CURRENT */
1013 	rqdata[1] &= 0xc0;
1014 	rqdata[1] |= 0x80;
1015 
1016 	rsp = intf->sendrecv(intf, &req);
1017 	if (rsp == NULL) {
1018 		lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
1019 		return -1;
1020 	}
1021 	if (rsp->ccode > 0) {
1022 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1023 			channel, val2str(rsp->ccode, completion_code_vals));
1024 		return -1;
1025 	}
1026 
1027 	return 0;
1028 }
1029 
1030 /* TODO - we already have functions for this elsewere!!! */
1031 static int
1032 ipmi_set_channel_access(struct ipmi_intf * intf, uint8_t channel, uint8_t enable)
1033 {
1034 	struct ipmi_rs * rsp;
1035 	struct ipmi_rq req;
1036 	uint8_t rqdata[3];
1037 	uint8_t byteEnable;
1038 
1039 	memset(&req, 0, sizeof(req));
1040 
1041 	/* RETREIVE VALUE IN NVRAM */
1042 	req.msg.netfn = IPMI_NETFN_APP;
1043 	req.msg.cmd = 0x41;  /* Get Channel Access Command */
1044 	req.msg.data = rqdata;
1045 	req.msg.data_len = 2;
1046 
1047 	memset(rqdata, 0, 2);
1048 	rqdata[0] = channel & 0xf;
1049 	rqdata[1] = 0x40; /* retreive NV */
1050 
1051 	rsp = intf->sendrecv(intf, &req);
1052 	if (rsp == NULL) {
1053 		lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel);
1054 		return -1;
1055 	} else if (rsp->ccode > 0) {
1056 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1057 			channel, val2str(rsp->ccode, completion_code_vals));
1058 		return -1;
1059 	} else {
1060 		byteEnable = *(rsp->data + 0);
1061 	}
1062 
1063 	/* SAVE TO NVRAM */
1064 	memset(&req, 0, sizeof(req));
1065 
1066 	req.msg.netfn = IPMI_NETFN_APP;
1067 	req.msg.cmd = 0x40;   /* Set Channel Access Command */
1068 	req.msg.data = rqdata;
1069 	req.msg.data_len = 3;
1070 
1071 	memset(rqdata, 0, 3);
1072 	rqdata[0] = channel & 0xf;
1073 	rqdata[1] = 0x40 | (byteEnable & 0x38);  /* use previously set values */
1074 	if (enable != 0)
1075 		rqdata[1] |= 0x2; /* set always available if enable is set */
1076 	rqdata[2] = 0x44; 	/* set channel privilege limit to ADMIN */
1077 
1078 	rsp = intf->sendrecv(intf, &req);
1079 	if (rsp == NULL) {
1080 		lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
1081 		return -1;
1082 	} else if (rsp->ccode > 0) {
1083 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1084 			channel, val2str(rsp->ccode, completion_code_vals));
1085 		return -1;
1086 	}
1087 
1088 	/* RETREIVE VALUE IN NVRAM */
1089 	req.msg.netfn = IPMI_NETFN_APP;
1090 	req.msg.cmd = 0x41;  /* Get Channel Access Command */
1091 	req.msg.data = rqdata;
1092 	req.msg.data_len = 2;
1093 
1094 	memset(rqdata, 0, 2);
1095 	rqdata[0] = channel & 0xf;
1096 	rqdata[1] = 0x80; /* retreive NV */
1097 
1098 	rsp = intf->sendrecv(intf, &req);
1099 	if (rsp == NULL) {
1100 		lprintf(LOG_ERR, "Unable to Get Channel Access for channel %d", channel);
1101 		return -1;
1102 	} else if (rsp->ccode > 0) {
1103 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1104 			channel, val2str(rsp->ccode, completion_code_vals));
1105 		return -1;
1106 	} else {
1107 		byteEnable = *(rsp->data + 0);
1108 	}
1109 
1110 	/* SAVE TO CURRENT */
1111 	memset(&req, 0, sizeof(req));
1112 
1113 	req.msg.netfn = IPMI_NETFN_APP;
1114 	req.msg.cmd = 0x40;   /* Set Channel Access Command */
1115 	req.msg.data = rqdata;
1116 	req.msg.data_len = 3;
1117 
1118 	memset(rqdata, 0, 3);
1119 	rqdata[0] = channel & 0xf;
1120 	rqdata[1] = 0x80 | (byteEnable & 0x38);  /* use previously set values */
1121 	if (enable != 0)
1122 		rqdata[1] |= 0x2; /* set always available if enable is set */
1123 	rqdata[2] = 0x84; 	/* set channel privilege limit to ADMIN */
1124 
1125 	rsp = intf->sendrecv(intf, &req);
1126 	if (rsp == NULL) {
1127 		lprintf(LOG_ERR, "Unable to Set Channel Access for channel %d", channel);
1128 		return -1;
1129 	} else if (rsp->ccode > 0) {
1130 		lprintf(LOG_ERR, "Set Channel Access for channel %d failed: %s",
1131 			channel, val2str(rsp->ccode, completion_code_vals));
1132 		return -1;
1133 	}
1134 
1135 	/* can't send close session if access off so abort instead */
1136 	if (enable == 0)
1137 		intf->abort = 1;
1138 
1139 	return 0;
1140 }
1141 
1142 /* TODO - we already have functions for this elsewhere!!! */
1143 static int
1144 ipmi_set_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
1145 {
1146 	struct ipmi_rs * rsp;
1147 	struct ipmi_rq req;
1148 	uint8_t rqdata[4];
1149 
1150 	memset(rqdata, 0, 4);
1151 	rqdata[0] = 0x90 | (channel & 0xf);
1152 	rqdata[1] = userid & 0x3f;
1153 	rqdata[2] = 0x4;
1154 	rqdata[3] = 0;
1155 
1156 	memset(&req, 0, sizeof(req));
1157 	req.msg.netfn = IPMI_NETFN_APP;
1158 	req.msg.cmd = 0x43;
1159 	req.msg.data = rqdata;
1160 	req.msg.data_len = 4;
1161 
1162 	rsp = intf->sendrecv(intf, &req);
1163 	if (rsp == NULL) {
1164 		lprintf(LOG_ERR, "Unable to Set User Access for channel %d", channel);
1165 		return -1;
1166 	}
1167 	if (rsp->ccode > 0) {
1168 		lprintf(LOG_ERR, "Set User Access for channel %d failed: %s",
1169 			channel, val2str(rsp->ccode, completion_code_vals));
1170 		return -1;
1171 	}
1172 
1173 	return 0;
1174 }
1175 
1176 /* get_cmdline_macaddr - parse-out MAC address from given string and store it
1177  * into buffer.
1178  *
1179  * @arg: string to be parsed.
1180  * @buf: buffer of 6 to hold parsed MAC address.
1181  *
1182  * returns zero on success, (-1) on error and error message is printed-out.
1183  */
1184 static int
1185 get_cmdline_macaddr(char *arg, uint8_t *buf)
1186 {
1187 	uint32_t m1 = 0;
1188 	uint32_t m2 = 0;
1189 	uint32_t m3 = 0;
1190 	uint32_t m4 = 0;
1191 	uint32_t m5 = 0;
1192 	uint32_t m6 = 0;
1193 	if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
1194 		   &m1, &m2, &m3, &m4, &m5, &m6) != 6) {
1195 		lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
1196 		return -1;
1197 	}
1198 	if (m1 > UINT8_MAX || m2 > UINT8_MAX
1199 			|| m3 > UINT8_MAX || m4 > UINT8_MAX
1200 			|| m5 > UINT8_MAX || m6 > UINT8_MAX) {
1201 		lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
1202 		return -1;
1203 	}
1204 	buf[0] = (uint8_t)m1;
1205 	buf[1] = (uint8_t)m2;
1206 	buf[2] = (uint8_t)m3;
1207 	buf[3] = (uint8_t)m4;
1208 	buf[4] = (uint8_t)m5;
1209 	buf[5] = (uint8_t)m6;
1210 	return 0;
1211 }
1212 
1213 
1214 static int
1215 get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf)
1216 {
1217 	int i, ret = 0;
1218 
1219 	if (strlen(arg) != 15)
1220 	{
1221 		lprintf(LOG_ERR, "Invalid privilege specification length: %d",
1222 			strlen(arg));
1223 		return -1;
1224 	}
1225 
1226 	/*
1227 	 * The first byte is reserved (0).  The rest of the buffer is setup
1228 	 * so that each nibble holds the maximum privilege level available for
1229 	 * that cipher suite number.  The number of nibbles (15) matches the number
1230 	 * of fixed cipher suite IDs.  This command documentation mentions 16 IDs
1231 	 * but table 22-19 shows that there are only 15 (0-14).
1232 	 *
1233 	 * data 1 - reserved
1234 	 * data 2 - maximum priv level for first (LSN) and second (MSN) ciphers
1235 	 * data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers
1236 	 * data 9 - maximum priv level for 15th (LSN) cipher.
1237 	 */
1238 	memset(buf, 0, 9);
1239 	for (i = 0; i < 15; ++i)
1240 	{
1241 		unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN;
1242 
1243 		switch (arg[i])
1244 		{
1245 		case 'X':
1246 			priv_level = IPMI_SESSION_PRIV_UNSPECIFIED; /* 0 */
1247 			break;
1248 		case 'c':
1249 			priv_level = IPMI_SESSION_PRIV_CALLBACK;    /* 1 */
1250 			break;
1251 		case 'u':
1252 			priv_level = IPMI_SESSION_PRIV_USER;        /* 2 */
1253 			break;
1254 		case 'o':
1255 			priv_level = IPMI_SESSION_PRIV_OPERATOR;    /* 3 */
1256 			break;
1257 		case 'a':
1258 			priv_level = IPMI_SESSION_PRIV_ADMIN;       /* 4 */
1259 			break;
1260 		case 'O':
1261 			priv_level = IPMI_SESSION_PRIV_OEM;         /* 5 */
1262 			break;
1263 		default:
1264 			lprintf(LOG_ERR, "Invalid privilege specification char: %c",
1265 				arg[i]);
1266 			ret = -1;
1267 			break;
1268 		}
1269 
1270 		if (ret != 0)
1271 			break;
1272 		else
1273 		{
1274 			if ((i + 1) % 2)
1275 			{
1276 				// Odd number cipher suites will be in the LSN
1277 				buf[1 + (i / 2)] += priv_level;
1278 			}
1279 			else
1280 			{
1281 				// Even number cipher suites will be in the MSN
1282 				buf[1 + (i / 2)] += (priv_level << 4);
1283 			}
1284 		}
1285 	}
1286 
1287 	return ret;
1288 }
1289 
1290 
1291 static int
1292 get_cmdline_ipaddr(char * arg, uint8_t * buf)
1293 {
1294 	uint32_t ip1, ip2, ip3, ip4;
1295 	if (sscanf(arg,
1296 				"%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
1297 				&ip1, &ip2, &ip3, &ip4) != 4) {
1298 		lprintf(LOG_ERR, "Invalid IP address: %s", arg);
1299 		return (-1);
1300 	}
1301 	if (ip1 > UINT8_MAX || ip2 > UINT8_MAX
1302 			|| ip3 > UINT8_MAX || ip4 > UINT8_MAX) {
1303 		lprintf(LOG_ERR, "Invalid IP address: %s", arg);
1304 		return (-1);
1305 	}
1306 	buf[0] = (uint8_t)ip1;
1307 	buf[1] = (uint8_t)ip2;
1308 	buf[2] = (uint8_t)ip3;
1309 	buf[3] = (uint8_t)ip4;
1310 	return 0;
1311 }
1312 
1313 static int
1314 ipmi_lan_set_vlan_id(struct ipmi_intf *intf,  uint8_t chan, char *string)
1315 {
1316 	uint8_t data[2];
1317 	int rc;
1318 
1319 	if (string == NULL) {
1320 		data[0] = 0;
1321 		data[1] = 0;
1322 	}
1323 	else {
1324 		int id = 0;
1325 		if (str2int(string, &id) != 0) {
1326 			lprintf(LOG_ERR, "Given VLAN ID '%s' is invalid.", string);
1327 			return (-1);
1328 		}
1329 
1330 		if (id < 1 || id > 4094) {
1331 			lprintf(LOG_NOTICE, "VLAN ID must be between 1 and 4094.");
1332 			return (-1);
1333 		}
1334 		else {
1335 			data[0] = (uint8_t)id;
1336 			data[1] = (uint8_t)(id >> 8) | 0x80;
1337 		}
1338 	}
1339 	rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_ID, data, 2);
1340 	return rc;
1341 }
1342 
1343 static int
1344 ipmi_lan_set_vlan_priority(struct ipmi_intf *intf,  uint8_t chan, char *string)
1345 {
1346 	uint8_t data;
1347 	int rc;
1348 	int priority = 0;
1349 	if (str2int(string, &priority) != 0) {
1350 		lprintf(LOG_ERR, "Given VLAN priority '%s' is invalid.", string);
1351 		return (-1);
1352 	}
1353 
1354 	if (priority < 0 || priority > 7) {
1355 		lprintf(LOG_NOTICE, "VLAN priority must be between 0 and 7.");
1356 		return (-1);
1357 	}
1358 	data = (uint8_t)priority;
1359 	rc = set_lan_param(intf, chan, IPMI_LANP_VLAN_PRIORITY, &data, 1);
1360 	return rc;
1361 }
1362 
1363 static int
1364 ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
1365 {
1366 	uint8_t data[32];
1367 	uint8_t chan;
1368 	int rc = 0;
1369 
1370 	if (argc < 2) {
1371 		print_lan_set_usage();
1372 		return (-1);
1373 	}
1374 
1375 	if (strncmp(argv[0], "help", 4) == 0 ||
1376 	    strncmp(argv[1], "help", 4) == 0) {
1377 		print_lan_set_usage();
1378 		return 0;
1379 	}
1380 
1381 	if (str2uchar(argv[0], &chan) != 0) {
1382 		lprintf(LOG_ERR, "Invalid channel: %s", argv[0]);
1383 		return (-1);
1384 	}
1385 
1386 	/* find type of channel and only accept 802.3 LAN */
1387 	if (!is_lan_channel(intf, chan)) {
1388 		lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan);
1389 		print_lan_set_usage();
1390 		return -1;
1391 	}
1392 
1393 	memset(&data, 0, sizeof(data));
1394 
1395 	/* set user access */
1396 	if (strncmp(argv[1], "user", 4) == 0) {
1397 		rc = ipmi_set_user_access(intf, chan, 1);
1398 	}
1399 	/* set channel access mode */
1400 	else if (strncmp(argv[1], "access", 6) == 0) {
1401 		if (argc < 3) {
1402 			print_lan_set_access_usage();
1403 			return (-1);
1404 		}
1405 		else if (strncmp(argv[2], "help", 4) == 0) {
1406 			print_lan_set_access_usage();
1407 			return 0;
1408 		}
1409 		else if (strncmp(argv[2], "on", 2) == 0) {
1410 			rc = ipmi_set_channel_access(intf, chan, 1);
1411 		}
1412 		else if (strncmp(argv[2], "off", 3) == 0) {
1413 			rc = ipmi_set_channel_access(intf, chan, 0);
1414 		}
1415 		else {
1416 			print_lan_set_access_usage();
1417 			return (-1);
1418 		}
1419 	}
1420 	/* set ARP control */
1421 	else if (strncmp(argv[1], "arp", 3) == 0) {
1422 		if (argc < 3) {
1423 			print_lan_set_arp_usage();
1424 			return (-1);
1425 		}
1426 		else if (strncmp(argv[2], "help", 4) == 0) {
1427 			print_lan_set_arp_usage();
1428 		}
1429 		else if (strncmp(argv[2], "interval", 8) == 0) {
1430 			uint8_t interval = 0;
1431 			if (str2uchar(argv[3], &interval) != 0) {
1432 				lprintf(LOG_ERR, "Given ARP interval '%s' is invalid.", argv[3]);
1433 				return (-1);
1434 			}
1435 			rc = lan_set_arp_interval(intf, chan, interval);
1436 		}
1437 		else if (strncmp(argv[2], "generate", 8) == 0) {
1438 			if (argc < 4) {
1439 				print_lan_set_arp_usage();
1440 				return (-1);
1441 			}
1442 			else if (strncmp(argv[3], "on", 2) == 0)
1443 				rc = lan_set_arp_generate(intf, chan, 1);
1444 			else if (strncmp(argv[3], "off", 3) == 0)
1445 				rc = lan_set_arp_generate(intf, chan, 0);
1446 			else {
1447 				print_lan_set_arp_usage();
1448 				return (-1);
1449 			}
1450 		}
1451 		else if (strncmp(argv[2], "respond", 7) == 0) {
1452 			if (argc < 4) {
1453 				print_lan_set_arp_usage();
1454 				return (-1);
1455 			}
1456 			else if (strncmp(argv[3], "on", 2) == 0)
1457 				rc = lan_set_arp_respond(intf, chan, 1);
1458 			else if (strncmp(argv[3], "off", 3) == 0)
1459 				rc = lan_set_arp_respond(intf, chan, 0);
1460 			else {
1461 				print_lan_set_arp_usage();
1462 				return (-1);
1463 			}
1464 		}
1465 		else {
1466 			print_lan_set_arp_usage();
1467 		}
1468 	}
1469 	/* set authentication types */
1470 	else if (strncmp(argv[1], "auth", 4) == 0) {
1471 		if (argc < 3) {
1472 			print_lan_set_auth_usage();
1473 			return (-1);
1474 		}
1475 		else if (strncmp(argv[2], "help", 4) == 0) {
1476 			print_lan_set_auth_usage();
1477 			return 0;
1478 		} else {
1479 			rc = ipmi_lan_set_auth(intf, chan, argv[2], argv[3]);
1480 		}
1481 	}
1482 	/* ip address source */
1483 	else if (strncmp(argv[1], "ipsrc", 5) == 0) {
1484 		if (argc < 3) {
1485 			print_lan_set_ipsrc_usage();
1486 			return (-1);
1487 		}
1488 		else if (strncmp(argv[2], "help", 4) == 0) {
1489 			print_lan_set_ipsrc_usage();
1490 			return 0;
1491 		}
1492 		else if (strncmp(argv[2], "none", 4) == 0)
1493 			data[0] = 0;
1494 		else if (strncmp(argv[2], "static", 5) == 0)
1495 			data[0] = 1;
1496 		else if (strncmp(argv[2], "dhcp", 4) == 0)
1497 			data[0] = 2;
1498 		else if (strncmp(argv[2], "bios", 4) == 0)
1499 			data[0] = 3;
1500 		else {
1501 			print_lan_set_ipsrc_usage();
1502 			return -1;
1503 		}
1504 		rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR_SRC, data, 1);
1505 	}
1506 	/* session password
1507 	 * not strictly a lan setting, but its used for lan connections */
1508 	else if (strncmp(argv[1], "password", 8) == 0) {
1509 		rc = ipmi_lan_set_password(intf, 1, (uint8_t *)argv[2]);
1510 	}
1511 	/* snmp community string */
1512 	else if (strncmp(argv[1], "snmp", 4) == 0) {
1513 		if (argc < 3) {
1514 			print_lan_set_snmp_usage();
1515 			return (-1);
1516 		}
1517 		else if (strncmp(argv[2], "help", 4) == 0) {
1518 			print_lan_set_snmp_usage();
1519 			return 0;
1520 		} else {
1521 			memcpy(data, argv[2], __min(strlen(argv[2]), 18));
1522 			printf("Setting LAN %s to %s\n",
1523 			       ipmi_lan_params[IPMI_LANP_SNMP_STRING].desc, data);
1524 			rc = set_lan_param(intf, chan, IPMI_LANP_SNMP_STRING, data, 18);
1525 		}
1526 	}
1527 	/* ip address */
1528 	else if (strncmp(argv[1], "ipaddr", 6) == 0) {
1529 		if(argc != 3)
1530 		{
1531 			print_lan_set_usage();
1532 			return -1;
1533 		}
1534 		rc = get_cmdline_ipaddr(argv[2], data);
1535 		if (rc == 0) {
1536 			printf("Setting LAN %s to %d.%d.%d.%d\n",
1537 				ipmi_lan_params[IPMI_LANP_IP_ADDR].desc,
1538 				data[0], data[1], data[2], data[3]);
1539 			rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4);
1540 		}
1541 	}
1542 	/* network mask */
1543 	else if (strncmp(argv[1], "netmask", 7) == 0) {
1544 		if(argc != 3)
1545 		{
1546 			print_lan_set_usage();
1547 			return -1;
1548 		}
1549 		rc = get_cmdline_ipaddr(argv[2], data);
1550 		if (rc == 0) {
1551 			printf("Setting LAN %s to %d.%d.%d.%d\n",
1552 		       		ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc,
1553 		       		data[0], data[1], data[2], data[3]);
1554 			rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4);
1555 		}
1556 	}
1557 	/* mac address */
1558 	else if (strncmp(argv[1], "macaddr", 7) == 0) {
1559 		if(argc != 3)
1560 		{
1561 			print_lan_set_usage();
1562 			return -1;
1563 		}
1564 		rc = get_cmdline_macaddr(argv[2], data);
1565 		if (rc == 0) {
1566 			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1567 		       		ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc,
1568 		       		data[0], data[1], data[2], data[3], data[4], data[5]);
1569 			rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6);
1570 		}
1571 	}
1572 	/* default gateway settings */
1573 	else if (strncmp(argv[1], "defgw", 5) == 0) {
1574 		if (argc < 4) {
1575 			print_lan_set_defgw_usage();
1576 			return (-1);
1577 		}
1578 		else if (strncmp(argv[2], "help", 4) == 0) {
1579 			print_lan_set_defgw_usage();
1580 			return 0;
1581 		}
1582 		else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
1583 			 (get_cmdline_ipaddr(argv[3], data) == 0)) {
1584 			printf("Setting LAN %s to %d.%d.%d.%d\n",
1585 			       ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_IP].desc,
1586 			       data[0], data[1], data[2], data[3]);
1587 			rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4);
1588 		}
1589 		else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
1590 			 (get_cmdline_macaddr(argv[3], data) == 0)) {
1591 			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1592 			       ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc,
1593 			       data[0], data[1], data[2], data[3], data[4], data[5]);
1594 			rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6);
1595 		}
1596 		else {
1597 			print_lan_set_usage();
1598 			return -1;
1599 		}
1600 	}
1601 	/* backup gateway settings */
1602 	else if (strncmp(argv[1], "bakgw", 5) == 0) {
1603 		if (argc < 4) {
1604 			print_lan_set_bakgw_usage();
1605 			return (-1);
1606 		}
1607 		else if (strncmp(argv[2], "help", 4) == 0) {
1608 			print_lan_set_bakgw_usage();
1609 			return 0;
1610 		}
1611 		else if ((strncmp(argv[2], "ipaddr", 5) == 0) &&
1612 			 (get_cmdline_ipaddr(argv[3], data) == 0)) {
1613 			printf("Setting LAN %s to %d.%d.%d.%d\n",
1614 			       ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_IP].desc,
1615 			       data[0], data[1], data[2], data[3]);
1616 			rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4);
1617 		}
1618 		else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
1619 			 (get_cmdline_macaddr(argv[3], data) == 0)) {
1620 			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
1621 			       ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc,
1622 			       data[0], data[1], data[2], data[3], data[4], data[5]);
1623 			rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6);
1624 		}
1625 		else {
1626 			print_lan_set_usage();
1627 			return -1;
1628 		}
1629 	}
1630 	else if (strncasecmp(argv[1], "vlan", 4) == 0) {
1631 		if (argc < 4) {
1632 			print_lan_set_vlan_usage();
1633 			return (-1);
1634 		}
1635 		else if (strncmp(argv[2], "help", 4) == 0) {
1636 			print_lan_set_vlan_usage();
1637 			return 0;
1638 		}
1639 		else if (strncasecmp(argv[2], "id", 2) == 0) {
1640 			if (strncasecmp(argv[3], "off", 3) == 0) {
1641 				ipmi_lan_set_vlan_id(intf, chan, NULL);
1642 			}
1643 			else {
1644 				ipmi_lan_set_vlan_id(intf, chan, argv[3]);
1645 			}
1646 		}
1647 		else if (strncasecmp(argv[2], "priority", 8) == 0) {
1648 			ipmi_lan_set_vlan_priority(intf, chan, argv[3]);
1649 		}
1650 		else {
1651 			print_lan_set_vlan_usage();
1652 			return (-1);
1653 		}
1654 	}
1655 	/* set PEF alerting on or off */
1656 	else if (strncasecmp(argv[1], "alert", 5) == 0) {
1657 		if (argc < 3) {
1658 			lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'");
1659 			return (-1);
1660 		}
1661 		else if (strncasecmp(argv[2], "on", 2) == 0 ||
1662 			 strncasecmp(argv[2], "enable", 6) == 0) {
1663 			printf("Enabling PEF alerts for LAN channel %d\n", chan);
1664 			rc = ipmi_set_alert_enable(intf, chan, 1);
1665 		}
1666 		else if (strncasecmp(argv[2], "off", 3) == 0 ||
1667 			 strncasecmp(argv[2], "disable", 7) == 0) {
1668 			printf("Disabling PEF alerts for LAN channel %d\n", chan);
1669 			rc = ipmi_set_alert_enable(intf, chan, 0);
1670 		}
1671 		else {
1672 			lprintf(LOG_NOTICE, "LAN set alert must be 'on' or 'off'");
1673 			return 0;
1674 		}
1675 	}
1676 	/* RMCP+ cipher suite privilege levels */
1677 	else if (strncmp(argv[1], "cipher_privs", 12) == 0)
1678 	{
1679 		if (argc != 3) {
1680 			print_lan_set_cipher_privs_usage();
1681 			return (-1);
1682 		}
1683 		else if ((strncmp(argv[2], "help", 4) == 0) ||
1684 		    get_cmdline_cipher_suite_priv_data(argv[2], data))
1685 		{
1686 			print_lan_set_cipher_privs_usage();
1687 			return 0;
1688 		}
1689 		else
1690 		{
1691 			rc = set_lan_param(intf, chan, IPMI_LANP_RMCP_PRIV_LEVELS, data, 9);
1692 		}
1693 	}
1694 	else {
1695 		print_lan_set_usage();
1696 		return (-1);
1697 	}
1698 
1699 	return rc;
1700 }
1701 
1702 
1703 static int
1704 is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert)
1705 {
1706 	struct lan_param * p;
1707 
1708 	p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST);
1709 	if (p == NULL)
1710 		return 0;
1711 	if (p->data == NULL)
1712 		return 0;
1713 
1714 	if (alert <= (p->data[0] & 0xf))
1715 		return 1;
1716 	else
1717 		return 0;
1718 }
1719 
1720 static int
1721 ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert)
1722 {
1723 # define PTYPE_LEN	4
1724 # define PADDR_LEN	13
1725 	struct lan_param *lp_ptr = NULL;
1726 	int isack = 0;
1727 	uint8_t ptype[PTYPE_LEN];
1728 	uint8_t paddr[PADDR_LEN];
1729 
1730 	lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert);
1731 	if (lp_ptr == NULL || lp_ptr->data == NULL
1732 			|| lp_ptr->data_len < PTYPE_LEN) {
1733 		return (-1);
1734 	}
1735 	memcpy(ptype, lp_ptr->data, PTYPE_LEN);
1736 
1737 	lp_ptr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert);
1738 	if (lp_ptr == NULL || lp_ptr->data == NULL
1739 			|| lp_ptr->data_len < PADDR_LEN) {
1740 		return (-1);
1741 	}
1742 	memcpy(paddr, lp_ptr->data, PADDR_LEN);
1743 
1744 	printf("%-24s: %d\n", "Alert Destination",
1745 			ptype[0]);
1746 
1747 	if (ptype[1] & 0x80) {
1748 		isack = 1;
1749 	}
1750 	printf("%-24s: %s\n", "Alert Acknowledge",
1751 			isack ? "Acknowledged" : "Unacknowledged");
1752 
1753 	printf("%-24s: ", "Destination Type");
1754 	switch (ptype[1] & 0x7) {
1755 	case 0:
1756 		printf("PET Trap\n");
1757 		break;
1758 	case 6:
1759 		printf("OEM 1\n");
1760 		break;
1761 	case 7:
1762 		printf("OEM 2\n");
1763 		break;
1764 	default:
1765 		printf("Unknown\n");
1766 		break;
1767 	}
1768 
1769 	printf("%-24s: %d\n",
1770 			isack ? "Acknowledge Timeout" : "Retry Interval",
1771 			ptype[2]);
1772 
1773 	printf("%-24s: %d\n", "Number of Retries",
1774 			ptype[3] & 0x7);
1775 
1776 	if ((paddr[1] & 0xf0) != 0) {
1777 		/* unknown address format */
1778 		printf("\n");
1779 		return 0;
1780 	}
1781 
1782 	printf("%-24s: %s\n", "Alert Gateway",
1783 			(paddr[2] & 1) ? "Backup" : "Default");
1784 
1785 	printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address",
1786 			paddr[3], paddr[4], paddr[5], paddr[6]);
1787 
1788 	printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address",
1789 			paddr[7], paddr[8], paddr[9],
1790 			paddr[10], paddr[11], paddr[12]);
1791 
1792 	printf("\n");
1793 	return 0;
1794 }
1795 
1796 static int
1797 ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel)
1798 {
1799 	int j, ndest;
1800 	struct lan_param * p;
1801 
1802 	p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST);
1803 	if (p == NULL)
1804 		return -1;
1805 	if (p->data == NULL)
1806 		return -1;
1807 	ndest = p->data[0] & 0xf;
1808 
1809 	for (j=0; j<=ndest; j++) {
1810 		ipmi_lan_alert_print(intf, channel, j);
1811 	}
1812 
1813 	return 0;
1814 }
1815 
1816 static int
1817 ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
1818 		   int argc, char ** argv)
1819 {
1820 	struct lan_param * p;
1821 	uint8_t data[32], temp[32];
1822 	int rc = 0;
1823 
1824 	if (argc < 2) {
1825 		print_lan_alert_set_usage();
1826 		return (-1);
1827 	}
1828 
1829 	if (strncmp(argv[0], "help", 4) == 0 ||
1830 	    strncmp(argv[1], "help", 4) == 0) {
1831 		print_lan_alert_set_usage();
1832 		return 0;
1833 	}
1834 
1835 	memset(data, 0, sizeof(data));
1836 	memset(temp, 0, sizeof(temp));
1837 
1838 	/* alert destination ip address */
1839 	if (strncasecmp(argv[0], "ipaddr", 6) == 0 &&
1840 	    (get_cmdline_ipaddr(argv[1], temp) == 0)) {
1841 		/* get current parameter */
1842 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1843 		if (p == NULL) {
1844 			return (-1);
1845 		}
1846 		memcpy(data, p->data, p->data_len);
1847 		/* set new ipaddr */
1848 		memcpy(data+3, temp, 4);
1849 		printf("Setting LAN Alert %d IP Address to %d.%d.%d.%d\n", alert,
1850 		       data[3], data[4], data[5], data[6]);
1851 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1852 	}
1853 	/* alert destination mac address */
1854 	else if (strncasecmp(argv[0], "macaddr", 7) == 0 &&
1855 		 (get_cmdline_macaddr(argv[1], temp) == 0)) {
1856 		/* get current parameter */
1857 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1858 		if (p == NULL) {
1859 			return (-1);
1860 		}
1861 		memcpy(data, p->data, p->data_len);
1862 		/* set new macaddr */
1863 		memcpy(data+7, temp, 6);
1864 		printf("Setting LAN Alert %d MAC Address to "
1865 		       "%02x:%02x:%02x:%02x:%02x:%02x\n", alert,
1866 		       data[7], data[8], data[9], data[10], data[11], data[12]);
1867 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1868 	}
1869 	/* alert destination gateway selector */
1870 	else if (strncasecmp(argv[0], "gateway", 7) == 0) {
1871 		/* get current parameter */
1872 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
1873 		if (p == NULL) {
1874 			return (-1);
1875 		}
1876 		memcpy(data, p->data, p->data_len);
1877 
1878 		if (strncasecmp(argv[1], "def", 3) == 0 ||
1879 		    strncasecmp(argv[1], "default", 7) == 0) {
1880 			printf("Setting LAN Alert %d to use Default Gateway\n", alert);
1881 			data[2] = 0;
1882 		}
1883 		else if (strncasecmp(argv[1], "bak", 3) == 0 ||
1884 			 strncasecmp(argv[1], "backup", 6) == 0) {
1885 			printf("Setting LAN Alert %d to use Backup Gateway\n", alert);
1886 			data[2] = 1;
1887 		}
1888 		else {
1889 			print_lan_alert_set_usage();
1890 			return -1;
1891 		}
1892 
1893 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
1894 	}
1895 	/* alert acknowledgement */
1896 	else if (strncasecmp(argv[0], "ack", 3) == 0) {
1897 		/* get current parameter */
1898 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1899 		if (p == NULL) {
1900 			return (-1);
1901 		}
1902 		memcpy(data, p->data, p->data_len);
1903 
1904 		if (strncasecmp(argv[1], "on", 2) == 0 ||
1905 		    strncasecmp(argv[1], "yes", 3) == 0) {
1906 			printf("Setting LAN Alert %d to Acknowledged\n", alert);
1907 			data[1] |= 0x80;
1908 		}
1909 		else if (strncasecmp(argv[1], "off", 3) == 0 ||
1910 			 strncasecmp(argv[1], "no", 2) == 0) {
1911 			printf("Setting LAN Alert %d to Unacknowledged\n", alert);
1912 			data[1] &= ~0x80;
1913 		}
1914 		else {
1915 			print_lan_alert_set_usage();
1916 			return -1;
1917 		}
1918 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1919 	}
1920 	/* alert destination type */
1921 	else if (strncasecmp(argv[0], "type", 4) == 0) {
1922 		/* get current parameter */
1923 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1924 		if (p == NULL) {
1925 			return (-1);
1926 		}
1927 		memcpy(data, p->data, p->data_len);
1928 
1929 		if (strncasecmp(argv[1], "pet", 3) == 0) {
1930 			printf("Setting LAN Alert %d destination to PET Trap\n", alert);
1931 			data[1] &= ~0x07;
1932 		}
1933 		else if (strncasecmp(argv[1], "oem1", 4) == 0) {
1934 			printf("Setting LAN Alert %d destination to OEM 1\n", alert);
1935 			data[1] &= ~0x07;
1936 			data[1] |= 0x06;
1937 		}
1938 		else if (strncasecmp(argv[1], "oem2", 4) == 0) {
1939 			printf("Setting LAN Alert %d destination to OEM 2\n", alert);
1940 			data[1] |= 0x07;
1941 		}
1942 		else {
1943 			print_lan_alert_set_usage();
1944 			return -1;
1945 		}
1946 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1947 	}
1948 	/* alert acknowledge timeout or retry interval */
1949 	else if (strncasecmp(argv[0], "time", 4) == 0) {
1950 		/* get current parameter */
1951 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1952 		if (p == NULL) {
1953 			return (-1);
1954 		}
1955 		memcpy(data, p->data, p->data_len);
1956 
1957 		if (str2uchar(argv[1], &data[2]) != 0) {
1958 			lprintf(LOG_ERR, "Invalid time: %s", argv[1]);
1959 			return (-1);
1960 		}
1961 		printf("Setting LAN Alert %d timeout/retry to %d seconds\n", alert, data[2]);
1962 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1963 	}
1964 	/* number of retries */
1965 	else if (strncasecmp(argv[0], "retry", 5) == 0) {
1966 		/* get current parameter */
1967 		p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_TYPE, alert);
1968 		if (p == NULL) {
1969 			return (-1);
1970 		}
1971 		memcpy(data, p->data, p->data_len);
1972 
1973 		if (str2uchar(argv[1], &data[3]) != 0) {
1974 			lprintf(LOG_ERR, "Invalid retry: %s", argv[1]);
1975 			return (-1);
1976 		}
1977 		data[3] = data[3] & 0x7;
1978 		printf("Setting LAN Alert %d number of retries to %d\n", alert, data[3]);
1979 		rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_TYPE, data, p->data_len);
1980 	}
1981 	else {
1982 		print_lan_alert_set_usage();
1983 		return -1;
1984 	}
1985 
1986 	return rc;
1987 }
1988 
1989 static int
1990 ipmi_lan_alert(struct ipmi_intf * intf, int argc, char ** argv)
1991 {
1992 	uint8_t alert;
1993 	uint8_t channel = 1;
1994 
1995 	if (argc < 1) {
1996 		print_lan_alert_print_usage();
1997 		print_lan_alert_set_usage();
1998 		return (-1);
1999 	}
2000 	else if (strncasecmp(argv[0], "help", 4) == 0) {
2001 		print_lan_alert_print_usage();
2002 		print_lan_alert_set_usage();
2003 		return 0;
2004 	}
2005 
2006 	/* alert print [channel] [alert] */
2007 	if (strncasecmp(argv[0], "print", 5) == 0) {
2008 		if (argc < 2) {
2009 			channel = find_lan_channel(intf, 1);
2010 			if (!is_lan_channel(intf, channel)) {
2011 				lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2012 				return -1;
2013 			}
2014 			return ipmi_lan_alert_print_all(intf, channel);
2015 		}
2016 
2017 		if (strncasecmp(argv[1], "help", 4) == 0) {
2018 			print_lan_alert_print_usage();
2019 			return 0;
2020 		}
2021 
2022 		if (str2uchar(argv[1], &channel) != 0) {
2023 			lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2024 			return (-1);
2025 		}
2026 		if (!is_lan_channel(intf, channel)) {
2027 			lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2028 			return -1;
2029 		}
2030 
2031 		if (argc < 3)
2032 			return ipmi_lan_alert_print_all(intf, channel);
2033 
2034 		if (str2uchar(argv[2], &alert) != 0) {
2035 			lprintf(LOG_ERR, "Invalid alert: %s", argv[2]);
2036 			return (-1);
2037 		}
2038 		if (is_alert_destination(intf, channel, alert) == 0) {
2039 			lprintf(LOG_ERR, "Alert %d is not a valid destination", alert);
2040 			return -1;
2041 		}
2042 		return ipmi_lan_alert_print(intf, channel, alert);
2043 	}
2044 
2045 	/* alert set <channel> <alert> [option] */
2046 	if (strncasecmp(argv[0], "set", 3) == 0) {
2047 		if (argc < 5) {
2048 			print_lan_alert_set_usage();
2049 			return (-1);
2050 		}
2051 		else if (strncasecmp(argv[1], "help", 4) == 0) {
2052 			print_lan_alert_set_usage();
2053 			return 0;
2054 		}
2055 
2056 		if (str2uchar(argv[1], &channel) != 0) {
2057 			lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2058 			return (-1);
2059 		}
2060 		if (!is_lan_channel(intf, channel)) {
2061 			lprintf(LOG_ERR, "Channel %d is not a LAN channel", channel);
2062 			return -1;
2063 		}
2064 
2065 		if (str2uchar(argv[2], &alert) != 0) {
2066 			lprintf(LOG_ERR, "Invalid alert: %s", argv[2]);
2067 			return (-1);
2068 		}
2069 		if (is_alert_destination(intf, channel, alert) == 0) {
2070 			lprintf(LOG_ERR, "Alert %d is not a valid destination", alert);
2071 			return -1;
2072 		}
2073 
2074 		return ipmi_lan_alert_set(intf, channel, alert, argc-3, &(argv[3]));
2075 	}
2076 
2077 	return 0;
2078 }
2079 
2080 
2081 static int
2082 ipmi_lan_stats_get(struct ipmi_intf * intf, uint8_t chan)
2083 {
2084 	int rc = 0;
2085 	struct ipmi_rs * rsp;
2086 	struct ipmi_rq req;
2087 	uint8_t msg_data[2];
2088 	uint16_t statsTemp;
2089 
2090 	if (!is_lan_channel(intf, chan)) {
2091 		lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan);
2092 		return -1;
2093 	}
2094 
2095 	/* From here, we are ready to get the stats */
2096 
2097 	msg_data[0] = chan;
2098 	msg_data[1] = 0;   /* Don't clear */
2099 
2100 	memset(&req, 0, sizeof(req));
2101 	req.msg.netfn    = IPMI_NETFN_TRANSPORT;
2102 	req.msg.cmd      = IPMI_LAN_GET_STAT;
2103 	req.msg.data     = msg_data;
2104 	req.msg.data_len = 2;
2105 
2106 	rsp = intf->sendrecv(intf, &req);
2107 	if (rsp == NULL) {
2108 		lprintf(LOG_ERR, "Get LAN Stats command failed");
2109 		return (-1);
2110 	}
2111 
2112 	if (rsp->ccode > 0) {
2113 		lprintf(LOG_ERR, "Get LAN Stats command failed: %s",
2114 			val2str(rsp->ccode, completion_code_vals));
2115 		return (-1);
2116 	}
2117 
2118 	if (verbose > 1) {
2119 		uint8_t counter;
2120 		printf("--- Rx Stats ---\n");
2121 		for (counter=0; counter<18; counter+=2) {
2122 			printf("%02X", *(rsp->data + counter));
2123 			printf(" %02X - ", *(rsp->data + counter+1));
2124 		}
2125 		printf("\n");
2126 	}
2127 
2128 	statsTemp = ((*(rsp->data + 0)) << 8) | (*(rsp->data + 1));
2129 	printf("IP Rx Packet              : %d\n", statsTemp);
2130 
2131 	statsTemp = ((*(rsp->data + 2)) << 8) | (*(rsp->data + 3));
2132 	printf("IP Rx Header Errors       : %u\n", statsTemp);
2133 
2134 	statsTemp = ((*(rsp->data + 4)) << 8) | (*(rsp->data + 5));
2135 	printf("IP Rx Address Errors      : %u\n", statsTemp);
2136 
2137 	statsTemp = ((*(rsp->data + 6)) << 8) | (*(rsp->data + 7));
2138 	printf("IP Rx Fragmented          : %u\n", statsTemp);
2139 
2140 	statsTemp = ((*(rsp->data + 8)) << 8) | (*(rsp->data + 9));
2141 	printf("IP Tx Packet              : %u\n", statsTemp);
2142 
2143 	statsTemp = ((*(rsp->data +10)) << 8) | (*(rsp->data +11));
2144 	printf("UDP Rx Packet             : %u\n", statsTemp);
2145 
2146 	statsTemp = ((*(rsp->data + 12)) << 8) | (*(rsp->data + 13));
2147 	printf("RMCP Rx Valid             : %u\n", statsTemp);
2148 
2149 	statsTemp = ((*(rsp->data + 14)) << 8) | (*(rsp->data + 15));
2150 	printf("UDP Proxy Packet Received : %u\n", statsTemp);
2151 
2152 	statsTemp = ((*(rsp->data + 16)) << 8) | (*(rsp->data + 17));
2153 	printf("UDP Proxy Packet Dropped  : %u\n", statsTemp);
2154 
2155 	return rc;
2156 }
2157 
2158 
2159 static int
2160 ipmi_lan_stats_clear(struct ipmi_intf * intf, uint8_t chan)
2161 {
2162 	int rc = 0;
2163 	struct ipmi_rs * rsp;
2164 	struct ipmi_rq req;
2165 	uint8_t msg_data[2];
2166 
2167 	if (!is_lan_channel(intf, chan)) {
2168 		lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan);
2169 		return -1;
2170 	}
2171 
2172 	/* From here, we are ready to get the stats */
2173 	msg_data[0] = chan;
2174 	msg_data[1] = 1;   /* Clear */
2175 
2176 	memset(&req, 0, sizeof(req));
2177 	req.msg.netfn    = IPMI_NETFN_TRANSPORT;
2178 	req.msg.cmd      = IPMI_LAN_GET_STAT;
2179 	req.msg.data     = msg_data;
2180 	req.msg.data_len = 2;
2181 
2182 	rsp = intf->sendrecv(intf, &req);
2183 	if (rsp == NULL) {
2184 		lprintf(LOG_INFO, "Get LAN Stats command failed");
2185 		return (-1);
2186 	}
2187 
2188 	if (rsp->ccode > 0) {
2189 		lprintf(LOG_INFO, "Get LAN Stats command failed: %s",
2190 			val2str(rsp->ccode, completion_code_vals));
2191 		return (-1);
2192 	}
2193 
2194 	return rc;
2195 }
2196 
2197 static void
2198 print_lan_alert_print_usage(void)
2199 {
2200 	lprintf(LOG_NOTICE,
2201 "");
2202 	lprintf(LOG_NOTICE,
2203 "usage: lan alert print [channel number] [alert destination]");
2204 	lprintf(LOG_NOTICE,
2205 "");
2206 	lprintf(LOG_NOTICE,
2207 "Default will print all alerts for the first found LAN channel");
2208 }
2209 
2210 static void
2211 print_lan_alert_set_usage(void)
2212 {
2213 	lprintf(LOG_NOTICE,
2214 "");
2215 	lprintf(LOG_NOTICE,
2216 "usage: lan alert set <channel number> <alert destination> <command> <parameter>");
2217 	lprintf(LOG_NOTICE,
2218 "");
2219 	lprintf(LOG_NOTICE,
2220 "    Command/parameter options:");
2221 	lprintf(LOG_NOTICE,
2222 "");
2223 	lprintf(LOG_NOTICE,
2224 "    ipaddr <x.x.x.x>               Set alert IP address");
2225 	lprintf(LOG_NOTICE,
2226 "    macaddr <x:x:x:x:x:x>          Set alert MAC address");
2227 	lprintf(LOG_NOTICE,
2228 "    gateway <default|backup>       Set channel gateway to use for alerts");
2229 	lprintf(LOG_NOTICE,
2230 "    ack <on|off>                   Set Alert Acknowledge on or off");
2231 	lprintf(LOG_NOTICE,
2232 "    type <pet|oem1|oem2>           Set destination type as PET or OEM");
2233 	lprintf(LOG_NOTICE,
2234 "    time <seconds>                 Set ack timeout or unack retry interval");
2235 	lprintf(LOG_NOTICE,
2236 "    retry <number>                 Set number of alert retries");
2237 	lprintf(LOG_NOTICE,
2238 "");
2239 }
2240 
2241 static void
2242 print_lan_set_usage(void)
2243 {
2244 	lprintf(LOG_NOTICE,
2245 "");
2246 	lprintf(LOG_NOTICE,
2247 "usage: lan set <channel> <command> <parameter>");
2248 	lprintf(LOG_NOTICE,
2249 "");
2250 	lprintf(LOG_NOTICE,
2251 "LAN set command/parameter options:");
2252 	lprintf(LOG_NOTICE,
2253 "  ipaddr <x.x.x.x>               Set channel IP address");
2254 	lprintf(LOG_NOTICE,
2255 "  netmask <x.x.x.x>              Set channel IP netmask");
2256 	lprintf(LOG_NOTICE,
2257 "  macaddr <x:x:x:x:x:x>          Set channel MAC address");
2258 	lprintf(LOG_NOTICE,
2259 "  defgw ipaddr <x.x.x.x>         Set default gateway IP address");
2260 	lprintf(LOG_NOTICE,
2261 "  defgw macaddr <x:x:x:x:x:x>    Set default gateway MAC address");
2262 	lprintf(LOG_NOTICE,
2263 "  bakgw ipaddr <x.x.x.x>         Set backup gateway IP address");
2264 	lprintf(LOG_NOTICE,
2265 "  bakgw macaddr <x:x:x:x:x:x>    Set backup gateway MAC address");
2266 	lprintf(LOG_NOTICE,
2267 "  password <password>            Set session password for this channel");
2268 	lprintf(LOG_NOTICE,
2269 "  snmp <community string>        Set SNMP public community string");
2270 	lprintf(LOG_NOTICE,
2271 "  user                           Enable default user for this channel");
2272 	lprintf(LOG_NOTICE,
2273 "  access <on|off>                Enable or disable access to this channel");
2274 	lprintf(LOG_NOTICE,
2275 "  alert <on|off>                 Enable or disable PEF alerting for this channel");
2276 	lprintf(LOG_NOTICE,
2277 "  arp respond <on|off>           Enable or disable BMC ARP responding");
2278 	lprintf(LOG_NOTICE,
2279 "  arp generate <on|off>          Enable or disable BMC gratuitous ARP generation");
2280 	lprintf(LOG_NOTICE,
2281 "  arp interval <seconds>         Set gratuitous ARP generation interval");
2282 	lprintf(LOG_NOTICE,
2283 "  vlan id <off|<id>>             Disable or enable VLAN and set ID (1-4094)");
2284 	lprintf(LOG_NOTICE,
2285 "  vlan priority <priority>       Set vlan priority (0-7)");
2286 	lprintf(LOG_NOTICE,
2287 "  auth <level> <type,..>         Set channel authentication types");
2288 	lprintf(LOG_NOTICE,
2289 "    level  = CALLBACK, USER, OPERATOR, ADMIN");
2290 	lprintf(LOG_NOTICE,
2291 "    type   = NONE, MD2, MD5, PASSWORD, OEM");
2292 	lprintf(LOG_NOTICE,
2293 "  ipsrc <source>                 Set IP Address source");
2294 	lprintf(LOG_NOTICE,
2295 "    none   = unspecified source");
2296 	lprintf(LOG_NOTICE,
2297 "    static = address manually configured to be static");
2298 	lprintf(LOG_NOTICE,
2299 "    dhcp   = address obtained by BMC running DHCP");
2300 	lprintf(LOG_NOTICE,
2301 "    bios   = address loaded by BIOS or system software");
2302 	lprintf(LOG_NOTICE,
2303 "  cipher_privs XXXXXXXXXXXXXXX   Set RMCP+ cipher suite privilege levels");
2304 	lprintf(LOG_NOTICE,
2305 "    X = Cipher Suite Unused");
2306 	lprintf(LOG_NOTICE,
2307 "    c = CALLBACK");
2308 	lprintf(LOG_NOTICE,
2309 "    u = USER");
2310 	lprintf(LOG_NOTICE,
2311 "    o = OPERATOR");
2312 	lprintf(LOG_NOTICE,
2313 "    a = ADMIN");
2314 	lprintf(LOG_NOTICE,
2315 "    O = OEM");
2316 	lprintf(LOG_NOTICE,
2317 "");
2318 }
2319 
2320 static void
2321 print_lan_set_access_usage(void)
2322 {
2323 	lprintf(LOG_NOTICE,
2324 "lan set access <on|off>");
2325 }
2326 
2327 static void
2328 print_lan_set_arp_usage(void)
2329 {
2330 	lprintf(LOG_NOTICE,
2331 "lan set <channel> arp respond <on|off>");
2332 	lprintf(LOG_NOTICE,
2333 "lan set <channel> arp generate <on|off>");
2334 	lprintf(LOG_NOTICE,
2335 "lan set <channel> arp interval <seconds>");
2336 	lprintf(LOG_NOTICE,
2337 "");
2338 	lprintf(LOG_NOTICE,
2339 "example: lan set 7 arp gratuitous off");
2340 }
2341 
2342 static void
2343 print_lan_set_auth_usage(void)
2344 {
2345 	lprintf(LOG_NOTICE,
2346 "lan set <channel> auth <level> <type,type,...>");
2347 	lprintf(LOG_NOTICE,
2348 "  level = CALLBACK, USER, OPERATOR, ADMIN");
2349 	lprintf(LOG_NOTICE,
2350 "  types = NONE, MD2, MD5, PASSWORD, OEM");
2351 	lprintf(LOG_NOTICE,
2352 "example: lan set 7 auth ADMIN PASSWORD,MD5");
2353 }
2354 
2355 static void
2356 print_lan_set_bakgw_usage(void)
2357 {
2358 	lprintf(LOG_NOTICE,
2359 "LAN set backup gateway commands: ipaddr, macaddr");
2360 }
2361 
2362 static void
2363 print_lan_set_cipher_privs_usage(void)
2364 {
2365 	lprintf(LOG_NOTICE,
2366 "lan set <channel> cipher_privs XXXXXXXXXXXXXXX");
2367 	lprintf(LOG_NOTICE,
2368 "    X = Cipher Suite Unused");
2369 	lprintf(LOG_NOTICE,
2370 "    c = CALLBACK");
2371 	lprintf(LOG_NOTICE,
2372 "    u = USER");
2373 	lprintf(LOG_NOTICE,
2374 "    o = OPERATOR");
2375 	lprintf(LOG_NOTICE,
2376 "    a = ADMIN");
2377 	lprintf(LOG_NOTICE,
2378 "    O = OEM");
2379 	lprintf(LOG_NOTICE,
2380 "");
2381 }
2382 
2383 static void
2384 print_lan_set_defgw_usage(void)
2385 {
2386 	lprintf(LOG_NOTICE,
2387 "LAN set default gateway Commands: ipaddr, macaddr");
2388 }
2389 
2390 static void
2391 print_lan_set_ipsrc_usage(void)
2392 {
2393 	lprintf(LOG_NOTICE,
2394 "lan set <channel> ipsrc <source>");
2395 	lprintf(LOG_NOTICE,
2396 "  none   = unspecified");
2397 	lprintf(LOG_NOTICE,
2398 "  static = static address (manually configured)");
2399 	lprintf(LOG_NOTICE,
2400 "  dhcp   = address obtained by BMC running DHCP");
2401 	lprintf(LOG_NOTICE,
2402 "  bios   = address loaded by BIOS or system software");
2403 }
2404 
2405 static void
2406 print_lan_set_snmp_usage(void)
2407 {
2408 	lprintf(LOG_NOTICE,
2409 "lan set <channel> snmp <community string>");
2410 }
2411 
2412 static void
2413 print_lan_set_vlan_usage(void)
2414 {
2415 	lprintf(LOG_NOTICE,
2416 "lan set <channel> vlan id <id>");
2417 	lprintf(LOG_NOTICE,
2418 "lan set <channel> vlan id off");
2419 	lprintf(LOG_NOTICE,
2420 "lan set <channel> vlan priority <priority>");
2421 }
2422 
2423 /*
2424  * print_lan_usage
2425  */
2426 static void
2427 print_lan_usage(void)
2428 {
2429 	lprintf(LOG_NOTICE,
2430 "LAN Commands:");
2431 	lprintf(LOG_NOTICE,
2432 "		   print [<channel number>]");
2433 	lprintf(LOG_NOTICE,
2434 "		   set <channel number> <command> <parameter>");
2435 	lprintf(LOG_NOTICE,
2436 "		   alert print <channel number> <alert destination>");
2437 	lprintf(LOG_NOTICE,
2438 "		   alert set <channel number> <alert destination> <command> <parameter>");
2439 	lprintf(LOG_NOTICE,
2440 "		   stats get [<channel number>]");
2441 	lprintf(LOG_NOTICE,
2442 "		   stats clear [<channel number>]");
2443 }
2444 
2445 
2446 int
2447 ipmi_lanp_main(struct ipmi_intf * intf, int argc, char ** argv)
2448 {
2449 	int rc = 0;
2450 	uint8_t chan = 0;
2451 
2452 	if (argc == 0) {
2453 		print_lan_usage();
2454 		return (-1);
2455 	} else if (strncmp(argv[0], "help", 4) == 0) {
2456 		print_lan_usage();
2457 		return 0;
2458 	}
2459 
2460 	chan = find_lan_channel(intf, 1);
2461 
2462 	if (strncmp(argv[0], "printconf", 9) == 0 ||
2463 			strncmp(argv[0], "print", 5) == 0)
2464 	{
2465 		if (argc > 2) {
2466 			print_lan_usage();
2467 			return (-1);
2468 		} else if (argc == 2) {
2469 			if (str2uchar(argv[1], &chan) != 0) {
2470 				lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
2471 				return (-1);
2472 			}
2473 		}
2474 		if (!is_lan_channel(intf, chan)) {
2475 			lprintf(LOG_ERR, "Invalid channel: %d", chan);
2476 			return (-1);
2477 		}
2478 		rc = ipmi_lan_print(intf, chan);
2479 	} else if (strncmp(argv[0], "set", 3) == 0) {
2480 		rc = ipmi_lan_set(intf, argc-1, &(argv[1]));
2481 	} else if (strncmp(argv[0], "alert", 5) == 0) {
2482 		rc = ipmi_lan_alert(intf, argc-1, &(argv[1]));
2483 	} else if (strncmp(argv[0], "stats", 5) == 0) {
2484 		if (argc < 2) {
2485 			print_lan_usage();
2486 			return (-1);
2487 		} else if (argc == 3) {
2488 			if (str2uchar(argv[2], &chan) != 0) {
2489 				lprintf(LOG_ERR, "Invalid channel: %s", argv[2]);
2490 				return (-1);
2491 			}
2492 		}
2493 		if (!is_lan_channel(intf, chan)) {
2494 			lprintf(LOG_ERR, "Invalid channel: %d", chan);
2495 			return (-1);
2496 		}
2497 		if (strncmp(argv[1], "get", 3) == 0) {
2498 			rc = ipmi_lan_stats_get(intf, chan);
2499 		} else if (strncmp(argv[1], "clear", 5) == 0) {
2500 			rc = ipmi_lan_stats_clear(intf, chan);
2501 		} else {
2502 			print_lan_usage();
2503 			return (-1);
2504 		}
2505 	} else {
2506 		lprintf(LOG_NOTICE, "Invalid LAN command: %s", argv[0]);
2507 		return (-1);
2508 	}
2509 	return rc;
2510 }
2511