xref: /openbmc/ipmitool/lib/ipmi_channel.c (revision c18ec02f)
1*c18ec02fSPetter Reinholdtsen /* -*-mode: C; indent-tabs-mode: t; -*-
2*c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3*c18ec02fSPetter Reinholdtsen  *
4*c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5*c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6*c18ec02fSPetter Reinholdtsen  * are met:
7*c18ec02fSPetter Reinholdtsen  *
8*c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10*c18ec02fSPetter Reinholdtsen  *
11*c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13*c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14*c18ec02fSPetter Reinholdtsen  *
15*c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16*c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17*c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18*c18ec02fSPetter Reinholdtsen  *
19*c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20*c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21*c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22*c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23*c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24*c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25*c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26*c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27*c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28*c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29*c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30*c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31*c18ec02fSPetter Reinholdtsen  */
32*c18ec02fSPetter Reinholdtsen 
33*c18ec02fSPetter Reinholdtsen #include <stdlib.h>
34*c18ec02fSPetter Reinholdtsen #include <stdio.h>
35*c18ec02fSPetter Reinholdtsen #include <string.h>
36*c18ec02fSPetter Reinholdtsen #include <strings.h>
37*c18ec02fSPetter Reinholdtsen #include <sys/types.h>
38*c18ec02fSPetter Reinholdtsen #include <sys/socket.h>
39*c18ec02fSPetter Reinholdtsen #include <netinet/in.h>
40*c18ec02fSPetter Reinholdtsen #include <arpa/inet.h>
41*c18ec02fSPetter Reinholdtsen #include <errno.h>
42*c18ec02fSPetter Reinholdtsen #include <unistd.h>
43*c18ec02fSPetter Reinholdtsen #include <signal.h>
44*c18ec02fSPetter Reinholdtsen 
45*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
46*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
47*c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
48*c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
49*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_lanp.h>
50*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_channel.h>
51*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
52*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h>
53*c18ec02fSPetter Reinholdtsen 
54*c18ec02fSPetter Reinholdtsen extern int csv_output;
55*c18ec02fSPetter Reinholdtsen extern int verbose;
56*c18ec02fSPetter Reinholdtsen 
57*c18ec02fSPetter Reinholdtsen void printf_channel_usage (void);
58*c18ec02fSPetter Reinholdtsen 
59*c18ec02fSPetter Reinholdtsen /**
60*c18ec02fSPetter Reinholdtsen  * ipmi_1_5_authtypes
61*c18ec02fSPetter Reinholdtsen  *
62*c18ec02fSPetter Reinholdtsen  * Create a string describing the supported authentication types as
63*c18ec02fSPetter Reinholdtsen  * specificed by the parameter n
64*c18ec02fSPetter Reinholdtsen  */
65*c18ec02fSPetter Reinholdtsen static const char *
66*c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(uint8_t n)
67*c18ec02fSPetter Reinholdtsen {
68*c18ec02fSPetter Reinholdtsen 	uint32_t i;
69*c18ec02fSPetter Reinholdtsen 	static char supportedTypes[128];
70*c18ec02fSPetter Reinholdtsen 
71*c18ec02fSPetter Reinholdtsen 	bzero(supportedTypes, 128);
72*c18ec02fSPetter Reinholdtsen 
73*c18ec02fSPetter Reinholdtsen 	for (i = 0; ipmi_authtype_vals[i].val != 0; i++) {
74*c18ec02fSPetter Reinholdtsen 		if (n & ipmi_authtype_vals[i].val) {
75*c18ec02fSPetter Reinholdtsen 			strcat(supportedTypes, ipmi_authtype_vals[i].str);
76*c18ec02fSPetter Reinholdtsen 			strcat(supportedTypes, " ");
77*c18ec02fSPetter Reinholdtsen 		}
78*c18ec02fSPetter Reinholdtsen 	}
79*c18ec02fSPetter Reinholdtsen 
80*c18ec02fSPetter Reinholdtsen 	return supportedTypes;
81*c18ec02fSPetter Reinholdtsen }
82*c18ec02fSPetter Reinholdtsen 
83*c18ec02fSPetter Reinholdtsen 
84*c18ec02fSPetter Reinholdtsen 
85*c18ec02fSPetter Reinholdtsen /**
86*c18ec02fSPetter Reinholdtsen  * ipmi_get_channel_auth_cap
87*c18ec02fSPetter Reinholdtsen  *
88*c18ec02fSPetter Reinholdtsen  * return 0 on success
89*c18ec02fSPetter Reinholdtsen  *        -1 on failure
90*c18ec02fSPetter Reinholdtsen  */
91*c18ec02fSPetter Reinholdtsen int
92*c18ec02fSPetter Reinholdtsen ipmi_get_channel_auth_cap(struct ipmi_intf * intf,
93*c18ec02fSPetter Reinholdtsen 			  uint8_t channel,
94*c18ec02fSPetter Reinholdtsen 			  uint8_t priv)
95*c18ec02fSPetter Reinholdtsen {
96*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
97*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
98*c18ec02fSPetter Reinholdtsen 	struct get_channel_auth_cap_rsp auth_cap;
99*c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[2];
100*c18ec02fSPetter Reinholdtsen 
101*c18ec02fSPetter Reinholdtsen 	msg_data[0] = channel | 0x80; // Ask for IPMI v2 data as well
102*c18ec02fSPetter Reinholdtsen 	msg_data[1] = priv;
103*c18ec02fSPetter Reinholdtsen 
104*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
105*c18ec02fSPetter Reinholdtsen 	req.msg.netfn    = IPMI_NETFN_APP;            // 0x06
106*c18ec02fSPetter Reinholdtsen 	req.msg.cmd      = IPMI_GET_CHANNEL_AUTH_CAP; // 0x38
107*c18ec02fSPetter Reinholdtsen 	req.msg.data     = msg_data;
108*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
109*c18ec02fSPetter Reinholdtsen 
110*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
111*c18ec02fSPetter Reinholdtsen 
112*c18ec02fSPetter Reinholdtsen 	if ((rsp == NULL) || (rsp->ccode > 0))	{
113*c18ec02fSPetter Reinholdtsen 		/*
114*c18ec02fSPetter Reinholdtsen 		 * It's very possible that this failed because we asked for IPMI v2 data
115*c18ec02fSPetter Reinholdtsen 		 * Ask again, without requesting IPMI v2 data
116*c18ec02fSPetter Reinholdtsen 		 */
117*c18ec02fSPetter Reinholdtsen 		msg_data[0] &= 0x7F;
118*c18ec02fSPetter Reinholdtsen 
119*c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
120*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
121*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities");
122*c18ec02fSPetter Reinholdtsen 			return -1;
123*c18ec02fSPetter Reinholdtsen 		}
124*c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0) {
125*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s",
126*c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
127*c18ec02fSPetter Reinholdtsen 			return -1;
128*c18ec02fSPetter Reinholdtsen 		}
129*c18ec02fSPetter Reinholdtsen 	}
130*c18ec02fSPetter Reinholdtsen 
131*c18ec02fSPetter Reinholdtsen 	memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp));
132*c18ec02fSPetter Reinholdtsen 
133*c18ec02fSPetter Reinholdtsen 	printf("Channel number             : %d\n",
134*c18ec02fSPetter Reinholdtsen 		   auth_cap.channel_number);
135*c18ec02fSPetter Reinholdtsen 	printf("IPMI v1.5  auth types      : %s\n",
136*c18ec02fSPetter Reinholdtsen 		   ipmi_1_5_authtypes(auth_cap.enabled_auth_types));
137*c18ec02fSPetter Reinholdtsen 
138*c18ec02fSPetter Reinholdtsen 	if (auth_cap.v20_data_available)
139*c18ec02fSPetter Reinholdtsen 		printf("KG status                  : %s\n",
140*c18ec02fSPetter Reinholdtsen 			   (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)");
141*c18ec02fSPetter Reinholdtsen 
142*c18ec02fSPetter Reinholdtsen 	printf("Per message authentication : %sabled\n",
143*c18ec02fSPetter Reinholdtsen 		   (auth_cap.per_message_auth) ? "dis" : "en");
144*c18ec02fSPetter Reinholdtsen 	printf("User level authentication  : %sabled\n",
145*c18ec02fSPetter Reinholdtsen 		   (auth_cap.user_level_auth) ? "dis" : "en");
146*c18ec02fSPetter Reinholdtsen 
147*c18ec02fSPetter Reinholdtsen 	printf("Non-null user names exist  : %s\n",
148*c18ec02fSPetter Reinholdtsen 		   (auth_cap.non_null_usernames) ? "yes" : "no");
149*c18ec02fSPetter Reinholdtsen 	printf("Null user names exist      : %s\n",
150*c18ec02fSPetter Reinholdtsen 		   (auth_cap.null_usernames) ? "yes" : "no");
151*c18ec02fSPetter Reinholdtsen 	printf("Anonymous login enabled    : %s\n",
152*c18ec02fSPetter Reinholdtsen 		   (auth_cap.anon_login_enabled) ? "yes" : "no");
153*c18ec02fSPetter Reinholdtsen 
154*c18ec02fSPetter Reinholdtsen 	if (auth_cap.v20_data_available) {
155*c18ec02fSPetter Reinholdtsen 		printf("Channel supports IPMI v1.5 : %s\n",
156*c18ec02fSPetter Reinholdtsen 			   (auth_cap.ipmiv15_support) ? "yes" : "no");
157*c18ec02fSPetter Reinholdtsen 		printf("Channel supports IPMI v2.0 : %s\n",
158*c18ec02fSPetter Reinholdtsen 			   (auth_cap.ipmiv20_support) ? "yes" : "no");
159*c18ec02fSPetter Reinholdtsen 	}
160*c18ec02fSPetter Reinholdtsen 
161*c18ec02fSPetter Reinholdtsen 	/*
162*c18ec02fSPetter Reinholdtsen 	 * If there is support for an OEM authentication type, there is some
163*c18ec02fSPetter Reinholdtsen 	 * information.
164*c18ec02fSPetter Reinholdtsen 	 */
165*c18ec02fSPetter Reinholdtsen 	if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) {
166*c18ec02fSPetter Reinholdtsen 		printf("IANA Number for OEM        : %d\n",
167*c18ec02fSPetter Reinholdtsen 			   auth_cap.oem_id[0]      |
168*c18ec02fSPetter Reinholdtsen 			   auth_cap.oem_id[1] << 8 |
169*c18ec02fSPetter Reinholdtsen 			   auth_cap.oem_id[2] << 16);
170*c18ec02fSPetter Reinholdtsen 		printf("OEM Auxiliary Data         : 0x%x\n",
171*c18ec02fSPetter Reinholdtsen 			   auth_cap.oem_aux_data);
172*c18ec02fSPetter Reinholdtsen 	}
173*c18ec02fSPetter Reinholdtsen 
174*c18ec02fSPetter Reinholdtsen 	return 0;
175*c18ec02fSPetter Reinholdtsen }
176*c18ec02fSPetter Reinholdtsen 
177*c18ec02fSPetter Reinholdtsen 
178*c18ec02fSPetter Reinholdtsen 
179*c18ec02fSPetter Reinholdtsen /**
180*c18ec02fSPetter Reinholdtsen  * ipmi_get_channel_info
181*c18ec02fSPetter Reinholdtsen  *
182*c18ec02fSPetter Reinholdtsen  * returns 0 on success
183*c18ec02fSPetter Reinholdtsen  *         -1 on failure
184*c18ec02fSPetter Reinholdtsen  *
185*c18ec02fSPetter Reinholdtsen  */
186*c18ec02fSPetter Reinholdtsen int
187*c18ec02fSPetter Reinholdtsen ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel)
188*c18ec02fSPetter Reinholdtsen {
189*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
190*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
191*c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[2];
192*c18ec02fSPetter Reinholdtsen 	uint8_t medium;
193*c18ec02fSPetter Reinholdtsen 	struct get_channel_info_rsp   channel_info;
194*c18ec02fSPetter Reinholdtsen 	struct get_channel_access_rsp channel_access;
195*c18ec02fSPetter Reinholdtsen 
196*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
197*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;        // 0x06
198*c18ec02fSPetter Reinholdtsen 	req.msg.cmd   = IPMI_GET_CHANNEL_INFO; // 0x42
199*c18ec02fSPetter Reinholdtsen 	req.msg.data = &channel;
200*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
201*c18ec02fSPetter Reinholdtsen 
202*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
203*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
204*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Get Channel Info");
205*c18ec02fSPetter Reinholdtsen 		return -1;
206*c18ec02fSPetter Reinholdtsen 	}
207*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
208*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Channel Info failed: %s",
209*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
210*c18ec02fSPetter Reinholdtsen 		return -1;
211*c18ec02fSPetter Reinholdtsen 	}
212*c18ec02fSPetter Reinholdtsen 
213*c18ec02fSPetter Reinholdtsen 	memcpy(&channel_info, rsp->data, sizeof(struct get_channel_info_rsp));
214*c18ec02fSPetter Reinholdtsen 
215*c18ec02fSPetter Reinholdtsen 	printf("Channel 0x%x info:\n", channel_info.channel_number);
216*c18ec02fSPetter Reinholdtsen 
217*c18ec02fSPetter Reinholdtsen 	printf("  Channel Medium Type   : %s\n",
218*c18ec02fSPetter Reinholdtsen 		   val2str(channel_info.channel_medium, ipmi_channel_medium_vals));
219*c18ec02fSPetter Reinholdtsen 
220*c18ec02fSPetter Reinholdtsen 	printf("  Channel Protocol Type : %s\n",
221*c18ec02fSPetter Reinholdtsen 		   val2str(channel_info.channel_protocol, ipmi_channel_protocol_vals));
222*c18ec02fSPetter Reinholdtsen 
223*c18ec02fSPetter Reinholdtsen 	printf("  Session Support       : ");
224*c18ec02fSPetter Reinholdtsen 	switch (channel_info.session_support) {
225*c18ec02fSPetter Reinholdtsen 		case 0x0:
226*c18ec02fSPetter Reinholdtsen 			printf("session-less\n");
227*c18ec02fSPetter Reinholdtsen 			break;
228*c18ec02fSPetter Reinholdtsen 		case 0x1:
229*c18ec02fSPetter Reinholdtsen 			printf("single-session\n");
230*c18ec02fSPetter Reinholdtsen 			break;
231*c18ec02fSPetter Reinholdtsen 		case 0x2:
232*c18ec02fSPetter Reinholdtsen 			printf("multi-session\n");
233*c18ec02fSPetter Reinholdtsen 			break;
234*c18ec02fSPetter Reinholdtsen 		case 0x3:
235*c18ec02fSPetter Reinholdtsen 		default:
236*c18ec02fSPetter Reinholdtsen 			printf("session-based\n");
237*c18ec02fSPetter Reinholdtsen 			break;
238*c18ec02fSPetter Reinholdtsen 	}
239*c18ec02fSPetter Reinholdtsen 
240*c18ec02fSPetter Reinholdtsen 	printf("  Active Session Count  : %d\n",
241*c18ec02fSPetter Reinholdtsen 		   channel_info.active_sessions);
242*c18ec02fSPetter Reinholdtsen 
243*c18ec02fSPetter Reinholdtsen 	printf("  Protocol Vendor ID    : %d\n",
244*c18ec02fSPetter Reinholdtsen 		   channel_info.vendor_id[0]      |
245*c18ec02fSPetter Reinholdtsen 		   channel_info.vendor_id[1] << 8 |
246*c18ec02fSPetter Reinholdtsen 		   channel_info.vendor_id[2] << 16);
247*c18ec02fSPetter Reinholdtsen 
248*c18ec02fSPetter Reinholdtsen 
249*c18ec02fSPetter Reinholdtsen 	/* only proceed if this is LAN channel */
250*c18ec02fSPetter Reinholdtsen 	medium = ipmi_get_channel_medium(intf, channel);
251*c18ec02fSPetter Reinholdtsen 	if (medium != IPMI_CHANNEL_MEDIUM_LAN &&
252*c18ec02fSPetter Reinholdtsen 	    medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) {
253*c18ec02fSPetter Reinholdtsen 		return 0;
254*c18ec02fSPetter Reinholdtsen 	}
255*c18ec02fSPetter Reinholdtsen 
256*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
257*c18ec02fSPetter Reinholdtsen 	rqdata[0] = channel & 0xf;
258*c18ec02fSPetter Reinholdtsen 
259*c18ec02fSPetter Reinholdtsen 	/* get volatile settings */
260*c18ec02fSPetter Reinholdtsen 
261*c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x80; /* 0x80=active */
262*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;          // 0x06
263*c18ec02fSPetter Reinholdtsen 	req.msg.cmd   = IPMI_GET_CHANNEL_ACCESS; // 0x41
264*c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
265*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
266*c18ec02fSPetter Reinholdtsen 
267*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
268*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
269*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)");
270*c18ec02fSPetter Reinholdtsen 		return -1;
271*c18ec02fSPetter Reinholdtsen 	}
272*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
273*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Channel Access (volatile) failed: %s",
274*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
275*c18ec02fSPetter Reinholdtsen 		return -1;
276*c18ec02fSPetter Reinholdtsen 	}
277*c18ec02fSPetter Reinholdtsen 
278*c18ec02fSPetter Reinholdtsen 	memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp));
279*c18ec02fSPetter Reinholdtsen 
280*c18ec02fSPetter Reinholdtsen 
281*c18ec02fSPetter Reinholdtsen 	printf("  Volatile(active) Settings\n");
282*c18ec02fSPetter Reinholdtsen 	printf("    Alerting            : %sabled\n",
283*c18ec02fSPetter Reinholdtsen 		   (channel_access.alerting) ? "dis" : "en");
284*c18ec02fSPetter Reinholdtsen 	printf("    Per-message Auth    : %sabled\n",
285*c18ec02fSPetter Reinholdtsen 		   (channel_access.per_message_auth) ? "dis" : "en");
286*c18ec02fSPetter Reinholdtsen 	printf("    User Level Auth     : %sabled\n",
287*c18ec02fSPetter Reinholdtsen 		   (channel_access.user_level_auth) ? "dis" : "en");
288*c18ec02fSPetter Reinholdtsen 
289*c18ec02fSPetter Reinholdtsen 	printf("    Access Mode         : ");
290*c18ec02fSPetter Reinholdtsen 	switch (channel_access.access_mode) {
291*c18ec02fSPetter Reinholdtsen 		case 0:
292*c18ec02fSPetter Reinholdtsen 			printf("disabled\n");
293*c18ec02fSPetter Reinholdtsen 			break;
294*c18ec02fSPetter Reinholdtsen 		case 1:
295*c18ec02fSPetter Reinholdtsen 			printf("pre-boot only\n");
296*c18ec02fSPetter Reinholdtsen 			break;
297*c18ec02fSPetter Reinholdtsen 		case 2:
298*c18ec02fSPetter Reinholdtsen 			printf("always available\n");
299*c18ec02fSPetter Reinholdtsen 			break;
300*c18ec02fSPetter Reinholdtsen 		case 3:
301*c18ec02fSPetter Reinholdtsen 			printf("shared\n");
302*c18ec02fSPetter Reinholdtsen 			break;
303*c18ec02fSPetter Reinholdtsen 		default:
304*c18ec02fSPetter Reinholdtsen 			printf("unknown\n");
305*c18ec02fSPetter Reinholdtsen 			break;
306*c18ec02fSPetter Reinholdtsen 	}
307*c18ec02fSPetter Reinholdtsen 
308*c18ec02fSPetter Reinholdtsen 	/* get non-volatile settings */
309*c18ec02fSPetter Reinholdtsen 
310*c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x40; /* 0x40=non-volatile */
311*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
312*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
313*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)");
314*c18ec02fSPetter Reinholdtsen 		return -1;
315*c18ec02fSPetter Reinholdtsen 	}
316*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
317*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Channel Access (non-volatile) failed: %s",
318*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
319*c18ec02fSPetter Reinholdtsen 		return -1;
320*c18ec02fSPetter Reinholdtsen 	}
321*c18ec02fSPetter Reinholdtsen 
322*c18ec02fSPetter Reinholdtsen 	memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp));
323*c18ec02fSPetter Reinholdtsen 
324*c18ec02fSPetter Reinholdtsen 	printf("  Non-Volatile Settings\n");
325*c18ec02fSPetter Reinholdtsen 	printf("    Alerting            : %sabled\n",
326*c18ec02fSPetter Reinholdtsen 		   (channel_access.alerting) ? "dis" : "en");
327*c18ec02fSPetter Reinholdtsen 	printf("    Per-message Auth    : %sabled\n",
328*c18ec02fSPetter Reinholdtsen 		   (channel_access.per_message_auth) ? "dis" : "en");
329*c18ec02fSPetter Reinholdtsen 	printf("    User Level Auth     : %sabled\n",
330*c18ec02fSPetter Reinholdtsen 		   (channel_access.user_level_auth) ? "dis" : "en");
331*c18ec02fSPetter Reinholdtsen 
332*c18ec02fSPetter Reinholdtsen 	printf("    Access Mode         : ");
333*c18ec02fSPetter Reinholdtsen 	switch (channel_access.access_mode) {
334*c18ec02fSPetter Reinholdtsen 		case 0:
335*c18ec02fSPetter Reinholdtsen 			printf("disabled\n");
336*c18ec02fSPetter Reinholdtsen 			break;
337*c18ec02fSPetter Reinholdtsen 		case 1:
338*c18ec02fSPetter Reinholdtsen 			printf("pre-boot only\n");
339*c18ec02fSPetter Reinholdtsen 			break;
340*c18ec02fSPetter Reinholdtsen 		case 2:
341*c18ec02fSPetter Reinholdtsen 			printf("always available\n");
342*c18ec02fSPetter Reinholdtsen 			break;
343*c18ec02fSPetter Reinholdtsen 		case 3:
344*c18ec02fSPetter Reinholdtsen 			printf("shared\n");
345*c18ec02fSPetter Reinholdtsen 			break;
346*c18ec02fSPetter Reinholdtsen 		default:
347*c18ec02fSPetter Reinholdtsen 			printf("unknown\n");
348*c18ec02fSPetter Reinholdtsen 			break;
349*c18ec02fSPetter Reinholdtsen 	}
350*c18ec02fSPetter Reinholdtsen 
351*c18ec02fSPetter Reinholdtsen 	return 0;
352*c18ec02fSPetter Reinholdtsen }
353*c18ec02fSPetter Reinholdtsen 
354*c18ec02fSPetter Reinholdtsen static int
355*c18ec02fSPetter Reinholdtsen ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid)
356*c18ec02fSPetter Reinholdtsen {
357*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
358*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req1, req2;
359*c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[2];
360*c18ec02fSPetter Reinholdtsen 	struct get_user_access_rsp user_access;
361*c18ec02fSPetter Reinholdtsen 	int curr_uid, max_uid = 0, init = 1;
362*c18ec02fSPetter Reinholdtsen 
363*c18ec02fSPetter Reinholdtsen 	curr_uid = userid ? : 1;
364*c18ec02fSPetter Reinholdtsen 
365*c18ec02fSPetter Reinholdtsen 	memset(&req1, 0, sizeof(req1));
366*c18ec02fSPetter Reinholdtsen 	req1.msg.netfn = IPMI_NETFN_APP;
367*c18ec02fSPetter Reinholdtsen 	req1.msg.cmd = IPMI_GET_USER_ACCESS;
368*c18ec02fSPetter Reinholdtsen 	req1.msg.data = rqdata;
369*c18ec02fSPetter Reinholdtsen 	req1.msg.data_len = 2;
370*c18ec02fSPetter Reinholdtsen 
371*c18ec02fSPetter Reinholdtsen 	memset(&req2, 0, sizeof(req2));
372*c18ec02fSPetter Reinholdtsen 	req2.msg.netfn = IPMI_NETFN_APP;
373*c18ec02fSPetter Reinholdtsen 	req2.msg.cmd = IPMI_GET_USER_NAME;
374*c18ec02fSPetter Reinholdtsen 	req2.msg.data = rqdata;
375*c18ec02fSPetter Reinholdtsen 	req2.msg.data_len = 1;
376*c18ec02fSPetter Reinholdtsen 
377*c18ec02fSPetter Reinholdtsen 	do
378*c18ec02fSPetter Reinholdtsen 	{
379*c18ec02fSPetter Reinholdtsen 		rqdata[0] = channel & 0xf;
380*c18ec02fSPetter Reinholdtsen 		rqdata[1] = curr_uid & 0x3f;
381*c18ec02fSPetter Reinholdtsen 
382*c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req1);
383*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
384*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)",
385*c18ec02fSPetter Reinholdtsen 				rqdata[0], rqdata[1]);
386*c18ec02fSPetter Reinholdtsen 			return -1;
387*c18ec02fSPetter Reinholdtsen 		}
388*c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0) {
389*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s",
390*c18ec02fSPetter Reinholdtsen 				rqdata[0], rqdata[1],
391*c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
392*c18ec02fSPetter Reinholdtsen 			return -1;
393*c18ec02fSPetter Reinholdtsen 		}
394*c18ec02fSPetter Reinholdtsen 
395*c18ec02fSPetter Reinholdtsen 		memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
396*c18ec02fSPetter Reinholdtsen 
397*c18ec02fSPetter Reinholdtsen 		rqdata[0] = curr_uid & 0x3f;
398*c18ec02fSPetter Reinholdtsen 
399*c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req2);
400*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
401*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to Get User Name (id %d)", rqdata[0]);
402*c18ec02fSPetter Reinholdtsen 			return -1;
403*c18ec02fSPetter Reinholdtsen 		}
404*c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0) {
405*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get User Name (id %d) failed: %s",
406*c18ec02fSPetter Reinholdtsen 				rqdata[0], val2str(rsp->ccode, completion_code_vals));
407*c18ec02fSPetter Reinholdtsen 			return -1;
408*c18ec02fSPetter Reinholdtsen 		}
409*c18ec02fSPetter Reinholdtsen 
410*c18ec02fSPetter Reinholdtsen 		if (init) {
411*c18ec02fSPetter Reinholdtsen 			printf("Maximum User IDs     : %d\n", user_access.max_user_ids);
412*c18ec02fSPetter Reinholdtsen 			printf("Enabled User IDs     : %d\n", user_access.enabled_user_ids);
413*c18ec02fSPetter Reinholdtsen 			max_uid = user_access.max_user_ids;
414*c18ec02fSPetter Reinholdtsen 			init = 0;
415*c18ec02fSPetter Reinholdtsen 		}
416*c18ec02fSPetter Reinholdtsen 
417*c18ec02fSPetter Reinholdtsen 		printf("\n");
418*c18ec02fSPetter Reinholdtsen 		printf("User ID              : %d\n", curr_uid);
419*c18ec02fSPetter Reinholdtsen 		printf("User Name            : %s\n", rsp->data);
420*c18ec02fSPetter Reinholdtsen 		printf("Fixed Name           : %s\n",
421*c18ec02fSPetter Reinholdtsen 		       (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No");
422*c18ec02fSPetter Reinholdtsen 		printf("Access Available     : %s\n",
423*c18ec02fSPetter Reinholdtsen 		       (user_access.callin_callback) ? "callback" : "call-in / callback");
424*c18ec02fSPetter Reinholdtsen 		printf("Link Authentication  : %sabled\n",
425*c18ec02fSPetter Reinholdtsen 		       (user_access.link_auth) ? "en" : "dis");
426*c18ec02fSPetter Reinholdtsen 		printf("IPMI Messaging       : %sabled\n",
427*c18ec02fSPetter Reinholdtsen 		       (user_access.ipmi_messaging) ? "en" : "dis");
428*c18ec02fSPetter Reinholdtsen 		printf("Privilege Level      : %s\n",
429*c18ec02fSPetter Reinholdtsen 		       val2str(user_access.privilege_limit, ipmi_privlvl_vals));
430*c18ec02fSPetter Reinholdtsen 
431*c18ec02fSPetter Reinholdtsen 		curr_uid ++;
432*c18ec02fSPetter Reinholdtsen 
433*c18ec02fSPetter Reinholdtsen 	} while (!userid && curr_uid <= max_uid);
434*c18ec02fSPetter Reinholdtsen 
435*c18ec02fSPetter Reinholdtsen 	return 0;
436*c18ec02fSPetter Reinholdtsen }
437*c18ec02fSPetter Reinholdtsen 
438*c18ec02fSPetter Reinholdtsen static int
439*c18ec02fSPetter Reinholdtsen ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv)
440*c18ec02fSPetter Reinholdtsen {
441*c18ec02fSPetter Reinholdtsen 	uint8_t channel, privilege_limit, userid;
442*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
443*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
444*c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[2];
445*c18ec02fSPetter Reinholdtsen 	struct get_user_access_rsp user_access;
446*c18ec02fSPetter Reinholdtsen 	struct set_user_access_data set_access;
447*c18ec02fSPetter Reinholdtsen 	int i;
448*c18ec02fSPetter Reinholdtsen 
449*c18ec02fSPetter Reinholdtsen 	if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) {
450*c18ec02fSPetter Reinholdtsen 		printf_channel_usage();
451*c18ec02fSPetter Reinholdtsen 		return 0;
452*c18ec02fSPetter Reinholdtsen 	}
453*c18ec02fSPetter Reinholdtsen 
454*c18ec02fSPetter Reinholdtsen 	if (str2uchar(argv[0], &channel) != 0) {
455*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[0]);
456*c18ec02fSPetter Reinholdtsen 		return (-1);
457*c18ec02fSPetter Reinholdtsen 	}
458*c18ec02fSPetter Reinholdtsen 	if (str2uchar(argv[1], &userid) != 0) {
459*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]);
460*c18ec02fSPetter Reinholdtsen 		return (-1);
461*c18ec02fSPetter Reinholdtsen 	}
462*c18ec02fSPetter Reinholdtsen 
463*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
464*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
465*c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_USER_ACCESS;
466*c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
467*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
468*c18ec02fSPetter Reinholdtsen 
469*c18ec02fSPetter Reinholdtsen 	rqdata[0] = channel & 0xf;
470*c18ec02fSPetter Reinholdtsen 	rqdata[1] = userid & 0x3f;
471*c18ec02fSPetter Reinholdtsen 
472*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
473*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
474*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)",
475*c18ec02fSPetter Reinholdtsen 			rqdata[0], rqdata[1]);
476*c18ec02fSPetter Reinholdtsen 		return -1;
477*c18ec02fSPetter Reinholdtsen 	}
478*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
479*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s",
480*c18ec02fSPetter Reinholdtsen 			rqdata[0], rqdata[1],
481*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
482*c18ec02fSPetter Reinholdtsen 		return -1;
483*c18ec02fSPetter Reinholdtsen 	}
484*c18ec02fSPetter Reinholdtsen 
485*c18ec02fSPetter Reinholdtsen 	memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp));
486*c18ec02fSPetter Reinholdtsen 
487*c18ec02fSPetter Reinholdtsen 	memset(&set_access, 0, sizeof(set_access));
488*c18ec02fSPetter Reinholdtsen 	set_access.change_bits = 1;
489*c18ec02fSPetter Reinholdtsen 	set_access.callin_callback = user_access.callin_callback;
490*c18ec02fSPetter Reinholdtsen 	set_access.link_auth = user_access.link_auth;
491*c18ec02fSPetter Reinholdtsen 	set_access.ipmi_messaging = user_access.ipmi_messaging;
492*c18ec02fSPetter Reinholdtsen 	set_access.channel = channel;
493*c18ec02fSPetter Reinholdtsen 	set_access.user_id = userid;
494*c18ec02fSPetter Reinholdtsen 	set_access.privilege_limit = user_access.privilege_limit;
495*c18ec02fSPetter Reinholdtsen 	set_access.session_limit = 0;
496*c18ec02fSPetter Reinholdtsen 
497*c18ec02fSPetter Reinholdtsen 	for (i = 2; i < argc; i ++)
498*c18ec02fSPetter Reinholdtsen 	{
499*c18ec02fSPetter Reinholdtsen 		if (strncmp(argv[i], "callin=", 7) == 0) {
500*c18ec02fSPetter Reinholdtsen 			set_access.callin_callback = !(strncmp (argv[i]+7, "off", 3));
501*c18ec02fSPetter Reinholdtsen 		}
502*c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "link=", 5) == 0) {
503*c18ec02fSPetter Reinholdtsen 			set_access.link_auth = strncmp (argv[i]+5, "off", 3);
504*c18ec02fSPetter Reinholdtsen 		}
505*c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "ipmi=", 5) == 0) {
506*c18ec02fSPetter Reinholdtsen 			set_access.ipmi_messaging = strncmp (argv[i]+5, "off", 3);
507*c18ec02fSPetter Reinholdtsen 		}
508*c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "privilege=", 10) == 0) {
509*c18ec02fSPetter Reinholdtsen 			if (str2uchar(argv[i]+10, &privilege_limit) != 0) {
510*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[i]+10);
511*c18ec02fSPetter Reinholdtsen 				return (-1);
512*c18ec02fSPetter Reinholdtsen 			}
513*c18ec02fSPetter Reinholdtsen 			set_access.privilege_limit = privilege_limit;
514*c18ec02fSPetter Reinholdtsen 		}
515*c18ec02fSPetter Reinholdtsen 		else {
516*c18ec02fSPetter Reinholdtsen 			printf ("Invalid option: %s\n", argv [i]);
517*c18ec02fSPetter Reinholdtsen 			return -1;
518*c18ec02fSPetter Reinholdtsen 		}
519*c18ec02fSPetter Reinholdtsen 	}
520*c18ec02fSPetter Reinholdtsen 
521*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
522*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
523*c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_SET_USER_ACCESS;
524*c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *) &set_access;
525*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 4;
526*c18ec02fSPetter Reinholdtsen 
527*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
528*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
529*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Set User Access (channel %d id %d)",
530*c18ec02fSPetter Reinholdtsen 			set_access.channel, set_access.user_id);
531*c18ec02fSPetter Reinholdtsen 		return -1;
532*c18ec02fSPetter Reinholdtsen 	}
533*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
534*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set User Access (channel %d id %d) failed: %s",
535*c18ec02fSPetter Reinholdtsen 			set_access.channel, set_access.user_id,
536*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
537*c18ec02fSPetter Reinholdtsen 		return -1;
538*c18ec02fSPetter Reinholdtsen 	}
539*c18ec02fSPetter Reinholdtsen 
540*c18ec02fSPetter Reinholdtsen 	return 0;
541*c18ec02fSPetter Reinholdtsen }
542*c18ec02fSPetter Reinholdtsen 
543*c18ec02fSPetter Reinholdtsen 
544*c18ec02fSPetter Reinholdtsen static const char *
545*c18ec02fSPetter Reinholdtsen iana_string(uint32_t iana)
546*c18ec02fSPetter Reinholdtsen {
547*c18ec02fSPetter Reinholdtsen 	static char s[10];
548*c18ec02fSPetter Reinholdtsen 
549*c18ec02fSPetter Reinholdtsen 	if (iana)
550*c18ec02fSPetter Reinholdtsen 	{
551*c18ec02fSPetter Reinholdtsen 		sprintf(s, "%06x", iana);
552*c18ec02fSPetter Reinholdtsen 		return s;
553*c18ec02fSPetter Reinholdtsen 	}
554*c18ec02fSPetter Reinholdtsen 	else
555*c18ec02fSPetter Reinholdtsen 		return "N/A";
556*c18ec02fSPetter Reinholdtsen }
557*c18ec02fSPetter Reinholdtsen 
558*c18ec02fSPetter Reinholdtsen 
559*c18ec02fSPetter Reinholdtsen static int
560*c18ec02fSPetter Reinholdtsen ipmi_get_channel_cipher_suites(struct ipmi_intf * intf,
561*c18ec02fSPetter Reinholdtsen 			       const char * payload_type,
562*c18ec02fSPetter Reinholdtsen 			       uint8_t channel)
563*c18ec02fSPetter Reinholdtsen {
564*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
565*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
566*c18ec02fSPetter Reinholdtsen 
567*c18ec02fSPetter Reinholdtsen 	uint8_t  oem_record;
568*c18ec02fSPetter Reinholdtsen 	uint8_t  rqdata[3];
569*c18ec02fSPetter Reinholdtsen 	uint32_t iana;
570*c18ec02fSPetter Reinholdtsen 	uint8_t  auth_alg, integrity_alg, crypt_alg;
571*c18ec02fSPetter Reinholdtsen 	uint8_t  cipher_suite_id;
572*c18ec02fSPetter Reinholdtsen 	uint8_t  list_index = 0;
573*c18ec02fSPetter Reinholdtsen 	uint8_t  cipher_suite_data[1024]; // 0x40 sets * 16 bytes per set
574*c18ec02fSPetter Reinholdtsen 	uint16_t offset = 0;
575*c18ec02fSPetter Reinholdtsen 	uint16_t cipher_suite_data_length = 0; // how much was returned, total
576*c18ec02fSPetter Reinholdtsen 
577*c18ec02fSPetter Reinholdtsen 	memset(cipher_suite_data, 0, sizeof(cipher_suite_data));
578*c18ec02fSPetter Reinholdtsen 
579*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
580*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;                 // 0x06
581*c18ec02fSPetter Reinholdtsen 	req.msg.cmd   = IPMI_GET_CHANNEL_CIPHER_SUITES; // 0x54
582*c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
583*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
584*c18ec02fSPetter Reinholdtsen 
585*c18ec02fSPetter Reinholdtsen 	rqdata[0] = channel;
586*c18ec02fSPetter Reinholdtsen 	rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1);
587*c18ec02fSPetter Reinholdtsen 	rqdata[2] = 0x80; // Always ask for cipher suite format
588*c18ec02fSPetter Reinholdtsen 
589*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
590*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
591*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
592*c18ec02fSPetter Reinholdtsen 		return -1;
593*c18ec02fSPetter Reinholdtsen 	}
594*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
595*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
596*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
597*c18ec02fSPetter Reinholdtsen 		return -1;
598*c18ec02fSPetter Reinholdtsen 	}
599*c18ec02fSPetter Reinholdtsen 
600*c18ec02fSPetter Reinholdtsen 
601*c18ec02fSPetter Reinholdtsen 	// Grab the returned channel number once.  We assume it's the same
602*c18ec02fSPetter Reinholdtsen 	// in future calls.
603*c18ec02fSPetter Reinholdtsen 	if (rsp->data_len >= 1)
604*c18ec02fSPetter Reinholdtsen 		channel = rsp->data[0];
605*c18ec02fSPetter Reinholdtsen 
606*c18ec02fSPetter Reinholdtsen 	while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F))
607*c18ec02fSPetter Reinholdtsen 	{
608*c18ec02fSPetter Reinholdtsen 		//
609*c18ec02fSPetter Reinholdtsen 		// We got back cipher suite data -- store it.
610*c18ec02fSPetter Reinholdtsen 		//printf("copying data to offset %d\n", offset);
611*c18ec02fSPetter Reinholdtsen 		//printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data");
612*c18ec02fSPetter Reinholdtsen 		memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1);
613*c18ec02fSPetter Reinholdtsen 		offset += rsp->data_len - 1;
614*c18ec02fSPetter Reinholdtsen 
615*c18ec02fSPetter Reinholdtsen 		//
616*c18ec02fSPetter Reinholdtsen 		// Increment our list for the next call
617*c18ec02fSPetter Reinholdtsen 		//
618*c18ec02fSPetter Reinholdtsen 		++list_index;
619*c18ec02fSPetter Reinholdtsen 		rqdata[2] =  (rqdata[2] & 0x80) + list_index;
620*c18ec02fSPetter Reinholdtsen 
621*c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
622*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
623*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
624*c18ec02fSPetter Reinholdtsen 			return -1;
625*c18ec02fSPetter Reinholdtsen 		}
626*c18ec02fSPetter Reinholdtsen 		if (rsp->ccode > 0) {
627*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
628*c18ec02fSPetter Reinholdtsen 					val2str(rsp->ccode, completion_code_vals));
629*c18ec02fSPetter Reinholdtsen 			return -1;
630*c18ec02fSPetter Reinholdtsen 		}
631*c18ec02fSPetter Reinholdtsen 	}
632*c18ec02fSPetter Reinholdtsen 
633*c18ec02fSPetter Reinholdtsen 	/* Copy last chunk */
634*c18ec02fSPetter Reinholdtsen 	if(rsp->data_len > 1)
635*c18ec02fSPetter Reinholdtsen 	{
636*c18ec02fSPetter Reinholdtsen 		//
637*c18ec02fSPetter Reinholdtsen 		// We got back cipher suite data -- store it.
638*c18ec02fSPetter Reinholdtsen 		//printf("copying data to offset %d\n", offset);
639*c18ec02fSPetter Reinholdtsen 		//printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data");
640*c18ec02fSPetter Reinholdtsen 		memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1);
641*c18ec02fSPetter Reinholdtsen 		offset += rsp->data_len - 1;
642*c18ec02fSPetter Reinholdtsen 	}
643*c18ec02fSPetter Reinholdtsen 
644*c18ec02fSPetter Reinholdtsen 	//
645*c18ec02fSPetter Reinholdtsen 	// We can chomp on all our data now.
646*c18ec02fSPetter Reinholdtsen 	//
647*c18ec02fSPetter Reinholdtsen 	cipher_suite_data_length = offset;
648*c18ec02fSPetter Reinholdtsen 	offset = 0;
649*c18ec02fSPetter Reinholdtsen 
650*c18ec02fSPetter Reinholdtsen 	if (! csv_output)
651*c18ec02fSPetter Reinholdtsen 		printf("ID   IANA    Auth Alg        Integrity Alg   Confidentiality Alg\n");
652*c18ec02fSPetter Reinholdtsen 
653*c18ec02fSPetter Reinholdtsen 	while (offset < cipher_suite_data_length)
654*c18ec02fSPetter Reinholdtsen 	{
655*c18ec02fSPetter Reinholdtsen 		if (cipher_suite_data[offset++] == 0xC0)
656*c18ec02fSPetter Reinholdtsen 		{
657*c18ec02fSPetter Reinholdtsen 			oem_record = 0; // standard type
658*c18ec02fSPetter Reinholdtsen 			iana       = 0;
659*c18ec02fSPetter Reinholdtsen 
660*c18ec02fSPetter Reinholdtsen 			// Verify that we have at least a full record left
661*c18ec02fSPetter Reinholdtsen 			if ((cipher_suite_data_length - offset) < 4) // id + 3 algs
662*c18ec02fSPetter Reinholdtsen 			{
663*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
664*c18ec02fSPetter Reinholdtsen 				return -1;
665*c18ec02fSPetter Reinholdtsen 			}
666*c18ec02fSPetter Reinholdtsen 
667*c18ec02fSPetter Reinholdtsen 			cipher_suite_id = cipher_suite_data[offset++];
668*c18ec02fSPetter Reinholdtsen 
669*c18ec02fSPetter Reinholdtsen 		}
670*c18ec02fSPetter Reinholdtsen 		else if (cipher_suite_data[offset++] == 0xC1)
671*c18ec02fSPetter Reinholdtsen 		{
672*c18ec02fSPetter Reinholdtsen 			oem_record = 1; // OEM record type
673*c18ec02fSPetter Reinholdtsen 
674*c18ec02fSPetter Reinholdtsen 			// Verify that we have at least a full record left
675*c18ec02fSPetter Reinholdtsen 			if ((cipher_suite_data_length - offset) < 4) // id + iana + 3 algs
676*c18ec02fSPetter Reinholdtsen 			{
677*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Incomplete data record in cipher suite data");
678*c18ec02fSPetter Reinholdtsen 				return -1;
679*c18ec02fSPetter Reinholdtsen 			}
680*c18ec02fSPetter Reinholdtsen 
681*c18ec02fSPetter Reinholdtsen 			cipher_suite_id = cipher_suite_data[offset++];
682*c18ec02fSPetter Reinholdtsen 
683*c18ec02fSPetter Reinholdtsen 			//
684*c18ec02fSPetter Reinholdtsen 			// Grab the IANA
685*c18ec02fSPetter Reinholdtsen 			//
686*c18ec02fSPetter Reinholdtsen 			iana =
687*c18ec02fSPetter Reinholdtsen 				cipher_suite_data[offset]            |
688*c18ec02fSPetter Reinholdtsen 				(cipher_suite_data[offset + 1] << 8) |
689*c18ec02fSPetter Reinholdtsen 				(cipher_suite_data[offset + 2] << 16);
690*c18ec02fSPetter Reinholdtsen 			offset += 3;
691*c18ec02fSPetter Reinholdtsen 		}
692*c18ec02fSPetter Reinholdtsen 		else
693*c18ec02fSPetter Reinholdtsen 		{
694*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Bad start of record byte in cipher suite data");
695*c18ec02fSPetter Reinholdtsen 			return -1;
696*c18ec02fSPetter Reinholdtsen 		}
697*c18ec02fSPetter Reinholdtsen 
698*c18ec02fSPetter Reinholdtsen 		//
699*c18ec02fSPetter Reinholdtsen 		// Grab the algorithms for this cipher suite.  I guess we can't be
700*c18ec02fSPetter Reinholdtsen 		// sure of what order they'll come in.  Also, I suppose we default
701*c18ec02fSPetter Reinholdtsen 		// to the NONE algorithm if one were absent.  This part of the spec is
702*c18ec02fSPetter Reinholdtsen 		// poorly written -- I have read the errata document.  For now, I'm only
703*c18ec02fSPetter Reinholdtsen 		// allowing one algorithm per type (auth, integrity, crypt) because I
704*c18ec02fSPetter Reinholdtsen 		// don't I understand how it could be otherwise.
705*c18ec02fSPetter Reinholdtsen 		//
706*c18ec02fSPetter Reinholdtsen 		auth_alg      = IPMI_AUTH_RAKP_NONE;
707*c18ec02fSPetter Reinholdtsen 		integrity_alg = IPMI_INTEGRITY_NONE;
708*c18ec02fSPetter Reinholdtsen 		crypt_alg     = IPMI_CRYPT_NONE;
709*c18ec02fSPetter Reinholdtsen 
710*c18ec02fSPetter Reinholdtsen 		while (((cipher_suite_data[offset] & 0xC0) != 0xC0) &&
711*c18ec02fSPetter Reinholdtsen 			   ((cipher_suite_data_length - offset) > 0))
712*c18ec02fSPetter Reinholdtsen 		{
713*c18ec02fSPetter Reinholdtsen 			switch (cipher_suite_data[offset] & 0xC0)
714*c18ec02fSPetter Reinholdtsen 			{
715*c18ec02fSPetter Reinholdtsen 			case 0x00:
716*c18ec02fSPetter Reinholdtsen 				// Authentication algorithm specifier
717*c18ec02fSPetter Reinholdtsen 				auth_alg = cipher_suite_data[offset++] & 0x3F;
718*c18ec02fSPetter Reinholdtsen 				break;
719*c18ec02fSPetter Reinholdtsen 			case 0x40:
720*c18ec02fSPetter Reinholdtsen 				// Interity algorithm specifier
721*c18ec02fSPetter Reinholdtsen 				integrity_alg = cipher_suite_data[offset++] & 0x3F;
722*c18ec02fSPetter Reinholdtsen 				break;
723*c18ec02fSPetter Reinholdtsen 			case 0x80:
724*c18ec02fSPetter Reinholdtsen 				// Confidentiality algorithm specifier
725*c18ec02fSPetter Reinholdtsen 				crypt_alg = cipher_suite_data[offset++] & 0x3F;
726*c18ec02fSPetter Reinholdtsen 				break;
727*c18ec02fSPetter Reinholdtsen 			}
728*c18ec02fSPetter Reinholdtsen 		}
729*c18ec02fSPetter Reinholdtsen 
730*c18ec02fSPetter Reinholdtsen 
731*c18ec02fSPetter Reinholdtsen 		//
732*c18ec02fSPetter Reinholdtsen 		// We have everything we need to spit out a cipher suite record
733*c18ec02fSPetter Reinholdtsen 		//
734*c18ec02fSPetter Reinholdtsen 		printf((csv_output? "%d,%s,%s,%s,%s\n" :
735*c18ec02fSPetter Reinholdtsen 			"%-4d %-7s %-15s %-15s %-15s\n"),
736*c18ec02fSPetter Reinholdtsen 		       cipher_suite_id,
737*c18ec02fSPetter Reinholdtsen 		       iana_string(iana),
738*c18ec02fSPetter Reinholdtsen 		       val2str(auth_alg, ipmi_auth_algorithms),
739*c18ec02fSPetter Reinholdtsen 		       val2str(integrity_alg, ipmi_integrity_algorithms),
740*c18ec02fSPetter Reinholdtsen 		       val2str(crypt_alg, ipmi_encryption_algorithms));
741*c18ec02fSPetter Reinholdtsen 	}
742*c18ec02fSPetter Reinholdtsen 
743*c18ec02fSPetter Reinholdtsen 
744*c18ec02fSPetter Reinholdtsen 	return 0;
745*c18ec02fSPetter Reinholdtsen }
746*c18ec02fSPetter Reinholdtsen 
747*c18ec02fSPetter Reinholdtsen 
748*c18ec02fSPetter Reinholdtsen 
749*c18ec02fSPetter Reinholdtsen uint8_t
750*c18ec02fSPetter Reinholdtsen ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel)
751*c18ec02fSPetter Reinholdtsen {
752*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
753*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
754*c18ec02fSPetter Reinholdtsen 	struct get_channel_info_rsp info;
755*c18ec02fSPetter Reinholdtsen 
756*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
757*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
758*c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_CHANNEL_INFO;
759*c18ec02fSPetter Reinholdtsen 	req.msg.data = &channel;
760*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
761*c18ec02fSPetter Reinholdtsen 
762*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
763*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
764*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Channel Info command failed");
765*c18ec02fSPetter Reinholdtsen 		return 0;
766*c18ec02fSPetter Reinholdtsen 	}
767*c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
768*c18ec02fSPetter Reinholdtsen 		if (rsp->ccode == 0xcc)
769*c18ec02fSPetter Reinholdtsen 			return IPMI_CHANNEL_MEDIUM_RESERVED;
770*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_INFO, "Get Channel Info command failed: %s",
771*c18ec02fSPetter Reinholdtsen 		       val2str(rsp->ccode, completion_code_vals));
772*c18ec02fSPetter Reinholdtsen 		return IPMI_CHANNEL_MEDIUM_RESERVED;
773*c18ec02fSPetter Reinholdtsen 	}
774*c18ec02fSPetter Reinholdtsen 
775*c18ec02fSPetter Reinholdtsen 	memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp));
776*c18ec02fSPetter Reinholdtsen 
777*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_DEBUG, "Channel type: %s",
778*c18ec02fSPetter Reinholdtsen 		val2str(info.channel_medium, ipmi_channel_medium_vals));
779*c18ec02fSPetter Reinholdtsen 
780*c18ec02fSPetter Reinholdtsen 	return info.channel_medium;
781*c18ec02fSPetter Reinholdtsen }
782*c18ec02fSPetter Reinholdtsen 
783*c18ec02fSPetter Reinholdtsen uint8_t
784*c18ec02fSPetter Reinholdtsen ipmi_current_channel_medium(struct ipmi_intf * intf)
785*c18ec02fSPetter Reinholdtsen {
786*c18ec02fSPetter Reinholdtsen 	return ipmi_get_channel_medium(intf, 0xE);
787*c18ec02fSPetter Reinholdtsen }
788*c18ec02fSPetter Reinholdtsen 
789*c18ec02fSPetter Reinholdtsen void
790*c18ec02fSPetter Reinholdtsen printf_channel_usage()
791*c18ec02fSPetter Reinholdtsen {
792*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "Channel Commands: authcap   <channel number> <max privilege>");
793*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "                  getaccess <channel number> [user id]");
794*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "                  setaccess <channel number> "
795*c18ec02fSPetter Reinholdtsen 		"<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]");
796*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "                  info      [channel number]");
797*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "                  getciphers <ipmi | sol> [channel]\n");
798*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "Possible privilege levels are:");
799*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   1   Callback level");
800*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   2   User level");
801*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   3   Operator level");
802*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   4   Administrator level");
803*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   5   OEM Proprietary level");
804*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "  15   No access");
805*c18ec02fSPetter Reinholdtsen }
806*c18ec02fSPetter Reinholdtsen 
807*c18ec02fSPetter Reinholdtsen 
808*c18ec02fSPetter Reinholdtsen int
809*c18ec02fSPetter Reinholdtsen ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv)
810*c18ec02fSPetter Reinholdtsen {
811*c18ec02fSPetter Reinholdtsen 	int retval = 0;
812*c18ec02fSPetter Reinholdtsen 	uint8_t channel, priv = 0;
813*c18ec02fSPetter Reinholdtsen 
814*c18ec02fSPetter Reinholdtsen 	if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0))
815*c18ec02fSPetter Reinholdtsen 	{
816*c18ec02fSPetter Reinholdtsen 		printf_channel_usage();
817*c18ec02fSPetter Reinholdtsen 	}
818*c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "authcap", 7) == 0)
819*c18ec02fSPetter Reinholdtsen 	{
820*c18ec02fSPetter Reinholdtsen 		if (argc != 3) {
821*c18ec02fSPetter Reinholdtsen 			printf_channel_usage();
822*c18ec02fSPetter Reinholdtsen 			return (-1);
823*c18ec02fSPetter Reinholdtsen 		} else {
824*c18ec02fSPetter Reinholdtsen 			if (str2uchar(argv[1], &channel) != 0) {
825*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]);
826*c18ec02fSPetter Reinholdtsen 				return (-1);
827*c18ec02fSPetter Reinholdtsen 			}
828*c18ec02fSPetter Reinholdtsen 			if (str2uchar(argv[2], &priv) != 0) {
829*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]);
830*c18ec02fSPetter Reinholdtsen 				return (-1);
831*c18ec02fSPetter Reinholdtsen 			}
832*c18ec02fSPetter Reinholdtsen 			retval = ipmi_get_channel_auth_cap(intf, channel, priv);
833*c18ec02fSPetter Reinholdtsen 		}
834*c18ec02fSPetter Reinholdtsen 	}
835*c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "getaccess", 10) == 0)
836*c18ec02fSPetter Reinholdtsen 	{
837*c18ec02fSPetter Reinholdtsen 		if ((argc < 2) || (argc > 3))
838*c18ec02fSPetter Reinholdtsen 			printf_channel_usage();
839*c18ec02fSPetter Reinholdtsen 		else {
840*c18ec02fSPetter Reinholdtsen 			uint8_t ch = 0;
841*c18ec02fSPetter Reinholdtsen 			uint8_t id = 0;
842*c18ec02fSPetter Reinholdtsen 			if (str2uchar(argv[1], &ch) != 0) {
843*c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]);
844*c18ec02fSPetter Reinholdtsen 				return (-1);
845*c18ec02fSPetter Reinholdtsen 			}
846*c18ec02fSPetter Reinholdtsen 			if (argc == 3) {
847*c18ec02fSPetter Reinholdtsen 				if (str2uchar(argv[2], &id) != 0) {
848*c18ec02fSPetter Reinholdtsen 					lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]);
849*c18ec02fSPetter Reinholdtsen 					return (-1);
850*c18ec02fSPetter Reinholdtsen 				}
851*c18ec02fSPetter Reinholdtsen 			}
852*c18ec02fSPetter Reinholdtsen 			retval = ipmi_get_user_access(intf, ch, id);
853*c18ec02fSPetter Reinholdtsen 		}
854*c18ec02fSPetter Reinholdtsen 	}
855*c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "setaccess", 9) == 0)
856*c18ec02fSPetter Reinholdtsen 	{
857*c18ec02fSPetter Reinholdtsen 		retval = ipmi_set_user_access(intf, argc-1, &(argv[1]));
858*c18ec02fSPetter Reinholdtsen 	}
859*c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "info", 4) == 0)
860*c18ec02fSPetter Reinholdtsen 	{
861*c18ec02fSPetter Reinholdtsen 		if (argc > 2)
862*c18ec02fSPetter Reinholdtsen 			printf_channel_usage();
863*c18ec02fSPetter Reinholdtsen 		else {
864*c18ec02fSPetter Reinholdtsen 			uint8_t ch = 0xe;
865*c18ec02fSPetter Reinholdtsen 			if (argc == 2) {
866*c18ec02fSPetter Reinholdtsen 				if (str2uchar(argv[1], &ch) != 0) {
867*c18ec02fSPetter Reinholdtsen 					lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]);
868*c18ec02fSPetter Reinholdtsen 					return (-1);
869*c18ec02fSPetter Reinholdtsen 				}
870*c18ec02fSPetter Reinholdtsen 			}
871*c18ec02fSPetter Reinholdtsen 			retval = ipmi_get_channel_info(intf, ch);
872*c18ec02fSPetter Reinholdtsen 		}
873*c18ec02fSPetter Reinholdtsen 	}
874*c18ec02fSPetter Reinholdtsen 
875*c18ec02fSPetter Reinholdtsen 	// it channel getciphers <ipmi | sol> [channel]
876*c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "getciphers", 10) == 0)
877*c18ec02fSPetter Reinholdtsen 	{
878*c18ec02fSPetter Reinholdtsen 		if ((argc < 2) || (argc > 3)  ||
879*c18ec02fSPetter Reinholdtsen 		    (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol",  3)))
880*c18ec02fSPetter Reinholdtsen 			printf_channel_usage();
881*c18ec02fSPetter Reinholdtsen 		else
882*c18ec02fSPetter Reinholdtsen 		{
883*c18ec02fSPetter Reinholdtsen 			uint8_t ch = 0xe;
884*c18ec02fSPetter Reinholdtsen 			if (argc == 3) {
885*c18ec02fSPetter Reinholdtsen 				if (str2uchar(argv[2], &ch) != 0) {
886*c18ec02fSPetter Reinholdtsen 					lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]);
887*c18ec02fSPetter Reinholdtsen 					return (-1);
888*c18ec02fSPetter Reinholdtsen 				}
889*c18ec02fSPetter Reinholdtsen 			}
890*c18ec02fSPetter Reinholdtsen 			retval = ipmi_get_channel_cipher_suites(intf,
891*c18ec02fSPetter Reinholdtsen 								argv[1], // ipmi | sol
892*c18ec02fSPetter Reinholdtsen 								ch);
893*c18ec02fSPetter Reinholdtsen 		}
894*c18ec02fSPetter Reinholdtsen 	}
895*c18ec02fSPetter Reinholdtsen 	else
896*c18ec02fSPetter Reinholdtsen 	{
897*c18ec02fSPetter Reinholdtsen 		printf("Invalid CHANNEL command: %s\n", argv[0]);
898*c18ec02fSPetter Reinholdtsen 		printf_channel_usage();
899*c18ec02fSPetter Reinholdtsen 		retval = -1;
900*c18ec02fSPetter Reinholdtsen 	}
901*c18ec02fSPetter Reinholdtsen 
902*c18ec02fSPetter Reinholdtsen 	return retval;
903*c18ec02fSPetter Reinholdtsen }
904