diff --git a/ipmitool/lib/ipmi_lanp.c b/ipmitool/lib/ipmi_lanp.c index bbb8b12..5eb1ca5 100644 --- a/ipmitool/lib/ipmi_lanp.c +++ b/ipmitool/lib/ipmi_lanp.c @@ -59,8 +59,53 @@ extern int verbose; +/* is_lan_channel - Check if channel is LAN medium + * + * return 1 if channel is LAN + * return 0 if channel is not LAN + * + * @intf: ipmi interface handle + * @chan: channel number to check + */ +static int +is_lan_channel(struct ipmi_intf * intf, uint8_t chan) +{ + uint8_t medium; -/* get_lan_param - Query BMC for LAN parameter data + if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) + return 0; + + medium = ipmi_get_channel_medium(intf, chan); + + if (medium == IPMI_CHANNEL_MEDIUM_LAN || + medium == IPMI_CHANNEL_MEDIUM_LAN_OTHER) + return 1; + + return 0; +} + +/* find_lan_channel - Find first channel that is LAN + * + * return channel number if successful + * return -1 if no lan channel found + * + * @intf: ipmi interface handle + * @start: channel number to start searching from + */ +static int +find_lan_channel(struct ipmi_intf * intf, int start) +{ + uint8_t chan; + + for (chan = start; chan < IPMI_CHANNEL_NUMBER_MAX; chan++) { + if (is_lan_channel(intf, chan)) { + return chan; + } + } + return -1; +} + +/* get_lan_param_select - Query BMC for LAN parameter data * * return pointer to lan_param if successful * if parameter not supported then @@ -71,9 +116,10 @@ extern int verbose; * @intf: ipmi interface handle * @chan: ipmi channel * @param: lan parameter id + * @select: lan parameter set selector */ static struct lan_param * -get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) +get_lan_param_select(struct ipmi_intf * intf, uint8_t chan, int param, int select) { struct lan_param * p; struct ipmi_rs * rsp; @@ -86,7 +132,7 @@ get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) msg_data[0] = chan; msg_data[1] = p->cmd; - msg_data[2] = 0; + msg_data[2] = select; msg_data[3] = 0; memset(&req, 0, sizeof(req)); @@ -131,6 +177,24 @@ get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) return p; } +/* get_lan_param - Query BMC for LAN parameter data + * + * return pointer to lan_param if successful + * if parameter not supported then + * return pointer to lan_param with + * lan_param->data == NULL and lan_param->data_len == 0 + * return NULL on error + * + * @intf: ipmi interface handle + * @chan: ipmi channel + * @param: lan parameter id + */ +static struct lan_param * +get_lan_param(struct ipmi_intf * intf, uint8_t chan, int param) +{ + return get_lan_param_select(intf, chan, param, 0); +} + /* set_lan_param_wait - Wait for Set LAN Parameter command to complete * * On some systems this can take unusually long so we wait for the write @@ -358,6 +422,26 @@ set_lan_param(struct ipmi_intf * intf, uint8_t chan, return rc; } +/* set_lan_param_nowait - Wrap LAN parameter write without set-in-progress lock + * + * Returns value from __set_lan_param() + * + * @intf: ipmi interface handle + * @chan: ipmi channel + * @param: lan parameter id + * @data: lan parameter data + * @len: length of lan parameter data + */ +static int +set_lan_param_nowait(struct ipmi_intf * intf, uint8_t chan, + int param, uint8_t * data, int len) +{ + int rc; + ipmi_lanp_lock(intf, chan); + rc = __set_lan_param(intf, chan, param, data, len, 0); + ipmi_lanp_unlock(intf, chan); + return rc; +} static int lan_set_arp_interval(struct ipmi_intf * intf, @@ -466,7 +550,6 @@ static int ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan) { struct lan_param * p; - uint8_t medium; int rc = 0; if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) { @@ -475,11 +558,8 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan) } /* find type of channel and only accept 802.3 LAN */ - medium = ipmi_get_channel_medium(intf, chan); - if (medium != IPMI_CHANNEL_MEDIUM_LAN && - medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { - lprintf(LOG_ERR, "Channel %d (%s) is not a LAN channel", - chan, val2str(medium, ipmi_channel_medium_vals)); + if (is_lan_channel(intf, chan) == 0) { + lprintf(LOG_ERR, "Channel %d is not a LAN channel", chan); return -1; } @@ -655,8 +735,6 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan) printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc, p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]); - - /* Determine supported Cipher Suites -- Requires two calls */ p = get_lan_param(intf, chan, IPMI_LANP_RMCP_CIPHER_SUPPORT); if (p == NULL) @@ -1080,7 +1158,7 @@ static int ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) { uint8_t data[32]; - uint8_t chan, medium; + uint8_t chan; int rc = 0; if (argc < 2) { @@ -1096,17 +1174,10 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) chan = (uint8_t)strtol(argv[0], NULL, 0); - if (chan < 1 || chan > IPMI_CHANNEL_NUMBER_MAX) { - lprintf(LOG_ERR, "Invalid Channel %d", chan); - ipmi_lan_set_usage(); - return -1; - } - /* find type of channel and only accept 802.3 LAN */ - medium = ipmi_get_channel_medium(intf, chan); - if (medium != IPMI_CHANNEL_MEDIUM_LAN && - medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { + if (is_lan_channel(intf, chan) == 0) { lprintf(LOG_ERR, "Channel %d is not a LAN channel!", chan); + ipmi_lan_set_usage(); return -1; } @@ -1317,20 +1388,358 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv) } +static int +is_alert_destination(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) +{ + struct lan_param * p; + + p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); + if (p == NULL) + return 0; + if (p->data == NULL) + return 0; + + if (alert <= (p->data[0] & 0xf)) + return 1; + else + return 0; +} + +static int +ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert) +{ + struct lan_param * ptype, * paddr; + int isack = 0; + + ptype = get_lan_param_select(intf, channel, IPMI_LANP_DEST_TYPE, alert); + paddr = get_lan_param_select(intf, channel, IPMI_LANP_DEST_ADDR, alert); + if (ptype == NULL || paddr == NULL) + return -1; + if (ptype->data == NULL || paddr->data == NULL) + return -1; + + printf("%-24s: %d\n", "Alert Destination", + ptype->data[0]); + + if (ptype->data[1] & 0x80) + isack = 1; + printf("%-24s: %s\n", "Alert Acknowledge", + isack ? "Acknowledged" : "Unacknowledged"); + + printf("%-24s: ", "Destination Type"); + switch (ptype->data[1] & 0x7) { + case 0: + printf("PET Trap\n"); + break; + case 6: + printf("OEM 1\n"); + break; + case 7: + printf("OEM 2\n"); + break; + default: + printf("Unknown\n"); + break; + } + + printf("%-24s: %d\n", + isack ? "Acknowledge Timeout" : "Retry Interval", + ptype->data[2]); + + printf("%-24s: %d\n", "Number of Retries", + ptype->data[3] & 0x7); + + if ((paddr->data[1] & 0xf0) != 0) { + /* unknown address format */ + printf("\n"); + return 0; + } + + printf("%-24s: %s\n", "Alert Gateway", + (paddr->data[2] & 1) ? "Backup" : "Default"); + + printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address", + paddr->data[3], paddr->data[4], paddr->data[5], paddr->data[6]); + + printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address", + paddr->data[7], paddr->data[8], paddr->data[9], + paddr->data[10], paddr->data[11], paddr->data[12]); + + printf("\n"); +} + +static int +ipmi_lan_alert_print_all(struct ipmi_intf * intf, uint8_t channel) +{ + int j, ndest; + struct lan_param * p; + + p = get_lan_param(intf, channel, IPMI_LANP_NUM_DEST); + if (p == NULL) + return -1; + if (p->data == NULL) + return -1; + ndest = p->data[0] & 0xf; + + for (j=0; j<=ndest; j++) { + ipmi_lan_alert_print(intf, channel, j); + } + + return 0; +} + +static void +ipmi_lan_alert_print_usage(void) +{ + lprintf(LOG_NOTICE, "\nusage: lan alert print [channel] [alert]\n"); + lprintf(LOG_NOTICE, "Default will print all alerts for the first found LAN channel"); +} + +static void +ipmi_lan_alert_set_usage(void) +{ + lprintf(LOG_NOTICE, "\nusage: lan alert set