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 150c18ec02fSPetter Reinholdtsen /** 151c18ec02fSPetter Reinholdtsen * ipmi_1_5_authtypes 152c18ec02fSPetter Reinholdtsen * 153c18ec02fSPetter Reinholdtsen * Create a string describing the supported authentication types as 154c18ec02fSPetter Reinholdtsen * specificed by the parameter n 155c18ec02fSPetter Reinholdtsen */ 156c18ec02fSPetter Reinholdtsen static const char * 157c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(uint8_t n) 158c18ec02fSPetter Reinholdtsen { 159c18ec02fSPetter Reinholdtsen uint32_t i; 160c18ec02fSPetter Reinholdtsen static char supportedTypes[128]; 161c18ec02fSPetter Reinholdtsen 1620a1f5c03SZdenek Styblik memset(supportedTypes, 0, sizeof(supportedTypes)); 163c18ec02fSPetter Reinholdtsen for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { 164c18ec02fSPetter Reinholdtsen if (n & ipmi_authtype_vals[i].val) { 165c18ec02fSPetter Reinholdtsen strcat(supportedTypes, ipmi_authtype_vals[i].str); 166c18ec02fSPetter Reinholdtsen strcat(supportedTypes, " "); 167c18ec02fSPetter Reinholdtsen } 168c18ec02fSPetter Reinholdtsen } 169c18ec02fSPetter Reinholdtsen 170c18ec02fSPetter Reinholdtsen return supportedTypes; 171c18ec02fSPetter Reinholdtsen } 172c18ec02fSPetter Reinholdtsen 173c18ec02fSPetter Reinholdtsen 174c18ec02fSPetter Reinholdtsen 175c18ec02fSPetter Reinholdtsen /** 176c18ec02fSPetter Reinholdtsen * ipmi_get_channel_auth_cap 177c18ec02fSPetter Reinholdtsen * 178c18ec02fSPetter Reinholdtsen * return 0 on success 179c18ec02fSPetter Reinholdtsen * -1 on failure 180c18ec02fSPetter Reinholdtsen */ 181c18ec02fSPetter Reinholdtsen int 182a87b2cccSZdenek Styblik ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) 183c18ec02fSPetter Reinholdtsen { 184c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 185c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 186c18ec02fSPetter Reinholdtsen struct get_channel_auth_cap_rsp auth_cap; 187c18ec02fSPetter Reinholdtsen uint8_t msg_data[2]; 188c18ec02fSPetter Reinholdtsen 189a87b2cccSZdenek Styblik /* Ask for IPMI v2 data as well */ 190a87b2cccSZdenek Styblik msg_data[0] = channel | 0x80; 191c18ec02fSPetter Reinholdtsen msg_data[1] = priv; 192c18ec02fSPetter Reinholdtsen 193c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 194a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 195a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; 196c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 197c18ec02fSPetter Reinholdtsen req.msg.data_len = 2; 198c18ec02fSPetter Reinholdtsen 199c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 200c18ec02fSPetter Reinholdtsen 201c18ec02fSPetter Reinholdtsen if ((rsp == NULL) || (rsp->ccode > 0)) { 202c18ec02fSPetter Reinholdtsen /* 203c18ec02fSPetter Reinholdtsen * It's very possible that this failed because we asked for IPMI v2 data 204c18ec02fSPetter Reinholdtsen * Ask again, without requesting IPMI v2 data 205c18ec02fSPetter Reinholdtsen */ 206c18ec02fSPetter Reinholdtsen msg_data[0] &= 0x7F; 207c18ec02fSPetter Reinholdtsen 208c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 209c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 210c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); 211a87b2cccSZdenek Styblik return (-1); 212c18ec02fSPetter Reinholdtsen } 213c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 214c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", 215c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 216a87b2cccSZdenek Styblik return (-1); 217c18ec02fSPetter Reinholdtsen } 218c18ec02fSPetter Reinholdtsen } 219c18ec02fSPetter Reinholdtsen 220c18ec02fSPetter Reinholdtsen memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp)); 221c18ec02fSPetter Reinholdtsen 222c18ec02fSPetter Reinholdtsen printf("Channel number : %d\n", 223c18ec02fSPetter Reinholdtsen auth_cap.channel_number); 224c18ec02fSPetter Reinholdtsen printf("IPMI v1.5 auth types : %s\n", 225c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); 226c18ec02fSPetter Reinholdtsen 227a87b2cccSZdenek Styblik if (auth_cap.v20_data_available) { 228c18ec02fSPetter Reinholdtsen printf("KG status : %s\n", 229c18ec02fSPetter Reinholdtsen (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); 230a87b2cccSZdenek Styblik } 231c18ec02fSPetter Reinholdtsen 232c18ec02fSPetter Reinholdtsen printf("Per message authentication : %sabled\n", 233c18ec02fSPetter Reinholdtsen (auth_cap.per_message_auth) ? "dis" : "en"); 234c18ec02fSPetter Reinholdtsen printf("User level authentication : %sabled\n", 235c18ec02fSPetter Reinholdtsen (auth_cap.user_level_auth) ? "dis" : "en"); 236c18ec02fSPetter Reinholdtsen 237c18ec02fSPetter Reinholdtsen printf("Non-null user names exist : %s\n", 238c18ec02fSPetter Reinholdtsen (auth_cap.non_null_usernames) ? "yes" : "no"); 239c18ec02fSPetter Reinholdtsen printf("Null user names exist : %s\n", 240c18ec02fSPetter Reinholdtsen (auth_cap.null_usernames) ? "yes" : "no"); 241c18ec02fSPetter Reinholdtsen printf("Anonymous login enabled : %s\n", 242c18ec02fSPetter Reinholdtsen (auth_cap.anon_login_enabled) ? "yes" : "no"); 243c18ec02fSPetter Reinholdtsen 244c18ec02fSPetter Reinholdtsen if (auth_cap.v20_data_available) { 245c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v1.5 : %s\n", 246c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv15_support) ? "yes" : "no"); 247c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v2.0 : %s\n", 248c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv20_support) ? "yes" : "no"); 249c18ec02fSPetter Reinholdtsen } 250c18ec02fSPetter Reinholdtsen 251c18ec02fSPetter Reinholdtsen /* 252c18ec02fSPetter Reinholdtsen * If there is support for an OEM authentication type, there is some 253c18ec02fSPetter Reinholdtsen * information. 254c18ec02fSPetter Reinholdtsen */ 255c18ec02fSPetter Reinholdtsen if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) { 256c18ec02fSPetter Reinholdtsen printf("IANA Number for OEM : %d\n", 257c18ec02fSPetter Reinholdtsen auth_cap.oem_id[0] | 258c18ec02fSPetter Reinholdtsen auth_cap.oem_id[1] << 8 | 259c18ec02fSPetter Reinholdtsen auth_cap.oem_id[2] << 16); 260c18ec02fSPetter Reinholdtsen printf("OEM Auxiliary Data : 0x%x\n", 261c18ec02fSPetter Reinholdtsen auth_cap.oem_aux_data); 262c18ec02fSPetter Reinholdtsen } 263c18ec02fSPetter Reinholdtsen 264c18ec02fSPetter Reinholdtsen return 0; 265c18ec02fSPetter Reinholdtsen } 266c18ec02fSPetter Reinholdtsen 267c18ec02fSPetter Reinholdtsen /** 268c18ec02fSPetter Reinholdtsen * ipmi_get_channel_info 269c18ec02fSPetter Reinholdtsen * 270c18ec02fSPetter Reinholdtsen * returns 0 on success 271c18ec02fSPetter Reinholdtsen * -1 on failure 272c18ec02fSPetter Reinholdtsen * 273c18ec02fSPetter Reinholdtsen */ 274c18ec02fSPetter Reinholdtsen int 275c18ec02fSPetter Reinholdtsen ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) 276c18ec02fSPetter Reinholdtsen { 27756aa025dSZdenek Styblik struct channel_info_t channel_info = {0}; 27856aa025dSZdenek Styblik struct channel_access_t channel_access = {0}; 27956aa025dSZdenek Styblik int ccode = 0; 280c18ec02fSPetter Reinholdtsen 28156aa025dSZdenek Styblik channel_info.channel = channel; 28256aa025dSZdenek Styblik ccode = _ipmi_get_channel_info(intf, &channel_info); 28356aa025dSZdenek Styblik if (eval_ccode(ccode) != 0) { 284c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Info"); 28556aa025dSZdenek Styblik return (-1); 286c18ec02fSPetter Reinholdtsen } 287c18ec02fSPetter Reinholdtsen 28856aa025dSZdenek Styblik printf("Channel 0x%x info:\n", channel_info.channel); 289c18ec02fSPetter Reinholdtsen printf(" Channel Medium Type : %s\n", 29056aa025dSZdenek Styblik val2str(channel_info.medium, 29156aa025dSZdenek Styblik ipmi_channel_medium_vals)); 292c18ec02fSPetter Reinholdtsen printf(" Channel Protocol Type : %s\n", 29356aa025dSZdenek Styblik val2str(channel_info.protocol, 29456aa025dSZdenek Styblik ipmi_channel_protocol_vals)); 295c18ec02fSPetter Reinholdtsen printf(" Session Support : "); 296c18ec02fSPetter Reinholdtsen switch (channel_info.session_support) { 29756aa025dSZdenek Styblik case IPMI_CHANNEL_SESSION_LESS: 298c18ec02fSPetter Reinholdtsen printf("session-less\n"); 299c18ec02fSPetter Reinholdtsen break; 30056aa025dSZdenek Styblik case IPMI_CHANNEL_SESSION_SINGLE: 301c18ec02fSPetter Reinholdtsen printf("single-session\n"); 302c18ec02fSPetter Reinholdtsen break; 30356aa025dSZdenek Styblik case IPMI_CHANNEL_SESSION_MULTI: 304c18ec02fSPetter Reinholdtsen printf("multi-session\n"); 305c18ec02fSPetter Reinholdtsen break; 30656aa025dSZdenek Styblik case IPMI_CHANNEL_SESSION_BASED: 307c18ec02fSPetter Reinholdtsen printf("session-based\n"); 308c18ec02fSPetter Reinholdtsen break; 30956aa025dSZdenek Styblik default: 31056aa025dSZdenek Styblik printf("unknown\n"); 31156aa025dSZdenek Styblik break; 312c18ec02fSPetter Reinholdtsen } 313c18ec02fSPetter Reinholdtsen printf(" Active Session Count : %d\n", 314c18ec02fSPetter Reinholdtsen channel_info.active_sessions); 315c18ec02fSPetter Reinholdtsen printf(" Protocol Vendor ID : %d\n", 316c18ec02fSPetter Reinholdtsen channel_info.vendor_id[0] | 317c18ec02fSPetter Reinholdtsen channel_info.vendor_id[1] << 8 | 318c18ec02fSPetter Reinholdtsen channel_info.vendor_id[2] << 16); 319c18ec02fSPetter Reinholdtsen 320c18ec02fSPetter Reinholdtsen /* only proceed if this is LAN channel */ 32156aa025dSZdenek Styblik if (channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN 32256aa025dSZdenek Styblik && channel_info.medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { 323c18ec02fSPetter Reinholdtsen return 0; 324c18ec02fSPetter Reinholdtsen } 325c18ec02fSPetter Reinholdtsen 32656aa025dSZdenek Styblik channel_access.channel = channel_info.channel; 32756aa025dSZdenek Styblik ccode = _ipmi_get_channel_access(intf, &channel_access, 1); 32856aa025dSZdenek Styblik if (eval_ccode(ccode) != 0) { 329c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)"); 33056aa025dSZdenek Styblik return (-1); 331c18ec02fSPetter Reinholdtsen } 332c18ec02fSPetter Reinholdtsen 333c18ec02fSPetter Reinholdtsen printf(" Volatile(active) Settings\n"); 334c18ec02fSPetter Reinholdtsen printf(" Alerting : %sabled\n", 335c18ec02fSPetter Reinholdtsen (channel_access.alerting) ? "dis" : "en"); 336c18ec02fSPetter Reinholdtsen printf(" Per-message Auth : %sabled\n", 337c18ec02fSPetter Reinholdtsen (channel_access.per_message_auth) ? "dis" : "en"); 338c18ec02fSPetter Reinholdtsen printf(" User Level Auth : %sabled\n", 339c18ec02fSPetter Reinholdtsen (channel_access.user_level_auth) ? "dis" : "en"); 340c18ec02fSPetter Reinholdtsen printf(" Access Mode : "); 341c18ec02fSPetter Reinholdtsen switch (channel_access.access_mode) { 342c18ec02fSPetter Reinholdtsen case 0: 343c18ec02fSPetter Reinholdtsen printf("disabled\n"); 344c18ec02fSPetter Reinholdtsen break; 345c18ec02fSPetter Reinholdtsen case 1: 346c18ec02fSPetter Reinholdtsen printf("pre-boot only\n"); 347c18ec02fSPetter Reinholdtsen break; 348c18ec02fSPetter Reinholdtsen case 2: 349c18ec02fSPetter Reinholdtsen printf("always available\n"); 350c18ec02fSPetter Reinholdtsen break; 351c18ec02fSPetter Reinholdtsen case 3: 352c18ec02fSPetter Reinholdtsen printf("shared\n"); 353c18ec02fSPetter Reinholdtsen break; 354c18ec02fSPetter Reinholdtsen default: 355c18ec02fSPetter Reinholdtsen printf("unknown\n"); 356c18ec02fSPetter Reinholdtsen break; 357c18ec02fSPetter Reinholdtsen } 358c18ec02fSPetter Reinholdtsen 35956aa025dSZdenek Styblik memset(&channel_access, 0, sizeof(channel_access)); 36056aa025dSZdenek Styblik channel_access.channel = channel_info.channel; 361c18ec02fSPetter Reinholdtsen /* get non-volatile settings */ 36256aa025dSZdenek Styblik ccode = _ipmi_get_channel_access(intf, &channel_access, 0); 36356aa025dSZdenek Styblik if (eval_ccode(ccode) != 0) { 364c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)"); 36556aa025dSZdenek Styblik return (-1); 366c18ec02fSPetter Reinholdtsen } 367c18ec02fSPetter Reinholdtsen 368c18ec02fSPetter Reinholdtsen printf(" Non-Volatile Settings\n"); 369c18ec02fSPetter Reinholdtsen printf(" Alerting : %sabled\n", 370c18ec02fSPetter Reinholdtsen (channel_access.alerting) ? "dis" : "en"); 371c18ec02fSPetter Reinholdtsen printf(" Per-message Auth : %sabled\n", 372c18ec02fSPetter Reinholdtsen (channel_access.per_message_auth) ? "dis" : "en"); 373c18ec02fSPetter Reinholdtsen printf(" User Level Auth : %sabled\n", 374c18ec02fSPetter Reinholdtsen (channel_access.user_level_auth) ? "dis" : "en"); 375c18ec02fSPetter Reinholdtsen printf(" Access Mode : "); 376c18ec02fSPetter Reinholdtsen switch (channel_access.access_mode) { 377c18ec02fSPetter Reinholdtsen case 0: 378c18ec02fSPetter Reinholdtsen printf("disabled\n"); 379c18ec02fSPetter Reinholdtsen break; 380c18ec02fSPetter Reinholdtsen case 1: 381c18ec02fSPetter Reinholdtsen printf("pre-boot only\n"); 382c18ec02fSPetter Reinholdtsen break; 383c18ec02fSPetter Reinholdtsen case 2: 384c18ec02fSPetter Reinholdtsen printf("always available\n"); 385c18ec02fSPetter Reinholdtsen break; 386c18ec02fSPetter Reinholdtsen case 3: 387c18ec02fSPetter Reinholdtsen printf("shared\n"); 388c18ec02fSPetter Reinholdtsen break; 389c18ec02fSPetter Reinholdtsen default: 390c18ec02fSPetter Reinholdtsen printf("unknown\n"); 391c18ec02fSPetter Reinholdtsen break; 392c18ec02fSPetter Reinholdtsen } 393c18ec02fSPetter Reinholdtsen return 0; 394c18ec02fSPetter Reinholdtsen } 395c18ec02fSPetter Reinholdtsen 396585cb7c8SZdenek Styblik /* ipmi_get_user_access - Get User Access for given Channel and User or Users. 397585cb7c8SZdenek Styblik * 398585cb7c8SZdenek Styblik * @intf - IPMI interface 399585cb7c8SZdenek Styblik * @channel - IPMI Channel we're getting access for 40069f66830SZdenek Styblik * @user_id - User ID. If 0 is passed, all IPMI users will be listed 401585cb7c8SZdenek Styblik * 402585cb7c8SZdenek Styblik * returns - 0 on success, (-1) on error 403585cb7c8SZdenek Styblik */ 404c18ec02fSPetter Reinholdtsen static int 40569f66830SZdenek Styblik ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id) 406c18ec02fSPetter Reinholdtsen { 407e4be291cSZdenek Styblik struct user_access_t user_access; 408e4be291cSZdenek Styblik struct user_name_t user_name; 409e4be291cSZdenek Styblik int ccode = 0; 410a87b2cccSZdenek Styblik int curr_uid; 411a87b2cccSZdenek Styblik int init = 1; 412e4be291cSZdenek Styblik int max_uid = 0; 413c18ec02fSPetter Reinholdtsen 41469f66830SZdenek Styblik curr_uid = user_id ? user_id : 1; 415a87b2cccSZdenek Styblik do { 416e4be291cSZdenek Styblik memset(&user_access, 0, sizeof(user_access)); 417e4be291cSZdenek Styblik user_access.channel = channel; 418e4be291cSZdenek Styblik user_access.user_id = curr_uid; 419e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 420e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 421e4be291cSZdenek Styblik lprintf(LOG_ERR, 422e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 423e4be291cSZdenek Styblik channel, curr_uid); 424e4be291cSZdenek Styblik return (-1); 425c18ec02fSPetter Reinholdtsen } 426c18ec02fSPetter Reinholdtsen 427e4be291cSZdenek Styblik memset(&user_name, 0, sizeof(user_name)); 428e4be291cSZdenek Styblik user_name.user_id = curr_uid; 429e4be291cSZdenek Styblik ccode = _ipmi_get_user_name(intf, &user_name); 430e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 431e4be291cSZdenek Styblik lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); 432e4be291cSZdenek Styblik return (-1); 433c18ec02fSPetter Reinholdtsen } 434c18ec02fSPetter Reinholdtsen if (init) { 435c18ec02fSPetter Reinholdtsen printf("Maximum User IDs : %d\n", user_access.max_user_ids); 436c18ec02fSPetter Reinholdtsen printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 437c18ec02fSPetter Reinholdtsen max_uid = user_access.max_user_ids; 438c18ec02fSPetter Reinholdtsen init = 0; 439c18ec02fSPetter Reinholdtsen } 440c18ec02fSPetter Reinholdtsen 441c18ec02fSPetter Reinholdtsen printf("\n"); 442c18ec02fSPetter Reinholdtsen printf("User ID : %d\n", curr_uid); 443e4be291cSZdenek Styblik printf("User Name : %s\n", user_name.user_name); 444c18ec02fSPetter Reinholdtsen printf("Fixed Name : %s\n", 445c18ec02fSPetter Reinholdtsen (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 446c18ec02fSPetter Reinholdtsen printf("Access Available : %s\n", 447c18ec02fSPetter Reinholdtsen (user_access.callin_callback) ? "callback" : "call-in / callback"); 448c18ec02fSPetter Reinholdtsen printf("Link Authentication : %sabled\n", 449c18ec02fSPetter Reinholdtsen (user_access.link_auth) ? "en" : "dis"); 450c18ec02fSPetter Reinholdtsen printf("IPMI Messaging : %sabled\n", 451c18ec02fSPetter Reinholdtsen (user_access.ipmi_messaging) ? "en" : "dis"); 452c18ec02fSPetter Reinholdtsen printf("Privilege Level : %s\n", 453c18ec02fSPetter Reinholdtsen val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 454c18ec02fSPetter Reinholdtsen 455c18ec02fSPetter Reinholdtsen curr_uid ++; 45669f66830SZdenek Styblik } while (!user_id && curr_uid <= max_uid); 457c18ec02fSPetter Reinholdtsen 458c18ec02fSPetter Reinholdtsen return 0; 459c18ec02fSPetter Reinholdtsen } 460c18ec02fSPetter Reinholdtsen 461c18ec02fSPetter Reinholdtsen static const char * 462c18ec02fSPetter Reinholdtsen iana_string(uint32_t iana) 463c18ec02fSPetter Reinholdtsen { 464c18ec02fSPetter Reinholdtsen static char s[10]; 465c18ec02fSPetter Reinholdtsen 466a87b2cccSZdenek Styblik if (iana) { 467c18ec02fSPetter Reinholdtsen sprintf(s, "%06x", iana); 468c18ec02fSPetter Reinholdtsen return s; 469a87b2cccSZdenek Styblik } else { 470c18ec02fSPetter Reinholdtsen return "N/A"; 471c18ec02fSPetter Reinholdtsen } 472a87b2cccSZdenek Styblik } 473c18ec02fSPetter Reinholdtsen 474c18ec02fSPetter Reinholdtsen 475c18ec02fSPetter Reinholdtsen static int 476a87b2cccSZdenek Styblik ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 477c18ec02fSPetter Reinholdtsen uint8_t channel) 478c18ec02fSPetter Reinholdtsen { 479c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 480c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 481c18ec02fSPetter Reinholdtsen 482c18ec02fSPetter Reinholdtsen uint8_t rqdata[3]; 483c18ec02fSPetter Reinholdtsen uint32_t iana; 484c18ec02fSPetter Reinholdtsen uint8_t auth_alg, integrity_alg, crypt_alg; 485c18ec02fSPetter Reinholdtsen uint8_t cipher_suite_id; 486c18ec02fSPetter Reinholdtsen uint8_t list_index = 0; 487a87b2cccSZdenek Styblik /* 0x40 sets * 16 bytes per set */ 488a87b2cccSZdenek Styblik uint8_t cipher_suite_data[1024]; 489c18ec02fSPetter Reinholdtsen uint16_t offset = 0; 490a87b2cccSZdenek Styblik /* how much was returned, total */ 491a87b2cccSZdenek Styblik uint16_t cipher_suite_data_length = 0; 492c18ec02fSPetter Reinholdtsen 493c18ec02fSPetter Reinholdtsen memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 494c18ec02fSPetter Reinholdtsen 495c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 496a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 497a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 498c18ec02fSPetter Reinholdtsen req.msg.data = rqdata; 499c18ec02fSPetter Reinholdtsen req.msg.data_len = 3; 500c18ec02fSPetter Reinholdtsen 501c18ec02fSPetter Reinholdtsen rqdata[0] = channel; 502c18ec02fSPetter Reinholdtsen rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 503a87b2cccSZdenek Styblik /* Always ask for cipher suite format */ 504a87b2cccSZdenek Styblik rqdata[2] = 0x80; 505c18ec02fSPetter Reinholdtsen 506c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 507c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 508c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 509c18ec02fSPetter Reinholdtsen return -1; 510c18ec02fSPetter Reinholdtsen } 511c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 512c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 513c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 514c18ec02fSPetter Reinholdtsen return -1; 515c18ec02fSPetter Reinholdtsen } 516c18ec02fSPetter Reinholdtsen 517c18ec02fSPetter Reinholdtsen 518a87b2cccSZdenek Styblik /* 519a87b2cccSZdenek Styblik * Grab the returned channel number once. We assume it's the same 520a87b2cccSZdenek Styblik * in future calls. 521a87b2cccSZdenek Styblik */ 522a87b2cccSZdenek Styblik if (rsp->data_len >= 1) { 523c18ec02fSPetter Reinholdtsen channel = rsp->data[0]; 524a87b2cccSZdenek Styblik } 525c18ec02fSPetter Reinholdtsen 526a87b2cccSZdenek Styblik while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 527a87b2cccSZdenek Styblik /* 528a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 529a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 530a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 531a87b2cccSZdenek Styblik */ 532c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 533c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 534c18ec02fSPetter Reinholdtsen 535a87b2cccSZdenek Styblik /* 536a87b2cccSZdenek Styblik * Increment our list for the next call 537a87b2cccSZdenek Styblik */ 538c18ec02fSPetter Reinholdtsen ++list_index; 539c18ec02fSPetter Reinholdtsen rqdata[2] = (rqdata[2] & 0x80) + list_index; 540c18ec02fSPetter Reinholdtsen 541c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 542c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 543c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 544c18ec02fSPetter Reinholdtsen return -1; 545c18ec02fSPetter Reinholdtsen } 546c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 547c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 548c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 549c18ec02fSPetter Reinholdtsen return -1; 550c18ec02fSPetter Reinholdtsen } 551c18ec02fSPetter Reinholdtsen } 552c18ec02fSPetter Reinholdtsen 553c18ec02fSPetter Reinholdtsen /* Copy last chunk */ 554a87b2cccSZdenek Styblik if(rsp->data_len > 1) { 555a87b2cccSZdenek Styblik /* 556a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 557a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 558a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 559a87b2cccSZdenek Styblik */ 560c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 561c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 562c18ec02fSPetter Reinholdtsen } 563c18ec02fSPetter Reinholdtsen 564a87b2cccSZdenek Styblik /* We can chomp on all our data now. */ 565c18ec02fSPetter Reinholdtsen cipher_suite_data_length = offset; 566c18ec02fSPetter Reinholdtsen offset = 0; 567c18ec02fSPetter Reinholdtsen 568a87b2cccSZdenek Styblik if (! csv_output) { 569c18ec02fSPetter Reinholdtsen printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 570a87b2cccSZdenek Styblik } 571a87b2cccSZdenek Styblik while (offset < cipher_suite_data_length) { 572a87b2cccSZdenek Styblik if (cipher_suite_data[offset++] == 0xC0) { 573a87b2cccSZdenek Styblik /* standard type */ 574c18ec02fSPetter Reinholdtsen iana = 0; 575c18ec02fSPetter Reinholdtsen 576a87b2cccSZdenek Styblik /* Verify that we have at least a full record left; id + 3 algs */ 577a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 578a87b2cccSZdenek Styblik lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 579a87b2cccSZdenek Styblik return -1; 580a87b2cccSZdenek Styblik } 581a87b2cccSZdenek Styblik cipher_suite_id = cipher_suite_data[offset++]; 582a87b2cccSZdenek Styblik } else if (cipher_suite_data[offset++] == 0xC1) { 583a87b2cccSZdenek Styblik /* OEM record type */ 584a87b2cccSZdenek Styblik /* Verify that we have at least a full record left 585a87b2cccSZdenek Styblik * id + iana + 3 algs 586a87b2cccSZdenek Styblik */ 587a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 588c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 589c18ec02fSPetter Reinholdtsen return -1; 590c18ec02fSPetter Reinholdtsen } 591c18ec02fSPetter Reinholdtsen 592c18ec02fSPetter Reinholdtsen cipher_suite_id = cipher_suite_data[offset++]; 593c18ec02fSPetter Reinholdtsen 594a87b2cccSZdenek Styblik /* Grab the IANA */ 595c18ec02fSPetter Reinholdtsen iana = 596c18ec02fSPetter Reinholdtsen cipher_suite_data[offset] | 597c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 1] << 8) | 598c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 2] << 16); 599c18ec02fSPetter Reinholdtsen offset += 3; 600a87b2cccSZdenek Styblik } else { 601c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 602c18ec02fSPetter Reinholdtsen return -1; 603c18ec02fSPetter Reinholdtsen } 604c18ec02fSPetter Reinholdtsen 605a87b2cccSZdenek Styblik /* 606a87b2cccSZdenek Styblik * Grab the algorithms for this cipher suite. I guess we can't be 607a87b2cccSZdenek Styblik * sure of what order they'll come in. Also, I suppose we default 608a87b2cccSZdenek Styblik * to the NONE algorithm if one were absent. This part of the spec is 609a87b2cccSZdenek Styblik * poorly written -- I have read the errata document. For now, I'm only 610a87b2cccSZdenek Styblik * allowing one algorithm per type (auth, integrity, crypt) because I 611a87b2cccSZdenek Styblik * don't I understand how it could be otherwise. 612a87b2cccSZdenek Styblik */ 613c18ec02fSPetter Reinholdtsen auth_alg = IPMI_AUTH_RAKP_NONE; 614c18ec02fSPetter Reinholdtsen integrity_alg = IPMI_INTEGRITY_NONE; 615c18ec02fSPetter Reinholdtsen crypt_alg = IPMI_CRYPT_NONE; 616c18ec02fSPetter Reinholdtsen 617c18ec02fSPetter Reinholdtsen while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 618c18ec02fSPetter Reinholdtsen ((cipher_suite_data_length - offset) > 0)) 619c18ec02fSPetter Reinholdtsen { 620c18ec02fSPetter Reinholdtsen switch (cipher_suite_data[offset] & 0xC0) 621c18ec02fSPetter Reinholdtsen { 622c18ec02fSPetter Reinholdtsen case 0x00: 623a87b2cccSZdenek Styblik /* Authentication algorithm specifier */ 624c18ec02fSPetter Reinholdtsen auth_alg = cipher_suite_data[offset++] & 0x3F; 625c18ec02fSPetter Reinholdtsen break; 626c18ec02fSPetter Reinholdtsen case 0x40: 627a87b2cccSZdenek Styblik /* Interity algorithm specifier */ 628c18ec02fSPetter Reinholdtsen integrity_alg = cipher_suite_data[offset++] & 0x3F; 629c18ec02fSPetter Reinholdtsen break; 630c18ec02fSPetter Reinholdtsen case 0x80: 631a87b2cccSZdenek Styblik /* Confidentiality algorithm specifier */ 632c18ec02fSPetter Reinholdtsen crypt_alg = cipher_suite_data[offset++] & 0x3F; 633c18ec02fSPetter Reinholdtsen break; 634c18ec02fSPetter Reinholdtsen } 635c18ec02fSPetter Reinholdtsen } 636a87b2cccSZdenek Styblik /* We have everything we need to spit out a cipher suite record */ 637c18ec02fSPetter Reinholdtsen printf((csv_output? "%d,%s,%s,%s,%s\n" : 638c18ec02fSPetter Reinholdtsen "%-4d %-7s %-15s %-15s %-15s\n"), 639c18ec02fSPetter Reinholdtsen cipher_suite_id, 640c18ec02fSPetter Reinholdtsen iana_string(iana), 641c18ec02fSPetter Reinholdtsen val2str(auth_alg, ipmi_auth_algorithms), 642c18ec02fSPetter Reinholdtsen val2str(integrity_alg, ipmi_integrity_algorithms), 643c18ec02fSPetter Reinholdtsen val2str(crypt_alg, ipmi_encryption_algorithms)); 644c18ec02fSPetter Reinholdtsen } 645c18ec02fSPetter Reinholdtsen return 0; 646c18ec02fSPetter Reinholdtsen } 647c18ec02fSPetter Reinholdtsen 648c18ec02fSPetter Reinholdtsen uint8_t 649c18ec02fSPetter Reinholdtsen ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 650c18ec02fSPetter Reinholdtsen { 6510801b458SZdenek Styblik struct channel_info_t channel_info = {0}; 6520801b458SZdenek Styblik int ccode = 0; 653c18ec02fSPetter Reinholdtsen 6540801b458SZdenek Styblik channel_info.channel = channel; 6550801b458SZdenek Styblik ccode = _ipmi_get_channel_info(intf, &channel_info); 656*6b8d55d6SZdenek Styblik if (ccode == 0xCC) { 6570801b458SZdenek Styblik return IPMI_CHANNEL_MEDIUM_RESERVED; 658*6b8d55d6SZdenek Styblik } else if (ccode < 0 && eval_ccode(ccode) != 0) { 659*6b8d55d6SZdenek Styblik return 0; 660*6b8d55d6SZdenek Styblik } else if (ccode > 0) { 6610801b458SZdenek Styblik lprintf(LOG_ERR, "Get Channel Info command failed: %s", 6620801b458SZdenek Styblik val2str(ccode, completion_code_vals)); 663c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 664a87b2cccSZdenek Styblik } 665c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "Channel type: %s", 6660801b458SZdenek Styblik val2str(channel_info.medium, ipmi_channel_medium_vals)); 6670801b458SZdenek Styblik return channel_info.medium; 668c18ec02fSPetter Reinholdtsen } 669c18ec02fSPetter Reinholdtsen 670c18ec02fSPetter Reinholdtsen uint8_t 671c18ec02fSPetter Reinholdtsen ipmi_current_channel_medium(struct ipmi_intf *intf) 672c18ec02fSPetter Reinholdtsen { 673c18ec02fSPetter Reinholdtsen return ipmi_get_channel_medium(intf, 0xE); 674c18ec02fSPetter Reinholdtsen } 675c18ec02fSPetter Reinholdtsen 676585cb7c8SZdenek Styblik /* printf_channel_usage - print-out help. */ 677c18ec02fSPetter Reinholdtsen void 678c18ec02fSPetter Reinholdtsen printf_channel_usage() 679c18ec02fSPetter Reinholdtsen { 680a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 681a87b2cccSZdenek Styblik "Channel Commands: authcap <channel number> <max privilege>"); 682a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 683a87b2cccSZdenek Styblik " getaccess <channel number> [user id]"); 684a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 685a87b2cccSZdenek Styblik " setaccess <channel number> " 686c18ec02fSPetter Reinholdtsen "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 687a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 688a87b2cccSZdenek Styblik " info [channel number]"); 689a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 690a87b2cccSZdenek Styblik " getciphers <ipmi | sol> [channel]"); 691a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 692a87b2cccSZdenek Styblik ""); 693a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 694a87b2cccSZdenek Styblik "Possible privilege levels are:"); 695a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 696a87b2cccSZdenek Styblik " 1 Callback level"); 697a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 698a87b2cccSZdenek Styblik " 2 User level"); 699a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 700a87b2cccSZdenek Styblik " 3 Operator level"); 701a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 702a87b2cccSZdenek Styblik " 4 Administrator level"); 703a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 704a87b2cccSZdenek Styblik " 5 OEM Proprietary level"); 705a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 706a87b2cccSZdenek Styblik " 15 No access"); 707c18ec02fSPetter Reinholdtsen } 708c18ec02fSPetter Reinholdtsen 709585cb7c8SZdenek Styblik /* ipmi_set_user_access - Query BMC for current Channel ACLs, parse CLI args 710585cb7c8SZdenek Styblik * and update current ACLs. 711585cb7c8SZdenek Styblik * 712585cb7c8SZdenek Styblik * returns - 0 on success, (-1) on error 713585cb7c8SZdenek Styblik */ 714e4be291cSZdenek Styblik int 715e4be291cSZdenek Styblik ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) 716e4be291cSZdenek Styblik { 717e4be291cSZdenek Styblik struct user_access_t user_access = {0}; 718e4be291cSZdenek Styblik int ccode = 0; 719e4be291cSZdenek Styblik int i = 0; 720e4be291cSZdenek Styblik uint8_t channel = 0; 721e4be291cSZdenek Styblik uint8_t priv = 0; 722e4be291cSZdenek Styblik uint8_t user_id = 0; 723e4be291cSZdenek Styblik if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 724e4be291cSZdenek Styblik printf_channel_usage(); 725e4be291cSZdenek Styblik return 0; 726e4be291cSZdenek Styblik } else if (argc < 3) { 727e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 728e4be291cSZdenek Styblik printf_channel_usage(); 729e4be291cSZdenek Styblik return (-1); 730e4be291cSZdenek Styblik } 731e4be291cSZdenek Styblik if (is_ipmi_channel_num(argv[0], &channel) != 0 732e4be291cSZdenek Styblik || is_ipmi_user_id(argv[1], &user_id) != 0) { 733e4be291cSZdenek Styblik return (-1); 734e4be291cSZdenek Styblik } 735e4be291cSZdenek Styblik user_access.channel = channel; 736e4be291cSZdenek Styblik user_access.user_id = user_id; 737e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 738e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 739e4be291cSZdenek Styblik lprintf(LOG_ERR, 740e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 741e4be291cSZdenek Styblik channel, user_id); 742e4be291cSZdenek Styblik return (-1); 743e4be291cSZdenek Styblik } 744e4be291cSZdenek Styblik for (i = 3; i < argc; i ++) { 745e4be291cSZdenek Styblik if (strncmp(argv[i], "callin=", 7) == 0) { 746e4be291cSZdenek Styblik if (strncmp(argv[i] + 7, "off", 3) == 0) { 747e4be291cSZdenek Styblik user_access.callin_callback = 1; 748e4be291cSZdenek Styblik } else { 749e4be291cSZdenek Styblik user_access.callin_callback = 0; 750e4be291cSZdenek Styblik } 751e4be291cSZdenek Styblik } else if (strncmp(argv[i], "link=", 5) == 0) { 752e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 753e4be291cSZdenek Styblik user_access.link_auth = 0; 754e4be291cSZdenek Styblik } else { 755e4be291cSZdenek Styblik user_access.link_auth = 1; 756e4be291cSZdenek Styblik } 757e4be291cSZdenek Styblik } else if (strncmp(argv[i], "ipmi=", 5) == 0) { 758e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 759e4be291cSZdenek Styblik user_access.ipmi_messaging = 0; 760e4be291cSZdenek Styblik } else { 761e4be291cSZdenek Styblik user_access.ipmi_messaging = 1; 762e4be291cSZdenek Styblik } 763e4be291cSZdenek Styblik } else if (strncmp(argv[i], "privilege=", 10) == 0) { 764e4be291cSZdenek Styblik if (str2uchar(argv[i] + 10, &priv) != 0) { 765e4be291cSZdenek Styblik lprintf(LOG_ERR, 766e4be291cSZdenek Styblik "Numeric value expected, but '%s' given.", 767e4be291cSZdenek Styblik argv[i] + 10); 768e4be291cSZdenek Styblik return (-1); 769e4be291cSZdenek Styblik } 770e4be291cSZdenek Styblik user_access.privilege_limit = priv; 771e4be291cSZdenek Styblik } else { 772e4be291cSZdenek Styblik lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); 773e4be291cSZdenek Styblik return (-1); 774e4be291cSZdenek Styblik } 775e4be291cSZdenek Styblik } 776708be8bcSZdenek Styblik ccode = _ipmi_set_user_access(intf, &user_access, 0); 777e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 778e4be291cSZdenek Styblik lprintf(LOG_ERR, 779e4be291cSZdenek Styblik "Unable to Set User Access (channel %d id %d)", 780e4be291cSZdenek Styblik channel, user_id); 781e4be291cSZdenek Styblik return (-1); 782e4be291cSZdenek Styblik } 783e4be291cSZdenek Styblik printf("Set User Access (channel %d id %d) successful.\n", 784e4be291cSZdenek Styblik channel, user_id); 785e4be291cSZdenek Styblik return 0; 786e4be291cSZdenek Styblik } 787c18ec02fSPetter Reinholdtsen 788c18ec02fSPetter Reinholdtsen int 789c18ec02fSPetter Reinholdtsen ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 790c18ec02fSPetter Reinholdtsen { 791c18ec02fSPetter Reinholdtsen int retval = 0; 792a87b2cccSZdenek Styblik uint8_t channel; 793a87b2cccSZdenek Styblik uint8_t priv = 0; 7940562c809SZdenek Styblik if (argc < 1) { 7950562c809SZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 796c18ec02fSPetter Reinholdtsen printf_channel_usage(); 7970562c809SZdenek Styblik return (-1); 7980562c809SZdenek Styblik } else if (strncmp(argv[0], "help", 4) == 0) { 7990562c809SZdenek Styblik printf_channel_usage(); 8000562c809SZdenek Styblik return 0; 801a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "authcap", 7) == 0) { 802c18ec02fSPetter Reinholdtsen if (argc != 3) { 803c18ec02fSPetter Reinholdtsen printf_channel_usage(); 804c18ec02fSPetter Reinholdtsen return (-1); 8050562c809SZdenek Styblik } 806140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0 807140add9dSZdenek Styblik || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 808c18ec02fSPetter Reinholdtsen return (-1); 809c18ec02fSPetter Reinholdtsen } 810c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_auth_cap(intf, channel, priv); 811a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getaccess", 10) == 0) { 812140add9dSZdenek Styblik uint8_t user_id = 0; 8130562c809SZdenek Styblik if ((argc < 2) || (argc > 3)) { 814e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 8150562c809SZdenek Styblik printf_channel_usage(); 8160562c809SZdenek Styblik return (-1); 8170562c809SZdenek Styblik } 818140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 819c18ec02fSPetter Reinholdtsen return (-1); 820c18ec02fSPetter Reinholdtsen } 821c18ec02fSPetter Reinholdtsen if (argc == 3) { 822140add9dSZdenek Styblik if (is_ipmi_user_id(argv[2], &user_id) != 0) { 823c18ec02fSPetter Reinholdtsen return (-1); 824c18ec02fSPetter Reinholdtsen } 825c18ec02fSPetter Reinholdtsen } 826140add9dSZdenek Styblik retval = ipmi_get_user_access(intf, channel, user_id); 827a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "setaccess", 9) == 0) { 828e4be291cSZdenek Styblik return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); 829a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "info", 4) == 0) { 830140add9dSZdenek Styblik channel = 0xE; 831a87b2cccSZdenek Styblik if (argc > 2) { 832c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8330562c809SZdenek Styblik return (-1); 8340562c809SZdenek Styblik } 835c18ec02fSPetter Reinholdtsen if (argc == 2) { 836140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 837c18ec02fSPetter Reinholdtsen return (-1); 838c18ec02fSPetter Reinholdtsen } 839c18ec02fSPetter Reinholdtsen } 840140add9dSZdenek Styblik retval = ipmi_get_channel_info(intf, channel); 841a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getciphers", 10) == 0) { 8420562c809SZdenek Styblik /* channel getciphers <ipmi|sol> [channel] */ 843140add9dSZdenek Styblik channel = 0xE; 844c18ec02fSPetter Reinholdtsen if ((argc < 2) || (argc > 3) || 845a87b2cccSZdenek Styblik (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 846c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8470562c809SZdenek Styblik return (-1); 8480562c809SZdenek Styblik } 849c18ec02fSPetter Reinholdtsen if (argc == 3) { 850140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 851c18ec02fSPetter Reinholdtsen return (-1); 852c18ec02fSPetter Reinholdtsen } 853c18ec02fSPetter Reinholdtsen } 854c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_cipher_suites(intf, 8550562c809SZdenek Styblik argv[1], /* ipmi | sol */ 856140add9dSZdenek Styblik channel); 857a87b2cccSZdenek Styblik } else { 858278dc84bSZdenek Styblik lprintf(LOG_ERR, "Invalid CHANNEL command: %s\n", argv[0]); 859c18ec02fSPetter Reinholdtsen printf_channel_usage(); 860c18ec02fSPetter Reinholdtsen retval = -1; 861c18ec02fSPetter Reinholdtsen } 862c18ec02fSPetter Reinholdtsen return retval; 863c18ec02fSPetter Reinholdtsen } 864