1 /*
2  * cmd_lanparm.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_lanparm.h>
41 #include <OpenIPMI/ipmi_cmdlang.h>
42 #include <OpenIPMI/ipmi_mc.h>
43 
44 /* Internal includes, do not use in your programs */
45 #include <OpenIPMI/internal/ipmi_malloc.h>
46 #include <OpenIPMI/internal/locked_list.h>
47 
48 static locked_list_t *lancs;
49 
50 static void
lanparm_list_handler(ipmi_lanparm_t * lanparm,void * cb_data)51 lanparm_list_handler(ipmi_lanparm_t *lanparm, void *cb_data)
52 {
53     ipmi_cmd_info_t *cmd_info = cb_data;
54     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
55     char            lanparm_name[IPMI_LANPARM_NAME_LEN];
56 
57     if (cmdlang->err)
58 	return;
59 
60     ipmi_lanparm_get_name(lanparm, lanparm_name, sizeof(lanparm_name));
61 
62     ipmi_cmdlang_out(cmd_info, "Name", lanparm_name);
63 }
64 
65 static void
lanparm_list(ipmi_domain_t * domain,void * cb_data)66 lanparm_list(ipmi_domain_t *domain, void *cb_data)
67 {
68     ipmi_cmd_info_t *cmd_info = cb_data;
69     char             domain_name[IPMI_DOMAIN_NAME_LEN];
70 
71     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
72     ipmi_cmdlang_out(cmd_info, "Domain", NULL);
73     ipmi_cmdlang_down(cmd_info);
74     ipmi_cmdlang_out(cmd_info, "Name", domain_name);
75     ipmi_cmdlang_out(cmd_info, "LANPARMs", NULL);
76     ipmi_cmdlang_down(cmd_info);
77     ipmi_lanparm_iterate_lanparms(domain, lanparm_list_handler, cmd_info);
78     ipmi_cmdlang_up(cmd_info);
79     ipmi_cmdlang_up(cmd_info);
80 }
81 
82 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)83 get_mc_name(ipmi_mc_t *mc, void *cb_data)
84 {
85     ipmi_cmd_info_t *cmd_info = cb_data;
86     char            mc_name[IPMI_MC_NAME_LEN];
87 
88     ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
89     ipmi_cmdlang_out(cmd_info, "MC", mc_name);
90 }
91 
92 static void
lanparm_info(ipmi_lanparm_t * lanparm,void * cb_data)93 lanparm_info(ipmi_lanparm_t *lanparm, void *cb_data)
94 {
95     ipmi_cmd_info_t *cmd_info = cb_data;
96     int             rv;
97     char            lanparm_name[IPMI_LANPARM_NAME_LEN];
98 
99     ipmi_lanparm_get_name(lanparm, lanparm_name, sizeof(lanparm_name));
100 
101     ipmi_cmdlang_out(cmd_info, "LANPARM", NULL);
102     ipmi_cmdlang_down(cmd_info);
103     ipmi_cmdlang_out(cmd_info, "Name", lanparm_name);
104     rv = ipmi_mc_pointer_cb(ipmi_lanparm_get_mc_id(lanparm), get_mc_name,
105 			    cmd_info);
106     if (rv) {
107 	ipmi_cmdlang_out_int(cmd_info, "Error getting MC", rv);
108     }
109     ipmi_cmdlang_out_int(cmd_info, "Channel",
110 			 ipmi_lanparm_get_channel(lanparm));
111     ipmi_cmdlang_up(cmd_info);
112 }
113 
114 static void
lanparm_new(ipmi_mc_t * mc,void * cb_data)115 lanparm_new(ipmi_mc_t *mc, void *cb_data)
116 {
117     ipmi_cmd_info_t *cmd_info = cb_data;
118     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
119     int             channel;
120     int             rv;
121     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
122     int             argc = ipmi_cmdlang_get_argc(cmd_info);
123     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
124     ipmi_lanparm_t  *lanparm;
125     char            lanparm_name[IPMI_LANPARM_NAME_LEN];
126 
127     if ((argc - curr_arg) < 1) {
128 	/* Not enough parameters */
129 	cmdlang->errstr = "Not enough parameters";
130 	cmdlang->err = EINVAL;
131 	goto out_err;
132     }
133 
134     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
135     if (cmdlang->err) {
136 	cmdlang->errstr = "channel invalid";
137 	goto out_err;
138     }
139     curr_arg++;
140 
141     rv = ipmi_lanparm_alloc(mc, channel, &lanparm);
142     if (rv) {
143 	cmdlang->errstr = "Error from ipmi_lanparm_alloc";
144 	cmdlang->err = rv;
145 	goto out_err;
146     }
147 
148     ipmi_lanparm_get_name(lanparm, lanparm_name, sizeof(lanparm_name));
149     ipmi_cmdlang_out(cmd_info, "LANPARM", lanparm_name);
150 
151     return;
152 
153  out_err:
154     ipmi_mc_get_name(mc, cmdlang->objstr,
155 		     cmdlang->objstr_len);
156     cmdlang->location = "cmd_lanparm.c(lanparm_new)";
157 }
158 
159 typedef struct lanparm_info_s
160 {
161     char            name[IPMI_LANPARM_NAME_LEN];
162     ipmi_cmd_info_t *cmd_info;
163 } lanparm_info_t;
164 
165 static void
lanparm_close_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)166 lanparm_close_done(ipmi_lanparm_t *lanparm, int err, void *cb_data)
167 {
168     lanparm_info_t  *info = cb_data;
169     ipmi_cmd_info_t *cmd_info = info->cmd_info;
170     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
171 
172     ipmi_cmdlang_lock(cmd_info);
173     if (err) {
174 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
175 			  cmdlang->objstr_len);
176 	cmdlang->errstr = "Error closing LANPARM";
177 	cmdlang->err = err;
178 	cmdlang->location = "cmd_lanparm.c(lanparm_close_done)";
179 	goto out;
180     }
181 
182     ipmi_cmdlang_out(cmd_info, "LANPARM destroyed", info->name);
183 
184  out:
185     ipmi_cmdlang_unlock(cmd_info);
186     ipmi_cmdlang_cmd_info_put(cmd_info);
187     ipmi_mem_free(info);
188 }
189 
190 static void
lanparm_close(ipmi_lanparm_t * lanparm,void * cb_data)191 lanparm_close(ipmi_lanparm_t *lanparm, void *cb_data)
192 {
193     ipmi_cmd_info_t *cmd_info = cb_data;
194     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
195     int             rv;
196     lanparm_info_t  *info;
197 
198     info = ipmi_mem_alloc(sizeof(*info));
199     if (!info) {
200 	cmdlang->errstr = "Out of memory";
201 	cmdlang->err = ENOMEM;
202 	goto out_err;
203     }
204     info->cmd_info = cmd_info;
205     ipmi_lanparm_get_name(lanparm, info->name, sizeof(info->name));
206 
207     ipmi_cmdlang_cmd_info_get(cmd_info);
208     rv = ipmi_lanparm_destroy(lanparm, lanparm_close_done, info);
209     if (rv) {
210 	ipmi_cmdlang_cmd_info_put(cmd_info);
211 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
212 			      cmdlang->objstr_len);
213 	cmdlang->errstr = "Error closing LANPARM";
214 	cmdlang->err = rv;
215 	ipmi_mem_free(info);
216     }
217     return;
218 
219  out_err:
220     cmdlang->location = "cmd_lanparm.c(lanparm_close)";
221 }
222 
223 #define LAN_CONFIG_NAME_LEN 80
224 typedef struct lan_config_info_s
225 {
226     char              name[LAN_CONFIG_NAME_LEN];
227     ipmi_lan_config_t *config;
228 } lan_config_info_t;
229 
230 static unsigned int unique_num = 0;
231 
232 typedef struct find_config_s
233 {
234     char              *name;
235     ipmi_lan_config_t *config;
236     int               delete;
237 } find_config_t;
238 
239 static int
find_config_handler(void * cb_data,void * item1,void * item2)240 find_config_handler(void *cb_data, void *item1, void *item2)
241 {
242     lan_config_info_t *info = item1;
243     find_config_t     *find = cb_data;
244 
245     if (strcmp(find->name, info->name) == 0) {
246 	find->config = info->config;
247 	if (find->delete) {
248 	    locked_list_remove(lancs, item1, item2);
249 	    ipmi_mem_free(info);
250 	}
251 	return LOCKED_LIST_ITER_STOP;
252     }
253 
254     return LOCKED_LIST_ITER_CONTINUE;
255 }
256 
257 static ipmi_lan_config_t *
find_config(char * name,int delete)258 find_config(char *name, int delete)
259 {
260     find_config_t find;
261 
262     find.name = name;
263     find.config = NULL;
264     find.delete = delete;
265     locked_list_iterate(lancs, find_config_handler, &find);
266     return find.config;
267 }
268 
269 typedef void (*lp_set)(ipmi_cmd_info_t *cmd_info, char *val,
270 		       ipmi_lan_config_t *lanc, void *func);
271 typedef void (*lp_out)(ipmi_cmd_info_t *cmd_info, char *name,
272 		       ipmi_lan_config_t *lanc, void *func);
273 typedef struct lp_item_s
274 {
275     lp_set set;
276     lp_out out;
277 } lp_item_t;
278 
279 static void
set_retint(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)280 set_retint(ipmi_cmd_info_t *cmd_info, char *val,
281 	   ipmi_lan_config_t *lanc, void *func)
282 {
283     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
284     int            (*f)(ipmi_lan_config_t *l, unsigned int v) = func;
285     int            v;
286 
287     ipmi_cmdlang_get_int(val, &v, cmd_info);
288     if (!cmdlang->err) {
289 	cmdlang->err = f(lanc, v);
290 	if (cmdlang->err) {
291 	    cmdlang->errstr = "Error setting parameter";
292 	}
293     }
294 }
295 static void
out_retint(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)296 out_retint(ipmi_cmd_info_t *cmd_info, char *name,
297 	   ipmi_lan_config_t *lanc, void *func)
298 {
299     unsigned int   (*f)(ipmi_lan_config_t *l) = func;
300     ipmi_cmdlang_out_int(cmd_info, name, f(lanc));
301 }
302 static lp_item_t lp_retint = {set_retint, out_retint};
303 
304 static void
set_retbool(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)305 set_retbool(ipmi_cmd_info_t *cmd_info, char *val,
306 	    ipmi_lan_config_t *lanc, void *func)
307 {
308     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
309     int            (*f)(ipmi_lan_config_t *l, unsigned int v) = func;
310     int            v;
311 
312     ipmi_cmdlang_get_bool(val, &v, cmd_info);
313     if (!cmdlang->err) {
314 	cmdlang->err = f(lanc, v);
315 	if (cmdlang->err) {
316 	    cmdlang->errstr = "Error setting parameter";
317 	}
318     }
319 }
320 static void
out_retbool(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)321 out_retbool(ipmi_cmd_info_t *cmd_info, char *name,
322 	    ipmi_lan_config_t *lanc, void *func)
323 {
324     unsigned int   (*f)(ipmi_lan_config_t *l) = func;
325     ipmi_cmdlang_out_bool(cmd_info, name, f(lanc));
326 }
327 static lp_item_t lp_retbool = {set_retbool, out_retbool};
328 
329 static void
set_int(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)330 set_int(ipmi_cmd_info_t *cmd_info, char *val,
331 	ipmi_lan_config_t *lanc, void *func)
332 {
333     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
334     int            (*f)(ipmi_lan_config_t *l, unsigned int v) = func;
335     int            v;
336 
337     ipmi_cmdlang_get_int(val, &v, cmd_info);
338     if (!cmdlang->err) {
339 	cmdlang->err = f(lanc, v);
340 	if (cmdlang->err) {
341 	    cmdlang->errstr = "Error setting parameter";
342 	}
343     }
344 }
345 static void
out_int(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)346 out_int(ipmi_cmd_info_t *cmd_info, char *name,
347 	ipmi_lan_config_t *lanc, void *func)
348 {
349     unsigned int   v;
350     int            rv;
351     int            (*f)(ipmi_lan_config_t *l, unsigned int *v) = func;
352 
353     rv = f(lanc, &v);
354     if (!rv)
355 	ipmi_cmdlang_out_int(cmd_info, name, v);
356 }
357 static lp_item_t lp_int = {set_int, out_int};
358 
359 static void
set_bool(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)360 set_bool(ipmi_cmd_info_t *cmd_info, char *val,
361 	 ipmi_lan_config_t *lanc, void *func)
362 {
363     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
364     int            (*f)(ipmi_lan_config_t *l, unsigned int v) = func;
365     int            v;
366 
367     ipmi_cmdlang_get_bool(val, &v, cmd_info);
368     if (!cmdlang->err) {
369 	cmdlang->err = f(lanc, v);
370 	if (cmdlang->err) {
371 	    cmdlang->errstr = "Error setting parameter";
372 	}
373     }
374 }
375 static void
out_bool(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)376 out_bool(ipmi_cmd_info_t *cmd_info, char *name,
377 	 ipmi_lan_config_t *lanc, void *func)
378 {
379     unsigned int   v;
380     int            rv;
381     int            (*f)(ipmi_lan_config_t *l, unsigned int *v) = func;
382 
383     rv = f(lanc, &v);
384     if (!rv)
385 	ipmi_cmdlang_out_bool(cmd_info, name, v);
386 }
387 static lp_item_t lp_bool = {set_bool, out_bool};
388 
389 static void
set_ip(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)390 set_ip(ipmi_cmd_info_t *cmd_info, char *val,
391        ipmi_lan_config_t *lanc, void *func)
392 {
393     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
394     int            (*f)(ipmi_lan_config_t *l, unsigned char *v,
395 			unsigned int dl) = func;
396     struct in_addr v;
397 
398     ipmi_cmdlang_get_ip(val, &v, cmd_info);
399     if (!cmdlang->err) {
400 	cmdlang->err = f(lanc, (unsigned char *) &v, sizeof(v));
401 	if (cmdlang->err) {
402 	    cmdlang->errstr = "Error setting parameter";
403 	}
404     }
405 }
406 static void
out_ip(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)407 out_ip(ipmi_cmd_info_t *cmd_info, char *name,
408        ipmi_lan_config_t *lanc, void *func)
409 {
410     struct in_addr v;
411     int            rv;
412     int            (*f)(ipmi_lan_config_t *l, unsigned char *v,
413 			unsigned int *dl) = func;
414     unsigned int   len = sizeof(v);
415 
416     rv = f(lanc, (unsigned char *) &v, &len);
417     if (!rv)
418 	ipmi_cmdlang_out_ip(cmd_info, name, &v);
419 }
420 static lp_item_t lp_ip = {set_ip, out_ip};
421 
422 static void
set_port(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)423 set_port(ipmi_cmd_info_t *cmd_info, char *val,
424 	 ipmi_lan_config_t *lanc, void *func)
425 {
426     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
427     int            (*f)(ipmi_lan_config_t *l, unsigned char *v,
428 			unsigned int dl) = func;
429     int            v;
430 
431     ipmi_cmdlang_get_int(val, &v, cmd_info);
432     if (!cmdlang->err) {
433 	cmdlang->err = f(lanc, (unsigned char *) &v, sizeof(v));
434 	if (cmdlang->err) {
435 	    cmdlang->errstr = "Error setting parameter";
436 	}
437     }
438 }
439 static void
out_port(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)440 out_port(ipmi_cmd_info_t *cmd_info, char *name,
441 	 ipmi_lan_config_t *lanc, void *func)
442 {
443     short          v;
444     int            rv;
445     int            (*f)(ipmi_lan_config_t *l, unsigned char *v,
446 			unsigned int *dl) = func;
447     unsigned int   len = sizeof(v);
448 
449     rv = f(lanc, (unsigned char *) &v, &len);
450     if (!rv) {
451 	v = ntohs(v);
452 	ipmi_cmdlang_out_int(cmd_info, name, v);
453     }
454 }
455 static lp_item_t lp_port = {set_port, out_port};
456 
457 static void
set_mac(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)458 set_mac(ipmi_cmd_info_t *cmd_info, char *val,
459 	ipmi_lan_config_t *lanc, void *func)
460 {
461     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
462     int            (*f)(ipmi_lan_config_t *l, unsigned char *v,
463 			unsigned int dl) = func;
464     unsigned char  v[6];
465 
466     ipmi_cmdlang_get_mac(val, v, cmd_info);
467     if (!cmdlang->err) {
468 	cmdlang->err = f(lanc, v, sizeof(v));
469 	if (cmdlang->err) {
470 	    cmdlang->errstr = "Error setting parameter";
471 	}
472     }
473 }
474 static void
out_mac(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)475 out_mac(ipmi_cmd_info_t *cmd_info, char *name,
476 	ipmi_lan_config_t *lanc, void *func)
477 {
478     unsigned char v[6];
479     int           rv;
480     int           (*f)(ipmi_lan_config_t *l, unsigned char *v,
481 		       unsigned int *dl) = func;
482     unsigned int  len = sizeof(v);
483 
484     rv = f(lanc, v, &len);
485     if (!rv)
486 	ipmi_cmdlang_out_mac(cmd_info, name, v);
487 }
488 static lp_item_t lp_mac = {set_mac, out_mac};
489 
490 static void
set_str(ipmi_cmd_info_t * cmd_info,char * val,ipmi_lan_config_t * lanc,void * func)491 set_str(ipmi_cmd_info_t *cmd_info, char *val,
492 	ipmi_lan_config_t *lanc, void *func)
493 {
494     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
495     int            (*f)(ipmi_lan_config_t *l, char *v,
496 			unsigned int dl) = func;
497 
498     if (!cmdlang->err) {
499 	cmdlang->err = f(lanc, val, strlen(val));
500 	if (cmdlang->err) {
501 	    cmdlang->errstr = "Error setting parameter";
502 	}
503     }
504 }
505 static void
out_str(ipmi_cmd_info_t * cmd_info,char * name,ipmi_lan_config_t * lanc,void * func)506 out_str(ipmi_cmd_info_t *cmd_info, char *name,
507 	ipmi_lan_config_t *lanc, void *func)
508 {
509     char          v[100];
510     int           rv;
511     int           (*f)(ipmi_lan_config_t *l, char *v,
512 		       unsigned int *dl) = func;
513     unsigned int  len = sizeof(v);
514 
515     rv = f(lanc, v, &len);
516     if (!rv)
517 	ipmi_cmdlang_out(cmd_info, name, v);
518 }
519 static lp_item_t lp_str = {set_str, out_str};
520 
521 static struct lps_s
522 {
523     char      *name;
524     lp_item_t *lpi;
525     void      *get_func;
526     void      *set_func;
527 } lps[] =
528 /* read-only */
529 #define FR(name, type) { #name, &lp_ ## type, ipmi_lanconfig_get_ ## name, \
530 		         NULL }
531 /* Writable */
532 #define F(name, type) { #name, &lp_ ## type, ipmi_lanconfig_get_ ## name, \
533 		        ipmi_lanconfig_set_ ## name }
534 {
535     FR(support_auth_oem, retbool),
536     FR(support_auth_straight, retbool),
537     FR(support_auth_md5, retbool),
538     FR(support_auth_md2, retbool),
539     FR(support_auth_none, retbool),
540     F(ip_addr_source, retint),
541     FR(num_alert_destinations, retint),
542     F(ipv4_ttl, int),
543     F(ipv4_flags, int),
544     F(ipv4_precedence, int),
545     F(ipv4_tos, int),
546     F(ip_addr, ip),
547     F(mac_addr, mac),
548     F(subnet_mask, ip),
549     F(primary_rmcp_port, port),
550     F(secondary_rmcp_port, port),
551     F(bmc_generated_arps, bool),
552     F(bmc_generated_garps, bool),
553     F(garp_interval, int),
554     F(default_gateway_ip_addr, ip),
555     F(default_gateway_mac_addr, mac),
556     F(backup_gateway_ip_addr, ip),
557     F(backup_gateway_mac_addr, mac),
558     F(community_string, str),
559     F(vlan_id_enable, bool),
560     F(vlan_id, int),
561     F(vlan_priority, int),
562     { NULL }
563 };
564 
565 /*
566  * per-user items
567  */
568 typedef void (*ulp_set)(ipmi_cmd_info_t *cmd_info, int sel, char *val,
569 			ipmi_lan_config_t *lanc, void *func);
570 typedef void (*ulp_out)(ipmi_cmd_info_t *cmd_info, int sel, char *name,
571 			ipmi_lan_config_t *lanc, void *func);
572 typedef struct ulp_item_s
573 {
574     ulp_set set;
575     ulp_out out;
576 } ulp_item_t;
577 
578 static void
uset_bool(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_lan_config_t * lanc,void * func)579 uset_bool(ipmi_cmd_info_t *cmd_info, int sel, char *val,
580 	 ipmi_lan_config_t *lanc, void *func)
581 {
582     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
583     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
584 			unsigned int v) = func;
585     int            v;
586 
587     ipmi_cmdlang_get_bool(val, &v, cmd_info);
588     if (!cmdlang->err) {
589 	cmdlang->err = f(lanc, sel, v);
590 	if (cmdlang->err) {
591 	    cmdlang->errstr = "Error setting parameter";
592 	}
593     }
594 }
595 static void
uout_bool(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_lan_config_t * lanc,void * func)596 uout_bool(ipmi_cmd_info_t *cmd_info, int sel, char *name,
597 	 ipmi_lan_config_t *lanc, void *func)
598 {
599     unsigned int   v;
600     int            rv;
601     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
602 			unsigned int *v) = func;
603 
604     rv = f(lanc, sel, &v);
605     if (!rv)
606 	ipmi_cmdlang_out_bool(cmd_info, name, v);
607 }
608 static ulp_item_t lp_ubool = {uset_bool, uout_bool};
609 
610 static struct ulps_s
611 {
612     char       *name;
613     ulp_item_t *lpi;
614     void       *get_func;
615     void       *set_func;
616 } ulps[] =
617 {
618     F(enable_auth_oem, ubool),
619     F(enable_auth_straight, ubool),
620     F(enable_auth_md5, ubool),
621     F(enable_auth_md2, ubool),
622     F(enable_auth_none, ubool),
623     { NULL }
624 };
625 
626 /*
627  * per-alert-dest items
628  */
629 static void
uset_int(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_lan_config_t * lanc,void * func)630 uset_int(ipmi_cmd_info_t *cmd_info, int sel, char *val,
631 	 ipmi_lan_config_t *lanc, void *func)
632 {
633     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
634     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
635 			unsigned int v) = func;
636     int            v;
637 
638     ipmi_cmdlang_get_int(val, &v, cmd_info);
639     if (!cmdlang->err) {
640 	cmdlang->err = f(lanc, sel, v);
641 	if (cmdlang->err) {
642 	    cmdlang->errstr = "Error setting parameter";
643 	}
644     }
645 }
646 static void
uout_int(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_lan_config_t * lanc,void * func)647 uout_int(ipmi_cmd_info_t *cmd_info, int sel, char *name,
648 	 ipmi_lan_config_t *lanc, void *func)
649 {
650     unsigned int   v;
651     int            rv;
652     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
653 			unsigned int *v) = func;
654 
655     rv = f(lanc, sel, &v);
656     if (!rv)
657 	ipmi_cmdlang_out_int(cmd_info, name, v);
658 }
659 static ulp_item_t lp_uint = {uset_int, uout_int};
660 
661 static void
uset_ip(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_lan_config_t * lanc,void * func)662 uset_ip(ipmi_cmd_info_t *cmd_info, int sel, char *val,
663 	ipmi_lan_config_t *lanc, void *func)
664 {
665     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
666     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
667 			unsigned char *v, unsigned int dl) = func;
668     struct in_addr v;
669 
670     ipmi_cmdlang_get_ip(val, &v, cmd_info);
671     if (!cmdlang->err) {
672 	cmdlang->err = f(lanc, sel, (unsigned char *) &v, sizeof(v));
673 	if (cmdlang->err) {
674 	    cmdlang->errstr = "Error setting parameter";
675 	}
676     }
677 }
678 static void
uout_ip(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_lan_config_t * lanc,void * func)679 uout_ip(ipmi_cmd_info_t *cmd_info, int sel, char *name,
680 	ipmi_lan_config_t *lanc, void *func)
681 {
682     struct in_addr v;
683     int            rv;
684     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
685 			unsigned char *v, unsigned int *dl) = func;
686     unsigned int   len = sizeof(v);
687 
688     rv = f(lanc, sel, (unsigned char *) &v, &len);
689     if (!rv)
690 	ipmi_cmdlang_out_ip(cmd_info, name, &v);
691 }
692 static ulp_item_t lp_uip = {uset_ip, uout_ip};
693 
694 static void
uset_mac(ipmi_cmd_info_t * cmd_info,int sel,char * val,ipmi_lan_config_t * lanc,void * func)695 uset_mac(ipmi_cmd_info_t *cmd_info, int sel, char *val,
696 	 ipmi_lan_config_t *lanc, void *func)
697 {
698     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
699     int            (*f)(ipmi_lan_config_t *l, unsigned int sel,
700 			unsigned char *v, unsigned int dl) = func;
701     unsigned char  v[6];
702 
703     ipmi_cmdlang_get_mac(val, v, cmd_info);
704     if (!cmdlang->err) {
705 	cmdlang->err = f(lanc, sel, v, sizeof(v));
706 	if (cmdlang->err) {
707 	    cmdlang->errstr = "Error setting parameter";
708 	}
709     }
710 }
711 static void
uout_mac(ipmi_cmd_info_t * cmd_info,int sel,char * name,ipmi_lan_config_t * lanc,void * func)712 uout_mac(ipmi_cmd_info_t *cmd_info, int sel, char *name,
713 	 ipmi_lan_config_t *lanc, void *func)
714 {
715     unsigned char v[6];
716     int           rv;
717     int           (*f)(ipmi_lan_config_t *l, unsigned int sel,
718 		       unsigned char *v, unsigned int *dl) = func;
719     unsigned int  len = sizeof(v);
720 
721     rv = f(lanc, sel, v, &len);
722     if (!rv)
723 	ipmi_cmdlang_out_mac(cmd_info, name, v);
724 }
725 static ulp_item_t lp_umac = {uset_mac, uout_mac};
726 
727 static struct ulps_s alps[] =
728 {
729     F(alert_ack, ubool),
730     F(dest_type, uint),
731     F(alert_retry_interval, uint),
732     F(max_alert_retries, uint),
733     F(dest_format, uint),
734     F(gw_to_use, uint),
735     F(dest_ip_addr, uip),
736     F(dest_mac_addr, umac),
737     F(dest_vlan_tag_type, uint),
738     F(dest_vlan_tag, uint),
739     { NULL }
740 };
741 
742 static struct ulps_s clps[] =
743 {
744     F(cipher_suite_entry, uint),
745     F(max_priv_for_cipher_suite, uint),
746     { NULL }
747 };
748 
749 static char *user_names[5] =
750     { "callback", "user", "operator", "admin", "oem" };
751 
752 static void
config_info(ipmi_cmd_info_t * cmd_info,ipmi_lan_config_t * config)753 config_info(ipmi_cmd_info_t *cmd_info, ipmi_lan_config_t *config)
754 {
755     int i;
756     int user;
757     int num;
758 
759     /* Basic items */
760     for (i=0; lps[i].name; i++) {
761 	lp_item_t *lp = lps[i].lpi;
762 	lp->out(cmd_info, lps[i].name, config, lps[i].get_func);
763     }
764 
765     /* per-user items */
766     for (user=0; user<5; user++) {
767 	ipmi_cmdlang_out(cmd_info, "User", NULL);
768 	ipmi_cmdlang_down(cmd_info);
769 	ipmi_cmdlang_out(cmd_info, "Name", user_names[user]);
770 	for (i=0; ulps[i].name; i++) {
771 	    ulp_item_t *lp = ulps[i].lpi;
772 	    lp->out(cmd_info, user, ulps[i].name, config, ulps[i].get_func);
773 	}
774 	ipmi_cmdlang_up(cmd_info);
775     }
776 
777     /* per-destination items */
778     num = ipmi_lanconfig_get_num_alert_destinations(config);
779     for (user=0; user<num; user++) {
780 	ipmi_cmdlang_out(cmd_info, "Alert Destination", NULL);
781 	ipmi_cmdlang_down(cmd_info);
782 	ipmi_cmdlang_out_int(cmd_info, "Number", user);
783 	for (i=0; alps[i].name; i++) {
784 	    ulp_item_t *lp = alps[i].lpi;
785 	    lp->out(cmd_info, user, alps[i].name, config, alps[i].get_func);
786 	}
787 	ipmi_cmdlang_up(cmd_info);
788     }
789 
790     /* per-cipher-suite items */
791     num = ipmi_lanconfig_get_num_cipher_suites(config);
792     for (user=0; user<num; user++) {
793 	ipmi_cmdlang_out(cmd_info, "Cipher Suite", NULL);
794 	ipmi_cmdlang_down(cmd_info);
795 	ipmi_cmdlang_out_int(cmd_info, "Number", user);
796 	for (i=0; clps[i].name; i++) {
797 	    ulp_item_t *lp = clps[i].lpi;
798 	    lp->out(cmd_info, user, clps[i].name, config, clps[i].get_func);
799 	}
800 	ipmi_cmdlang_up(cmd_info);
801     }
802 }
803 
804 static void
lanparm_config_get_done(ipmi_lanparm_t * lanparm,int err,ipmi_lan_config_t * config,void * cb_data)805 lanparm_config_get_done(ipmi_lanparm_t    *lanparm,
806 			int               err,
807 			ipmi_lan_config_t *config,
808 			void              *cb_data)
809 {
810     ipmi_cmd_info_t   *cmd_info = cb_data;
811     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
812     char              lanparm_name[IPMI_LANPARM_NAME_LEN];
813     lan_config_info_t *info;
814 
815     ipmi_cmdlang_lock(cmd_info);
816     if (err) {
817 	cmdlang->errstr = "Error getting LANPARM";
818 	cmdlang->err = err;
819 	goto out;
820     }
821 
822     ipmi_lanparm_get_name(lanparm, lanparm_name, sizeof(lanparm_name));
823 
824     info = ipmi_mem_alloc(sizeof(*info));
825     if (!info) {
826 	cmdlang->errstr = "Out of memory";
827 	cmdlang->err = ENOMEM;
828 	ipmi_lan_free_config(config);
829 	goto out;
830     }
831     snprintf(info->name, sizeof(info->name), "%s.%u",
832 	     lanparm_name, unique_num);
833     info->config = config;
834     if (!locked_list_add(lancs, info, NULL)) {
835 	cmdlang->errstr = "Out of memory";
836 	cmdlang->err = ENOMEM;
837 	ipmi_lan_free_config(config);
838 	ipmi_mem_free(info);
839 	goto out;
840     }
841     unique_num++;
842 
843     ipmi_cmdlang_out(cmd_info, "LANPARM Config", NULL);
844     ipmi_cmdlang_down(cmd_info);
845     ipmi_cmdlang_out(cmd_info, "Name", info->name);
846     config_info(cmd_info, config);
847     ipmi_cmdlang_up(cmd_info);
848 
849  out:
850     if (cmdlang->err) {
851 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
852 			      cmdlang->objstr_len);
853 	cmdlang->location = "cmd_lanparm.c(lanparm_config_get_done)";
854     }
855     ipmi_cmdlang_unlock(cmd_info);
856     ipmi_cmdlang_cmd_info_put(cmd_info);
857 }
858 
859 static void
lanparm_config_get(ipmi_lanparm_t * lanparm,void * cb_data)860 lanparm_config_get(ipmi_lanparm_t *lanparm, void *cb_data)
861 {
862     ipmi_cmd_info_t *cmd_info = cb_data;
863     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
864     int             rv;
865 
866     ipmi_cmdlang_cmd_info_get(cmd_info);
867     rv = ipmi_lan_get_config(lanparm, lanparm_config_get_done, cmd_info);
868     if (rv) {
869 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
870 			      cmdlang->objstr_len);
871 	ipmi_cmdlang_cmd_info_put(cmd_info);
872 	cmdlang->errstr = "Error getting LANPARM";
873 	cmdlang->err = rv;
874 	cmdlang->location = "cmd_lanparm.c(lanparm_config_get)";
875     }
876 }
877 
878 typedef struct lp_config_op_s
879 {
880     char            name[LAN_CONFIG_NAME_LEN];
881     ipmi_cmd_info_t *cmd_info;
882 } lp_config_op_t;
883 
884 static void
lanparm_config_set_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)885 lanparm_config_set_done(ipmi_lanparm_t    *lanparm,
886 			int               err,
887 			void              *cb_data)
888 {
889     lp_config_op_t  *info = cb_data;
890     ipmi_cmd_info_t *cmd_info = info->cmd_info;
891     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
892 
893     ipmi_cmdlang_lock(cmd_info);
894     if (err) {
895 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
896 			      cmdlang->objstr_len);
897 	cmdlang->errstr = "Error setting LANPARM";
898 	cmdlang->err = err;
899 	cmdlang->location = "cmd_lanparm.c(lanparm_config_set_done)";
900 	goto out;
901     }
902 
903     ipmi_cmdlang_out(cmd_info, "LANPARM config set", info->name);
904 
905  out:
906     ipmi_mem_free(info);
907     ipmi_cmdlang_unlock(cmd_info);
908     ipmi_cmdlang_cmd_info_put(cmd_info);
909 }
910 
911 static void
lanparm_config_set(ipmi_lanparm_t * lanparm,void * cb_data)912 lanparm_config_set(ipmi_lanparm_t *lanparm, void *cb_data)
913 {
914     ipmi_cmd_info_t   *cmd_info = cb_data;
915     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
916     int               rv;
917     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
918     int               argc = ipmi_cmdlang_get_argc(cmd_info);
919     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
920     ipmi_lan_config_t *lanc;
921     lp_config_op_t    *info = cb_data;
922     char              *name;
923 
924     if ((argc - curr_arg) < 1) {
925 	/* Not enough parameters */
926 	cmdlang->errstr = "Not enough parameters";
927 	cmdlang->err = EINVAL;
928 	goto out_err;
929     }
930 
931     name = argv[curr_arg];
932     curr_arg++;
933 
934     lanc = find_config(name, 0);
935     if (!lanc) {
936 	cmdlang->errstr = "Invalid LAN config";
937 	cmdlang->err = EINVAL;
938 	goto out_err;
939     }
940 
941     info = ipmi_mem_alloc(sizeof(*info));
942     if (!info) {
943 	cmdlang->errstr = "Out of memory";
944 	cmdlang->err = ENOMEM;
945 	goto out_err;
946     }
947     info->cmd_info = cmd_info;
948     strncpy(info->name, name, sizeof(info->name) - 1);
949     info->name[sizeof(info->name) - 1] = '\0';
950 
951     ipmi_cmdlang_cmd_info_get(cmd_info);
952     rv = ipmi_lan_set_config(lanparm, lanc, lanparm_config_set_done, info);
953     if (rv) {
954 	ipmi_cmdlang_cmd_info_put(cmd_info);
955 	cmdlang->errstr = "Error setting LANPARM";
956 	cmdlang->err = rv;
957 	ipmi_mem_free(info);
958 	goto out_err;
959     }
960 
961     return;
962 
963  out_err:
964     ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
965 			  cmdlang->objstr_len);
966     cmdlang->location = "cmd_lanparm.c(lanparm_config_set)";
967 }
968 
969 static void
lanparm_config_unlock_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)970 lanparm_config_unlock_done(ipmi_lanparm_t    *lanparm,
971 			   int               err,
972 			   void              *cb_data)
973 {
974     lp_config_op_t  *info = cb_data;
975     ipmi_cmd_info_t *cmd_info = info->cmd_info;
976     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
977 
978     ipmi_cmdlang_lock(cmd_info);
979     if (err) {
980 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
981 			      cmdlang->objstr_len);
982 	cmdlang->errstr = "Error unlocking LANPARM";
983 	cmdlang->err = err;
984 	cmdlang->location = "cmd_lanparm.c(lanparm_config_unlock_done)";
985 	goto out;
986     }
987 
988     ipmi_cmdlang_out(cmd_info, "LANPARM config unlocked", info->name);
989 
990  out:
991     ipmi_mem_free(info);
992     ipmi_cmdlang_unlock(cmd_info);
993     ipmi_cmdlang_cmd_info_put(cmd_info);
994 }
995 
996 static void
lanparm_config_unlock(ipmi_lanparm_t * lanparm,void * cb_data)997 lanparm_config_unlock(ipmi_lanparm_t *lanparm, void *cb_data)
998 {
999     ipmi_cmd_info_t   *cmd_info = cb_data;
1000     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1001     int               rv;
1002     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1003     int               argc = ipmi_cmdlang_get_argc(cmd_info);
1004     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
1005     ipmi_lan_config_t *lanc;
1006     lp_config_op_t    *info = cb_data;
1007     char              *name;
1008 
1009     if ((argc - curr_arg) < 1) {
1010 	/* Not enough parameters */
1011 	cmdlang->errstr = "Not enough parameters";
1012 	cmdlang->err = EINVAL;
1013 	goto out_err;
1014     }
1015 
1016     name = argv[curr_arg];
1017     curr_arg++;
1018     lanc = find_config(name, 0);
1019     if (!lanc) {
1020 	cmdlang->errstr = "Invalid LAN config";
1021 	cmdlang->err = EINVAL;
1022 	goto out_err;
1023     }
1024 
1025     info = ipmi_mem_alloc(sizeof(*info));
1026     if (!info) {
1027 	cmdlang->errstr = "Out of memory";
1028 	cmdlang->err = ENOMEM;
1029 	goto out_err;
1030     }
1031     info->cmd_info = cmd_info;
1032     strncpy(info->name, name, sizeof(info->name) - 1);
1033     info->name[sizeof(info->name) - 1] = '\0';
1034 
1035     ipmi_cmdlang_cmd_info_get(cmd_info);
1036     rv = ipmi_lan_clear_lock(lanparm, lanc, lanparm_config_unlock_done, info);
1037     if (rv) {
1038 	ipmi_cmdlang_cmd_info_put(cmd_info);
1039 	cmdlang->errstr = "Error getting LANPARM";
1040 	cmdlang->err = rv;
1041 	ipmi_mem_free(info);
1042 	goto out_err;
1043     }
1044 
1045     return;
1046 
1047  out_err:
1048     ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
1049 			  cmdlang->objstr_len);
1050     cmdlang->location = "cmd_lanparm.c(lanparm_config_unlock)";
1051 }
1052 
1053 static void
lanparm_config_close(ipmi_cmd_info_t * cmd_info)1054 lanparm_config_close(ipmi_cmd_info_t *cmd_info)
1055 {
1056     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1057     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1058     int               argc = ipmi_cmdlang_get_argc(cmd_info);
1059     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
1060     ipmi_lan_config_t *lanc;
1061     char              *lanc_name;
1062 
1063     if ((argc - curr_arg) < 1) {
1064 	/* Not enough parameters */
1065 	cmdlang->errstr = "Not enough parameters";
1066 	cmdlang->err = EINVAL;
1067 	lanc_name = "";
1068 	goto out_err;
1069     }
1070     lanc_name = argv[curr_arg];
1071 
1072     lanc = find_config(lanc_name, 1);
1073     if (!lanc) {
1074 	cmdlang->errstr = "Invalid LAN config";
1075 	cmdlang->err = EINVAL;
1076 	goto out_err;
1077     }
1078 
1079     ipmi_lan_free_config(lanc);
1080     ipmi_cmdlang_out(cmd_info, "LANPARM config destroyed", lanc_name);
1081     return;
1082 
1083  out_err:
1084     strncpy(cmdlang->objstr, lanc_name, cmdlang->objstr_len);
1085     cmdlang->location = "cmd_lanparm.c(lanparm_config_close)";
1086 }
1087 
1088 static int
lanparm_config_list_handler(void * cb_data,void * item1,void * item2)1089 lanparm_config_list_handler(void *cb_data, void *item1, void *item2)
1090 {
1091     ipmi_cmd_info_t   *cmd_info = cb_data;
1092     lan_config_info_t *info = item1;
1093 
1094     ipmi_cmdlang_out(cmd_info, "Name", info->name);
1095     return LOCKED_LIST_ITER_CONTINUE;
1096 }
1097 
1098 static void
lanparm_config_list(ipmi_cmd_info_t * cmd_info)1099 lanparm_config_list(ipmi_cmd_info_t *cmd_info)
1100 {
1101     ipmi_cmdlang_out(cmd_info, "LANPARM Configs", NULL);
1102     ipmi_cmdlang_down(cmd_info);
1103     locked_list_iterate(lancs, lanparm_config_list_handler, cmd_info);
1104     ipmi_cmdlang_up(cmd_info);
1105 }
1106 
1107 static int
lanparm_config_info_handler(void * cb_data,void * item1,void * item2)1108 lanparm_config_info_handler(void *cb_data, void *item1, void *item2)
1109 {
1110     ipmi_cmd_info_t   *cmd_info = cb_data;
1111     lan_config_info_t *info = item1;
1112 
1113     ipmi_cmdlang_out(cmd_info, "LANPARM Config", NULL);
1114     ipmi_cmdlang_down(cmd_info);
1115     ipmi_cmdlang_out(cmd_info, "Name", info->name);
1116     config_info(cmd_info, info->config);
1117     ipmi_cmdlang_up(cmd_info);
1118     return LOCKED_LIST_ITER_CONTINUE;
1119 }
1120 
1121 static void
lanparm_config_info(ipmi_cmd_info_t * cmd_info)1122 lanparm_config_info(ipmi_cmd_info_t *cmd_info)
1123 {
1124     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1125     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1126     int               argc = ipmi_cmdlang_get_argc(cmd_info);
1127     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
1128     ipmi_lan_config_t *lanc;
1129 
1130     if ((argc - curr_arg) < 1) {
1131 	locked_list_iterate(lancs, lanparm_config_info_handler, cmd_info);
1132     } else {
1133 	lanc = find_config(argv[curr_arg], 0);
1134 	if (!lanc) {
1135 	    cmdlang->errstr = "Invalid LAN config";
1136 	    cmdlang->err = EINVAL;
1137 	    goto out_err;
1138 	}
1139 	ipmi_cmdlang_out(cmd_info, "LANPARM Config", NULL);
1140 	ipmi_cmdlang_down(cmd_info);
1141 	ipmi_cmdlang_out(cmd_info, "Name", argv[curr_arg]);
1142 	config_info(cmd_info, lanc);
1143 	ipmi_cmdlang_up(cmd_info);
1144     }
1145     return;
1146 
1147  out_err:
1148     strncpy(cmdlang->objstr, argv[curr_arg], cmdlang->objstr_len);
1149     cmdlang->location = "cmd_lanparm.c(lanparm_config_info)";
1150 }
1151 
1152 static void
lanparm_config_update(ipmi_cmd_info_t * cmd_info)1153 lanparm_config_update(ipmi_cmd_info_t *cmd_info)
1154 {
1155     ipmi_cmdlang_t    *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1156     int               curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1157     int               argc = ipmi_cmdlang_get_argc(cmd_info);
1158     char              **argv = ipmi_cmdlang_get_argv(cmd_info);
1159     ipmi_lan_config_t *lanc;
1160     int               i;
1161     char              *name;
1162     char              *val;
1163     char              *lanc_name;
1164     int               sel;
1165 
1166     if ((argc - curr_arg) < 3) {
1167 	/* Not enough parameters */
1168 	cmdlang->errstr = "Not enough parameters";
1169 	cmdlang->err = EINVAL;
1170 	lanc_name = "";
1171 	goto out_err;
1172     }
1173     lanc_name = argv[curr_arg];
1174     curr_arg++;
1175 
1176     lanc = find_config(lanc_name, 0);
1177     if (!lanc) {
1178 	cmdlang->errstr = "Invalid LAN config";
1179 	cmdlang->err = EINVAL;
1180 	goto out_err;
1181     }
1182 
1183     name = argv[curr_arg];
1184     curr_arg++;
1185     val = argv[curr_arg];
1186     curr_arg++;
1187 
1188     /* Basic items */
1189     for (i=0; lps[i].name; i++) {
1190 	if (strcmp(lps[i].name, name) == 0) {
1191 	    lp_item_t *lp = lps[i].lpi;
1192 	    if (!lp->set) {
1193 		cmdlang->errstr = "Parameter is read-only";
1194 		cmdlang->err = EINVAL;
1195 		goto out_err;
1196 	    }
1197 	    lp->set(cmd_info, val, lanc, lps[i].set_func);
1198 	    goto out;
1199 	}
1200     }
1201 
1202     /* per-user items */
1203     for (i=0; ulps[i].name; i++) {
1204 	if (strcmp(ulps[i].name, name) == 0) {
1205 	    ulp_item_t *lp = ulps[i].lpi;
1206 
1207 	    if ((argc - curr_arg) < 1) {
1208 		/* Not enough parameters */
1209 		cmdlang->errstr = "Not enough parameters";
1210 		cmdlang->err = EINVAL;
1211 		goto out_err;
1212 	    }
1213 	    if (!lp->set) {
1214 		cmdlang->errstr = "Parameter is read-only";
1215 		cmdlang->err = EINVAL;
1216 		goto out_err;
1217 	    }
1218 	    ipmi_cmdlang_get_user(val, &sel, cmd_info);
1219 	    if (cmdlang->err) {
1220 		cmdlang->errstr = "selector invalid";
1221 		goto out_err;
1222 	    }
1223 	    sel--; /* Numbers are 1-based, value is zero based. */
1224 	    val = argv[curr_arg];
1225 	    curr_arg++;
1226 	    lp->set(cmd_info, sel, val, lanc, ulps[i].set_func);
1227 	    goto out;
1228 	}
1229     }
1230 
1231     /* per-destination items */
1232     for (i=0; alps[i].name; i++) {
1233 	if (strcmp(alps[i].name, name) == 0) {
1234 	    ulp_item_t *lp = alps[i].lpi;
1235 
1236 	    if ((argc - curr_arg) < 1) {
1237 		/* Not enough parameters */
1238 		cmdlang->errstr = "Not enough parameters";
1239 		cmdlang->err = EINVAL;
1240 		goto out_err;
1241 	    }
1242 	    if (!lp->set) {
1243 		cmdlang->errstr = "Parameter is read-only";
1244 		cmdlang->err = EINVAL;
1245 		goto out_err;
1246 	    }
1247 	    ipmi_cmdlang_get_int(val, &sel, cmd_info);
1248 	    if (cmdlang->err) {
1249 		cmdlang->errstr = "selector invalid";
1250 		goto out_err;
1251 	    }
1252 	    val = argv[curr_arg];
1253 	    curr_arg++;
1254 	    lp->set(cmd_info, sel, val, lanc, alps[i].set_func);
1255 	    goto out;
1256 	}
1257     }
1258 
1259     cmdlang->errstr = "Invalid parameter name";
1260     cmdlang->err = EINVAL;
1261     goto out_err;
1262 
1263  out:
1264     ipmi_cmdlang_out(cmd_info, "LANPARM config updated", lanc_name);
1265     return;
1266 
1267  out_err:
1268     strncpy(cmdlang->objstr, lanc_name, cmdlang->objstr_len);
1269     cmdlang->location = "cmd_lanparm.c(lanparm_config_update)";
1270 }
1271 
1272 typedef struct lanparm_mc_unlock_s
1273 {
1274     char            name[IPMI_MC_NAME_LEN];
1275     ipmi_cmd_info_t *cmd_info;
1276 } lanparm_mc_unlock_t;
1277 
1278 static void
lanparm_unlock_mc_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)1279 lanparm_unlock_mc_done(ipmi_lanparm_t *lanparm, int err, void *cb_data)
1280 {
1281     lanparm_mc_unlock_t *info = cb_data;
1282     ipmi_cmd_info_t     *cmd_info = info->cmd_info;
1283     ipmi_cmdlang_t      *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1284 
1285     ipmi_cmdlang_lock(cmd_info);
1286     if (err) {
1287 	ipmi_lanparm_get_name(lanparm, cmdlang->objstr,
1288 			  cmdlang->objstr_len);
1289 	cmdlang->errstr = "Error unlocking MC LANPARM";
1290 	cmdlang->err = err;
1291 	cmdlang->location = "cmd_lanparm.c(lanparm_unlock_mc_done)";
1292 	goto out;
1293     }
1294 
1295     ipmi_cmdlang_out(cmd_info, "LANPARM unlocked", info->name);
1296 
1297  out:
1298     ipmi_cmdlang_unlock(cmd_info);
1299     ipmi_lanparm_destroy(lanparm, NULL, NULL);
1300     ipmi_cmdlang_cmd_info_put(cmd_info);
1301     ipmi_mem_free(info);
1302 }
1303 
1304 static void
lanparm_unlock_mc(ipmi_mc_t * mc,void * cb_data)1305 lanparm_unlock_mc(ipmi_mc_t *mc, void *cb_data)
1306 {
1307     ipmi_cmd_info_t *cmd_info = cb_data;
1308     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
1309     int             channel;
1310     int             rv;
1311     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
1312     int             argc = ipmi_cmdlang_get_argc(cmd_info);
1313     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
1314     ipmi_lanparm_t  *lanparm = NULL;
1315     lanparm_mc_unlock_t *info;
1316 
1317     if ((argc - curr_arg) < 1) {
1318 	/* Not enough parameters */
1319 	cmdlang->errstr = "Not enough parameters";
1320 	cmdlang->err = EINVAL;
1321 	goto out_err;
1322     }
1323 
1324     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
1325     if (cmdlang->err) {
1326 	cmdlang->errstr = "channel invalid";
1327 	goto out_err;
1328     }
1329     curr_arg++;
1330 
1331     rv = ipmi_lanparm_alloc(mc, channel, &lanparm);
1332     if (rv) {
1333 	cmdlang->errstr = "Error from ipmi_lanparm_alloc";
1334 	cmdlang->err = rv;
1335 	goto out_err;
1336     }
1337 
1338     info = ipmi_mem_alloc(sizeof(*info));
1339     if (!info) {
1340 	cmdlang->errstr = "Out of memory";
1341 	cmdlang->err = ENOMEM;
1342 	goto out_err;
1343     }
1344     info->cmd_info = cmd_info;
1345     ipmi_mc_get_name(mc, info->name, sizeof(info->name));
1346 
1347     ipmi_cmdlang_cmd_info_get(cmd_info);
1348     rv = ipmi_lan_clear_lock(lanparm, NULL, lanparm_unlock_mc_done, info);
1349     if (rv) {
1350 	ipmi_cmdlang_cmd_info_put(cmd_info);
1351 	cmdlang->errstr = "Error from ipmi_lan_clear_lock";
1352 	cmdlang->err = rv;
1353 	ipmi_lanparm_destroy(lanparm, NULL, NULL);
1354 	ipmi_mem_free(info);
1355 	goto out_err;
1356     }
1357     return;
1358 
1359  out_err:
1360     if (lanparm)
1361 	ipmi_lanparm_destroy(lanparm, NULL, NULL);
1362     ipmi_mc_get_name(mc, cmdlang->objstr,
1363 		     cmdlang->objstr_len);
1364     cmdlang->location = "cmd_lanparm.c(lanparm_unlock_mc)";
1365 }
1366 
1367 static ipmi_cmdlang_cmd_t *lanparm_cmds;
1368 static ipmi_cmdlang_cmd_t *config_cmds;
1369 
1370 static ipmi_cmdlang_init_t cmds_lanparm[] =
1371 {
1372     { "lanparm", NULL,
1373       "- Commands dealing with LAN Parameters (lanparms)",
1374       NULL, NULL, &lanparm_cmds},
1375     { "list", &lanparm_cmds,
1376       "- List all the lanparms in the system",
1377       ipmi_cmdlang_domain_handler, lanparm_list,  NULL },
1378     { "new", &lanparm_cmds,
1379       "<mc> <channel>"
1380       " - Create a lanparm for the given MC and channel.",
1381       ipmi_cmdlang_mc_handler, lanparm_new, NULL },
1382     { "info", &lanparm_cmds,
1383       "<lanparm> - Dump information about a lanparm",
1384       ipmi_cmdlang_lanparm_handler, lanparm_info, NULL },
1385     { "config", &lanparm_cmds,
1386       "- Commands dealing with LANPARM configs",
1387       NULL, NULL, &config_cmds },
1388     { "list", &config_cmds,
1389       "- List the lan configurations that currently exist",
1390       lanparm_config_list, NULL, NULL },
1391     { "info", &config_cmds,
1392       "<config> - List info on lan configuration",
1393       lanparm_config_info, NULL, NULL },
1394     { "get", &config_cmds,
1395       "<lanparm> - Fetch the LAN information for the lanparm",
1396       ipmi_cmdlang_lanparm_handler, lanparm_config_get, NULL },
1397     { "set", &config_cmds,
1398       "<lanparm> <lanparm config> - Set the LAN information for the lanparm",
1399       ipmi_cmdlang_lanparm_handler, lanparm_config_set, NULL },
1400     { "unlock", &config_cmds,
1401       "<lanparm> <lanparm config> - Unlock, but do not set the config",
1402       ipmi_cmdlang_lanparm_handler, lanparm_config_unlock, NULL },
1403     { "update", &config_cmds,
1404       "<lanparm config> <parm> [selector] <value> - Set the given parameter"
1405       " in the lanparm config to the given value.  If the parameter has"
1406       " a selector of some type, the selector must be given, otherwise"
1407       " no selector should be given.",
1408       lanparm_config_update, NULL, NULL },
1409     { "close", &config_cmds,
1410       "<lanparm config> - free the config",
1411       lanparm_config_close, NULL, NULL },
1412     { "unlock_mc", &lanparm_cmds,
1413       "<mc> <channel> - Unlock the lanparms for the given mc/channel",
1414       ipmi_cmdlang_mc_handler, lanparm_unlock_mc, NULL },
1415     { "close", &lanparm_cmds,
1416       "<lanparm> - Close the lanparm",
1417       ipmi_cmdlang_lanparm_handler, lanparm_close, NULL },
1418 };
1419 #define CMDS_LANPARM_LEN (sizeof(cmds_lanparm)/sizeof(ipmi_cmdlang_init_t))
1420 
1421 int
ipmi_cmdlang_lanparm_init(os_handler_t * os_hnd)1422 ipmi_cmdlang_lanparm_init(os_handler_t *os_hnd)
1423 {
1424     int rv;
1425 
1426     lancs = locked_list_alloc(os_hnd);
1427     if (!lancs)
1428 	return ENOMEM;
1429 
1430     rv = ipmi_cmdlang_reg_table(cmds_lanparm, CMDS_LANPARM_LEN);
1431     if (rv) {
1432 	locked_list_destroy(lancs);
1433 	lancs = NULL;
1434     }
1435 
1436     return rv;
1437 }
1438 
1439 static int
config_destroy_handler(void * cb_data,void * item1,void * item2)1440 config_destroy_handler(void *cb_data, void *item1, void *item2)
1441 {
1442     lan_config_info_t *info = item1;
1443 
1444     ipmi_lan_free_config(info->config);
1445     ipmi_mem_free(info);
1446     return LOCKED_LIST_ITER_CONTINUE;
1447 }
1448 
1449 void
ipmi_cmdlang_lanparm_shutdown(void)1450 ipmi_cmdlang_lanparm_shutdown(void)
1451 {
1452     locked_list_iterate(lancs, config_destroy_handler, NULL);
1453     locked_list_destroy(lancs);
1454     lancs = NULL;
1455 }
1456