1 /*
2  * cmd_pet.c
3  *
4  * A command interpreter for OpenIPMI
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2004 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 <errno.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_pet.h>
41 #include <OpenIPMI/ipmi_mc.h>
42 #include <OpenIPMI/ipmi_cmdlang.h>
43 
44 
45 static void
pet_list_handler(ipmi_pet_t * pet,void * cb_data)46 pet_list_handler(ipmi_pet_t *pet, void *cb_data)
47 {
48     ipmi_cmd_info_t *cmd_info = cb_data;
49     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
50     char            pet_name[IPMI_PET_NAME_LEN];
51 
52     if (cmdlang->err)
53 	return;
54 
55     ipmi_pet_get_name(pet, pet_name, sizeof(pet_name));
56 
57     ipmi_cmdlang_out(cmd_info, "Name", pet_name);
58 }
59 
60 static void
pet_list(ipmi_domain_t * domain,void * cb_data)61 pet_list(ipmi_domain_t *domain, void *cb_data)
62 {
63     ipmi_cmd_info_t *cmd_info = cb_data;
64     char             domain_name[IPMI_DOMAIN_NAME_LEN];
65 
66     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
67     ipmi_cmdlang_out(cmd_info, "Domain", NULL);
68     ipmi_cmdlang_down(cmd_info);
69     ipmi_cmdlang_out(cmd_info, "Name", domain_name);
70     ipmi_cmdlang_out(cmd_info, "PETs", NULL);
71     ipmi_cmdlang_down(cmd_info);
72     ipmi_pet_iterate_pets(domain, pet_list_handler, cmd_info);
73     ipmi_cmdlang_up(cmd_info);
74     ipmi_cmdlang_up(cmd_info);
75 }
76 
77 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)78 get_mc_name(ipmi_mc_t *mc, void *cb_data)
79 {
80     ipmi_cmd_info_t *cmd_info = cb_data;
81     char            mc_name[IPMI_MC_NAME_LEN];
82 
83     ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
84     ipmi_cmdlang_out(cmd_info, "MC", mc_name);
85 }
86 
87 static void
pet_info(ipmi_pet_t * pet,void * cb_data)88 pet_info(ipmi_pet_t *pet, void *cb_data)
89 {
90     ipmi_cmd_info_t *cmd_info = cb_data;
91     int             rv;
92     unsigned char   mac_addr[6];
93     struct in_addr  ip_addr;
94     char            pet_name[IPMI_PET_NAME_LEN];
95 
96     ipmi_pet_get_name(pet, pet_name, sizeof(pet_name));
97     ipmi_cmdlang_out(cmd_info, "PET", NULL);
98     ipmi_cmdlang_down(cmd_info);
99     ipmi_cmdlang_out(cmd_info, "Name", pet_name);
100     rv = ipmi_mc_pointer_cb(ipmi_pet_get_mc_id(pet), get_mc_name, cmd_info);
101     if (rv)
102 	ipmi_cmdlang_out(cmd_info, "Domain", NULL);
103     ipmi_cmdlang_out_int(cmd_info, "Channel", ipmi_pet_get_channel(pet));
104     ipmi_cmdlang_out_ip(cmd_info, "IP Address",
105 			ipmi_pet_get_ip_addr(pet, &ip_addr));
106     ipmi_cmdlang_out_mac(cmd_info, "MAC Address",
107 			 ipmi_pet_get_mac_addr(pet, mac_addr));
108     ipmi_cmdlang_out_int(cmd_info, "EFT Selector", ipmi_pet_get_eft_sel(pet));
109     ipmi_cmdlang_out_int(cmd_info, "Policy Number",
110 			 ipmi_pet_get_policy_num(pet));
111     ipmi_cmdlang_out_int(cmd_info, "APT Selector", ipmi_pet_get_apt_sel(pet));
112     ipmi_cmdlang_out_int(cmd_info, "LAN Dest Selector",
113 			 ipmi_pet_get_lan_dest_sel(pet));
114     ipmi_cmdlang_up(cmd_info);
115 }
116 
117 static void
pet_done(ipmi_pet_t * pet,int err,void * cb_data)118 pet_done(ipmi_pet_t *pet, int err, void *cb_data)
119 {
120     ipmi_cmd_info_t *cmd_info = cb_data;
121     char            pet_name[IPMI_PET_NAME_LEN];
122 
123     ipmi_pet_get_name(pet, pet_name, sizeof(pet_name));
124     ipmi_cmdlang_out(cmd_info, "PET Created", pet_name);
125     ipmi_cmdlang_cmd_info_put(cmd_info);
126 }
127 
128 static void
pet_new(ipmi_domain_t * domain,void * cb_data)129 pet_new(ipmi_domain_t *domain, void *cb_data)
130 {
131     ipmi_cmd_info_t *cmd_info = cb_data;
132     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
133     int             connection;
134     int             channel;
135     struct in_addr  ip_addr;
136     unsigned char   mac_addr[6];
137     int             eft_selector;
138     int             policy_num;
139     int             apt_selector;
140     int             lan_dest_selector;
141     int             rv;
142     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
143     int             argc = ipmi_cmdlang_get_argc(cmd_info);
144     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
145 
146     if ((argc - curr_arg) < 8) {
147 	/* Not enough parameters */
148 	cmdlang->errstr = "Not enough parameters";
149 	cmdlang->err = EINVAL;
150 	goto out_err;
151     }
152 
153     ipmi_cmdlang_get_int(argv[curr_arg], &connection, cmd_info);
154     if (cmdlang->err) {
155 	cmdlang->errstr = "connection invalid";
156 	goto out_err;
157     }
158     curr_arg++;
159 
160     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
161     if (cmdlang->err) {
162 	cmdlang->errstr = "channel invalid";
163 	goto out_err;
164     }
165     curr_arg++;
166 
167     ipmi_cmdlang_get_ip(argv[curr_arg],	&ip_addr, cmd_info);
168     if (cmdlang->err) {
169 	cmdlang->errstr = "ip addr invalid";
170 	goto out_err;
171     }
172     curr_arg++;
173 
174     ipmi_cmdlang_get_mac(argv[curr_arg], mac_addr, cmd_info);
175     if (cmdlang->err) {
176 	cmdlang->errstr = "mac addr invalid";
177 	goto out_err;
178     }
179     curr_arg++;
180 
181     ipmi_cmdlang_get_int(argv[curr_arg], &eft_selector, cmd_info);
182     if (cmdlang->err) {
183 	cmdlang->errstr = "eft_selector invalid";
184 	goto out_err;
185     }
186     curr_arg++;
187 
188     ipmi_cmdlang_get_int(argv[curr_arg], &policy_num, cmd_info);
189     if (cmdlang->err) {
190 	cmdlang->errstr = "policy num invalid";
191 	goto out_err;
192     }
193     curr_arg++;
194 
195     ipmi_cmdlang_get_int(argv[curr_arg], &apt_selector, cmd_info);
196     if (cmdlang->err) {
197 	cmdlang->errstr = "apt selectory invalid";
198 	goto out_err;
199     }
200     curr_arg++;
201 
202     ipmi_cmdlang_get_int(argv[curr_arg], &lan_dest_selector, cmd_info);
203     if (cmdlang->err) {
204 	cmdlang->errstr = "lan dest selector invalid";
205 	goto out_err;
206     }
207     curr_arg++;
208 
209     ipmi_cmdlang_cmd_info_get(cmd_info);
210     rv = ipmi_pet_create(domain,
211 			 connection,
212 			 channel,
213 			 ip_addr,
214 			 mac_addr,
215 			 eft_selector,
216 			 policy_num,
217 			 apt_selector,
218 			 lan_dest_selector,
219 			 pet_done,
220 			 cmd_info,
221 			 NULL);
222     if (rv) {
223 	ipmi_cmdlang_cmd_info_put(cmd_info);
224 	cmdlang->errstr = "Error from ipmi_pet_create";
225 	cmdlang->err = rv;
226 	goto out_err;
227     }
228 
229     return;
230 
231  out_err:
232     ipmi_domain_get_name(domain, cmdlang->objstr,
233 			 cmdlang->objstr_len);
234     cmdlang->location = "cmd_pet.c(pet_new)";
235 }
236 
237 static void
pet_mcnew(ipmi_mc_t * mc,void * cb_data)238 pet_mcnew(ipmi_mc_t *mc, void *cb_data)
239 {
240     ipmi_cmd_info_t *cmd_info = cb_data;
241     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
242     int             channel;
243     struct in_addr  ip_addr;
244     unsigned char   mac_addr[6];
245     int             eft_selector;
246     int             policy_num;
247     int             apt_selector;
248     int             lan_dest_selector;
249     int             rv;
250     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
251     int             argc = ipmi_cmdlang_get_argc(cmd_info);
252     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
253 
254     if ((argc - curr_arg) < 7) {
255 	/* Not enough parameters */
256 	cmdlang->errstr = "Not enough parameters";
257 	cmdlang->err = EINVAL;
258 	goto out_err;
259     }
260 
261     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
262     if (cmdlang->err) {
263 	cmdlang->errstr = "channel invalid";
264 	goto out_err;
265     }
266     curr_arg++;
267 
268     ipmi_cmdlang_get_ip(argv[curr_arg],	&ip_addr, cmd_info);
269     if (cmdlang->err) {
270 	cmdlang->errstr = "ip addr invalid";
271 	goto out_err;
272     }
273     curr_arg++;
274 
275     ipmi_cmdlang_get_mac(argv[curr_arg], mac_addr, cmd_info);
276     if (cmdlang->err) {
277 	cmdlang->errstr = "mac addr invalid";
278 	goto out_err;
279     }
280     curr_arg++;
281 
282     ipmi_cmdlang_get_int(argv[curr_arg], &eft_selector, cmd_info);
283     if (cmdlang->err) {
284 	cmdlang->errstr = "eft_selector invalid";
285 	goto out_err;
286     }
287     curr_arg++;
288 
289     ipmi_cmdlang_get_int(argv[curr_arg], &policy_num, cmd_info);
290     if (cmdlang->err) {
291 	cmdlang->errstr = "policy num invalid";
292 	goto out_err;
293     }
294     curr_arg++;
295 
296     ipmi_cmdlang_get_int(argv[curr_arg], &apt_selector, cmd_info);
297     if (cmdlang->err) {
298 	cmdlang->errstr = "apt selectory invalid";
299 	goto out_err;
300     }
301     curr_arg++;
302 
303     ipmi_cmdlang_get_int(argv[curr_arg], &lan_dest_selector, cmd_info);
304     if (cmdlang->err) {
305 	cmdlang->errstr = "lan dest selector invalid";
306 	goto out_err;
307     }
308     curr_arg++;
309 
310     ipmi_cmdlang_cmd_info_get(cmd_info);
311     rv = ipmi_pet_create_mc(mc,
312 			    channel,
313 			    ip_addr,
314 			    mac_addr,
315 			    eft_selector,
316 			    policy_num,
317 			    apt_selector,
318 			    lan_dest_selector,
319 			    pet_done,
320 			    cmd_info,
321 			    NULL);
322     if (rv) {
323 	ipmi_cmdlang_cmd_info_put(cmd_info);
324 	cmdlang->errstr = "Error from ipmi_pet_create";
325 	cmdlang->err = rv;
326 	goto out_err;
327     }
328 
329     return;
330 
331  out_err:
332     ipmi_mc_get_name(mc, cmdlang->objstr,
333 		     cmdlang->objstr_len);
334     cmdlang->location = "cmd_pet.c(pet_mcnew)";
335 }
336 
337 static void
close_done(ipmi_pet_t * pet,int err,void * cb_data)338 close_done(ipmi_pet_t *pet, int err, void *cb_data)
339 {
340     ipmi_cmd_info_t *cmd_info = cb_data;
341     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
342     char            pet_name[IPMI_PET_NAME_LEN];
343 
344     ipmi_cmdlang_lock(cmd_info);
345     if (err) {
346 	ipmi_pet_get_name(pet, cmdlang->objstr,
347 			  cmdlang->objstr_len);
348 	cmdlang->errstr = "Error closing PET";
349 	cmdlang->err = err;
350 	cmdlang->location = "cmd_pet.c(close_done)";
351 	goto out;
352     }
353 
354     ipmi_pet_get_name(pet, pet_name, sizeof(pet_name));
355     ipmi_cmdlang_out(cmd_info, "PET destroyed", pet_name);
356 
357  out:
358     ipmi_cmdlang_unlock(cmd_info);
359     ipmi_cmdlang_cmd_info_put(cmd_info);
360 }
361 
362 static void
pet_close(ipmi_pet_t * pet,void * cb_data)363 pet_close(ipmi_pet_t *pet, void *cb_data)
364 {
365     ipmi_cmd_info_t *cmd_info = cb_data;
366     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
367     int             rv;
368 
369     ipmi_cmdlang_cmd_info_get(cmd_info);
370     rv = ipmi_pet_destroy(pet, close_done, cmd_info);
371     if (rv) {
372 	ipmi_pet_get_name(pet, cmdlang->objstr,
373 			  cmdlang->objstr_len);
374 	ipmi_cmdlang_cmd_info_put(cmd_info);
375 	cmdlang->errstr = "Error closing PET";
376 	cmdlang->err = rv;
377 	cmdlang->location = "cmd_pet.c(pet_close)";
378     }
379 }
380 
381 static ipmi_cmdlang_cmd_t *pet_cmds;
382 
383 static ipmi_cmdlang_init_t cmds_pet[] =
384 {
385     { "pet", NULL,
386       "- Commands dealing with Platform Event Traps (PETs)",
387       NULL, NULL, &pet_cmds},
388     { "list", &pet_cmds,
389       "- List all the pets in the system",
390       ipmi_cmdlang_domain_handler, pet_list,  NULL },
391     { "new", &pet_cmds,
392       "<domain> <connection> <channel> <ip addr> <mac_addr> <eft selector>"
393       " <policy num> <apt selector> <lan dest selector>"
394       " - Set up the domain to send PET traps from the given connection"
395       " to the given IP/MAC address over the given channel",
396       ipmi_cmdlang_domain_handler, pet_new, NULL },
397     { "mcnew", &pet_cmds,
398       "<mc> <channel> <ip addr> <mac_addr> <eft selector>"
399       " <policy num> <apt selector> <lan dest selector>"
400       " - Set up the domain to send PET traps from the given connection"
401       " to the given IP/MAC address over the given channel",
402       ipmi_cmdlang_mc_handler, pet_mcnew, NULL },
403     { "info", &pet_cmds,
404       "<pet> - Dump information about a pet",
405       ipmi_cmdlang_pet_handler, pet_info, NULL },
406     { "close", &pet_cmds,
407       "<pet> - Close the pet",
408       ipmi_cmdlang_pet_handler, pet_close, NULL },
409 };
410 #define CMDS_PET_LEN (sizeof(cmds_pet)/sizeof(ipmi_cmdlang_init_t))
411 
412 int
ipmi_cmdlang_pet_init(os_handler_t * os_hnd)413 ipmi_cmdlang_pet_init(os_handler_t *os_hnd)
414 {
415     return ipmi_cmdlang_reg_table(cmds_pet, CMDS_PET_LEN);
416 }
417