1 /*
2  * strings.c
3  *
4  * MontaVista IPMI code for converting values to strings.
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2002,2003 MontaVista Software Inc.
11  *
12  *  This program is free software; you can redistribute it and/or
13  *  modify it under the terms of the GNU Lesser General Public License
14  *  as published by the Free Software Foundation; either version 2 of
15  *  the License, or (at your option) any later version.
16  *
17  *
18  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *  You should have received a copy of the GNU Lesser General Public
30  *  License along with this program; if not, write to the Free
31  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32  */
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <OpenIPMI/ipmi_bits.h>
37 #include <OpenIPMI/ipmi_msgbits.h>
38 #include <OpenIPMI/ipmi_auth.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_err.h>
41 #include <OpenIPMI/ipmi_mc.h>
42 #include <string.h>
43 #include <OpenIPMI/internal/ipmi_malloc.h>
44 
45 const char *
ipmi_update_e_string(enum ipmi_update_e val)46 ipmi_update_e_string(enum ipmi_update_e val)
47 {
48     switch (val) {
49     case IPMI_ADDED: return "added";
50     case IPMI_DELETED: return "deleted";
51     case IPMI_CHANGED: return "changed";
52     default: return "invalid";
53     }
54 }
55 
56 const char *
ipmi_update_werr_e_string(enum ipmi_update_werr_e val)57 ipmi_update_werr_e_string(enum ipmi_update_werr_e val)
58 {
59     switch (val) {
60     case IPMIE_ADDED: return "added";
61     case IPMIE_DELETED: return "deleted";
62     case IPMIE_CHANGED: return "changed";
63     case IPMIE_ERROR: return "error";
64     default: return "invalid";
65     }
66 }
67 
68 static char *hysteresis_support_types[] =
69 {
70     "none",
71     "readable",
72     "settable",
73     "fixed",
74 };
75 #define NUM_HYSTERESIS_SUPPORT_TYPES (sizeof(hysteresis_support_types)/sizeof(char *))
76 const char *
ipmi_get_hysteresis_support_string(unsigned int val)77 ipmi_get_hysteresis_support_string(unsigned int val)
78 {
79     if (val >= NUM_HYSTERESIS_SUPPORT_TYPES)
80 	return "invalid";
81     return hysteresis_support_types[val];
82 }
83 
84 static char *threshold_access_support_types[] =
85 {
86     "none",
87     "readable",
88     "settable",
89     "fixed",
90 };
91 #define NUM_THRESHOLD_ACCESS_SUPPORT_TYPES (sizeof(threshold_access_support_types)/sizeof(char *))
92 const char *
ipmi_get_threshold_access_support_string(unsigned int val)93 ipmi_get_threshold_access_support_string(unsigned int val)
94 {
95     if (val >= NUM_THRESHOLD_ACCESS_SUPPORT_TYPES)
96 	return "invalid";
97     return threshold_access_support_types[val];
98 }
99 
100 static char *event_support_types[] =
101 {
102     "per_state",
103     "entire_sensor",
104     "global_disable",
105     "none",
106 };
107 #define NUM_EVENT_SUPPORT_TYPES (sizeof(event_support_types)/sizeof(char *))
108 const char *
ipmi_get_event_support_string(unsigned int val)109 ipmi_get_event_support_string(unsigned int val)
110 {
111     if (val >= NUM_EVENT_SUPPORT_TYPES)
112 	return "invalid";
113     return event_support_types[val];
114 }
115 
116 static char *sensor_types[] =
117 {
118     "unspecified",
119     "temperature",
120     "voltage",
121     "current",
122     "fan",
123     "physical_security",
124     "platform_security",
125     "processor",
126     "power_supply",
127     "power_unit",
128     "cooling_device",
129     "other_units_based_sensor",
130     "memory",
131     "drive_slot",
132     "power_memory_resize",
133     "system_firmware_progress",
134     "event_logging_disabled",
135     "watchdog_1",
136     "system_event",
137     "critical_interrupt",
138     "button",
139     "module_board",
140     "microcontroller_coprocessor",
141     "add_in_card",
142     "chassis",
143     "chip_set",
144     "other_fru",
145     "cable_interconnect",
146     "terminator",
147     "system_boot_initiated",
148     "boot_error",
149     "os_boot",
150     "os_critical_stop",
151     "slot_connector",
152     "system_acpi_power_state",
153     "watchdog_2",
154     "platform_alert",
155     "entity_presence",
156     "monitor_asic_ic",
157     "lan",
158     "management_subsystem_health",
159     "battery",
160     "session_audit",
161     "version_change",
162     "fru_state",
163 };
164 #define NUM_SENSOR_TYPES (sizeof(sensor_types)/sizeof(char *))
165 const char *
ipmi_get_sensor_type_string(unsigned int val)166 ipmi_get_sensor_type_string(unsigned int val)
167 {
168     if (val >= NUM_SENSOR_TYPES)
169 	return "invalid";
170     return sensor_types[val];
171 }
172 
173 static char *event_reading_types[] =
174 {
175     "unspecified",
176     "threshold",
177     "discrete_usage",
178     "discrete_state",
179     "discrete_predictive_failure",
180     "discrete_limit_exceeded",
181     "discrete_performance_met",
182     "discrete_severity",
183     "discrete_device_presence",
184     "discrete_device_enable",
185     "discrete_availability",
186     "discrete_redundancy",
187     "discrete_acpi_power",
188 };
189 #define NUM_EVENT_READING_TYPES (sizeof(event_reading_types)/sizeof(char *))
190 const char *
ipmi_get_event_reading_type_string(unsigned int val)191 ipmi_get_event_reading_type_string(unsigned int val)
192 {
193     if (val == IPMI_EVENT_READING_TYPE_SENSOR_SPECIFIC)
194 	return "sensor specific";
195 
196     if (val >= NUM_EVENT_READING_TYPES)
197 	return "invalid";
198     return event_reading_types[val];
199 }
200 
201 static char *sensor_directions[] =
202 {
203     "unspecified",
204     "input",
205     "output",
206 };
207 #define NUM_SENSOR_DIRECTIONS (sizeof(sensor_directions)/sizeof(char *))
208 const char *
ipmi_get_sensor_direction_string(unsigned int val)209 ipmi_get_sensor_direction_string(unsigned int val)
210 {
211     if (val >= NUM_SENSOR_DIRECTIONS)
212 	return "invalid";
213     return sensor_directions[val];
214 }
215 
216 static char *rate_unit_types[] =
217 {
218     "",
219     "/us",
220     "/ms",
221     "/sec",
222     "/min",
223     "/hour",
224     "/day",
225 };
226 #define NUM_RATE_UNIT_TYPES (sizeof(rate_unit_types)/sizeof(char *))
227 const char *
ipmi_get_rate_unit_string(unsigned int val)228 ipmi_get_rate_unit_string(unsigned int val)
229 {
230     if (val >= NUM_RATE_UNIT_TYPES)
231 	return "invalid";
232     return rate_unit_types[val];
233 }
234 
235 static char *unit_types[] =
236 {
237     "unspecified",
238     "C",
239     "F",
240     "K",
241     "volts",
242     "amps",
243     "watts",
244     "joules",
245     "coulombs",
246     "VA",
247     "nits",
248     "lumens",
249     "lux",
250     "candela",
251     "kpa",
252     "PSI",
253     "newtons",
254     "CFM",
255     "RPM",
256     "HZ",
257     "useconds",
258     "mseconds",
259     "seconds",
260     "minute",
261     "hour",
262     "day",
263     "week",
264     "mil",
265     "inches",
266     "feet",
267     "cubic inchs",
268     "cubic feet",
269     "millimeters",
270     "centimeters",
271     "meters",
272     "cubic centimeters"
273     "cubic meters",
274     "liters",
275     "fluid ounces",
276     "radians",
277     "seradians",
278     "revolutions",
279     "cycles",
280     "gravities",
281     "ounces",
282     "pounds",
283     "foot pounds",
284     "ounce inches",
285     "gauss",
286     "gilberts",
287     "henries",
288     "mhenries",
289     "farads",
290     "ufarads",
291     "ohms",
292     "siemens",
293     "moles",
294     "becquerels",
295     "PPM",
296     "unspecified",
297     "decibels",
298     "DbA",
299     "DbC",
300     "grays",
301     "sieverts",
302     "color temp deg K",
303     "bits",
304     "kbits",
305     "mbits",
306     "gbits",
307     "bytes",
308     "kbytes",
309     "mbytes",
310     "gbytes",
311     "words",
312     "dwords",
313     "qwords",
314     "lines",
315     "hits",
316     "misses",
317     "retries",
318     "resets",
319     "overruns",
320     "underruns",
321     "collisions",
322     "packets",
323     "messages",
324     "characters",
325     "errors",
326     "correctable_errors",
327     "uncorrectable_errors",
328     "fatal errors",
329     "grams",
330 };
331 #define NUM_UNIT_TYPES (sizeof(unit_types)/sizeof(char *))
332 const char *
ipmi_get_unit_type_string(unsigned int val)333 ipmi_get_unit_type_string(unsigned int val)
334 {
335     if (val >= NUM_UNIT_TYPES)
336 	return "invalid";
337     return unit_types[val];
338 }
339 
340 static char *threshold_types[] =
341 {
342     "lower non-critical",
343     "lower critical",
344     "lower non-recoverable",
345     "upper non-critical",
346     "upper critical",
347     "upper non-recoverable"
348 };
349 #define NUM_THRESHOLD_TYPES (sizeof(threshold_types)/sizeof(char *))
350 const char *
ipmi_get_threshold_string(enum ipmi_thresh_e val)351 ipmi_get_threshold_string(enum ipmi_thresh_e val)
352 {
353     if (val >= NUM_THRESHOLD_TYPES)
354 	return "invalid";
355     return threshold_types[val];
356 }
357 
358 static char *value_dir_types[] =
359 {
360     "going-low",
361     "going-high"
362 };
363 #define NUM_VALUE_DIR_TYPES (sizeof(value_dir_types)/sizeof(char *))
364 const char *
ipmi_get_value_dir_string(enum ipmi_event_value_dir_e val)365 ipmi_get_value_dir_string(enum ipmi_event_value_dir_e val)
366 {
367     if (val >= NUM_VALUE_DIR_TYPES)
368 	return "invalid";
369     return value_dir_types[val];
370 }
371 
372 static char *event_dir_types[] =
373 {
374     "assertion",
375     "deassertion"
376 };
377 #define NUM_EVENT_DIR_TYPES (sizeof(event_dir_types)/sizeof(char *))
378 const char *
ipmi_get_event_dir_string(enum ipmi_event_dir_e val)379 ipmi_get_event_dir_string(enum ipmi_event_dir_e val)
380 {
381     if (val >= NUM_EVENT_DIR_TYPES)
382 	return "invalid";
383     return event_dir_types[val];
384 }
385 
386 static char *entity_id_types[] =
387 {
388     "unspecified",					/* 0 */
389     "other",
390     "unkown",
391     "processor",
392     "disk",
393     "peripheral",
394     "system_management_module",
395     "system_board",
396     "memory_module",
397     "processor_module",
398     "power_supply",					/* 10 */
399     "add_in_card",
400     "front_panel_board",
401     "back_panel_board",
402     "power_system_board",
403     "drive_backplane",
404     "system_internal_expansion_board",
405     "other_system_board",
406     "processor_board",
407     "power_unit",
408     "power_module",					/* 20 */
409     "power_management_board",
410     "chassis_back_panel_board",
411     "system_chassis",
412     "sub_chassis",
413     "other_chassis_board",
414     "disk_drive_bay",
415     "peripheral_bay",
416     "device_bay",
417     "fan_cooling",
418     "cooling_unit",					/* 30 */
419     "cable_interconnect",
420     "memory_device",
421     "system_management_software",
422     "bios",
423     "operating_system",
424     "system_bus",
425     "group",
426     "remote_mgmt_comm_device",
427     "external_environment",
428     "battery",						/* 40 */
429     "processing blade",
430     "connectivity switch",
431     "processor/memory module",
432     "I/O module",
433     "processor I/O module",
434     "management controller firmware",
435     "ipmi channel",
436     "pci bus",
437     "pci express bus",
438     "scsi bus",						/* 50 */
439     "sata/sas bus",
440     "processor front side bus",
441 };
442 #define NUM_ENTITY_ID_TYPES (sizeof(entity_id_types)/sizeof(char *))
443 const char *
ipmi_get_entity_id_string(unsigned int val)444 ipmi_get_entity_id_string(unsigned int val)
445 {
446     if (val >= NUM_ENTITY_ID_TYPES)
447 	return "invalid";
448     return entity_id_types[val];
449 }
450 
451 static char *event_reading_states[256][16] =
452 {
453     { },
454     { "lower non-critical - going low",
455       "lower non-critical - going high",
456       "lower critical - going low",
457       "lower critical - going high",
458       "lower non-recoverable - going low",
459       "lower non-recoverable - going high",
460       "upper non-critical - going low",
461       "upper non-critical - going high",
462       "upper critical - going low",
463       "upper critical - going high",
464       "upper non-recoverable - going low",
465       "upper non-recoverable - going high", },
466     { "transition to idle", "transition to active", "transition to busy" },
467     { "state deasserted", "state asserted" },
468     { "predictive failure deasserted", "predictive failure asserted" },
469     { "limit not exceeded", "limit exceeded" },
470     { "performance met", "performance lags" },
471     { "transition to ok",
472       "transition to non-critical from ok",
473       "transition to critical from ok",
474       "transition to non-recoverable from less severe",
475       "transition to non-critical from more severe",
476       "transition to critical from non-recoverable",
477       "transition to non-recoverable",
478       "monitor",
479       "informational", },
480     { "device removed/absent", "device inserted/present" },
481     { "device disabled", "device enabled" },
482     { "transition to ",
483       "transition to in test",
484       "transition to power off",
485       "transition to on line",
486       "transition to off line",
487       "transition to off duty",
488       "transition to degraded",
489       "transition to power save",
490       "install error" },
491     { "fully redundant",
492       "redundancy lost",
493       "redundancy degraded",
494       "non-redundant: sufficient resources from redundant",
495       "non-redundant: sufficient resources from insufficient resources",
496       "non-redundant: insufficient resources",
497       "redundancy degraded from fully redundant",
498       "redundancy degraded from non-redundant" },
499     { "D0 power state",
500       "D1 power state",
501       "D2 power state",
502       "D3 power state" }
503 };
504 
505 static char *sensor_states[256][16] =
506 {
507     {}, /* 0x00 */
508     {}, /* 0x01 */
509     {}, /* 0x02 */
510     {}, /* 0x03 */
511     {}, /* 0x04 */
512     { /* 0x05 */
513 	"general chassis intrusion",
514 	"drive bay intrusion",
515 	"I/O card area intrusion",
516 	"processor area intrusion",
517 	"LAN leash lost",
518 	"unauthorized doc/undock",
519 	"fan area intrusion"
520     },
521     { /* 0x06 */
522 	"secure mode",
523 	"pre-boot password violation - user password",
524 	"pre-boot password violation - setup password",
525 	"pre-boot password violation - network boot password",
526 	"other pre-boot password violation",
527 	"out-of-band access password violation",
528     },
529     { /* 0x07 */
530 	"IERR",
531 	"Thermal Trip",
532 	"FRB1/BIST failure",
533 	"FRB2/Hand in POST failure",
534 	"FRB3/Processor startup/initialization failure",
535 	"configuration error",
536 	"SM BIOS 'uncorrectable CPU-complex error'",
537 	"processor presence detected",
538 	"processor disabled",
539 	"terminator presence detected"
540     },
541     { /* 0x08 */
542 	"presence detected",
543 	"power supply failure detected",
544 	"predictive failure",
545 	"power supply AC lost",
546 	"AC lost or out-of-range",
547 	"AC out of range, but present"
548     },
549     { /* 0x09 */
550 	"power off/power down",
551 	"power cycle",
552 	"240VA power down",
553 	"interlock power down",
554 	"AC lost",
555 	"soft power control failure",
556 	"power unit falure detected",
557 	"predictive failure",
558     },
559     {}, /* 0x0a */
560     {}, /* 0x0b */
561     { /* 0x0c */
562 	"correctable ECC",
563 	"uncorrectable ECC",
564 	"parity",
565 	"memory scrub failed (stuck bit)",
566 	"memory device disabled",
567 	"correctable ECC log limit reached",
568 	"presence detected",
569 	"configuration error",
570 	"spare",
571 	"memory automatically throttled",
572     },
573     { /* 0x0d */
574 	"drive presence",
575 	"drive fault",
576 	"predictive failure",
577 	"hot spare",
578 	"consistancy/parity check in progress",
579 	"in critical array",
580 	"in failed array",
581 	"rebuild/remap in progress",
582 	"rebuild/remap aborted",
583     },
584     {}, /* 0x0e */
585     { /* 0x0f */
586 	"system firmware error",
587 	"system firmware hang",
588 	"system firmware progress"
589     },
590     { /* 0x10 */
591 	"correctable memory error logging disabled",
592 	"event type logging disabled",
593 	"log area reset/cleared",
594 	"all event logging disabled",
595     },
596     { /* 0x11 */
597 	"BIOS watchdog reset",
598 	"OS watchdog reset",
599 	"os watchdog shutdown",
600 	"os watchdog power down",
601 	"os watchdog power cycle",
602 	"os watchdog NMI/diag interrupt",
603 	"os watchdog expired",
604 	"os watchdog pretimout interrupt",
605     },
606     { /* 0x12 */
607 	"system reconfigured",
608 	"OEM system boot event",
609 	"undetermined system hardware failure",
610 	"entry added to auxiliary log",
611 	"PEF action",
612 	"Timestamp clock sync"
613     },
614     { /* 0x13 */
615 	"front panel NMI/diag interrupt",
616 	"bus timeout",
617 	"I/O channel check NMI",
618 	"software NMI",
619 	"PCI PERR",
620 	"PCI SERR",
621 	"EISA fail safe timeout",
622 	"bus correctable error",
623 	"bus uncorrectable error",
624 	"fatal NMI"
625     },
626     { /* 0x14 */
627 	"power button pressed",
628 	"sleep button pressed",
629 	"reset button pressed"
630     },
631     {}, /* 0x15 */
632     {}, /* 0x16 */
633     {}, /* 0x17 */
634     {}, /* 0x18 */
635     {}, /* 0x19 */
636     {}, /* 0x1a */
637     { /* 0x1b */
638 	"cable/interconnect is connected",
639 	"configuration error",
640     },
641     {}, /* 0x1c */
642     { /* 0x1d */
643 	"initiated by power up",
644 	"initiated by hard reset",
645 	"initiated by warm reset",
646 	"user requested PXE boot",
647 	"automatic boot to diagnostic",
648 	"OS initiated hard reset",
649 	"OS initiated warm reset",
650 	"System restart",
651     },
652     { /* 0x1e */
653 	"no bootable media",
654 	"non-bootable diskette left in drive",
655 	"PXE server not found",
656 	"invalid boot sector",
657 	"timeout waiting for user selection of boot source"
658     },
659     { /* 0x1f */
660 	"A: boot completed",
661 	"C: boot completed",
662 	"PXE boot completed",
663 	"diagnostic boot completed",
664 	"CD-ROM boot completed",
665 	"ROM boot completed",
666 	"boot completed"
667     },
668     { /* 0x20 */
669 	"stop during OS load/initialization",
670 	"run time critical stop",
671 	"OS Graceful Stop",
672 	"Soft shutdown initiated by PEF",
673 	"Agent not responding, graceful shutdown did not occur"
674     },
675     { /* 0x21 */
676 	"fault status asserted",
677 	"identify status asserted",
678 	"slot/connector device installed/attached",
679 	"slot/connector ready for device installation",
680 	"slot/connector ready for device removal",
681 	"slot power is off",
682 	"slot/connector device removal request",
683 	"interlock asserted",
684 	"slot is disabled"
685     },
686     { /* 0x22 */
687 	"S0/G0 working",
688 	"S1 'Sleeping with system H/W & processor context maintained'",
689 	"S2 'sleeping, processor context lost'",
690 	"S3 'sleeping, processor & h/w context lost, memory retained'",
691 	"S4 'non-volatile sleep/suspend to disk'",
692 	"S5/G2 soft-off",
693 	"S4/S5 soft-off"
694 	"G3 mechanical off",
695 	"sleeping in an S1, S2, or S3 state",
696 	"G1 sleeping",
697 	"S5 entered by override",
698 	"legacy on state",
699 	"legacy off state",
700 	NULL,
701 	"unknown"
702     },
703     { /* 0x23 */
704 	"timer expired",
705 	"hard reset",
706 	"power down",
707 	"power cycle",
708 	NULL,
709 	NULL,
710 	NULL,
711 	NULL,
712 	"timer interrupt"
713     },
714     { /* 0x24 */
715 	"platform generated page",
716 	"platform generated LAN alert",
717 	"platform event trap generated",
718 	"platform generated SNMP trap"
719     },
720     { /* 0x25 */
721 	"entity present",
722 	"entity absent",
723 	"entity disabled"
724     },
725     {}, /* 0x26 */
726     { /* 0x27 */
727 	"LAN heartbeat lost",
728 	"LAN heartbeat"
729     },
730     { /* 0x28 */
731 	"sensor access degraded or unavailable",
732 	"controller access degraded or unavailable",
733 	"management controller off-line",
734 	"management controller unavailable",
735 	"sensor failure",
736 	"FRU failure"
737     },
738     { /* 0x29 */
739 	"battery low",
740 	"battery failed",
741 	"battery presence detected"
742     },
743 };
744 
745 const char *
ipmi_get_reading_name(unsigned int event_reading_type,unsigned int sensor_type,unsigned int val)746 ipmi_get_reading_name(unsigned int event_reading_type,
747 		      unsigned int sensor_type,
748 		      unsigned int val)
749 {
750     char *rv;
751     if (event_reading_type == IPMI_EVENT_READING_TYPE_SENSOR_SPECIFIC) {
752 	if ((sensor_type > 255) || (val > 15))
753 	    return "invalid";
754 	rv = sensor_states[sensor_type][val];
755     } else {
756 	if ((event_reading_type > 255) || (val > 15))
757 	    return "invalid";
758 	rv = event_reading_states[event_reading_type][val];
759     }
760     if (rv == NULL)
761 	return "unknown";
762     return rv;
763 }
764 
765 static char *control_types[] =
766 {
767     "unspecified",
768     "light",
769     "relay",
770     "display",
771     "alarm",
772     "reset",
773     "power",
774     "fan speed",
775     "identifier",
776     "one-shot reset",
777     "output",
778     "one-shot output",
779 };
780 #define NUM_CONTROL_TYPES (sizeof(control_types)/sizeof(char *))
781 const char *
ipmi_get_control_type_string(unsigned int val)782 ipmi_get_control_type_string(unsigned int val)
783 {
784     if (val >= NUM_CONTROL_TYPES)
785 	return "invalid";
786     return control_types[val];
787 }
788 
789 static char *colors[] =
790 {
791     "black",
792     "white",
793     "red",
794     "green",
795     "blue",
796     "yellow",
797     "orange",
798 };
799 #define NUM_COLORS (sizeof(colors)/sizeof(char *))
800 const char *
ipmi_get_color_string(unsigned int val)801 ipmi_get_color_string(unsigned int val)
802 {
803     if (val >= NUM_COLORS)
804 	return "invalid";
805     return colors[val];
806 }
807 
808 static char *ipmi_netfns[] =
809 {
810     "chassis(c):%02x",		// +0 : 0x00
811     "chassis(r):%02x",		// +1 : 0x01
812     "bridge(c):%02x",		// +2 : 0x02
813     "bridge(r):%02x",		// +3 : 0x03
814     "s/e(c):%02x",		// +4 : 0x04
815     "s/e(r):%02x",		// +5 : 0x05
816     "app(c):%02x",		// +6 : 0x06
817     "app(r):%02x",		// +7 : 0x07
818     "firmware(c):%02x",		// +8 : 0x08
819     "firmware(r):%02x",		// +9 : 0x09
820     "storage(c):%02x",		// +10: 0x0a
821     "storage(r):%02x",		// +11: 0x0b
822     "transport(c):%02x",	// +12: 0x0c
823     "transport(r):%02x",	// +13: 0x0d
824     "reserved(c):%02x",		// +14: 0x0e..0x2b reserved
825     "reserved(r):%02x",		// +15: 0x2b
826     "grpext(c):%02x",		// +16: 0x2c
827     "grpext(r):%02x",		// +17: 0x2d
828     "oem/grp(c):%02x",		// +18: 0x2e
829     "oem/grp(r):%02x",		// +19: 0x2f
830     "ctlrspec(c):%02x",		// +20: 0x30..3f Controller specific
831     "ctlrspec(r):%02x",		// +21: 0x3f
832 };
833 /*
834  * Convert a NetFN code into a string
835  */
836 char *
ipmi_get_netfn_string(unsigned int netfn,char * buffer,unsigned int buf_len)837 ipmi_get_netfn_string(unsigned int netfn,
838 		      char         *buffer,
839 		      unsigned int buf_len)
840 {
841     char *netfn_fs;
842 
843     netfn &= 0x3f;
844 
845     if ( netfn > 0x2f )
846 	netfn_fs = ipmi_netfns[(netfn & 0x01) + 20];
847     else if ( netfn > 0x2d )
848 	netfn_fs = ipmi_netfns[(netfn & 0x01) + 18];
849     else if ( netfn > 0x2b )
850 	netfn_fs = ipmi_netfns[(netfn & 0x01) + 16];
851     else if ( netfn > 0x0d )
852 	netfn_fs = ipmi_netfns[(netfn & 0x01) + 14];
853     else
854 	netfn_fs = ipmi_netfns[netfn];
855 
856     snprintf(buffer, buf_len, netfn_fs, netfn);
857 
858     return buffer;
859 }
860 
861 static char * ipmi_app_cmds[] =
862 {
863     "reserved:%02x",		// +0 : 0x00
864     "GetDevId:%02x",		// +1 : 0x01
865     "ColdReset:%02x",		// +2 : 0x02
866     "WarmReset:%02x",		// +3 : 0x03
867     "GetSelfTest:%02x",		// +4 : 0x04
868     "ManuTestOn:%02x",		// +5 : 0x05
869     "SetACPIpwr:%02x",		// +6 : 0x06
870     "GetACPIpwr:%02x",		// +7 : 0x07
871     "GetDevGUID:%02x",		// +8 : 0x08 (0x09..0x21 unassigned)
872     "ResetWdog:%02x",		// +9 : 0x22
873     "unassigned:%02x",		// +10: 0x23 unassigned
874     "SetWdog:%02x",		// +11: 0x24
875     "GetWdog:%02x",		// +12: 0x25 (0x26..0x2d unassigned)
876     "SetBMCgblEna:%02x",	// +13: 0x2e
877     "GetBMCgblEna:%02x",	// +14: 0x2f
878     "ClrMsgFlags:%02x",		// +15: 0x30
879     "GetMsgFlags:%02x",		// +16: 0x31
880     "EnaMsgChRcv:%02x",		// +17: 0x32
881     "GetMsg:%02x",		// +18: 0x33
882     "SndMsg:%02x",		// +19: 0x34
883     "ReadEvntMsg:%02x",		// +20: 0x35
884     "GetBTifCap:%02x",		// +21: 0x36
885     "GetSysGUID:%02x",		// +22: 0x37
886     "GetChAuthCap:%02x",	// +23: 0x38
887     "GetSessChlng:%02x",	// +24: 0x39
888     "ActiSess:%02x",		// +25: 0x3a
889     "SetSessPrivlvl:%02x",	// +26: 0x3b
890     "CloseSess:%02x",		// +27: 0x3c
891     "GetSessInfo:%02x",		// +28: 0x3d
892     "unassigned:%02x",		// +29: 0x3e unassigned
893     "GetAuthCode:%02x",		// +30: 0x3f
894     "SetChAccess:%02x",		// +31: 0x40
895     "GetChAccess:%02x",		// +32: 0x41
896     "GetChInfoCmd:%02x",	// +33: 0x42
897     "SetUsrAccCmd:%02x",	// +34: 0x43
898     "GetUsrAccCmd:%02x",	// +35: 0x44
899     "SetUsrName:%02x",		// +36: 0x45
900     "GetUsrName:%02x",		// +37: 0x46
901     "SetUsrPasswd:%02x",	// +38: 0x47
902     "ActPayload:%02x",		// +39: 0x48
903     "DeactPayload:%02x",	// +40: 0x49
904     "GetPayloadActStat:%02x",	// +41: 0x4a
905     "GetPayloadInstInfo:%02x",	// +42: 0x4b
906     "SetUserPayloadAcc:%02x",	// +43: 0x4c
907     "GetUserPayloadAcc:%02x",	// +44: 0x4d
908     "GetChanPayloadSup:%02x",	// +45: 0x4e
909     "GetChanPayloadVer:%02x",	// +46: 0x4f
910     "GetChanOEMPayloadInf:%02x",// +47: 0x50
911     "unassigned:%02x",		// +48: 0x51 unassigned
912     "MstrWrRd:%02x",		// +49: 0x52
913     "unassigned:%02x",		// +50: 0x53 unassigned
914     "GetChanCipherSuites:%02x",	// +51: 0x54
915     "SuspResPayloadEnc:%02x",	// +52: 0x55
916     "SetChanSecKey:%02x",	// +53: 0x56
917     "GetSysIntfCap:%02x",	// +54: 0x57
918 };
919 
920 static char * ipmi_chassis_cmds[] =
921 {
922     "GetChassisCap:%02x",	// +0 : 0x00
923     "GetChassisSts:%02x",	// +1 : 0x01
924     "ChassisCtrl:%02x",		// +2 : 0x02
925     "ChassisReset:%02x",	// +3 : 0x03
926     "ChassisIdent:%02x",	// +4 : 0x04
927     "SetChassisCap:%02x",	// +5 : 0x05
928     "SetPwrRestPol:%02x",	// +6 : 0x06
929     "GetSysRstCause:%02x",	// +7 : 0x07
930     "SetSysBootOp:%02x",	// +8 : 0x08
931     "GetSysBootOp:%02x",	// +9 : 0x09
932     "unassigned:%02x",		// +10: 0x0a..0x0e unassigned
933     "GetPOHcounter:%02x",	// +11: 0x0f
934 };
935 
936 static char * ipmi_se_cmds[] =
937 {
938     "SetEvntRcvr:%02x",		// +0 : 0x00
939     "GetEvntRcvr:%02x",		// +1 : 0x01
940     "EventMsg:%02x",		// +2 : 0x02 (0x03..0x0f unassigned)
941     "GetPEFcap:%02x",		// +3 : 0x10
942     "ArmPEFtimer:%02x",		// +4 : 0x11
943     "SetPEFconfig:%02x",	// +5 : 0x12
944     "GetPEFconfig:%02x",	// +6 : 0x13
945     "SetLastEvId:%02x",		// +7 : 0x14
946     "GetLastEvId:%02x",		// +8 : 0x15
947     "AlertImmed:%02x",		// +9 : 0x16
948     "PETackn:%02x",		// +10: 0x17 (0x18..0x1f unassigned)
949     "GetDevSDRinfo:%02x",	// +11: 0x20
950     "GetDevSDR:%02x",		// +12: 0x21
951     "ReservSDRreposit:%02x",	// +13: 0x22
952     "GetSensReadFact:%02x",	// +14: 0x23
953     "SetSensHyst:%02x",		// +15: 0x24
954     "GetSensHyst:%02x",		// +16: 0x25
955     "SetSensThresh:%02x",	// +17: 0x26
956     "GetSensThresh:%02x",	// +18: 0x27
957     "SetSensEvEna:%02x",	// +29: 0x28
958     "GetSensEvEna:%02x",	// +20: 0x29
959     "RearmSensEv:%02x",		// +21: 0x2a
960     "GetSensEvStat:%02x",	// +22: 0x2b
961     "unassigned:%02x",		// +23: 0x2c unassigned
962     "GetSensReading:%02x",	// +24: 0x2d
963     "SetSensType:%02x",		// +25: 0x2e
964     "GetSensType:%02x",		// +26: 0x2f
965 };
966 
967 static char * ipmi_storage_cmds[] =
968 {
969     "unassigned:%02x",		// +0 : 0x00..0x0f unassigned
970     "GetFRUinvInfo:%02x",	// +1 : 0x10
971     "ReadFRUdata:%02x",		// +2 : 0x11
972     "WriteFRUdata:%02x",	// +3 : 0x12 (0x13..0x1f unassigned)
973     "GetSDRrepInfo:%02x",	// +4 : 0x20
974     "GetSDRrepAlloc:%02x",	// +5 : 0x21
975     "ResrvSDRrepo:%02x",	// +6 : 0x22
976     "GetSDR:%02x",		// +7 : 0x23
977     "AddSDR:%02x",		// +8 : 0x24
978     "PartialAddSDR:%02x",	// +9 : 0x25
979     "DeleteSDR:%02x",		// +10: 0x26
980     "ClrSDRrepo:%02x",		// +11: 0x27
981     "GetSDRrepTime:%02x",	// +12: 0x28
982     "SetSDRrepTime:%02x",	// +13: 0x29
983     "EntrSDRrepUpd:%02x",	// +14: 0x2a
984     "ExitSDRrepUpd:%02x",	// +15: 0x2b
985     "RunInitAgent:%02x",	// +16: 0x2c (0x2d..0x3f unassigned)
986     "GetSELinfo:%02x",		// +17: 0x40
987     "GetSELallocInfo:%02x",	// +18: 0x41
988     "ReservSEL:%02x",		// +19: 0x42
989     "GetSELentry:%02x",		// +20: 0x43
990     "AddSELentry:%02x",		// +21: 0x44
991     "PartAddSELentry:%02x",	// +22: 0x45
992     "DeleteSELent:%02x",	// +23: 0x46
993     "ClrSEL:%02x",		// +24: 0x47
994     "GetSELtime:%02x",		// +25: 0x48
995     "SetSELtime:%02x",		// +26: 0x49 (0x4a..0x59 unassigned)
996     "GetAuxLogSts:%02x",	// +27: 0x5a
997     "SetAuxLogSts:%02x",	// +28: 0x5b
998 };
999 
1000 static char * ipmi_transport_cmds[] =
1001 {
1002     "unassigned:%02x",		// +0 : 0x00 unassigned
1003     "SetLANconfParm:%02x",	// +1 : 0x01
1004     "GetLANconfParm:%02x",	// +2 : 0x02
1005     "SuspBMCarps:%02x",		// +3 : 0x03
1006     "GetIPstats:%02x",		// +4 : 0x04 (0x05..0x0f unassigned)
1007     "SetSerialConf:%02x",	// +5 : 0x10
1008     "GetSerialConf:%02x",	// +6 : 0x11
1009     "SetSerialMux:%02x",	// +7 : 0x12
1010     "GetTAPrespCodes:%02x",	// +8 : 0x13
1011     "SetPPPproxyTx:%02x",	// +9 : 0x14
1012     "GetPPPproxyTx:%02x",	// +10: 0x15
1013     "SendPPPproxyPkt:%02x",	// +11: 0x16
1014     "GetPPPproxyRxData:%02x",	// +12: 0x17
1015     "SerialConnAct:%02x",	// +13: 0x18
1016     "Callback:%02x",		// +14: 0x19
1017     "SetUsrCallOpts:%02x",	// +15: 0x1a
1018     "GetUsrCallOpts:%02x",	// +16: 0x1b
1019     "unassigned:%02x",		// +17: 0x1c
1020     "unassigned:%02x",		// +18: 0x1d
1021     "unassigned:%02x",		// +19: 0x1e
1022     "unassigned:%02x",		// +20: 0x1f
1023     "SOLActivating:%02x",	// +21: 0x20
1024     "SetSOLConfParm:%02x",	// +22: 0x21
1025     "GetSOLConfParm:%02x",	// +23: 0x22
1026 };
1027 
1028 static char * ipmi_bridge_cmds[] =
1029 {
1030     "GetBridgeState:%02x",	// +0 : 0x00
1031     "SetBridgeState:%02x",	// +1 : 0x01
1032     "GetICMBaddr:%02x",		// +2 : 0x02
1033     "SetICMBaddr:%02x",		// +3 : 0x03
1034     "SetBridgeProxyAddr:%02x",	// +4 : 0x04
1035     "GetBridgeStats:%02x",	// +5 : 0x05
1036     "GetICMBcaps:%02x",		// +6 : 0x06
1037     "unassigned:%02x",		// +7 : 0x07 unassigned
1038     "ClrBridgeStats:%02x",	// +8 : 0x08
1039     "GetBridgeProxyAddr:%02x",	// +9 : 0x09
1040     "GetICMBConnInfo:%02x",	// +10: 0x0a
1041     "GetICMBConnId:%02x",	// +11: 0x0b
1042     "SendICMBConnId:%02x",	// +12: 0x0c (0x0d..0x0f unassigned)
1043     "Prep4Disc:%02x",		// +13: 0x10
1044     "GetAddresses:%02x",	// +14: 0x11
1045     "SetDiscovered:%02x",	// +15: 0x12
1046     "GetChassDevId:%02x",	// +16: 0x13
1047     "SetChassDevId:%02x",	// +17: 0x14 (0x15..0x1f unassigned)
1048     "BridgeRequest:%02x",	// +18: 0x20
1049     "BridgeMessage:%02x",	// +19: 0x21 (0x22..0x2f unassigned)
1050     "GetEventCnt:%02x",		// +20: 0x30
1051     "SetEventDest:%02x",	// +21: 0x31
1052     "SetEventRecpState:%02x",	// +22: 0x32
1053     "SndICMBevMsg:%02x",	// +23: 0x33
1054     "GetEventDest:%02x",	// +24: 0x34
1055     "GetEventRecpState:%02x",	// +25: 0x35 (0x36..0xbf unassigned)
1056     "OEMcommands:%02x",		// +26: 0xc0..0xfe
1057     "ErrorReport:%02x",		// +27: 0xff
1058 };
1059 
1060 /*
1061  * Convert a NetFN/Command code into a string
1062  */
1063 char *
ipmi_get_command_string(unsigned int netfn,unsigned int cmd,char * buffer,unsigned int buf_len)1064 ipmi_get_command_string(unsigned int netfn,
1065 			unsigned int cmd,
1066 			char         *buffer,
1067 			unsigned int buf_len)
1068 {
1069     char **netfn_table;
1070     char *cmd_fs = NULL;
1071 
1072     netfn &= 0x3f;
1073 
1074     if ( netfn <= 0x0d ) {
1075 	switch ( netfn ) {
1076 	    case IPMI_CHASSIS_NETFN:
1077 	    case IPMI_CHASSIS_NETFN | 1:
1078 	    {
1079 		netfn_table=ipmi_chassis_cmds;
1080 		if ( cmd < 0x0b )
1081 		    cmd_fs = netfn_table[cmd];
1082 		else if ( cmd == 0x0f )
1083 		    cmd_fs = netfn_table[11];
1084 		break;
1085 	    }
1086 	    case IPMI_BRIDGE_NETFN:
1087 	    case IPMI_BRIDGE_NETFN | 1:
1088 	    {
1089 		netfn_table=ipmi_bridge_cmds;
1090 		if ( cmd < 0x0d )
1091 		    cmd_fs = netfn_table[cmd];
1092 		else if ( (cmd > 0x0f) && (cmd < 0x15) )
1093 		    cmd_fs = netfn_table[cmd - 0x10 + 13];
1094 		else if ( (cmd > 0x1f) && (cmd < 0x22) )
1095 		    cmd_fs = netfn_table[cmd - 0x20 + 18];
1096 		else if ( (cmd > 0x2f) && (cmd < 0x36) )
1097 		    cmd_fs = netfn_table[cmd - 0x30 + 20];
1098 		else if ( (cmd > 0xbf) && (cmd < 0xff) )
1099 		    cmd_fs = netfn_table[26];
1100 		break;
1101 	    }
1102 	    case IPMI_SENSOR_EVENT_NETFN:
1103 	    case IPMI_SENSOR_EVENT_NETFN | 1:
1104 	    {
1105 		netfn_table=ipmi_se_cmds;
1106 		if ( cmd < 0x03 )
1107 		    cmd_fs = netfn_table[cmd];
1108 		else if ( (cmd > 0x0f) && (cmd < 0x18) )
1109 		    cmd_fs = netfn_table[cmd - 0x10 + 3];
1110 		else if ( (cmd > 0x1f) && (cmd < 0x30) )
1111 		    cmd_fs = netfn_table[cmd - 0x20 + 11];
1112 		break;
1113 	    }
1114 	    case IPMI_APP_NETFN:
1115 	    case IPMI_APP_NETFN | 1:
1116 	    {
1117 		netfn_table=ipmi_app_cmds;
1118 		if ( cmd < 0x09 )
1119 		    cmd_fs = netfn_table[cmd];
1120 		else if ( (cmd > 0x21) && (cmd < 0x26) )
1121 		    cmd_fs = netfn_table[cmd - 0x22 + 9];
1122 		else if ( (cmd > 0x2d) && (cmd < 0x58) )
1123 		    cmd_fs = netfn_table[cmd - 0x2e + 13];
1124 		break;
1125 	    }
1126 	    case IPMI_FIRMWARE_NETFN:
1127 	    case IPMI_FIRMWARE_NETFN | 1:
1128 	    {
1129 		cmd_fs="unknown:%02x";
1130 		break;
1131 	    }
1132 	    case IPMI_STORAGE_NETFN:
1133 	    case IPMI_STORAGE_NETFN | 1:
1134 	    {
1135 		netfn_table=ipmi_storage_cmds;
1136 		if ( cmd < 0x10 )
1137 		    cmd_fs = netfn_table[0];
1138 		else if ( (cmd > 0x0f) && (cmd < 0x13) )
1139 		    cmd_fs = netfn_table[cmd - 0x10 + 1];
1140 		else if ( (cmd > 0x1f) && (cmd < 0x2d) )
1141 		    cmd_fs = netfn_table[cmd - 0x20 + 4];
1142 		else if ( (cmd > 0x3f) && (cmd < 0x4a) )
1143 		    cmd_fs = netfn_table[cmd - 0x40 + 17];
1144 		else if ( (cmd > 0x59) && (cmd < 0x5c) )
1145 		    cmd_fs = netfn_table[cmd - 0x5a + 27];
1146 		break;
1147 	    }
1148 	    case IPMI_TRANSPORT_NETFN:
1149 	    case IPMI_TRANSPORT_NETFN | 1:
1150 	    {
1151 		netfn_table=ipmi_transport_cmds;
1152 		if ( cmd < 0x05 )
1153 		    cmd_fs = netfn_table[cmd];
1154 		else if ( (cmd > 0x0f) && (cmd < 0x23) )
1155 		    cmd_fs = netfn_table[cmd - 0x10 + 5];
1156 		break;
1157 	    }
1158 	}
1159     }
1160 
1161     if (!cmd_fs)
1162 	cmd_fs = "unknown:%02x";
1163 
1164     snprintf(buffer, buf_len, cmd_fs, cmd);
1165 
1166     return buffer;
1167 }
1168 
1169 static char *ipmi_ccodes[] =
1170 {
1171     "Normal:%02x",	// +0 : 0x00 (0x01..0xbf undefined)
1172     "NodeBusy:%02x",	// +1 : 0xc0
1173     "InvCmd:%02x",	// +2 : 0xc1
1174     "InvCmd4LUN:%02x",	// +3 : 0xc2
1175     "Timeout:%02x",	// +4 : 0xc3
1176     "OutOfSpace:%02x",	// +5 : 0xc4
1177     "ResvCancInv:%02x",	// +6 : 0xc5
1178     "DataTrunc:%02x",	// +7 : 0xc6
1179     "DataLenInv:%02x",	// +8 : 0xc7
1180     "DataLenOvr:%02x",	// +9 : 0xc8
1181     "PrmRangeErr:%02x",	// +10: 0xc9
1182     "InsuffData:%02x",	// +11: 0xca
1183     "ObjNotPres:%02x",	// +12: 0xcb
1184     "InvDataFld:%02x",	// +13: 0xcc
1185     "IllCmd4Obj:%02x",	// +14: 0xcd
1186     "NoResponse:%02x",	// +15: 0xce
1187     "DupReq:%02x",	// +16: 0xcf
1188     "SDRrepoBusy:%02x",	// +17: 0xd0
1189     "FirmwareUpd:%02x",	// +18: 0xd1
1190     "BMCiniting:%02x",	// +19: 0xd2
1191     "DestUnavail:%02x",	// +20: 0xd3
1192     "PrivError:%02x",	// +21: 0xd4
1193     "InvalState:%02x",	// +22: 0xd5 (0xd6..0xfe undefined)
1194     "Unspecified:%02x",	// +23: 0xff
1195 };
1196 /*
1197  * Convert a Completion Code into a string
1198  */
1199 char *
ipmi_get_cc_string(unsigned int cc,char * buffer,unsigned int buf_len)1200 ipmi_get_cc_string(unsigned int cc,
1201 		   char         *buffer,
1202 		   unsigned int buf_len)
1203 {
1204     char *cc_fs;
1205 
1206     if ( cc == 0x00 )
1207 	cc_fs = ipmi_ccodes[0];
1208     else if ( (cc > 0xbf) && (cc < 0xd6) )
1209 	cc_fs = ipmi_ccodes[cc - 0xc0 + 1];
1210     else if ( cc == 0xff )
1211 	cc_fs = ipmi_ccodes[23];
1212     else
1213 	cc_fs = "Unknown:%02x";
1214 
1215     snprintf(buffer, buf_len, cc_fs, cc);
1216 
1217     return buffer;
1218 }
1219 
1220 int
ipmi_get_cc_string_len(unsigned int cc)1221 ipmi_get_cc_string_len(unsigned int cc)
1222 {
1223     char *cc_fs;
1224     char dummy[1];
1225 
1226     if ( cc == 0x00 )
1227 	cc_fs = ipmi_ccodes[0];
1228     else if ( (cc > 0xbf) && (cc < 0xd6) )
1229 	cc_fs = ipmi_ccodes[cc - 0xc0 + 1];
1230     else if ( cc == 0xff )
1231 	cc_fs = ipmi_ccodes[23];
1232     else
1233 	cc_fs = "Unknown:%02x";
1234 
1235     return snprintf(dummy, 1, cc_fs, cc);
1236 }
1237 
1238 
1239 static const char *sol_error_codes[] =
1240 {
1241     "SoLCharTransUnavail",
1242     "SoLDeactivated",
1243     "SoLNotAvailable",
1244     "SoLDisconnected",
1245     "SoLUnconfirmOp",
1246     "SoLFlushed",
1247     "SoLUnknown"
1248 };
1249 
1250 static const char *rmcpp_error_codes[] =
1251 {
1252     "InsufResourForSess",
1253     "InvalSessID",
1254     "InvalPayloadType",
1255     "InvalAuthAlg",
1256     "InvalIntegAlg",
1257     "NoMatchAuthPayld",
1258     "NoMatchIntegPayld",
1259     "InactSessID",
1260     "InvalidRole",
1261     "UnauthRoleOrPriv",
1262     "InsufResourForRole",
1263     "InvalNameLength",
1264     "UnauthName",
1265     "UnauthGUID",
1266     "InvalIntegChkVal",
1267     "InvalConfidAlg",
1268     "NoCipherSuiteMatch",
1269     "IllegalParam",
1270     "RMCPPUnknown"
1271 };
1272 
1273 char *
ipmi_get_error_string(unsigned int err,char * buffer,unsigned int buf_len)1274 ipmi_get_error_string(unsigned int err,
1275 		      char         *buffer,
1276 		      unsigned int buf_len)
1277 {
1278     unsigned int len;
1279     char         *err_type;
1280 
1281     if (err == 0) {
1282 	strncpy(buffer, "Success (No error)", buf_len);
1283 	return buffer;
1284     }
1285 
1286     if (IPMI_IS_OS_ERR(err)) {
1287 	snprintf(buffer+4, buf_len-4, "%s", strerror(IPMI_GET_OS_ERR(err)));
1288 	err_type = "OS: ";
1289     } else if (IPMI_IS_IPMI_ERR(err)) {
1290 	ipmi_get_cc_string(IPMI_GET_IPMI_ERR(err), buffer+6, buf_len-6);
1291 	err_type = "IPMI: ";
1292     } else if (IPMI_IS_RMCPP_ERR(err)) {
1293 	int rmcpp_err = IPMI_GET_RMCPP_ERR(err);
1294 	if ((rmcpp_err <= 0) || (rmcpp_err > 0x12))
1295 	    rmcpp_err = 0x13;
1296 	snprintf(buffer+7, buf_len-7, "%s (0x%02x)",
1297 		 rmcpp_error_codes[rmcpp_err - 1],
1298 		 IPMI_GET_RMCPP_ERR(err));
1299 	err_type = "RMCP+: ";
1300     } else if (IPMI_IS_SOL_ERR(err)) {
1301 	int sol_err = IPMI_GET_SOL_ERR(err);
1302 	if ((sol_err < 1) || (sol_err > 7))
1303 	    sol_err = 7;
1304 	strncpy(buffer+5, sol_error_codes[sol_err - 1], buf_len-5);
1305 	err_type = "SoL: ";
1306     } else {
1307 	strncpy(buffer+9, "Unknown", buf_len-9);
1308 	err_type = "Unknown: ";
1309     }
1310 
1311     len = strlen(err_type);
1312     if (len > buf_len-1) {
1313 	len = buf_len-1;
1314 	buffer[buf_len-1] = '\0';
1315     }
1316     memcpy(buffer, err_type, len);
1317 
1318     return buffer;
1319 }
1320 
ipmi_get_error_string_len(unsigned int err)1321 int ipmi_get_error_string_len(unsigned int err)
1322 {
1323     if (err == 0)
1324 	return(strlen("Success (No error)"));
1325 
1326     if (IPMI_IS_OS_ERR(err))
1327 	return strlen(strerror(IPMI_GET_OS_ERR(err))) + 5;
1328     else if (IPMI_IS_IPMI_ERR(err)) {
1329 	return ipmi_get_cc_string_len(IPMI_GET_IPMI_ERR(err)) + 7;
1330     } else if (IPMI_IS_RMCPP_ERR(err)) {
1331 	int rmcpp_err = IPMI_GET_RMCPP_ERR(err);
1332 	if ((rmcpp_err <= 0) || (rmcpp_err > 0x12))
1333 	    rmcpp_err = 0x13;
1334 	return strlen(rmcpp_error_codes[rmcpp_err - 1]) + 15;
1335     } else if (IPMI_IS_SOL_ERR(err)) {
1336 	int sol_err = IPMI_GET_SOL_ERR(err);
1337 	if ((sol_err < 1) || (sol_err > 7))
1338 	    sol_err = 7;
1339 	return strlen(sol_error_codes[sol_err - 1]) + 6;
1340     } else {
1341 	return strlen("Unknown") + 10;
1342     }
1343 }
1344 
1345 /* Get a string name fo the hot swap state. */
1346 const char *
ipmi_hot_swap_state_name(enum ipmi_hot_swap_states state)1347 ipmi_hot_swap_state_name(enum ipmi_hot_swap_states state)
1348 {
1349     switch (state) {
1350     case IPMI_HOT_SWAP_NOT_PRESENT: return "not_present";
1351     case IPMI_HOT_SWAP_INACTIVE: return "inactive";
1352     case IPMI_HOT_SWAP_ACTIVATION_REQUESTED: return "activation_requested";
1353     case IPMI_HOT_SWAP_ACTIVATION_IN_PROGRESS: return "activation_in_progress";
1354     case IPMI_HOT_SWAP_ACTIVE: return "active";
1355     case IPMI_HOT_SWAP_DEACTIVATION_REQUESTED: return "deactivation_requested";
1356     case IPMI_HOT_SWAP_DEACTIVATION_IN_PROGRESS: return "deactivation_in_progress";
1357     case IPMI_HOT_SWAP_OUT_OF_CON: return "out_of_con";
1358     default: return "invalid_state";
1359     }
1360 }
1361 
1362 static char *domain_types[] =
1363 {
1364     "unknown",
1365     "MXP",
1366     "ATCA",
1367     "ATCA_BLADE",
1368 };
1369 #define NUM_DOMAIN_TYPES (sizeof(domain_types)/sizeof(char *))
1370 
1371 const char *
ipmi_domain_get_type_string(enum ipmi_domain_type dtype)1372 ipmi_domain_get_type_string(enum ipmi_domain_type dtype)
1373 {
1374     if ((dtype < 0) || (dtype >= NUM_DOMAIN_TYPES))
1375 	return "invalid";
1376     return domain_types[dtype];
1377 }
1378 
1379 const char *
ipmi_authtype_string(int authtype)1380 ipmi_authtype_string(int authtype)
1381 {
1382     switch(authtype) {
1383     case IPMI_AUTHTYPE_DEFAULT:
1384 	return "default";
1385     case IPMI_AUTHTYPE_NONE:
1386 	return "none";
1387     case IPMI_AUTHTYPE_MD2:
1388 	return "md2";
1389     case IPMI_AUTHTYPE_MD5:
1390 	return "md5";
1391     case IPMI_AUTHTYPE_STRAIGHT:
1392 	return "straight";
1393     case IPMI_AUTHTYPE_OEM:
1394 	return "oem";
1395     case IPMI_AUTHTYPE_RMCP_PLUS:
1396 	return "rmcp+";
1397     default:
1398 	return "invalid";
1399     }
1400 }
1401 
1402 const char *
ipmi_privilege_string(int privilege)1403 ipmi_privilege_string(int privilege)
1404 {
1405     switch(privilege) {
1406     case IPMI_PRIVILEGE_CALLBACK:
1407 	return "callback";
1408     case IPMI_PRIVILEGE_USER:
1409 	return "user";
1410     case IPMI_PRIVILEGE_OPERATOR:
1411 	return "operator";
1412     case IPMI_PRIVILEGE_ADMIN:
1413 	return "admin";
1414     case IPMI_PRIVILEGE_OEM:
1415 	return "oem";
1416     default:
1417 	return "invalid";
1418     }
1419 }
1420 
1421 const char *
ipmi_channel_medium_string(int val)1422 ipmi_channel_medium_string(int val)
1423 {
1424     switch (val) {
1425     case IPMI_CHANNEL_MEDIUM_IPMB:
1426 	return "IPMB";
1427     case IPMI_CHANNEL_MEDIUM_ICMB_V10:
1428 	return "ICMB_V10";
1429     case IPMI_CHANNEL_MEDIUM_ICMB_V09:
1430 	return "ICMB_V09";
1431     case IPMI_CHANNEL_MEDIUM_8023_LAN:
1432 	return "8023_LAN";
1433     case IPMI_CHANNEL_MEDIUM_RS232:
1434 	return "RS232";
1435     case IPMI_CHANNEL_MEDIUM_OTHER_LAN:
1436 	return "OTHER_LAN";
1437     case IPMI_CHANNEL_MEDIUM_PCI_SMBUS:
1438 	return "PCI_SMBUS";
1439     case IPMI_CHANNEL_MEDIUM_SMBUS_v1:
1440 	return "SMBUS_v1";
1441     case IPMI_CHANNEL_MEDIUM_SMBUS_v2:
1442 	return "SMBUS_v2";
1443     case IPMI_CHANNEL_MEDIUM_USB_v1:
1444 	return "USB_v1";
1445     case IPMI_CHANNEL_MEDIUM_USB_v2:
1446 	return "USB_v2";
1447     case IPMI_CHANNEL_MEDIUM_SYS_INTF:
1448 	return "SYS_INTF";
1449     default:
1450 	return "invalid";
1451     }
1452 }
1453 
1454 const char *
ipmi_channel_protocol_string(int val)1455 ipmi_channel_protocol_string(int val)
1456 {
1457     switch (val) {
1458     case IPMI_CHANNEL_PROTOCOL_IPMB:
1459 	return "IPMB";
1460     case IPMI_CHANNEL_PROTOCOL_ICMB:
1461 	return "ICMB";
1462     case IPMI_CHANNEL_PROTOCOL_SMBus:
1463 	return "SMBus";
1464     case IPMI_CHANNEL_PROTOCOL_KCS:
1465 	return "KCS";
1466     case IPMI_CHANNEL_PROTOCOL_SMIC:
1467 	return "SMIC";
1468     case IPMI_CHANNEL_PROTOCOL_BT_v10:
1469 	return "BT_v10";
1470     case IPMI_CHANNEL_PROTOCOL_BT_v15:
1471 	return "BT_v15";
1472     case IPMI_CHANNEL_PROTOCOL_TMODE:
1473 	return "TMODE";
1474     default:
1475 	return "invalid";
1476     }
1477 }
1478 
1479 const char *
ipmi_channel_session_support_string(int val)1480 ipmi_channel_session_support_string(int val)
1481 {
1482     switch (val) {
1483     case IPMI_CHANNEL_SESSION_LESS:
1484 	return "session-less";
1485     case IPMI_CHANNEL_SINGLE_SESSION:
1486 	return "single-session";
1487     case IPMI_CHANNEL_MULTI_SESSION:
1488 	return "multi-session";
1489     case IPMI_CHANNEL_SESSION_BASED:
1490 	return "session-based";
1491     default:
1492 	return "invalid";
1493     }
1494 }
1495 
1496 const char *
ipmi_channel_access_mode_string(int val)1497 ipmi_channel_access_mode_string(int val)
1498 {
1499     switch (val) {
1500     case IPMI_CHANNEL_ACCESS_MODE_DISABLED:
1501 	return "DISABLED";
1502     case IPMI_CHANNEL_ACCESS_MODE_PRE_BOOT:
1503 	return "PRE_BOOT";
1504     case IPMI_CHANNEL_ACCESS_MODE_ALWAYS:
1505 	return "ALWAYS";
1506     case IPMI_CHANNEL_ACCESS_MODE_SHARED:
1507 	return "SHARED";
1508     default:
1509 	return "invalid";
1510     }
1511 }
1512