/* * Copyright (c) 2004 Dell Computers. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Dell Computers, or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * DELL COMPUTERS ("DELL") AND ITS LICENSORS SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL * DELL OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF DELL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include #include #include #include #include #include #include #include extern int verbose; /* // common kywd/value printf() templates */ static const char * pef_fld_fmts[][2] = { {"%-*s : %u\n", " | %u"}, /* F_DEC: unsigned value */ {"%-*s : %d\n", " | %d"}, /* F_INT: signed value */ {"%-*s : %s\n", " | %s"}, /* F_STR: string value */ {"%-*s : 0x%x\n", " | 0x%x"}, /* F_HEX: "N hex digits" */ {"%-*s : 0x%04x\n", " | 0x%04x"}, /* F_2XD: "2 hex digits" */ {"%-*s : 0x%02x\n", " | 0x%02x"}, /* F_1XD: "1 hex digit" */ {"%-*s : %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", " | %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"}, }; typedef enum { F_DEC, F_INT, F_STR, F_HEX, F_2XD, F_1XD, F_UID, } fmt_e; #define KYWD_LENGTH 24 static int first_field = 1; static const char * pef_flag_fmts[][3] = { {"", "false", "true"}, {"supported", "un", ""}, {"active", "in", ""}, {"abled", "dis", "en"}, }; static const char * listitem[] = {" | %s", ",%s", "%s"}; static int ipmi_pef2_list_filters(struct ipmi_intf *); const char * ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t value) { /* // return description/text label(s) for the given value. // NB: uses a static buffer */ static char buf[128]; char * p; struct desc_map * pmap; uint32_t match, index; *(p = buf) = '\0'; index = 2; for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) { if (map->desc_map_type == BIT_DESC_MAP_LIST) match = (value == pmap->mask); else match = ((value & pmap->mask) == pmap->mask); if (match) { sprintf(p, listitem[index], pmap->desc); p = strchr(p, '\0'); if (map->desc_map_type != BIT_DESC_MAP_ALL) break; index = 1; } } if (p == buf) return("None"); return((const char *)buf); } void ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val) { /* // print features/flags, using val (a bitmask), according to map. // observe the verbose flag, and print any labels, etc. based on type */ struct desc_map * pmap; uint32_t maskval, index; index = 0; for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) { maskval = (val & pmap->mask); if (verbose) printf("%-*s : %s%s\n", KYWD_LENGTH, ipmi_pef_bit_desc(map, pmap->mask), pef_flag_fmts[type][1 + (maskval != 0)], pef_flag_fmts[type][0]); else if (maskval != 0) { printf(listitem[index], ipmi_pef_bit_desc(map, maskval)); index = 1; } } } static void ipmi_pef_print_field(const char * fmt[2], const char * label, unsigned long val) { /* // print a 'field' (observes 'verbose' flag) */ if (verbose) printf(fmt[0], KYWD_LENGTH, label, val); else if (first_field) printf(&fmt[1][2], val); /* skip field separator */ else printf(fmt[1], val); first_field = 0; } void ipmi_pef_print_dec(const char * text, uint32_t val) { /* unsigned */ ipmi_pef_print_field(pef_fld_fmts[F_DEC], text, val); } void ipmi_pef_print_int(const char * text, uint32_t val) { /* signed */ ipmi_pef_print_field(pef_fld_fmts[F_INT], text, val); } void ipmi_pef_print_hex(const char * text, uint32_t val) { /* hex */ ipmi_pef_print_field(pef_fld_fmts[F_HEX], text, val); } void ipmi_pef_print_str(const char * text, const char * val) { /* string */ ipmi_pef_print_field(pef_fld_fmts[F_STR], text, (unsigned long)val); } void ipmi_pef_print_2xd(const char * text, uint8_t u1, uint8_t u2) { /* 2 hex digits */ uint32_t val = ((u1 << 8) + u2) & 0xffff; ipmi_pef_print_field(pef_fld_fmts[F_2XD], text, val); } void ipmi_pef_print_1xd(const char * text, uint32_t val) { /* 1 hex digit */ ipmi_pef_print_field(pef_fld_fmts[F_1XD], text, val); } /* ipmi_pef_print_guid - print-out GUID. */ static int ipmi_pef_print_guid(uint8_t *guid) { if (guid == NULL) { return (-1); } if (verbose) { printf("%-*s : %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", KYWD_LENGTH, "System GUID", guid[0], guid[1], guid[2], guid[3], guid[4], guid[5], guid[6], guid[7], guid[8], guid[9], guid[10],guid[11], guid[12], guid[13], guid[14], guid[15]); } else { printf(" | %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid[0], guid[1], guid[2], guid[3], guid[4], guid[5], guid[6], guid[7], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]); } return 0; } static struct ipmi_rs * ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt) { /* // common IPMItool rqst/resp handling */ struct ipmi_rs * rsp = intf->sendrecv(intf, req); if (!rsp) { return(NULL); } else if (rsp->ccode == 0x80) { return(NULL); /* Do not output error, just unsupported parameters */ } else if (rsp->ccode) { lprintf(LOG_ERR, " **Error %x in '%s' command", rsp->ccode, txt); return(NULL); } if (verbose > 2) { printbuf(rsp->data, rsp->data_len, txt); } return(rsp); } /* _ipmi_get_pef_capabilities - Requests and returns result of (30.1) Get PEF * Capabilities. * * @pcap - pointer where to store results. * * returns - negative number means error, positive is a ccode. */ int _ipmi_get_pef_capabilities(struct ipmi_intf *intf, struct pef_capabilities *pcap) { struct ipmi_rs *rsp; struct ipmi_rq req; if (pcap == NULL) { return (-3); } memset(pcap, 0, sizeof(struct pef_capabilities)); memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES; rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 3) { return (-2); } pcap->version = rsp->data[0]; pcap->actions = rsp->data[1]; pcap->event_filter_count = rsp->data[2]; return 0; } /* _ipmi_get_pef_filter_entry - Fetches one Entry from Event Filter Table * identified by Filter ID. * * @filter_id - Filter ID of Entry in Event Filter Table. * @filter_entry - Pointer where to copy Filter Entry data. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_get_pef_filter_entry(struct ipmi_intf *intf, uint8_t filter_id, struct pef_cfgparm_filter_table_entry *filter_entry) { struct ipmi_rs *rsp; struct ipmi_rq req; uint8_t data[3]; uint8_t data_len = 3 * sizeof(uint8_t); int dest_size; if (filter_entry == NULL) { return (-3); } dest_size = (int)sizeof(struct pef_cfgparm_filter_table_entry); memset(filter_entry, 0, dest_size); memset(&data, 0, data_len); data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY; data[1] = filter_id; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&data; req.msg.data_len = data_len; rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 22 || (rsp->data_len - 1) != dest_size) { return (-2); } memcpy(filter_entry, &rsp->data[1], dest_size); return 0; } /* _ipmi_get_pef_filter_entry_cfg - Fetches configuration of one Entry from * Event Filter Table identified by Filter ID. * * @filter_id - Filter ID of Entry in Event Filter Table. * @filter_entry_cfg - Pointer where to copy Filter Entry configuration. * * returns - negative number means error, positive is a ccode. */ int _ipmi_get_pef_filter_entry_cfg(struct ipmi_intf *intf, uint8_t filter_id, struct pef_cfgparm_filter_table_data_1 *filter_cfg) { struct ipmi_rs *rsp; struct ipmi_rq req; uint8_t data[3]; uint8_t data_len = 3 * sizeof(uint8_t); int dest_size; if (filter_cfg == NULL) { return (-3); } dest_size = (int)sizeof(struct pef_cfgparm_filter_table_data_1); memset(filter_cfg, 0, dest_size); memset(&data, 0, data_len); data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1; data[1] = filter_id; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&data; req.msg.data_len = data_len; rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 3 || (rsp->data_len - 1) != dest_size) { return (-2); } memcpy(filter_cfg, &rsp->data[1], dest_size); return 0; } /* _ipmi_get_pef_policy_entry - Fetches one Entry from Alert Policy Table * identified by Policy ID. * * @policy_id - Policy ID of Entry in Alert Policy Table. * @policy_entry - Pointer where to copy Policy Entry data. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_get_pef_policy_entry(struct ipmi_intf *intf, uint8_t policy_id, struct pef_cfgparm_policy_table_entry *policy_entry) { struct ipmi_rs *rsp; struct ipmi_rq req; uint8_t data[3]; uint8_t data_len = 3 * sizeof(uint8_t); int dest_size; if (policy_entry == NULL) { return (-3); } dest_size = (int)sizeof(struct pef_cfgparm_policy_table_entry); memset(policy_entry, 0, dest_size); memset(&data, 0, data_len); data[0] = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY; data[1] = policy_id & PEF_POLICY_TABLE_ID_MASK; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&data; req.msg.data_len = data_len; rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 5 || (rsp->data_len - 1) != dest_size) { return (-2); } memcpy(policy_entry, &rsp->data[1], dest_size); return 0; } /* _ipmi_get_pef_filter_table_size - Fetch the Number of Event Filter Entries. * If the number is 0, it means feature is not supported. * * @table_size - ptr to where to store number of entries. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_get_pef_filter_table_size(struct ipmi_intf *intf, uint8_t *table_size) { struct ipmi_rs *rsp; struct ipmi_rq req; struct pef_cfgparm_selector psel; if (table_size == NULL) { return (-3); } *table_size = 0; memset(&psel, 0, sizeof(psel)); psel.id = PEF_CFGPARM_ID_PEF_FILTER_TABLE_SIZE; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&psel; req.msg.data_len = sizeof(psel); rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 2) { return (-2); } *table_size = rsp->data[1] & 0x7F; return 0; } /* _ipmi_get_pef_policy_table_size - Fetch the Number of Alert Policy Entries. If the * number is 0, it means feature is not supported. * * @table_size - ptr to where to store number of entries. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_get_pef_policy_table_size(struct ipmi_intf *intf, uint8_t *table_size) { struct ipmi_rs *rsp; struct ipmi_rq req; struct pef_cfgparm_selector psel; if (table_size == NULL) { return (-3); } *table_size = 0; memset(&psel, 0, sizeof(psel)); psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&psel; req.msg.data_len = sizeof(psel); rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 2) { return (-2); } *table_size = rsp->data[1] & 0x7F; return 0; } /* _ipmi_get_pef_system_guid - Fetches System GUID from PEF. This configuration * parameter is optional. If data1 is 0x0, then this GUID is ignored by BMC. * * @system_guid - pointer where to store received data. * * returns - negative number means error, positive is a ccode. */ int _ipmi_get_pef_system_guid(struct ipmi_intf *intf, struct pef_cfgparm_system_guid *system_guid) { struct ipmi_rs *rsp; struct ipmi_rq req; struct pef_cfgparm_selector psel; if (system_guid == NULL) { return (-3); } memset(system_guid, 0, sizeof(struct pef_cfgparm_system_guid)); memset(&psel, 0, sizeof(psel)); psel.id = PEF_CFGPARM_ID_SYSTEM_GUID; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&psel; req.msg.data_len = sizeof(psel); rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } else if (rsp->data_len != 18 || (rsp->data_len - 2) != sizeof(system_guid->guid)) { return (-2); } system_guid->data1 = rsp->data[1] & 0x1; memcpy(system_guid->guid, &rsp->data[2], sizeof(system_guid->guid)); return 0; } /* _ipmi_set_pef_filter_entry_cfg - Sets/updates configuration of Entry in Event * Filter Table identified by Filter ID. * * @filter_id - ID of Entry in Event Filter Table to be updated * @filter_cfg - Pointer to configuration data. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_set_pef_filter_entry_cfg(struct ipmi_intf *intf, uint8_t filter_id, struct pef_cfgparm_filter_table_data_1 *filter_cfg) { struct ipmi_rs *rsp; struct ipmi_rq req; uint8_t data[3]; uint8_t data_len = 3 * sizeof(uint8_t); if (filter_cfg == NULL) { return (-3); } memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&data; req.msg.data_len = data_len; memset(&data, 0, data_len); data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1; data[1] = filter_id; data[2] = filter_cfg->cfg; rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } return 0; } /* _ipmi_set_pef_policy_entry - Sets/updates Entry in Alert Policy Table identified by * Policy ID. * * @policy_id - Policy ID of Entry in Alert Policy Table to be updated * @policy_entry - Pointer to data. * * returns - negative number means error, positive is a ccode. */ static int _ipmi_set_pef_policy_entry(struct ipmi_intf *intf, uint8_t policy_id, struct pef_cfgparm_policy_table_entry *policy_entry) { struct ipmi_rs *rsp; struct ipmi_rq req; struct pef_cfgparm_set_policy_table_entry payload; if (policy_entry == NULL) { return (-3); } memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&payload; req.msg.data_len = sizeof(payload); memset(&payload, 0, sizeof(payload)); payload.param_selector = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY; payload.policy_id = policy_id & PEF_POLICY_TABLE_ID_MASK; memcpy(&payload.entry, &policy_entry->entry, sizeof(policy_entry->entry)); rsp = intf->sendrecv(intf, &req); if (rsp == NULL) { return (-1); } else if (rsp->ccode != 0) { return rsp->ccode; } return 0; } static void ipmi_pef_print_oem_lan_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest) { char address[128]; int len; int rc; int rlen; int set; uint8_t data[32]; if (ipmi_get_oem(intf) != IPMI_OEM_DELL) { return; } /* Get # of IPV6 trap destinations */ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_COUNT, 0x00, 0x00, 4, data); if (rc != 0 || dest > data[0]) { return; } ipmi_pef_print_str("Alert destination type", "xxx"); ipmi_pef_print_str("PET Community", "xxx"); ipmi_pef_print_dec("ACK timeout/retry (secs)", 0); ipmi_pef_print_dec("Retries", 0); /* Get IPv6 destination string (may be in multiple sets) */ memset(address, 0, sizeof(address)); memset(data, 0, sizeof(data)); rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, 0x00, dest, 19, data); if (rc != 0) { return; } /* Total length of IPv6 string */ len = data[4]; if ((rlen = len) > (IPMI_SYSINFO_SET0_SIZE-3)) { /* First set has 11 bytes */ rlen = IPMI_SYSINFO_SET0_SIZE - 3; } memcpy(address, data + 8, rlen); for (set = 1; len > 11; set++) { rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, set, dest, 19, data); if ((rlen = len - 11) >= (IPMI_SYSINFO_SETN_SIZE - 2)) { /* Remaining sets have 14 bytes */ rlen = IPMI_SYSINFO_SETN_SIZE - 2; } memcpy(address + (set * 11), data + 3, rlen); len -= rlen+3; } ipmi_pef_print_str("IPv6 Address", address); } /* TODO - rewrite */ static void ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest) { /* // print LAN alert destination info */ struct ipmi_rs * rsp; struct ipmi_rq req; struct pef_lan_cfgparm_selector lsel; struct pef_lan_cfgparm_dest_type * ptype; struct pef_lan_cfgparm_dest_info * pinfo; char buf[32]; uint8_t dsttype, timeout, retries; memset(&lsel, 0, sizeof(lsel)); lsel.id = PEF_LAN_CFGPARM_ID_DEST_COUNT; lsel.ch = ch; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_TRANSPORT; req.msg.cmd = IPMI_CMD_LAN_GET_CONFIG; req.msg.data = (uint8_t *)&lsel; req.msg.data_len = sizeof(lsel); rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count"); if (!rsp) { lprintf(LOG_ERR, " **Error retrieving %s", "Alert destination count"); return; } lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE; lsel.set = dest; rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination type"); if (!rsp || rsp->data[1] != lsel.set) { lprintf(LOG_ERR, " **Error retrieving %s", "Alert destination type"); return; } ptype = (struct pef_lan_cfgparm_dest_type *)&rsp->data[1]; dsttype = (ptype->dest_type & PEF_LAN_DEST_TYPE_MASK); timeout = ptype->alert_timeout; retries = (ptype->retries & PEF_LAN_RETRIES_MASK); ipmi_pef_print_str("Alert destination type", ipmi_pef_bit_desc(&pef_b2s_lan_desttype, dsttype)); if (dsttype == PEF_LAN_DEST_TYPE_PET) { lsel.id = PEF_LAN_CFGPARM_ID_PET_COMMUNITY; lsel.set = 0; rsp = ipmi_pef_msg_exchange(intf, &req, "PET community"); if (!rsp) lprintf(LOG_ERR, " **Error retrieving %s", "PET community"); else { rsp->data[19] = '\0'; ipmi_pef_print_str("PET Community", (const char *)&rsp->data[1]); } } ipmi_pef_print_dec("ACK timeout/retry (secs)", timeout); ipmi_pef_print_dec("Retries", retries); lsel.id = PEF_LAN_CFGPARM_ID_DESTADDR; lsel.set = dest; rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info"); if (!rsp || rsp->data[1] != lsel.set) lprintf(LOG_ERR, " **Error retrieving %s", "Alert destination info"); else { pinfo = (struct pef_lan_cfgparm_dest_info *)&rsp->data[1]; sprintf(buf, "%u.%u.%u.%u", pinfo->ip[0], pinfo->ip[1], pinfo->ip[2], pinfo->ip[3]); ipmi_pef_print_str("IP address", buf); ipmi_pef_print_str("MAC address", mac2str(pinfo->mac)); } } static void ipmi_pef_print_serial_dest_dial(struct ipmi_intf *intf, char *label, struct pef_serial_cfgparm_selector *ssel) { /* // print a dial string */ #define BLOCK_SIZE 16 struct ipmi_rs * rsp; struct ipmi_rq req; struct pef_serial_cfgparm_selector tmp; char * p, strval[(6 * BLOCK_SIZE) + 1]; memset(&tmp, 0, sizeof(tmp)); tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING_COUNT; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_TRANSPORT; req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG; req.msg.data = (uint8_t *)&tmp; req.msg.data_len = sizeof(tmp); rsp = ipmi_pef_msg_exchange(intf, &req, "Dial string count"); if (!rsp || (rsp->data[1] & PEF_SERIAL_DIAL_STRING_COUNT_MASK) == 0) return; /* sssh, not supported */ memcpy(&tmp, ssel, sizeof(tmp)); tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING; tmp.block = 1; memset(strval, 0, sizeof(strval)); p = strval; for (;;) { rsp = ipmi_pef_msg_exchange(intf, &req, label); if (!rsp || (rsp->data[1] != ssel->id) || (rsp->data[2] != tmp.block)) { lprintf(LOG_ERR, " **Error retrieving %s", label); return; } memcpy(p, &rsp->data[3], BLOCK_SIZE); if (strchr(p, '\0') <= (p + BLOCK_SIZE)) break; if ((p += BLOCK_SIZE) >= &strval[sizeof(strval)-1]) break; tmp.block++; } ipmi_pef_print_str(label, strval); #undef BLOCK_SIZE } static void ipmi_pef_print_serial_dest_tap(struct ipmi_intf *intf, struct pef_serial_cfgparm_selector *ssel) { /* // print TAP destination info */ struct ipmi_rs * rsp; struct ipmi_rq req; struct pef_serial_cfgparm_selector tmp; struct pef_serial_cfgparm_tap_svc_settings * pset; uint8_t dialstr_id, setting_id; memset(&tmp, 0, sizeof(tmp)); tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_COUNT; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_TRANSPORT; req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG; req.msg.data = (uint8_t *)&tmp; req.msg.data_len = sizeof(tmp); rsp = ipmi_pef_msg_exchange(intf, &req, "Number of TAP accounts"); if (!rsp || (rsp->data[1] & PEF_SERIAL_TAP_ACCT_COUNT_MASK) == 0) return; /* sssh, not supported */ memcpy(&tmp, ssel, sizeof(tmp)); tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_INFO; rsp = ipmi_pef_msg_exchange(intf, &req, "TAP account info"); if (!rsp || (rsp->data[1] != tmp.set)) { lprintf(LOG_ERR, " **Error retrieving %s", "TAP account info"); return; } dialstr_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_MASK); dialstr_id >>= PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_SHIFT; setting_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_SVC_SETTINGS_ID_MASK); tmp.set = dialstr_id; ipmi_pef_print_serial_dest_dial(intf, "TAP Dial string", &tmp); tmp.set = setting_id; rsp = ipmi_pef_msg_exchange(intf, &req, "TAP service settings"); if (!rsp || (rsp->data[1] != tmp.set)) { lprintf(LOG_ERR, " **Error retrieving %s", "TAP service settings"); return; } pset = (struct pef_serial_cfgparm_tap_svc_settings *)&rsp->data[1]; ipmi_pef_print_str("TAP confirmation", ipmi_pef_bit_desc(&pef_b2s_tap_svc_confirm, pset->confirmation_flags)); /* TODO : additional TAP settings? */ } /* static void ipmi_pef_print_serial_dest_ppp(struct ipmi_intf *intf, struct pef_serial_cfgparm_selector *ssel) { } static void ipmi_pef_print_serial_dest_callback(struct ipmi_intf *intf, struct pef_serial_cfgparm_selector *ssel) } */ static void ipmi_pef_print_serial_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest) { /* // print Serial/PPP alert destination info */ struct ipmi_rs * rsp; struct ipmi_rq req; struct pef_serial_cfgparm_selector ssel; uint8_t tbl_size, wrk; struct pef_serial_cfgparm_dest_info * pinfo; memset(&ssel, 0, sizeof(ssel)); ssel.id = PEF_SERIAL_CFGPARM_ID_DEST_COUNT; ssel.ch = ch; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_TRANSPORT; req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG; req.msg.data = (uint8_t *)&ssel; req.msg.data_len = sizeof(ssel); rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count"); if (!rsp) { lprintf(LOG_ERR, " **Error retrieving %s", "Alert destination count"); return; } tbl_size = (rsp->data[1] & PEF_SERIAL_DEST_TABLE_SIZE_MASK); if (!dest || tbl_size == 0) /* Page alerting not supported */ return; if (dest > tbl_size) { ipmi_pef_print_oem_lan_dest(intf, ch, dest - tbl_size); return; } ssel.id = PEF_SERIAL_CFGPARM_ID_DESTINFO; ssel.set = dest; rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info"); if (!rsp || rsp->data[1] != ssel.set) lprintf(LOG_ERR, " **Error retrieving %s", "Alert destination info"); else { pinfo = (struct pef_serial_cfgparm_dest_info *)rsp->data; wrk = (pinfo->dest_type & PEF_SERIAL_DEST_TYPE_MASK); ipmi_pef_print_str("Alert destination type", ipmi_pef_bit_desc(&pef_b2s_serial_desttype, wrk)); ipmi_pef_print_dec("ACK timeout (secs)", pinfo->alert_timeout); ipmi_pef_print_dec("Retries", (pinfo->retries & PEF_SERIAL_RETRIES_MASK)); switch (wrk) { case PEF_SERIAL_DEST_TYPE_DIAL: ipmi_pef_print_serial_dest_dial(intf, "Serial dial string", &ssel); break; case PEF_SERIAL_DEST_TYPE_TAP: ipmi_pef_print_serial_dest_tap(intf, &ssel); break; case PEF_SERIAL_DEST_TYPE_PPP: /* ipmi_pef_print_serial_dest_ppp(intf, &ssel); */ break; case PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK: case PEF_SERIAL_DEST_TYPE_PPP_CALLBACK: /* ipmi_pef_print_serial_dest_callback(intf, &ssel); */ break; } } } static void ipmi_pef_print_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest) { /* // print generic alert destination info */ ipmi_pef_print_dec("Destination ID", dest); } void ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * buf) { /* // print PEF entry Event info: class, severity, trigger, etc. */ static char * classes[] = {"Discrete", "Threshold", "OEM"}; uint16_t offmask; char * p; unsigned int i; uint8_t t; ipmi_pef_print_str("Event severity", ipmi_pef_bit_desc(&pef_b2s_severities, pef->entry.severity)); t = pef->entry.event_trigger; if (t == PEF_EVENT_TRIGGER_THRESHOLD) i = 1; else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC) i = 2; else i = 0; ipmi_pef_print_str("Event class", classes[i]); offmask = ((pef->entry.event_data_1_offset_mask[1] << 8) + pef->entry.event_data_1_offset_mask[0]); if (offmask == 0xffff || t == PEF_EVENT_TRIGGER_MATCH_ANY) strcpy(buf, "Any"); else if (t == PEF_EVENT_TRIGGER_UNSPECIFIED) strcpy(buf, "Unspecified"); else if (t == PEF_EVENT_TRIGGER_SENSOR_SPECIFIC) strcpy(buf, "Sensor-specific"); else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC) strcpy(buf, "OEM"); else { sprintf(buf, "(0x%02x/0x%04x)", t, offmask); p = strchr(buf, '\0'); for (i=0; i= PEF_B2S_GENERIC_ER_ENTRIES) { sprintf(p, ", Unrecognized event trigger"); } else { sprintf(p, ",%s", ipmi_pef_bit_desc(pef_b2s_generic_ER[t-1], i)); } p = strchr(p, '\0'); } offmask >>= 1; } } ipmi_pef_print_str("Event trigger(s)", buf); } /* ipmi_pef_print_filter_entry - Print-out Entry of Event Filter Table. */ static void ipmi_pef_print_filter_entry(struct pef_cfgparm_filter_table_entry *filter_entry) { char buf[128]; uint8_t filter_enabled; uint8_t set; ipmi_pef_print_dec("PEF Filter Table entry", filter_entry->data1); filter_enabled = filter_entry->entry.config & PEF_CONFIG_ENABLED; sprintf(buf, "%sabled", (filter_enabled ? "en" : "dis")); switch (filter_entry->entry.config & 0x60) { case 0x40: strcat(buf, ", pre-configured"); break; case 0x00: strcat(buf, ", configurable"); break; default: /* Covers 0x60 and 0x20 which are reserved */ strcat(buf, ", reserved"); break; } ipmi_pef_print_str("Status", buf); if (!filter_enabled) { return; } ipmi_pef_print_str("Sensor type", ipmi_pef_bit_desc(&pef_b2s_sensortypes, filter_entry->entry.sensor_type)); if (filter_entry->entry.sensor_number == PEF_SENSOR_NUMBER_MATCH_ANY) { ipmi_pef_print_str("Sensor number", "Any"); } else { ipmi_pef_print_dec("Sensor number", filter_entry->entry.sensor_number); } ipmi_pef_print_event_info(filter_entry, buf); ipmi_pef_print_str("Action", ipmi_pef_bit_desc(&pef_b2s_actions, filter_entry->entry.action)); if (filter_entry->entry.action & PEF_ACTION_ALERT) { set = (filter_entry->entry.policy_number & PEF_POLICY_NUMBER_MASK); ipmi_pef_print_int("Policy set", set); } } /* ipmi_pef2_filter_enable - Enable/Disable specific PEF Event Filter. * * @enable - enable(1) or disable(0) PEF Event Filter. * @filter_id - Filter ID of Entry in Event Filter Table. * * returns - 0 on success, any other value means error. */ static int ipmi_pef2_filter_enable(struct ipmi_intf *intf, uint8_t enable, uint8_t filter_id) { struct pef_cfgparm_filter_table_data_1 filter_cfg; int rc; uint8_t filter_table_size; rc = _ipmi_get_pef_filter_table_size(intf, &filter_table_size); if (eval_ccode(rc) != 0) { return (-1); } else if (filter_table_size == 0) { lprintf(LOG_ERR, "PEF Filter isn't supported."); return (-1); } else if (filter_id > filter_table_size) { lprintf(LOG_ERR, "PEF Filter ID out of range. Valid range is (1..%d).", filter_table_size); return (-1); } memset(&filter_cfg, 0, sizeof(filter_cfg)); rc = _ipmi_set_pef_filter_entry_cfg(intf, filter_id, &filter_cfg); if (eval_ccode(rc) != 0) { return (-1); } if (enable != 0) { /* Enable */ filter_cfg.cfg |= PEF_FILTER_ENABLED; } else { /* Disable */ filter_cfg.cfg &= PEF_FILTER_DISABLED; } rc = _ipmi_set_pef_filter_entry_cfg(intf, filter_id, &filter_cfg); if (eval_ccode(rc) != 0) { lprintf(LOG_ERR, "Failed to %s PEF Filter ID %d.", enable ? "enable" : "disable", filter_id); return (-1); } printf("PEF Filter ID %" PRIu8 " is %s now.\n", filter_id, enable ? "enabled" : "disabled"); return rc; } void ipmi_pef2_filter_help(void) { lprintf(LOG_NOTICE, "usage: pef filter help"); lprintf(LOG_NOTICE, " pef filter list"); lprintf(LOG_NOTICE, " pef filter enable "); lprintf(LOG_NOTICE, " pef filter disable "); lprintf(LOG_NOTICE, " pef filter create "); lprintf(LOG_NOTICE, " pef filter delete "); } /* ipmi_pef2_filter - Handle processing of "filter" CLI args. */ int ipmi_pef2_filter(struct ipmi_intf *intf, int argc, char **argv) { int rc = 0; if (argc < 1) { lprintf(LOG_ERR, "Not enough parameters given."); ipmi_pef2_filter_help(); rc = (-1); } else if (!strncmp(argv[0], "help\0", 5)) { ipmi_pef2_filter_help(); rc = 0; } else if (!strncmp(argv[0], "list\0", 5)) { rc = ipmi_pef2_list_filters(intf); } else if (!strncmp(argv[0], "enable\0", 7) ||(!strncmp(argv[0], "disable\0", 8))) { uint8_t enable; uint8_t filter_id; if (argc != 2) { lprintf(LOG_ERR, "Not enough arguments given."); ipmi_pef2_filter_help(); return (-1); } if (str2uchar(argv[1], &filter_id) != 0) { lprintf(LOG_ERR, "Invalid PEF Event Filter ID given: %s", argv[1]); return (-1); } else if (filter_id < 1) { lprintf(LOG_ERR, "PEF Event Filter ID out of range. " "Valid range is <1..255>."); return (-1); } if (!strncmp(argv[0], "enable\0", 7)) { enable = 1; } else { enable = 0; } rc = ipmi_pef2_filter_enable(intf, enable, filter_id); } else if (!strncmp(argv[0], "create\0", 7)) { lprintf(LOG_ERR, "Not implemented."); rc = 1; } else if (!strncmp(argv[0], "delete\0", 7)) { lprintf(LOG_ERR, "Not implemented."); rc = 1; } else { lprintf(LOG_ERR, "Invalid PEF Filter command: %s", argv[0]); ipmi_pef2_filter_help(); rc = 1; } return rc; } /* ipmi_pef2_get_info - Reports PEF capabilities + System GUID */ static int ipmi_pef2_get_info(struct ipmi_intf *intf) { struct pef_capabilities pcap; struct pef_cfgparm_system_guid psys_guid; struct ipmi_guid_t guid; int rc; uint8_t *guid_ptr = NULL; uint8_t policy_table_size; rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size); if (eval_ccode(rc) != 0) { lprintf(LOG_WARN, "Failed to get size of PEF Policy Table."); policy_table_size = 0; } rc = _ipmi_get_pef_capabilities(intf, &pcap); if (eval_ccode(rc) != 0) { lprintf(LOG_ERR, "Failed to get PEF Capabilities."); return (-1); } ipmi_pef_print_1xd("Version", pcap.version); ipmi_pef_print_dec("PEF Event Filter count", pcap.event_filter_count); ipmi_pef_print_dec("PEF Alert Policy Table size", policy_table_size); rc = _ipmi_get_pef_system_guid(intf, &psys_guid); if (rc != 0x80 && eval_ccode(rc) != 0) { lprintf(LOG_ERR, "Failed to get PEF System GUID. %i", rc); return (-1); } else if (psys_guid.data1 == 0x1) { /* IPMI_CMD_GET_SYSTEM_GUID */ guid_ptr = &psys_guid.guid[0]; } else { rc = _ipmi_mc_get_guid(intf, &guid); if (rc == 0) { guid_ptr = (uint8_t *)&guid; } } /* Got GUID? */ if (guid_ptr) { ipmi_pef_print_guid(guid_ptr); } ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, pcap.actions); return 0; } /* ipmi_pef2_get_status - TODO rewrite - report the PEF status */ static int ipmi_pef2_get_status(struct ipmi_intf *intf) { struct ipmi_rs *rsp; struct ipmi_rq req; struct pef_cfgparm_selector psel; char tbuf[40]; uint32_t timei; time_t ts; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_LAST_PROCESSED_EVT_ID; rsp = ipmi_pef_msg_exchange(intf, &req, "Last S/W processed ID"); if (!rsp) { lprintf(LOG_ERR, " **Error retrieving %s", "Last S/W processed ID"); return (-1); } memcpy(&timei, rsp->data, sizeof(timei)); #if WORDS_BIGENDIAN timei = BSWAP_32(timei); #endif ts = (time_t)timei; strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&ts)); ipmi_pef_print_str("Last SEL addition", tbuf); ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]); ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]); ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]); memset(&psel, 0, sizeof(psel)); psel.id = PEF_CFGPARM_ID_PEF_CONTROL; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_SE; req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS; req.msg.data = (uint8_t *)&psel; req.msg.data_len = sizeof(psel); rsp = ipmi_pef_msg_exchange(intf, &req, "PEF control"); if (!rsp) { lprintf(LOG_ERR, " **Error retrieving %s", "PEF control"); return (-1); } ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]); psel.id = PEF_CFGPARM_ID_PEF_ACTION; rsp = ipmi_pef_msg_exchange(intf, &req, "PEF action"); if (!rsp) { lprintf(LOG_ERR, " **Error retrieving %s", "PEF action"); return (-1); } ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]); return 0; } /* ipmi_pef2_list_filters - List all entries in PEF Event Filter Table. */ static int ipmi_pef2_list_filters(struct ipmi_intf *intf) { struct pef_capabilities pcap; struct pef_cfgparm_filter_table_entry filter_entry; int rc; uint8_t i; rc = _ipmi_get_pef_capabilities(intf, &pcap); if (eval_ccode(rc) != 0) { return (-1); } else if (pcap.event_filter_count == 0) { lprintf(LOG_ERR, "PEF Event Filtering isn't supported."); return (-1); } for (i = 1; i <= pcap.event_filter_count; i++) { first_field = 1; rc = _ipmi_get_pef_filter_entry(intf, i, &filter_entry); if (eval_ccode(rc) != 0) { lprintf(LOG_ERR, "Failed to get PEF Event Filter Entry %i.", i); continue; } ipmi_pef_print_filter_entry(&filter_entry); printf("\n"); } return 0; } /* ipmi_pef2_list_policies - List Entries in PEF Alert Policy Table. */ static int ipmi_pef2_list_policies(struct ipmi_intf *intf) { struct channel_info_t channel_info; struct pef_cfgparm_policy_table_entry entry; int rc; uint8_t dest; uint8_t i; uint8_t policy_table_size; rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size); if (eval_ccode(rc) != 0) { return (-1); } else if (policy_table_size == 0) { lprintf(LOG_ERR, "PEF Alert Policy isn't supported."); return (-1); } for (i = 1; i <= policy_table_size; i++) { first_field = 1; rc = _ipmi_get_pef_policy_entry(intf, i, &entry); if (eval_ccode(rc) != 0) { continue; } ipmi_pef_print_dec("Alert policy table entry", (entry.data1 & PEF_POLICY_TABLE_ID_MASK)); ipmi_pef_print_dec("Policy set", (entry.entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT); ipmi_pef_print_str("State", entry.entry.policy & PEF_POLICY_ENABLED ? "enabled" : "disabled"); ipmi_pef_print_str("Policy entry rule", ipmi_pef_bit_desc(&pef_b2s_policies, (entry.entry.policy & PEF_POLICY_FLAGS_MASK))); if (entry.entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) { ipmi_pef_print_str("Event-specific", "true"); } channel_info.channel = ((entry.entry.chan_dest & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT); rc = _ipmi_get_channel_info(intf, &channel_info); if (eval_ccode(rc) != 0) { continue; } ipmi_pef_print_dec("Channel number", channel_info.channel); ipmi_pef_print_str("Channel medium", ipmi_pef_bit_desc(&pef_b2s_ch_medium, channel_info.medium)); dest = entry.entry.chan_dest & PEF_POLICY_DESTINATION_MASK; switch (channel_info.medium) { case PEF_CH_MEDIUM_TYPE_LAN: ipmi_pef_print_lan_dest(intf, channel_info.channel, dest); break; case PEF_CH_MEDIUM_TYPE_SERIAL: ipmi_pef_print_serial_dest(intf, channel_info.channel, dest); break; default: ipmi_pef_print_dest(intf, channel_info.channel, dest); break; } printf("\n"); } return 0; } void ipmi_pef2_policy_help(void) { lprintf(LOG_NOTICE, "usage: pef policy help"); lprintf(LOG_NOTICE, " pef policy list"); lprintf(LOG_NOTICE, " pef policy enable "); lprintf(LOG_NOTICE, " pef policy disable "); lprintf(LOG_NOTICE, " pef policy create "); lprintf(LOG_NOTICE, " pef policy delete "); } /* ipmi_pef2_policy_enable - Enable/Disable specific PEF policy * * @enable - enable(1) or disable(0) PEF Alert Policy * @policy_id - Policy ID of Entry in Alert Policy Table. * * returns - 0 on success, any other value means error. */ static int ipmi_pef2_policy_enable(struct ipmi_intf *intf, int enable, uint8_t policy_id) { struct pef_cfgparm_policy_table_entry policy_entry; int rc; uint8_t policy_table_size; rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size); if (eval_ccode(rc) != 0) { return (-1); } else if (policy_table_size == 0) { lprintf(LOG_ERR, "PEF Policy isn't supported."); return (-1); } else if (policy_id > policy_table_size) { lprintf(LOG_ERR, "PEF Policy ID out of range. Valid range is (1..%d).", policy_table_size); return (-1); } memset(&policy_entry, 0, sizeof(policy_entry)); rc = _ipmi_get_pef_policy_entry(intf, policy_id, &policy_entry); if (eval_ccode(rc) != 0) { return (-1); } if (enable != 0) { /* Enable */ policy_entry.entry.policy |= PEF_POLICY_ENABLED; } else { /* Disable */ policy_entry.entry.policy &= PEF_POLICY_DISABLED; } rc = _ipmi_set_pef_policy_entry(intf, policy_id, &policy_entry); if (eval_ccode(rc) != 0) { lprintf(LOG_ERR, "Failed to %s PEF Policy ID %d.", enable ? "enable" : "disable", policy_id); return (-1); } printf("PEF Policy ID %" PRIu8 " is %s now.\n", policy_id, enable ? "enabled" : "disabled"); return rc; } /* ipmi_pef2_policy - Handle processing of "policy" CLI args. */ int ipmi_pef2_policy(struct ipmi_intf *intf, int argc, char **argv) { int rc = 0; if (argc < 1) { lprintf(LOG_ERR, "Not enough parameters given."); ipmi_pef2_policy_help(); rc = (-1); } else if (!strncmp(argv[0], "help\0", 5)) { ipmi_pef2_policy_help(); rc = 0; } else if (!strncmp(argv[0], "list\0", 5)) { rc = ipmi_pef2_list_policies(intf); } else if (!strncmp(argv[0], "enable\0", 7) || !strncmp(argv[0], "disable\0", 8)) { uint8_t enable; uint8_t policy_id; if (argc != 2) { lprintf(LOG_ERR, "Not enough arguments given."); ipmi_pef2_policy_help(); return (-1); } if (str2uchar(argv[1], &policy_id) != 0) { lprintf(LOG_ERR, "Invalid PEF Policy ID given: %s", argv[1]); return (-1); } else if (policy_id < 1 || policy_id > 127) { lprintf(LOG_ERR, "PEF Policy ID out of range. Valid range is <1..127>."); return (-1); } if (!strncmp(argv[0], "enable\0", 7)) { enable = 1; } else { enable = 0; } rc = ipmi_pef2_policy_enable(intf, enable, policy_id); } else if (!strncmp(argv[0], "create\0", 7)) { lprintf(LOG_ERR, "Not implemented."); rc = 1; } else if (!strncmp(argv[0], "delete\0", 7)) { lprintf(LOG_ERR, "Not implemented."); rc = 1; } else { lprintf(LOG_ERR, "Invalid PEF Policy command: %s", argv[0]); ipmi_pef2_policy_help(); rc = 1; } return rc; } /* ipmi_pef2_help - print-out help text. */ void ipmi_pef2_help(void) { lprintf(LOG_NOTICE, "usage: pef help"); lprintf(LOG_NOTICE, " pef capabilities"); lprintf(LOG_NOTICE, " pef event "); lprintf(LOG_NOTICE, " pef filter list"); lprintf(LOG_NOTICE, " pef filter enable "); lprintf(LOG_NOTICE, " pef filter disable "); lprintf(LOG_NOTICE, " pef filter create "); lprintf(LOG_NOTICE, " pef filter delete "); lprintf(LOG_NOTICE, " pef info"); lprintf(LOG_NOTICE, " pef policy list"); lprintf(LOG_NOTICE, " pef policy enable "); lprintf(LOG_NOTICE, " pef policy disable "); lprintf(LOG_NOTICE, " pef policy create "); lprintf(LOG_NOTICE, " pef policy delete "); lprintf(LOG_NOTICE, " pef pet ack "); lprintf(LOG_NOTICE, " pef status"); lprintf(LOG_NOTICE, " pef timer get"); lprintf(LOG_NOTICE, " pef timer set <0x00-0xFF>"); } int ipmi_pef_main(struct ipmi_intf *intf, int argc, char **argv) { int rc = 0; if (argc < 1) { lprintf(LOG_ERR, "Not enough parameters given."); ipmi_pef2_help(); rc = (-1); } else if (!strncmp(argv[0], "help\0", 5)) { ipmi_pef2_help(); rc = 0; } else if (!strncmp(argv[0], "capabilities\0", 13)) { /* rc = ipmi_pef2_get_capabilities(intf); */ lprintf(LOG_ERR, "Not implemented."); rc = 1; } else if (!strncmp(argv[0], "event\0", 6)) { /* rc = ipmi_pef2_event(intf, (argc - 1), ++argv); */ lprintf(LOG_ERR, "Not implemented."); rc = 1; } else if (!strncmp(argv[0], "filter\0", 7)) { rc = ipmi_pef2_filter(intf, (argc - 1), ++argv); } else if (!strncmp(argv[0], "info\0", 5)) { rc = ipmi_pef2_get_info(intf); } else if (!strncmp(argv[0], "pet\0", 4)) { /* rc = ipmi_pef2_pet(intf, (argc - 1), ++argv); */ lprintf(LOG_ERR, "Not implemented."); rc = 1; } else if (!strncmp(argv[0], "policy\0", 7)) { rc = ipmi_pef2_policy(intf, (argc - 1), ++argv); } else if (!strncmp(argv[0], "status\0", 7)) { rc = ipmi_pef2_get_status(intf); } else if (!strncmp(argv[0], "timer\0", 6)) { /* rc = ipmi_pef2_timer(intf, (argc - 1), ++argv); */ lprintf(LOG_ERR, "Not implemented."); rc = 1; } else { lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]); rc = (-1); } return rc; }