1c18ec02fSPetter Reinholdtsen /* -*-mode: C; indent-tabs-mode: t; -*- 2c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3c18ec02fSPetter Reinholdtsen * 4c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without 5c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions 6c18ec02fSPetter Reinholdtsen * are met: 7c18ec02fSPetter Reinholdtsen * 8c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright 9c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer. 10c18ec02fSPetter Reinholdtsen * 11c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright 12c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the 13c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution. 14c18ec02fSPetter Reinholdtsen * 15c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of 16c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived 17c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission. 18c18ec02fSPetter Reinholdtsen * 19c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind. 20c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31c18ec02fSPetter Reinholdtsen */ 32c18ec02fSPetter Reinholdtsen 33c18ec02fSPetter Reinholdtsen #include <stdlib.h> 34c18ec02fSPetter Reinholdtsen #include <stdio.h> 35c18ec02fSPetter Reinholdtsen #include <string.h> 36c18ec02fSPetter Reinholdtsen #include <strings.h> 37c18ec02fSPetter Reinholdtsen #include <sys/types.h> 38c18ec02fSPetter Reinholdtsen #include <sys/socket.h> 39c18ec02fSPetter Reinholdtsen #include <netinet/in.h> 40c18ec02fSPetter Reinholdtsen #include <arpa/inet.h> 41c18ec02fSPetter Reinholdtsen #include <errno.h> 42c18ec02fSPetter Reinholdtsen #include <unistd.h> 43c18ec02fSPetter Reinholdtsen #include <signal.h> 44c18ec02fSPetter Reinholdtsen 45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h> 46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h> 47c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h> 48c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h> 49c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_lanp.h> 50c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_channel.h> 51c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h> 52c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h> 53e4be291cSZdenek Styblik #include <ipmitool/ipmi_user.h> 54c18ec02fSPetter Reinholdtsen 55c18ec02fSPetter Reinholdtsen extern int csv_output; 56c18ec02fSPetter Reinholdtsen extern int verbose; 57c18ec02fSPetter Reinholdtsen 58c18ec02fSPetter Reinholdtsen void printf_channel_usage(void); 59c18ec02fSPetter Reinholdtsen 60238d3c4eSZdenek Styblik /* _ipmi_get_channel_access - Get Channel Access for given channel. Results are 61238d3c4eSZdenek Styblik * stored into passed struct. 62238d3c4eSZdenek Styblik * 63238d3c4eSZdenek Styblik * @intf - IPMI interface 64238d3c4eSZdenek Styblik * @channel_access - ptr to channel_access_t with Channel set. 65238d3c4eSZdenek Styblik * @get_volatile_settings - get volatile if != 0, else non-volatile settings. 66238d3c4eSZdenek Styblik * 67238d3c4eSZdenek Styblik * returns - negative number means error, positive is a ccode. 68238d3c4eSZdenek Styblik */ 69238d3c4eSZdenek Styblik int 70238d3c4eSZdenek Styblik _ipmi_get_channel_access(struct ipmi_intf *intf, 71238d3c4eSZdenek Styblik struct channel_access_t *channel_access, 72238d3c4eSZdenek Styblik uint8_t get_volatile_settings) 73238d3c4eSZdenek Styblik { 74238d3c4eSZdenek Styblik struct ipmi_rs *rsp; 75238d3c4eSZdenek Styblik struct ipmi_rq req = {0}; 76238d3c4eSZdenek Styblik uint8_t data[2]; 77238d3c4eSZdenek Styblik 78238d3c4eSZdenek Styblik if (channel_access == NULL) { 79238d3c4eSZdenek Styblik return (-3); 80238d3c4eSZdenek Styblik } 81238d3c4eSZdenek Styblik data[0] = channel_access->channel & 0x0F; 82238d3c4eSZdenek Styblik /* volatile - 0x80; non-volatile - 0x40 */ 83238d3c4eSZdenek Styblik data[1] = get_volatile_settings ? 0x80 : 0x40; 84238d3c4eSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 85238d3c4eSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; 86238d3c4eSZdenek Styblik req.msg.data = data; 87238d3c4eSZdenek Styblik req.msg.data_len = 2; 88238d3c4eSZdenek Styblik 89238d3c4eSZdenek Styblik rsp = intf->sendrecv(intf, &req); 90238d3c4eSZdenek Styblik if (rsp == NULL) { 91238d3c4eSZdenek Styblik return (-1); 92238d3c4eSZdenek Styblik } else if (rsp->ccode != 0) { 93238d3c4eSZdenek Styblik return rsp->ccode; 94238d3c4eSZdenek Styblik } else if (rsp->data_len != 2) { 95238d3c4eSZdenek Styblik return (-2); 96238d3c4eSZdenek Styblik } 97238d3c4eSZdenek Styblik channel_access->alerting = rsp->data[0] & 0x20; 98238d3c4eSZdenek Styblik channel_access->per_message_auth = rsp->data[0] & 0x10; 99238d3c4eSZdenek Styblik channel_access->user_level_auth = rsp->data[0] & 0x08; 100238d3c4eSZdenek Styblik channel_access->access_mode = rsp->data[0] & 0x07; 101238d3c4eSZdenek Styblik channel_access->privilege_limit = rsp->data[1] & 0x0F; 102238d3c4eSZdenek Styblik return 0; 103238d3c4eSZdenek Styblik } 104238d3c4eSZdenek Styblik 105238d3c4eSZdenek Styblik /* _ipmi_get_channel_info - Get Channel Info for given channel. Results are 106238d3c4eSZdenek Styblik * stored into passed struct. 107238d3c4eSZdenek Styblik * 108238d3c4eSZdenek Styblik * @intf - IPMI interface 109238d3c4eSZdenek Styblik * @channel_info - ptr to channel_info_t with Channel set. 110238d3c4eSZdenek Styblik * 111238d3c4eSZdenek Styblik * returns - negative number means error, positive is a ccode. 112238d3c4eSZdenek Styblik */ 113238d3c4eSZdenek Styblik int 114238d3c4eSZdenek Styblik _ipmi_get_channel_info(struct ipmi_intf *intf, 115238d3c4eSZdenek Styblik struct channel_info_t *channel_info) 116238d3c4eSZdenek Styblik { 117238d3c4eSZdenek Styblik struct ipmi_rs *rsp; 118238d3c4eSZdenek Styblik struct ipmi_rq req = {0}; 119238d3c4eSZdenek Styblik uint8_t data[1]; 120238d3c4eSZdenek Styblik 121238d3c4eSZdenek Styblik if (channel_info == NULL) { 122238d3c4eSZdenek Styblik return (-3); 123238d3c4eSZdenek Styblik } 124238d3c4eSZdenek Styblik data[0] = channel_info->channel & 0x0F; 125238d3c4eSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 126238d3c4eSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_INFO; 127238d3c4eSZdenek Styblik req.msg.data = data; 128238d3c4eSZdenek Styblik req.msg.data_len = 1; 129238d3c4eSZdenek Styblik 130238d3c4eSZdenek Styblik rsp = intf->sendrecv(intf, &req); 131238d3c4eSZdenek Styblik if (rsp == NULL) { 132238d3c4eSZdenek Styblik return (-1); 133238d3c4eSZdenek Styblik } else if (rsp->ccode != 0) { 134238d3c4eSZdenek Styblik return rsp->ccode; 135238d3c4eSZdenek Styblik } else if (rsp->data_len != 9) { 136238d3c4eSZdenek Styblik return (-2); 137238d3c4eSZdenek Styblik } 138238d3c4eSZdenek Styblik channel_info->channel = rsp->data[0] & 0x0F; 139238d3c4eSZdenek Styblik channel_info->medium = rsp->data[1] & 0x7F; 140238d3c4eSZdenek Styblik channel_info->protocol = rsp->data[2] & 0x1F; 141238d3c4eSZdenek Styblik channel_info->session_support = rsp->data[3] & 0xC0; 142238d3c4eSZdenek Styblik channel_info->active_sessions = rsp->data[3] & 0x3F; 143238d3c4eSZdenek Styblik memcpy(channel_info->vendor_id, &rsp->data[4], 144238d3c4eSZdenek Styblik sizeof(channel_info->vendor_id)); 145238d3c4eSZdenek Styblik memcpy(channel_info->aux_info, &rsp->data[7], 146238d3c4eSZdenek Styblik sizeof(channel_info->aux_info)); 147238d3c4eSZdenek Styblik return 0; 148238d3c4eSZdenek Styblik } 149238d3c4eSZdenek Styblik 150*026a8b6fSZdenek Styblik /* _ipmi_set_channel_access - Set Channel Access values for given channel. 151*026a8b6fSZdenek Styblik * 152*026a8b6fSZdenek Styblik * @intf - IPMI interface 153*026a8b6fSZdenek Styblik * @channel_access - channel_access_t with desired values and channel set. 154*026a8b6fSZdenek Styblik * @access_option: 155*026a8b6fSZdenek Styblik * - 0 = don't set/change Channel Access 156*026a8b6fSZdenek Styblik * - 1 = set non-volatile settings of Channel Access 157*026a8b6fSZdenek Styblik * - 2 = set volatile settings of Channel Access 158*026a8b6fSZdenek Styblik * @privilege_option: 159*026a8b6fSZdenek Styblik * - 0 = don't set/change Privilege Level Limit 160*026a8b6fSZdenek Styblik * - 1 = set non-volatile settings of Privilege Limit 161*026a8b6fSZdenek Styblik * - 2 = set volatile settings of Privilege Limit 162*026a8b6fSZdenek Styblik * 163*026a8b6fSZdenek Styblik * returns - negative number means error, positive is a ccode. See IPMI 164*026a8b6fSZdenek Styblik * specification for further information on ccodes for Set Channel Access. 165*026a8b6fSZdenek Styblik * 0x82 - set not supported on selected channel, eg. session-less channel. 166*026a8b6fSZdenek Styblik * 0x83 - access mode not supported 167*026a8b6fSZdenek Styblik */ 168*026a8b6fSZdenek Styblik int 169*026a8b6fSZdenek Styblik _ipmi_set_channel_access(struct ipmi_intf *intf, 170*026a8b6fSZdenek Styblik struct channel_access_t channel_access, 171*026a8b6fSZdenek Styblik uint8_t access_option, 172*026a8b6fSZdenek Styblik uint8_t privilege_option) 173*026a8b6fSZdenek Styblik { 174*026a8b6fSZdenek Styblik struct ipmi_rs *rsp; 175*026a8b6fSZdenek Styblik struct ipmi_rq req; 176*026a8b6fSZdenek Styblik uint8_t data[3]; 177*026a8b6fSZdenek Styblik /* Only values from <0..2> are accepted as valid. */ 178*026a8b6fSZdenek Styblik if (access_option > 2 || privilege_option > 2) { 179*026a8b6fSZdenek Styblik return (-3); 180*026a8b6fSZdenek Styblik } 181*026a8b6fSZdenek Styblik 182*026a8b6fSZdenek Styblik data[0] = channel_access.channel & 0x0F; 183*026a8b6fSZdenek Styblik data[1] = (access_option << 6); 184*026a8b6fSZdenek Styblik if (channel_access.alerting) { 185*026a8b6fSZdenek Styblik data[1] |= 0x20; 186*026a8b6fSZdenek Styblik } 187*026a8b6fSZdenek Styblik if (channel_access.per_message_auth) { 188*026a8b6fSZdenek Styblik data[1] |= 0x10; 189*026a8b6fSZdenek Styblik } 190*026a8b6fSZdenek Styblik if (channel_access.user_level_auth) { 191*026a8b6fSZdenek Styblik data[1] |= 0x08; 192*026a8b6fSZdenek Styblik } 193*026a8b6fSZdenek Styblik data[1] |= (channel_access.access_mode & 0x07); 194*026a8b6fSZdenek Styblik data[2] = (privilege_option << 6); 195*026a8b6fSZdenek Styblik data[2] |= (channel_access.privilege_limit & 0x0F); 196*026a8b6fSZdenek Styblik 197*026a8b6fSZdenek Styblik memset(&req, 0, sizeof(req)); 198*026a8b6fSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 199*026a8b6fSZdenek Styblik req.msg.cmd = IPMI_SET_CHANNEL_ACCESS; 200*026a8b6fSZdenek Styblik req.msg.data = data; 201*026a8b6fSZdenek Styblik req.msg.data_len = 3; 202*026a8b6fSZdenek Styblik 203*026a8b6fSZdenek Styblik rsp = intf->sendrecv(intf, &req); 204*026a8b6fSZdenek Styblik if (rsp == NULL) { 205*026a8b6fSZdenek Styblik return (-1); 206*026a8b6fSZdenek Styblik } 207*026a8b6fSZdenek Styblik return rsp->ccode; 208*026a8b6fSZdenek Styblik } 209*026a8b6fSZdenek Styblik 2106febd101SZdenek Styblik static const char * 2116febd101SZdenek Styblik iana_string(uint32_t iana) 2126febd101SZdenek Styblik { 2136febd101SZdenek Styblik static char s[10]; 2146febd101SZdenek Styblik 2156febd101SZdenek Styblik if (iana) { 2166febd101SZdenek Styblik sprintf(s, "%06x", iana); 2176febd101SZdenek Styblik return s; 2186febd101SZdenek Styblik } else { 2196febd101SZdenek Styblik return "N/A"; 2206febd101SZdenek Styblik } 2216febd101SZdenek Styblik } 2226febd101SZdenek Styblik 223c18ec02fSPetter Reinholdtsen /** 224c18ec02fSPetter Reinholdtsen * ipmi_1_5_authtypes 225c18ec02fSPetter Reinholdtsen * 226c18ec02fSPetter Reinholdtsen * Create a string describing the supported authentication types as 227c18ec02fSPetter Reinholdtsen * specificed by the parameter n 228c18ec02fSPetter Reinholdtsen */ 229c18ec02fSPetter Reinholdtsen static const char * 230c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(uint8_t n) 231c18ec02fSPetter Reinholdtsen { 232c18ec02fSPetter Reinholdtsen uint32_t i; 233c18ec02fSPetter Reinholdtsen static char supportedTypes[128]; 234c18ec02fSPetter Reinholdtsen 2350a1f5c03SZdenek Styblik memset(supportedTypes, 0, sizeof(supportedTypes)); 236c18ec02fSPetter Reinholdtsen for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { 237c18ec02fSPetter Reinholdtsen if (n & ipmi_authtype_vals[i].val) { 238c18ec02fSPetter Reinholdtsen strcat(supportedTypes, ipmi_authtype_vals[i].str); 239c18ec02fSPetter Reinholdtsen strcat(supportedTypes, " "); 240c18ec02fSPetter Reinholdtsen } 241c18ec02fSPetter Reinholdtsen } 242c18ec02fSPetter Reinholdtsen 243c18ec02fSPetter Reinholdtsen return supportedTypes; 244c18ec02fSPetter Reinholdtsen } 245c18ec02fSPetter Reinholdtsen 2466febd101SZdenek Styblik uint8_t 2476febd101SZdenek Styblik ipmi_current_channel_medium(struct ipmi_intf *intf) 2486febd101SZdenek Styblik { 2496febd101SZdenek Styblik return ipmi_get_channel_medium(intf, 0xE); 2506febd101SZdenek Styblik } 251c18ec02fSPetter Reinholdtsen 252c18ec02fSPetter Reinholdtsen /** 253c18ec02fSPetter Reinholdtsen * ipmi_get_channel_auth_cap 254c18ec02fSPetter Reinholdtsen * 255c18ec02fSPetter Reinholdtsen * return 0 on success 256c18ec02fSPetter Reinholdtsen * -1 on failure 257c18ec02fSPetter Reinholdtsen */ 258c18ec02fSPetter Reinholdtsen int 259a87b2cccSZdenek Styblik ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) 260c18ec02fSPetter Reinholdtsen { 261c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 262c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 263c18ec02fSPetter Reinholdtsen struct get_channel_auth_cap_rsp auth_cap; 264c18ec02fSPetter Reinholdtsen uint8_t msg_data[2]; 265c18ec02fSPetter Reinholdtsen 266a87b2cccSZdenek Styblik /* Ask for IPMI v2 data as well */ 267a87b2cccSZdenek Styblik msg_data[0] = channel | 0x80; 268c18ec02fSPetter Reinholdtsen msg_data[1] = priv; 269c18ec02fSPetter Reinholdtsen 270c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 271a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 272a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; 273c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 274c18ec02fSPetter Reinholdtsen req.msg.data_len = 2; 275c18ec02fSPetter Reinholdtsen 276c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 277c18ec02fSPetter Reinholdtsen 278c18ec02fSPetter Reinholdtsen if ((rsp == NULL) || (rsp->ccode > 0)) { 279c18ec02fSPetter Reinholdtsen /* 280c18ec02fSPetter Reinholdtsen * It's very possible that this failed because we asked for IPMI v2 data 281c18ec02fSPetter Reinholdtsen * Ask again, without requesting IPMI v2 data 282c18ec02fSPetter Reinholdtsen */ 283c18ec02fSPetter Reinholdtsen msg_data[0] &= 0x7F; 284c18ec02fSPetter Reinholdtsen 285c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 286c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 287c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); 288a87b2cccSZdenek Styblik return (-1); 289c18ec02fSPetter Reinholdtsen } 290c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 291c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", 292c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 293a87b2cccSZdenek Styblik return (-1); 294c18ec02fSPetter Reinholdtsen } 295c18ec02fSPetter Reinholdtsen } 296c18ec02fSPetter Reinholdtsen 297c18ec02fSPetter Reinholdtsen memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp)); 298c18ec02fSPetter Reinholdtsen 299c18ec02fSPetter Reinholdtsen printf("Channel number : %d\n", 300c18ec02fSPetter Reinholdtsen auth_cap.channel_number); 301c18ec02fSPetter Reinholdtsen printf("IPMI v1.5 auth types : %s\n", 302c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); 303c18ec02fSPetter Reinholdtsen 304a87b2cccSZdenek Styblik if (auth_cap.v20_data_available) { 305c18ec02fSPetter Reinholdtsen printf("KG status : %s\n", 306c18ec02fSPetter Reinholdtsen (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); 307a87b2cccSZdenek Styblik } 308c18ec02fSPetter Reinholdtsen 309c18ec02fSPetter Reinholdtsen printf("Per message authentication : %sabled\n", 310c18ec02fSPetter Reinholdtsen (auth_cap.per_message_auth) ? "dis" : "en"); 311c18ec02fSPetter Reinholdtsen printf("User level authentication : %sabled\n", 312c18ec02fSPetter Reinholdtsen (auth_cap.user_level_auth) ? "dis" : "en"); 313c18ec02fSPetter Reinholdtsen 314c18ec02fSPetter Reinholdtsen printf("Non-null user names exist : %s\n", 315c18ec02fSPetter Reinholdtsen (auth_cap.non_null_usernames) ? "yes" : "no"); 316c18ec02fSPetter Reinholdtsen printf("Null user names exist : %s\n", 317c18ec02fSPetter Reinholdtsen (auth_cap.null_usernames) ? "yes" : "no"); 318c18ec02fSPetter Reinholdtsen printf("Anonymous login enabled : %s\n", 319c18ec02fSPetter Reinholdtsen (auth_cap.anon_login_enabled) ? "yes" : "no"); 320c18ec02fSPetter Reinholdtsen 321c18ec02fSPetter Reinholdtsen if (auth_cap.v20_data_available) { 322c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v1.5 : %s\n", 323c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv15_support) ? "yes" : "no"); 324c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v2.0 : %s\n", 325c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv20_support) ? "yes" : "no"); 326c18ec02fSPetter Reinholdtsen } 327c18ec02fSPetter Reinholdtsen 328c18ec02fSPetter Reinholdtsen /* 329c18ec02fSPetter Reinholdtsen * If there is support for an OEM authentication type, there is some 330c18ec02fSPetter Reinholdtsen * information. 331c18ec02fSPetter Reinholdtsen */ 332c18ec02fSPetter Reinholdtsen if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) { 333c18ec02fSPetter Reinholdtsen printf("IANA Number for OEM : %d\n", 334c18ec02fSPetter Reinholdtsen auth_cap.oem_id[0] | 335c18ec02fSPetter Reinholdtsen auth_cap.oem_id[1] << 8 | 336c18ec02fSPetter Reinholdtsen auth_cap.oem_id[2] << 16); 337c18ec02fSPetter Reinholdtsen printf("OEM Auxiliary Data : 0x%x\n", 338c18ec02fSPetter Reinholdtsen auth_cap.oem_aux_data); 339c18ec02fSPetter Reinholdtsen } 340c18ec02fSPetter Reinholdtsen 341c18ec02fSPetter Reinholdtsen return 0; 342c18ec02fSPetter Reinholdtsen } 343c18ec02fSPetter Reinholdtsen 344c18ec02fSPetter Reinholdtsen static int 345a87b2cccSZdenek Styblik ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 346c18ec02fSPetter Reinholdtsen uint8_t channel) 347c18ec02fSPetter Reinholdtsen { 348c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 349c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 350c18ec02fSPetter Reinholdtsen 351c18ec02fSPetter Reinholdtsen uint8_t rqdata[3]; 352c18ec02fSPetter Reinholdtsen uint32_t iana; 353c18ec02fSPetter Reinholdtsen uint8_t auth_alg, integrity_alg, crypt_alg; 354c18ec02fSPetter Reinholdtsen uint8_t cipher_suite_id; 355c18ec02fSPetter Reinholdtsen uint8_t list_index = 0; 356a87b2cccSZdenek Styblik /* 0x40 sets * 16 bytes per set */ 357a87b2cccSZdenek Styblik uint8_t cipher_suite_data[1024]; 358c18ec02fSPetter Reinholdtsen uint16_t offset = 0; 359a87b2cccSZdenek Styblik /* how much was returned, total */ 360a87b2cccSZdenek Styblik uint16_t cipher_suite_data_length = 0; 361c18ec02fSPetter Reinholdtsen 362c18ec02fSPetter Reinholdtsen memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 363c18ec02fSPetter Reinholdtsen 364c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 365a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 366a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 367c18ec02fSPetter Reinholdtsen req.msg.data = rqdata; 368c18ec02fSPetter Reinholdtsen req.msg.data_len = 3; 369c18ec02fSPetter Reinholdtsen 370c18ec02fSPetter Reinholdtsen rqdata[0] = channel; 371c18ec02fSPetter Reinholdtsen rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 372a87b2cccSZdenek Styblik /* Always ask for cipher suite format */ 373a87b2cccSZdenek Styblik rqdata[2] = 0x80; 374c18ec02fSPetter Reinholdtsen 375c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 376c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 377c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 378c18ec02fSPetter Reinholdtsen return -1; 379c18ec02fSPetter Reinholdtsen } 380c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 381c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 382c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 383c18ec02fSPetter Reinholdtsen return -1; 384c18ec02fSPetter Reinholdtsen } 385c18ec02fSPetter Reinholdtsen 386c18ec02fSPetter Reinholdtsen 387a87b2cccSZdenek Styblik /* 388a87b2cccSZdenek Styblik * Grab the returned channel number once. We assume it's the same 389a87b2cccSZdenek Styblik * in future calls. 390a87b2cccSZdenek Styblik */ 391a87b2cccSZdenek Styblik if (rsp->data_len >= 1) { 392c18ec02fSPetter Reinholdtsen channel = rsp->data[0]; 393a87b2cccSZdenek Styblik } 394c18ec02fSPetter Reinholdtsen 395a87b2cccSZdenek Styblik while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 396a87b2cccSZdenek Styblik /* 397a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 398a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 399a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 400a87b2cccSZdenek Styblik */ 401c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 402c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 403c18ec02fSPetter Reinholdtsen 404a87b2cccSZdenek Styblik /* 405a87b2cccSZdenek Styblik * Increment our list for the next call 406a87b2cccSZdenek Styblik */ 407c18ec02fSPetter Reinholdtsen ++list_index; 408c18ec02fSPetter Reinholdtsen rqdata[2] = (rqdata[2] & 0x80) + list_index; 409c18ec02fSPetter Reinholdtsen 410c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 411c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 412c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 413c18ec02fSPetter Reinholdtsen return -1; 414c18ec02fSPetter Reinholdtsen } 415c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 416c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 417c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 418c18ec02fSPetter Reinholdtsen return -1; 419c18ec02fSPetter Reinholdtsen } 420c18ec02fSPetter Reinholdtsen } 421c18ec02fSPetter Reinholdtsen 422c18ec02fSPetter Reinholdtsen /* Copy last chunk */ 423a87b2cccSZdenek Styblik if(rsp->data_len > 1) { 424a87b2cccSZdenek Styblik /* 425a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 426a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 427a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 428a87b2cccSZdenek Styblik */ 429c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 430c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 431c18ec02fSPetter Reinholdtsen } 432c18ec02fSPetter Reinholdtsen 433a87b2cccSZdenek Styblik /* We can chomp on all our data now. */ 434c18ec02fSPetter Reinholdtsen cipher_suite_data_length = offset; 435c18ec02fSPetter Reinholdtsen offset = 0; 436c18ec02fSPetter Reinholdtsen 437a87b2cccSZdenek Styblik if (! csv_output) { 438c18ec02fSPetter Reinholdtsen printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 439a87b2cccSZdenek Styblik } 440a87b2cccSZdenek Styblik while (offset < cipher_suite_data_length) { 441a87b2cccSZdenek Styblik if (cipher_suite_data[offset++] == 0xC0) { 442a87b2cccSZdenek Styblik /* standard type */ 443c18ec02fSPetter Reinholdtsen iana = 0; 444c18ec02fSPetter Reinholdtsen 445a87b2cccSZdenek Styblik /* Verify that we have at least a full record left; id + 3 algs */ 446a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 447a87b2cccSZdenek Styblik lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 448a87b2cccSZdenek Styblik return -1; 449a87b2cccSZdenek Styblik } 450a87b2cccSZdenek Styblik cipher_suite_id = cipher_suite_data[offset++]; 451a87b2cccSZdenek Styblik } else if (cipher_suite_data[offset++] == 0xC1) { 452a87b2cccSZdenek Styblik /* OEM record type */ 453a87b2cccSZdenek Styblik /* Verify that we have at least a full record left 454a87b2cccSZdenek Styblik * id + iana + 3 algs 455a87b2cccSZdenek Styblik */ 456a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 457c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 458c18ec02fSPetter Reinholdtsen return -1; 459c18ec02fSPetter Reinholdtsen } 460c18ec02fSPetter Reinholdtsen 461c18ec02fSPetter Reinholdtsen cipher_suite_id = cipher_suite_data[offset++]; 462c18ec02fSPetter Reinholdtsen 463a87b2cccSZdenek Styblik /* Grab the IANA */ 464c18ec02fSPetter Reinholdtsen iana = 465c18ec02fSPetter Reinholdtsen cipher_suite_data[offset] | 466c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 1] << 8) | 467c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 2] << 16); 468c18ec02fSPetter Reinholdtsen offset += 3; 469a87b2cccSZdenek Styblik } else { 470c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 471c18ec02fSPetter Reinholdtsen return -1; 472c18ec02fSPetter Reinholdtsen } 473c18ec02fSPetter Reinholdtsen 474a87b2cccSZdenek Styblik /* 475a87b2cccSZdenek Styblik * Grab the algorithms for this cipher suite. I guess we can't be 476a87b2cccSZdenek Styblik * sure of what order they'll come in. Also, I suppose we default 477a87b2cccSZdenek Styblik * to the NONE algorithm if one were absent. This part of the spec is 478a87b2cccSZdenek Styblik * poorly written -- I have read the errata document. For now, I'm only 479a87b2cccSZdenek Styblik * allowing one algorithm per type (auth, integrity, crypt) because I 480a87b2cccSZdenek Styblik * don't I understand how it could be otherwise. 481a87b2cccSZdenek Styblik */ 482c18ec02fSPetter Reinholdtsen auth_alg = IPMI_AUTH_RAKP_NONE; 483c18ec02fSPetter Reinholdtsen integrity_alg = IPMI_INTEGRITY_NONE; 484c18ec02fSPetter Reinholdtsen crypt_alg = IPMI_CRYPT_NONE; 485c18ec02fSPetter Reinholdtsen 486c18ec02fSPetter Reinholdtsen while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 487c18ec02fSPetter Reinholdtsen ((cipher_suite_data_length - offset) > 0)) 488c18ec02fSPetter Reinholdtsen { 489c18ec02fSPetter Reinholdtsen switch (cipher_suite_data[offset] & 0xC0) 490c18ec02fSPetter Reinholdtsen { 491c18ec02fSPetter Reinholdtsen case 0x00: 492a87b2cccSZdenek Styblik /* Authentication algorithm specifier */ 493c18ec02fSPetter Reinholdtsen auth_alg = cipher_suite_data[offset++] & 0x3F; 494c18ec02fSPetter Reinholdtsen break; 495c18ec02fSPetter Reinholdtsen case 0x40: 496a87b2cccSZdenek Styblik /* Interity algorithm specifier */ 497c18ec02fSPetter Reinholdtsen integrity_alg = cipher_suite_data[offset++] & 0x3F; 498c18ec02fSPetter Reinholdtsen break; 499c18ec02fSPetter Reinholdtsen case 0x80: 500a87b2cccSZdenek Styblik /* Confidentiality algorithm specifier */ 501c18ec02fSPetter Reinholdtsen crypt_alg = cipher_suite_data[offset++] & 0x3F; 502c18ec02fSPetter Reinholdtsen break; 503c18ec02fSPetter Reinholdtsen } 504c18ec02fSPetter Reinholdtsen } 505a87b2cccSZdenek Styblik /* We have everything we need to spit out a cipher suite record */ 506c18ec02fSPetter Reinholdtsen printf((csv_output? "%d,%s,%s,%s,%s\n" : 507c18ec02fSPetter Reinholdtsen "%-4d %-7s %-15s %-15s %-15s\n"), 508c18ec02fSPetter Reinholdtsen cipher_suite_id, 509c18ec02fSPetter Reinholdtsen iana_string(iana), 510c18ec02fSPetter Reinholdtsen val2str(auth_alg, ipmi_auth_algorithms), 511c18ec02fSPetter Reinholdtsen val2str(integrity_alg, ipmi_integrity_algorithms), 512c18ec02fSPetter Reinholdtsen val2str(crypt_alg, ipmi_encryption_algorithms)); 513c18ec02fSPetter Reinholdtsen } 514c18ec02fSPetter Reinholdtsen return 0; 515c18ec02fSPetter Reinholdtsen } 516c18ec02fSPetter Reinholdtsen 5176febd101SZdenek Styblik /** 5186febd101SZdenek Styblik * ipmi_get_channel_info 5196febd101SZdenek Styblik * 5206febd101SZdenek Styblik * returns 0 on success 5216febd101SZdenek Styblik * -1 on failure 5226febd101SZdenek Styblik * 5236febd101SZdenek Styblik */ 5246febd101SZdenek Styblik int 5256febd101SZdenek Styblik ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) 5266febd101SZdenek Styblik { 5276febd101SZdenek Styblik struct channel_info_t channel_info = {0}; 5286febd101SZdenek Styblik struct channel_access_t channel_access = {0}; 5296febd101SZdenek Styblik int ccode = 0; 5306febd101SZdenek Styblik 5316febd101SZdenek Styblik channel_info.channel = channel; 5326febd101SZdenek Styblik ccode = _ipmi_get_channel_info(intf, &channel_info); 5336febd101SZdenek Styblik if (eval_ccode(ccode) != 0) { 5346febd101SZdenek Styblik lprintf(LOG_ERR, "Unable to Get Channel Info"); 5356febd101SZdenek Styblik return (-1); 5366febd101SZdenek Styblik } 5376febd101SZdenek Styblik 5386febd101SZdenek Styblik printf("Channel 0x%x info:\n", channel_info.channel); 5396febd101SZdenek Styblik printf(" Channel Medium Type : %s\n", 5406febd101SZdenek Styblik val2str(channel_info.medium, 5416febd101SZdenek Styblik ipmi_channel_medium_vals)); 5426febd101SZdenek Styblik printf(" Channel Protocol Type : %s\n", 5436febd101SZdenek Styblik val2str(channel_info.protocol, 5446febd101SZdenek Styblik ipmi_channel_protocol_vals)); 5456febd101SZdenek Styblik printf(" Session Support : "); 5466febd101SZdenek Styblik switch (channel_info.session_support) { 5476febd101SZdenek Styblik case IPMI_CHANNEL_SESSION_LESS: 5486febd101SZdenek Styblik printf("session-less\n"); 5496febd101SZdenek Styblik break; 5506febd101SZdenek Styblik case IPMI_CHANNEL_SESSION_SINGLE: 5516febd101SZdenek Styblik printf("single-session\n"); 5526febd101SZdenek Styblik break; 5536febd101SZdenek Styblik case IPMI_CHANNEL_SESSION_MULTI: 5546febd101SZdenek Styblik printf("multi-session\n"); 5556febd101SZdenek Styblik break; 5566febd101SZdenek Styblik case IPMI_CHANNEL_SESSION_BASED: 5576febd101SZdenek Styblik printf("session-based\n"); 5586febd101SZdenek Styblik break; 5596febd101SZdenek Styblik default: 5606febd101SZdenek Styblik printf("unknown\n"); 5616febd101SZdenek Styblik break; 5626febd101SZdenek Styblik } 5636febd101SZdenek Styblik printf(" Active Session Count : %d\n", 5646febd101SZdenek Styblik channel_info.active_sessions); 5656febd101SZdenek Styblik printf(" Protocol Vendor ID : %d\n", 5666febd101SZdenek Styblik channel_info.vendor_id[0] | 5676febd101SZdenek Styblik channel_info.vendor_id[1] << 8 | 5686febd101SZdenek Styblik channel_info.vendor_id[2] << 16); 5696febd101SZdenek Styblik 5706febd101SZdenek Styblik /* only proceed if this is LAN channel */ 5716febd101SZdenek Styblik if (channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN 5726febd101SZdenek Styblik && channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { 5736febd101SZdenek Styblik return 0; 5746febd101SZdenek Styblik } 5756febd101SZdenek Styblik 5766febd101SZdenek Styblik channel_access.channel = channel_info.channel; 5776febd101SZdenek Styblik ccode = _ipmi_get_channel_access(intf, &channel_access, 1); 5786febd101SZdenek Styblik if (eval_ccode(ccode) != 0) { 5796febd101SZdenek Styblik lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)"); 5806febd101SZdenek Styblik return (-1); 5816febd101SZdenek Styblik } 5826febd101SZdenek Styblik 5836febd101SZdenek Styblik printf(" Volatile(active) Settings\n"); 5846febd101SZdenek Styblik printf(" Alerting : %sabled\n", 5856febd101SZdenek Styblik (channel_access.alerting) ? "dis" : "en"); 5866febd101SZdenek Styblik printf(" Per-message Auth : %sabled\n", 5876febd101SZdenek Styblik (channel_access.per_message_auth) ? "dis" : "en"); 5886febd101SZdenek Styblik printf(" User Level Auth : %sabled\n", 5896febd101SZdenek Styblik (channel_access.user_level_auth) ? "dis" : "en"); 5906febd101SZdenek Styblik printf(" Access Mode : "); 5916febd101SZdenek Styblik switch (channel_access.access_mode) { 5926febd101SZdenek Styblik case 0: 5936febd101SZdenek Styblik printf("disabled\n"); 5946febd101SZdenek Styblik break; 5956febd101SZdenek Styblik case 1: 5966febd101SZdenek Styblik printf("pre-boot only\n"); 5976febd101SZdenek Styblik break; 5986febd101SZdenek Styblik case 2: 5996febd101SZdenek Styblik printf("always available\n"); 6006febd101SZdenek Styblik break; 6016febd101SZdenek Styblik case 3: 6026febd101SZdenek Styblik printf("shared\n"); 6036febd101SZdenek Styblik break; 6046febd101SZdenek Styblik default: 6056febd101SZdenek Styblik printf("unknown\n"); 6066febd101SZdenek Styblik break; 6076febd101SZdenek Styblik } 6086febd101SZdenek Styblik 6096febd101SZdenek Styblik memset(&channel_access, 0, sizeof(channel_access)); 6106febd101SZdenek Styblik channel_access.channel = channel_info.channel; 6116febd101SZdenek Styblik /* get non-volatile settings */ 6126febd101SZdenek Styblik ccode = _ipmi_get_channel_access(intf, &channel_access, 0); 6136febd101SZdenek Styblik if (eval_ccode(ccode) != 0) { 6146febd101SZdenek Styblik lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)"); 6156febd101SZdenek Styblik return (-1); 6166febd101SZdenek Styblik } 6176febd101SZdenek Styblik 6186febd101SZdenek Styblik printf(" Non-Volatile Settings\n"); 6196febd101SZdenek Styblik printf(" Alerting : %sabled\n", 6206febd101SZdenek Styblik (channel_access.alerting) ? "dis" : "en"); 6216febd101SZdenek Styblik printf(" Per-message Auth : %sabled\n", 6226febd101SZdenek Styblik (channel_access.per_message_auth) ? "dis" : "en"); 6236febd101SZdenek Styblik printf(" User Level Auth : %sabled\n", 6246febd101SZdenek Styblik (channel_access.user_level_auth) ? "dis" : "en"); 6256febd101SZdenek Styblik printf(" Access Mode : "); 6266febd101SZdenek Styblik switch (channel_access.access_mode) { 6276febd101SZdenek Styblik case 0: 6286febd101SZdenek Styblik printf("disabled\n"); 6296febd101SZdenek Styblik break; 6306febd101SZdenek Styblik case 1: 6316febd101SZdenek Styblik printf("pre-boot only\n"); 6326febd101SZdenek Styblik break; 6336febd101SZdenek Styblik case 2: 6346febd101SZdenek Styblik printf("always available\n"); 6356febd101SZdenek Styblik break; 6366febd101SZdenek Styblik case 3: 6376febd101SZdenek Styblik printf("shared\n"); 6386febd101SZdenek Styblik break; 6396febd101SZdenek Styblik default: 6406febd101SZdenek Styblik printf("unknown\n"); 6416febd101SZdenek Styblik break; 6426febd101SZdenek Styblik } 6436febd101SZdenek Styblik return 0; 6446febd101SZdenek Styblik } 6456febd101SZdenek Styblik 6466febd101SZdenek Styblik /* ipmi_get_channel_medium - Return Medium of given IPMI Channel. 6476febd101SZdenek Styblik * 6486febd101SZdenek Styblik * @channel - IPMI Channel 6496febd101SZdenek Styblik * 6506febd101SZdenek Styblik * returns - IPMI Channel Medium, IPMI_CHANNEL_MEDIUM_RESERVED if ccode > 0, 6516febd101SZdenek Styblik * 0 on error. 6526febd101SZdenek Styblik */ 653c18ec02fSPetter Reinholdtsen uint8_t 654c18ec02fSPetter Reinholdtsen ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 655c18ec02fSPetter Reinholdtsen { 6560801b458SZdenek Styblik struct channel_info_t channel_info = {0}; 6570801b458SZdenek Styblik int ccode = 0; 658c18ec02fSPetter Reinholdtsen 6590801b458SZdenek Styblik channel_info.channel = channel; 6600801b458SZdenek Styblik ccode = _ipmi_get_channel_info(intf, &channel_info); 6616b8d55d6SZdenek Styblik if (ccode == 0xCC) { 6620801b458SZdenek Styblik return IPMI_CHANNEL_MEDIUM_RESERVED; 6636b8d55d6SZdenek Styblik } else if (ccode < 0 && eval_ccode(ccode) != 0) { 6646b8d55d6SZdenek Styblik return 0; 6656b8d55d6SZdenek Styblik } else if (ccode > 0) { 6660801b458SZdenek Styblik lprintf(LOG_ERR, "Get Channel Info command failed: %s", 6670801b458SZdenek Styblik val2str(ccode, completion_code_vals)); 668c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 669a87b2cccSZdenek Styblik } 670c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "Channel type: %s", 6710801b458SZdenek Styblik val2str(channel_info.medium, ipmi_channel_medium_vals)); 6720801b458SZdenek Styblik return channel_info.medium; 673c18ec02fSPetter Reinholdtsen } 674c18ec02fSPetter Reinholdtsen 6756febd101SZdenek Styblik /* ipmi_get_user_access - Get User Access for given Channel and User or Users. 6766febd101SZdenek Styblik * 6776febd101SZdenek Styblik * @intf - IPMI interface 6786febd101SZdenek Styblik * @channel - IPMI Channel we're getting access for 6796febd101SZdenek Styblik * @user_id - User ID. If 0 is passed, all IPMI users will be listed 6806febd101SZdenek Styblik * 6816febd101SZdenek Styblik * returns - 0 on success, (-1) on error 6826febd101SZdenek Styblik */ 6836febd101SZdenek Styblik static int 6846febd101SZdenek Styblik ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id) 685c18ec02fSPetter Reinholdtsen { 6866febd101SZdenek Styblik struct user_access_t user_access; 6876febd101SZdenek Styblik struct user_name_t user_name; 6886febd101SZdenek Styblik int ccode = 0; 6896febd101SZdenek Styblik int curr_uid; 6906febd101SZdenek Styblik int init = 1; 6916febd101SZdenek Styblik int max_uid = 0; 6926febd101SZdenek Styblik 6936febd101SZdenek Styblik curr_uid = user_id ? user_id : 1; 6946febd101SZdenek Styblik do { 6956febd101SZdenek Styblik memset(&user_access, 0, sizeof(user_access)); 6966febd101SZdenek Styblik user_access.channel = channel; 6976febd101SZdenek Styblik user_access.user_id = curr_uid; 6986febd101SZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 6996febd101SZdenek Styblik if (eval_ccode(ccode) != 0) { 7006febd101SZdenek Styblik lprintf(LOG_ERR, 7016febd101SZdenek Styblik "Unable to Get User Access (channel %d id %d)", 7026febd101SZdenek Styblik channel, curr_uid); 7036febd101SZdenek Styblik return (-1); 704c18ec02fSPetter Reinholdtsen } 705c18ec02fSPetter Reinholdtsen 7066febd101SZdenek Styblik memset(&user_name, 0, sizeof(user_name)); 7076febd101SZdenek Styblik user_name.user_id = curr_uid; 7086febd101SZdenek Styblik ccode = _ipmi_get_user_name(intf, &user_name); 7096febd101SZdenek Styblik if (eval_ccode(ccode) != 0) { 7106febd101SZdenek Styblik lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); 7116febd101SZdenek Styblik return (-1); 7126febd101SZdenek Styblik } 7136febd101SZdenek Styblik if (init) { 7146febd101SZdenek Styblik printf("Maximum User IDs : %d\n", user_access.max_user_ids); 7156febd101SZdenek Styblik printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 7166febd101SZdenek Styblik max_uid = user_access.max_user_ids; 7176febd101SZdenek Styblik init = 0; 7186febd101SZdenek Styblik } 7196febd101SZdenek Styblik 7206febd101SZdenek Styblik printf("\n"); 7216febd101SZdenek Styblik printf("User ID : %d\n", curr_uid); 7226febd101SZdenek Styblik printf("User Name : %s\n", user_name.user_name); 7236febd101SZdenek Styblik printf("Fixed Name : %s\n", 7246febd101SZdenek Styblik (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 7256febd101SZdenek Styblik printf("Access Available : %s\n", 7266febd101SZdenek Styblik (user_access.callin_callback) ? "callback" : "call-in / callback"); 7276febd101SZdenek Styblik printf("Link Authentication : %sabled\n", 7286febd101SZdenek Styblik (user_access.link_auth) ? "en" : "dis"); 7296febd101SZdenek Styblik printf("IPMI Messaging : %sabled\n", 7306febd101SZdenek Styblik (user_access.ipmi_messaging) ? "en" : "dis"); 7316febd101SZdenek Styblik printf("Privilege Level : %s\n", 7326febd101SZdenek Styblik val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 7336febd101SZdenek Styblik 7346febd101SZdenek Styblik curr_uid ++; 7356febd101SZdenek Styblik } while (!user_id && curr_uid <= max_uid); 7366febd101SZdenek Styblik 7376febd101SZdenek Styblik return 0; 738c18ec02fSPetter Reinholdtsen } 739c18ec02fSPetter Reinholdtsen 740585cb7c8SZdenek Styblik /* ipmi_set_user_access - Query BMC for current Channel ACLs, parse CLI args 741585cb7c8SZdenek Styblik * and update current ACLs. 742585cb7c8SZdenek Styblik * 743585cb7c8SZdenek Styblik * returns - 0 on success, (-1) on error 744585cb7c8SZdenek Styblik */ 745e4be291cSZdenek Styblik int 746e4be291cSZdenek Styblik ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) 747e4be291cSZdenek Styblik { 748e4be291cSZdenek Styblik struct user_access_t user_access = {0}; 749e4be291cSZdenek Styblik int ccode = 0; 750e4be291cSZdenek Styblik int i = 0; 751e4be291cSZdenek Styblik uint8_t channel = 0; 752e4be291cSZdenek Styblik uint8_t priv = 0; 753e4be291cSZdenek Styblik uint8_t user_id = 0; 754e4be291cSZdenek Styblik if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 755e4be291cSZdenek Styblik printf_channel_usage(); 756e4be291cSZdenek Styblik return 0; 757e4be291cSZdenek Styblik } else if (argc < 3) { 758e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 759e4be291cSZdenek Styblik printf_channel_usage(); 760e4be291cSZdenek Styblik return (-1); 761e4be291cSZdenek Styblik } 762e4be291cSZdenek Styblik if (is_ipmi_channel_num(argv[0], &channel) != 0 763e4be291cSZdenek Styblik || is_ipmi_user_id(argv[1], &user_id) != 0) { 764e4be291cSZdenek Styblik return (-1); 765e4be291cSZdenek Styblik } 766e4be291cSZdenek Styblik user_access.channel = channel; 767e4be291cSZdenek Styblik user_access.user_id = user_id; 768e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 769e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 770e4be291cSZdenek Styblik lprintf(LOG_ERR, 771e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 772e4be291cSZdenek Styblik channel, user_id); 773e4be291cSZdenek Styblik return (-1); 774e4be291cSZdenek Styblik } 775e4be291cSZdenek Styblik for (i = 3; i < argc; i ++) { 776e4be291cSZdenek Styblik if (strncmp(argv[i], "callin=", 7) == 0) { 777e4be291cSZdenek Styblik if (strncmp(argv[i] + 7, "off", 3) == 0) { 778e4be291cSZdenek Styblik user_access.callin_callback = 1; 779e4be291cSZdenek Styblik } else { 780e4be291cSZdenek Styblik user_access.callin_callback = 0; 781e4be291cSZdenek Styblik } 782e4be291cSZdenek Styblik } else if (strncmp(argv[i], "link=", 5) == 0) { 783e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 784e4be291cSZdenek Styblik user_access.link_auth = 0; 785e4be291cSZdenek Styblik } else { 786e4be291cSZdenek Styblik user_access.link_auth = 1; 787e4be291cSZdenek Styblik } 788e4be291cSZdenek Styblik } else if (strncmp(argv[i], "ipmi=", 5) == 0) { 789e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 790e4be291cSZdenek Styblik user_access.ipmi_messaging = 0; 791e4be291cSZdenek Styblik } else { 792e4be291cSZdenek Styblik user_access.ipmi_messaging = 1; 793e4be291cSZdenek Styblik } 794e4be291cSZdenek Styblik } else if (strncmp(argv[i], "privilege=", 10) == 0) { 795e4be291cSZdenek Styblik if (str2uchar(argv[i] + 10, &priv) != 0) { 796e4be291cSZdenek Styblik lprintf(LOG_ERR, 797e4be291cSZdenek Styblik "Numeric value expected, but '%s' given.", 798e4be291cSZdenek Styblik argv[i] + 10); 799e4be291cSZdenek Styblik return (-1); 800e4be291cSZdenek Styblik } 801e4be291cSZdenek Styblik user_access.privilege_limit = priv; 802e4be291cSZdenek Styblik } else { 803e4be291cSZdenek Styblik lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); 804e4be291cSZdenek Styblik return (-1); 805e4be291cSZdenek Styblik } 806e4be291cSZdenek Styblik } 807708be8bcSZdenek Styblik ccode = _ipmi_set_user_access(intf, &user_access, 0); 808e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 809e4be291cSZdenek Styblik lprintf(LOG_ERR, 810e4be291cSZdenek Styblik "Unable to Set User Access (channel %d id %d)", 811e4be291cSZdenek Styblik channel, user_id); 812e4be291cSZdenek Styblik return (-1); 813e4be291cSZdenek Styblik } 814e4be291cSZdenek Styblik printf("Set User Access (channel %d id %d) successful.\n", 815e4be291cSZdenek Styblik channel, user_id); 816e4be291cSZdenek Styblik return 0; 817e4be291cSZdenek Styblik } 818c18ec02fSPetter Reinholdtsen 819c18ec02fSPetter Reinholdtsen int 820c18ec02fSPetter Reinholdtsen ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 821c18ec02fSPetter Reinholdtsen { 822c18ec02fSPetter Reinholdtsen int retval = 0; 823a87b2cccSZdenek Styblik uint8_t channel; 824a87b2cccSZdenek Styblik uint8_t priv = 0; 8250562c809SZdenek Styblik if (argc < 1) { 8260562c809SZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 827c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8280562c809SZdenek Styblik return (-1); 8290562c809SZdenek Styblik } else if (strncmp(argv[0], "help", 4) == 0) { 8300562c809SZdenek Styblik printf_channel_usage(); 8310562c809SZdenek Styblik return 0; 832a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "authcap", 7) == 0) { 833c18ec02fSPetter Reinholdtsen if (argc != 3) { 834c18ec02fSPetter Reinholdtsen printf_channel_usage(); 835c18ec02fSPetter Reinholdtsen return (-1); 8360562c809SZdenek Styblik } 837140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0 838140add9dSZdenek Styblik || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 839c18ec02fSPetter Reinholdtsen return (-1); 840c18ec02fSPetter Reinholdtsen } 841c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_auth_cap(intf, channel, priv); 842a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getaccess", 10) == 0) { 843140add9dSZdenek Styblik uint8_t user_id = 0; 8440562c809SZdenek Styblik if ((argc < 2) || (argc > 3)) { 845e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 8460562c809SZdenek Styblik printf_channel_usage(); 8470562c809SZdenek Styblik return (-1); 8480562c809SZdenek Styblik } 849140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 850c18ec02fSPetter Reinholdtsen return (-1); 851c18ec02fSPetter Reinholdtsen } 852c18ec02fSPetter Reinholdtsen if (argc == 3) { 853140add9dSZdenek Styblik if (is_ipmi_user_id(argv[2], &user_id) != 0) { 854c18ec02fSPetter Reinholdtsen return (-1); 855c18ec02fSPetter Reinholdtsen } 856c18ec02fSPetter Reinholdtsen } 857140add9dSZdenek Styblik retval = ipmi_get_user_access(intf, channel, user_id); 858a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "setaccess", 9) == 0) { 859e4be291cSZdenek Styblik return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); 860a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "info", 4) == 0) { 861140add9dSZdenek Styblik channel = 0xE; 862a87b2cccSZdenek Styblik if (argc > 2) { 863c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8640562c809SZdenek Styblik return (-1); 8650562c809SZdenek Styblik } 866c18ec02fSPetter Reinholdtsen if (argc == 2) { 867140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 868c18ec02fSPetter Reinholdtsen return (-1); 869c18ec02fSPetter Reinholdtsen } 870c18ec02fSPetter Reinholdtsen } 871140add9dSZdenek Styblik retval = ipmi_get_channel_info(intf, channel); 872a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getciphers", 10) == 0) { 8730562c809SZdenek Styblik /* channel getciphers <ipmi|sol> [channel] */ 874140add9dSZdenek Styblik channel = 0xE; 875c18ec02fSPetter Reinholdtsen if ((argc < 2) || (argc > 3) || 876a87b2cccSZdenek Styblik (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 877c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8780562c809SZdenek Styblik return (-1); 8790562c809SZdenek Styblik } 880c18ec02fSPetter Reinholdtsen if (argc == 3) { 881140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 882c18ec02fSPetter Reinholdtsen return (-1); 883c18ec02fSPetter Reinholdtsen } 884c18ec02fSPetter Reinholdtsen } 885c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_cipher_suites(intf, 8860562c809SZdenek Styblik argv[1], /* ipmi | sol */ 887140add9dSZdenek Styblik channel); 888a87b2cccSZdenek Styblik } else { 889278dc84bSZdenek Styblik lprintf(LOG_ERR, "Invalid CHANNEL command: %s\n", argv[0]); 890c18ec02fSPetter Reinholdtsen printf_channel_usage(); 891c18ec02fSPetter Reinholdtsen retval = -1; 892c18ec02fSPetter Reinholdtsen } 893c18ec02fSPetter Reinholdtsen return retval; 894c18ec02fSPetter Reinholdtsen } 8956febd101SZdenek Styblik 8966febd101SZdenek Styblik /* printf_channel_usage - print-out help. */ 8976febd101SZdenek Styblik void 8986febd101SZdenek Styblik printf_channel_usage() 8996febd101SZdenek Styblik { 9006febd101SZdenek Styblik lprintf(LOG_NOTICE, 9016febd101SZdenek Styblik "Channel Commands: authcap <channel number> <max privilege>"); 9026febd101SZdenek Styblik lprintf(LOG_NOTICE, 9036febd101SZdenek Styblik " getaccess <channel number> [user id]"); 9046febd101SZdenek Styblik lprintf(LOG_NOTICE, 9056febd101SZdenek Styblik " setaccess <channel number> " 9066febd101SZdenek Styblik "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 9076febd101SZdenek Styblik lprintf(LOG_NOTICE, 9086febd101SZdenek Styblik " info [channel number]"); 9096febd101SZdenek Styblik lprintf(LOG_NOTICE, 9106febd101SZdenek Styblik " getciphers <ipmi | sol> [channel]"); 9116febd101SZdenek Styblik lprintf(LOG_NOTICE, 9126febd101SZdenek Styblik ""); 9136febd101SZdenek Styblik lprintf(LOG_NOTICE, 9146febd101SZdenek Styblik "Possible privilege levels are:"); 9156febd101SZdenek Styblik lprintf(LOG_NOTICE, 9166febd101SZdenek Styblik " 1 Callback level"); 9176febd101SZdenek Styblik lprintf(LOG_NOTICE, 9186febd101SZdenek Styblik " 2 User level"); 9196febd101SZdenek Styblik lprintf(LOG_NOTICE, 9206febd101SZdenek Styblik " 3 Operator level"); 9216febd101SZdenek Styblik lprintf(LOG_NOTICE, 9226febd101SZdenek Styblik " 4 Administrator level"); 9236febd101SZdenek Styblik lprintf(LOG_NOTICE, 9246febd101SZdenek Styblik " 5 OEM Proprietary level"); 9256febd101SZdenek Styblik lprintf(LOG_NOTICE, 9266febd101SZdenek Styblik " 15 No access"); 9276febd101SZdenek Styblik } 928