1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <libipmi.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 static const char *pname;
31 static const char optstr[] = "h:p:u:t:";
32 
33 static void
34 usage()
35 {
36 	(void) fprintf(stderr,
37 	    "Usage: %s [-t <bmc|lan>] [-h hostname] [-u username] "
38 	    "[-p password]\n", pname);
39 }
40 
41 /*ARGSUSED*/
42 static int
43 sdr_print(ipmi_handle_t *ihp, ipmi_entity_t *ep, const char *name,
44     ipmi_sdr_t *sdrp, void *data)
45 {
46 	int indentation = (uintptr_t)data;
47 	ipmi_sdr_compact_sensor_t *csp;
48 	ipmi_sdr_full_sensor_t *fsp;
49 	uint8_t sensor_number, sensor_type, reading_type;
50 	boolean_t get_reading = B_FALSE;
51 	ipmi_sensor_reading_t *srp;
52 	char sensor_name[128];
53 	char reading_name[128];
54 
55 	if (name == NULL)
56 		return (0);
57 
58 	switch (sdrp->is_type) {
59 	case IPMI_SDR_TYPE_COMPACT_SENSOR:
60 		csp = (ipmi_sdr_compact_sensor_t *)sdrp->is_record;
61 		sensor_number = csp->is_cs_number;
62 		sensor_type = csp->is_cs_type;
63 		reading_type = csp->is_cs_reading_type;
64 		get_reading = B_TRUE;
65 		break;
66 
67 	case IPMI_SDR_TYPE_FULL_SENSOR:
68 		fsp = (ipmi_sdr_full_sensor_t *)sdrp->is_record;
69 		sensor_number = fsp->is_fs_number;
70 		sensor_type = fsp->is_fs_type;
71 		reading_type = fsp->is_fs_reading_type;
72 		get_reading = B_TRUE;
73 		break;
74 	}
75 
76 	(void) printf("%*s%-*s", indentation, "",
77 	    36 - indentation, name);
78 
79 	if (get_reading) {
80 		ipmi_sensor_type_name(sensor_type, sensor_name,
81 		    sizeof (sensor_name));
82 		ipmi_sensor_reading_name(sensor_type, reading_type,
83 		    reading_name, sizeof (reading_name));
84 		(void) printf("%12s  %12s", sensor_name, reading_name);
85 		if ((srp = ipmi_get_sensor_reading(ihp,
86 		    sensor_number)) == NULL) {
87 			if (ipmi_errno(ihp) == EIPMI_NOT_PRESENT) {
88 				(void) printf("      -\n");
89 			} else {
90 				(void) printf("\n");
91 				return (-1);
92 			}
93 		} else {
94 			(void) printf("   %04x\n", srp->isr_state);
95 		}
96 	} else {
97 		(void) printf("\n");
98 	}
99 
100 	return (0);
101 }
102 
103 static int
104 entity_print(ipmi_handle_t *ihp, ipmi_entity_t *ep, void *data)
105 {
106 	int indentation = (uintptr_t)data;
107 	char name[128];
108 	boolean_t present;
109 
110 	ipmi_entity_name(ep->ie_type, name, sizeof (name));
111 	(void) snprintf(name + strlen(name), sizeof (name) - strlen(name),
112 	    " %d", ep->ie_instance);
113 
114 	if (ipmi_entity_present(ihp, ep, &present) != 0) {
115 		(void) printf("%*s%-*s  %s (%s)\n", indentation, "",
116 		    24 - indentation, name, "unknown", ipmi_errmsg(ihp));
117 	} else {
118 		(void) printf("%*s%-*s  %s\n", indentation, "",
119 		    24 - indentation, name, present ? "present" : "absent");
120 	}
121 	(void) ipmi_entity_iter_sdr(ihp, ep, sdr_print,
122 	    (void *)(indentation + 2));
123 
124 	if (ep->ie_children != 0)
125 		(void) ipmi_entity_iter_children(ihp, ep, entity_print,
126 		    (void *)(indentation + 2));
127 	return (0);
128 }
129 
130 int
131 main(int argc, char **argv)
132 {
133 	ipmi_handle_t *ihp;
134 	char *errmsg;
135 	uint_t xport_type;
136 	char c, *host = NULL, *user = NULL, *passwd = NULL;
137 	int err;
138 	nvlist_t *params = NULL;
139 
140 	pname = argv[0];
141 	while (optind < argc) {
142 		while ((c = getopt(argc, argv, optstr)) != -1)
143 			switch (c) {
144 			case 'h':
145 				host = optarg;
146 				break;
147 			case 'p':
148 				passwd = optarg;
149 				break;
150 			case 't':
151 				if (strcmp(optarg, "bmc") == 0)
152 					xport_type = IPMI_TRANSPORT_BMC;
153 				else if (strcmp(optarg, "lan") == 0)
154 					xport_type = IPMI_TRANSPORT_LAN;
155 				else {
156 					(void) fprintf(stderr,
157 					    "ABORT: Invalid transport type\n");
158 					usage();
159 				}
160 				break;
161 			case 'u':
162 				user = optarg;
163 				break;
164 			default:
165 				usage();
166 				return (1);
167 			}
168 	}
169 
170 	if (xport_type == IPMI_TRANSPORT_LAN &&
171 	    (host == NULL || passwd == NULL || user == NULL)) {
172 		(void) fprintf(stderr, "-h/-u/-p must all be specified for "
173 		    "transport type \"lan\"\n");
174 		usage();
175 		return (1);
176 	}
177 	if (xport_type == IPMI_TRANSPORT_LAN) {
178 		if (nvlist_alloc(&params, NV_UNIQUE_NAME, 0) ||
179 		    nvlist_add_string(params, IPMI_LAN_HOST, host) ||
180 		    nvlist_add_string(params, IPMI_LAN_USER, user) ||
181 		    nvlist_add_string(params, IPMI_LAN_PASSWD, passwd)) {
182 			(void) fprintf(stderr,
183 			    "ABORT: nvlist construction failed\n");
184 			return (1);
185 		}
186 	}
187 	if ((ihp = ipmi_open(&err, &errmsg, xport_type, params)) == NULL) {
188 		(void) fprintf(stderr, "failed to open libipmi: %s\n",
189 		    errmsg);
190 		return (1);
191 	}
192 
193 	(void) printf("%-24s  %-8s  %12s  %12s  %5s\n",
194 	    "ENTITY/SENSOR", "PRESENT", "SENSOR", "READING", "STATE");
195 	(void) printf("-----------------------  --------  -------------  "
196 	    "------------  -----\n");
197 	if (ipmi_entity_iter(ihp, entity_print, NULL) != 0) {
198 		(void) fprintf(stderr, "failed to iterate entities: %s\n",
199 		    ipmi_errmsg(ihp));
200 		return (1);
201 	}
202 
203 	ipmi_close(ihp);
204 
205 	return (0);
206 }
207