1 /*
2 * ipmi.c
3 *
4 * MontaVista IPMI generic code
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 <config.h>
35
36 #include <string.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <netdb.h>
40
41 #include <OpenIPMI/os_handler.h>
42 #include <OpenIPMI/ipmi_conn.h>
43 #include <OpenIPMI/ipmi_err.h>
44 #include <OpenIPMI/ipmi_auth.h>
45 #include <OpenIPMI/ipmi_lan.h>
46 #include <OpenIPMI/ipmi_smi.h>
47 #include <OpenIPMI/ipmi_msgbits.h>
48
49 #include <OpenIPMI/internal/ipmi_domain.h>
50 #include <OpenIPMI/internal/ipmi_mc.h>
51 #include <OpenIPMI/internal/ipmi_int.h>
52 #include <OpenIPMI/internal/ipmi_oem.h>
53 #include <OpenIPMI/internal/locked_list.h>
54
55 #if defined(DEBUG_MSG) || defined(DEBUG_RAWMSG)
56 static void
dump_hex(const void * vdata,int len)57 dump_hex(const void *vdata, int len)
58 {
59 const unsigned char *data = vdata;
60 int i;
61 for (i=0; i<len; i++) {
62 if ((i != 0) && ((i % 16) == 0)) {
63 ipmi_log(IPMI_LOG_DEBUG_CONT, "\n ");
64 }
65 ipmi_log(IPMI_LOG_DEBUG_CONT, " %2.2x", data[i]);
66 }
67 }
68 #endif
69 static os_handler_t *ipmi_os_handler;
70
71 unsigned int i__ipmi_log_mask = 0;
72
73 os_handler_t *
ipmi_get_global_os_handler(void)74 ipmi_get_global_os_handler(void)
75 {
76 return ipmi_os_handler;
77 }
78
79 int
ipmi_create_global_lock(ipmi_lock_t ** new_lock)80 ipmi_create_global_lock(ipmi_lock_t **new_lock)
81 {
82 return ipmi_create_lock_os_hnd(ipmi_os_handler, new_lock);
83 }
84
85 int
ipmi_create_lock(ipmi_domain_t * domain,ipmi_lock_t ** new_lock)86 ipmi_create_lock(ipmi_domain_t *domain, ipmi_lock_t **new_lock)
87 {
88 return ipmi_create_lock_os_hnd(ipmi_domain_get_os_hnd(domain), new_lock);
89 }
90
91 void
ipmi_log(enum ipmi_log_type_e log_type,const char * format,...)92 ipmi_log(enum ipmi_log_type_e log_type, const char *format, ...)
93 {
94 va_list ap;
95
96 va_start(ap, format);
97 if (ipmi_os_handler && ipmi_os_handler->vlog)
98 ipmi_os_handler->vlog(ipmi_os_handler, log_type, format, ap);
99 else {
100 vfprintf(stderr, format, ap);
101 switch (log_type) {
102 case IPMI_LOG_DEBUG_START:
103 case IPMI_LOG_DEBUG_CONT:
104 break;
105 default:
106 fprintf(stderr, "\n");
107 }
108 }
109 va_end(ap);
110 }
111
112 static long seq = 0;
113 static os_hnd_lock_t *seq_lock;
114 long
ipmi_get_seq(void)115 ipmi_get_seq(void)
116 {
117 long rv;
118
119 if (seq_lock)
120 ipmi_os_handler->lock(ipmi_os_handler, seq_lock);
121 rv = seq;
122 seq++;
123 if (seq_lock)
124 ipmi_os_handler->unlock(ipmi_os_handler, seq_lock);
125
126 return rv;
127 }
128
129 void
ipmi_event_state_init(ipmi_event_state_t * events)130 ipmi_event_state_init(ipmi_event_state_t *events)
131 {
132 events->status = 0;
133 events->__assertion_events = 0;
134 events->__deassertion_events = 0;
135 }
136
137 void
ipmi_threshold_event_clear(ipmi_event_state_t * events,enum ipmi_thresh_e type,enum ipmi_event_value_dir_e value_dir,enum ipmi_event_dir_e dir)138 ipmi_threshold_event_clear(ipmi_event_state_t *events,
139 enum ipmi_thresh_e type,
140 enum ipmi_event_value_dir_e value_dir,
141 enum ipmi_event_dir_e dir)
142 {
143 if (dir == IPMI_ASSERTION) {
144 events->__assertion_events &= ~(1 << (type*2+value_dir));
145 } else {
146 events->__deassertion_events &= ~(1 << (type*2+value_dir));
147 }
148 }
149
150 void
ipmi_threshold_event_set(ipmi_event_state_t * events,enum ipmi_thresh_e type,enum ipmi_event_value_dir_e value_dir,enum ipmi_event_dir_e dir)151 ipmi_threshold_event_set(ipmi_event_state_t *events,
152 enum ipmi_thresh_e type,
153 enum ipmi_event_value_dir_e value_dir,
154 enum ipmi_event_dir_e dir)
155 {
156 if (dir == IPMI_ASSERTION) {
157 events->__assertion_events |= 1 << (type*2+value_dir);
158 } else {
159 events->__deassertion_events |= 1 << (type*2+value_dir);
160 }
161 }
162
163 int
ipmi_is_threshold_event_set(ipmi_event_state_t * events,enum ipmi_thresh_e type,enum ipmi_event_value_dir_e value_dir,enum ipmi_event_dir_e dir)164 ipmi_is_threshold_event_set(ipmi_event_state_t *events,
165 enum ipmi_thresh_e type,
166 enum ipmi_event_value_dir_e value_dir,
167 enum ipmi_event_dir_e dir)
168 {
169 if (dir == IPMI_ASSERTION) {
170 return (events->__assertion_events & (1 << (type*2+value_dir))) != 0;
171 } else {
172 return (events->__deassertion_events & (1 << (type*2+value_dir))) != 0;
173 }
174 }
175
176 void
ipmi_discrete_event_clear(ipmi_event_state_t * events,int event_offset,enum ipmi_event_dir_e dir)177 ipmi_discrete_event_clear(ipmi_event_state_t *events,
178 int event_offset,
179 enum ipmi_event_dir_e dir)
180 {
181 if (dir == IPMI_ASSERTION) {
182 events->__assertion_events &= ~(1 << event_offset);
183 } else {
184 events->__deassertion_events &= ~(1 << event_offset);
185 }
186 }
187
188 void
ipmi_discrete_event_set(ipmi_event_state_t * events,int event_offset,enum ipmi_event_dir_e dir)189 ipmi_discrete_event_set(ipmi_event_state_t *events,
190 int event_offset,
191 enum ipmi_event_dir_e dir)
192 {
193 if (dir == IPMI_ASSERTION) {
194 events->__assertion_events |= 1 << event_offset;
195 } else {
196 events->__deassertion_events |= 1 << event_offset;
197 }
198 }
199
200 int
ipmi_is_discrete_event_set(ipmi_event_state_t * events,int event_offset,enum ipmi_event_dir_e dir)201 ipmi_is_discrete_event_set(ipmi_event_state_t *events,
202 int event_offset,
203 enum ipmi_event_dir_e dir)
204 {
205 if (dir == IPMI_ASSERTION) {
206 return (events->__assertion_events & (1 << event_offset)) != 0;
207 } else {
208 return (events->__deassertion_events & (1 << event_offset)) != 0;
209 }
210 }
211
212 #define IPMI_SENSOR_EVENTS_ENABLED 0x80
213 #define IPMI_SENSOR_SCANNING_ENABLED 0x40
214 #define IPMI_SENSOR_BUSY 0x20
215
ipmi_event_state_size(void)216 unsigned int ipmi_event_state_size(void)
217 {
218 return sizeof(ipmi_event_state_t);
219 }
220
221 void
ipmi_copy_event_state(ipmi_event_state_t * dest,ipmi_event_state_t * src)222 ipmi_copy_event_state(ipmi_event_state_t *dest, ipmi_event_state_t *src)
223 {
224 *dest = *src;
225 }
226
227 void
ipmi_event_state_set_events_enabled(ipmi_event_state_t * events,int val)228 ipmi_event_state_set_events_enabled(ipmi_event_state_t *events, int val)
229 {
230 if (val)
231 events->status |= IPMI_SENSOR_EVENTS_ENABLED;
232 else
233 events->status &= ~IPMI_SENSOR_EVENTS_ENABLED;
234 }
235
236 int
ipmi_event_state_get_events_enabled(ipmi_event_state_t * events)237 ipmi_event_state_get_events_enabled(ipmi_event_state_t *events)
238 {
239 return (events->status >> 7) & 1;
240 }
241
242 void
ipmi_event_state_set_scanning_enabled(ipmi_event_state_t * events,int val)243 ipmi_event_state_set_scanning_enabled(ipmi_event_state_t *events, int val)
244 {
245 if (val)
246 events->status |= IPMI_SENSOR_SCANNING_ENABLED;
247 else
248 events->status &= ~IPMI_SENSOR_SCANNING_ENABLED;
249 }
250
251 int
ipmi_event_state_get_scanning_enabled(ipmi_event_state_t * events)252 ipmi_event_state_get_scanning_enabled(ipmi_event_state_t *events)
253 {
254 return (events->status >> 6) & 1;
255 }
256
257 void
ipmi_event_state_set_busy(ipmi_event_state_t * events,int val)258 ipmi_event_state_set_busy(ipmi_event_state_t *events, int val)
259 {
260 if (val)
261 events->status |= IPMI_SENSOR_BUSY;
262 else
263 events->status &= ~IPMI_SENSOR_BUSY;
264 }
265
266 int
ipmi_event_state_get_busy(ipmi_event_state_t * events)267 ipmi_event_state_get_busy(ipmi_event_state_t *events)
268 {
269 return (events->status >> 5) & 1;
270 }
271
ipmi_thresholds_size(void)272 unsigned int ipmi_thresholds_size(void)
273 {
274 return sizeof(ipmi_thresholds_t);
275 }
276
277 void
ipmi_copy_thresholds(ipmi_thresholds_t * dest,ipmi_thresholds_t * src)278 ipmi_copy_thresholds(ipmi_thresholds_t *dest, ipmi_thresholds_t *src)
279 {
280 *dest = *src;
281 }
282
ipmi_thresholds_init(ipmi_thresholds_t * th)283 int ipmi_thresholds_init(ipmi_thresholds_t *th)
284 {
285 int i;
286 for (i=0; i<6; i++)
287 th->vals[i].status = 0;
288 return 0;
289 }
290
ipmi_threshold_set(ipmi_thresholds_t * th,ipmi_sensor_t * sensor,enum ipmi_thresh_e threshold,double value)291 int ipmi_threshold_set(ipmi_thresholds_t *th,
292 ipmi_sensor_t *sensor,
293 enum ipmi_thresh_e threshold,
294 double value)
295 {
296 int rv = 0;
297
298 if (threshold > IPMI_UPPER_NON_RECOVERABLE)
299 return EINVAL;
300
301 if (sensor) {
302 int val;
303 rv = ipmi_sensor_threshold_settable(sensor, threshold, &val);
304 if (rv)
305 return rv;
306 if (!val)
307 return ENOSYS;
308 }
309
310 th->vals[threshold].status = 1;
311 th->vals[threshold].val = value;
312 return 0;
313 }
314
ipmi_threshold_get(ipmi_thresholds_t * th,enum ipmi_thresh_e threshold,double * value)315 int ipmi_threshold_get(ipmi_thresholds_t *th,
316 enum ipmi_thresh_e threshold,
317 double *value)
318 {
319 if (threshold > IPMI_UPPER_NON_RECOVERABLE)
320 return EINVAL;
321
322 if (th->vals[threshold].status) {
323 *value = th->vals[threshold].val;
324 return 0;
325 } else {
326 return ENOSYS;
327 }
328 }
329
ipmi_states_size(void)330 unsigned int ipmi_states_size(void)
331 {
332 return sizeof(ipmi_states_t);
333 }
334
335 void
ipmi_copy_states(ipmi_states_t * dest,ipmi_states_t * src)336 ipmi_copy_states(ipmi_states_t *dest, ipmi_states_t *src)
337 {
338 *dest = *src;
339 }
340
341 void
ipmi_init_states(ipmi_states_t * states)342 ipmi_init_states(ipmi_states_t *states)
343 {
344 states->__event_messages_enabled = 0;
345 states->__sensor_scanning_enabled = 0;
346 states->__initial_update_in_progress = 0;
347 states->__states = 0;
348 }
349
350 int
ipmi_is_event_messages_enabled(ipmi_states_t * states)351 ipmi_is_event_messages_enabled(ipmi_states_t *states)
352 {
353 return states->__event_messages_enabled;
354 }
355
356 void
ipmi_set_event_messages_enabled(ipmi_states_t * states,int val)357 ipmi_set_event_messages_enabled(ipmi_states_t *states, int val)
358 {
359 states->__event_messages_enabled = val;
360 }
361
362 int
ipmi_is_sensor_scanning_enabled(ipmi_states_t * states)363 ipmi_is_sensor_scanning_enabled(ipmi_states_t *states)
364 {
365 return states->__sensor_scanning_enabled;
366 }
367
368 void
ipmi_set_sensor_scanning_enabled(ipmi_states_t * states,int val)369 ipmi_set_sensor_scanning_enabled(ipmi_states_t *states, int val)
370 {
371 states->__sensor_scanning_enabled = val;
372 }
373
374 int
ipmi_is_initial_update_in_progress(ipmi_states_t * states)375 ipmi_is_initial_update_in_progress(ipmi_states_t *states)
376 {
377 return states->__initial_update_in_progress;
378 }
379
380 void
ipmi_set_initial_update_in_progress(ipmi_states_t * states,int val)381 ipmi_set_initial_update_in_progress(ipmi_states_t *states, int val)
382 {
383 states->__initial_update_in_progress = val;
384 }
385
386 int
ipmi_is_state_set(ipmi_states_t * states,int state_num)387 ipmi_is_state_set(ipmi_states_t *states,
388 int state_num)
389 {
390 return (states->__states & (1 << state_num)) != 0;
391 }
392
393 void
ipmi_set_state(ipmi_states_t * states,int state_num,int val)394 ipmi_set_state(ipmi_states_t *states,
395 int state_num,
396 int val)
397 {
398 if (val)
399 states->__states |= 1 << state_num;
400 else
401 states->__states &= ~(1 << state_num);
402 }
403
404 int
ipmi_is_threshold_out_of_range(ipmi_states_t * states,enum ipmi_thresh_e thresh)405 ipmi_is_threshold_out_of_range(ipmi_states_t *states,
406 enum ipmi_thresh_e thresh)
407 {
408 return (states->__states & (1 << thresh)) != 0;
409 }
410
411 void
ipmi_set_threshold_out_of_range(ipmi_states_t * states,enum ipmi_thresh_e thresh,int val)412 ipmi_set_threshold_out_of_range(ipmi_states_t *states,
413 enum ipmi_thresh_e thresh,
414 int val)
415 {
416 if (val)
417 states->__states |= 1 << thresh;
418 else
419 states->__states &= ~(1 << thresh);
420 }
421
422 void ipmi_oem_force_conn_init(void);
423 int ipmi_oem_motorola_mxp_init(void);
424 int ipmi_oem_intel_init(void);
425 int ipmi_oem_kontron_conn_init(void);
426 int ipmi_oem_atca_conn_init(void);
427 int ipmi_oem_atca_init(void);
428 int init_oem_test(void);
429 int i_ipmi_smi_init(os_handler_t *os_hnd);
430 int i_ipmi_lan_init(os_handler_t *os_hnd);
431 int ipmi_malloc_init(os_handler_t *os_hnd);
432 void ipmi_malloc_shutdown(void);
433 int i_ipmi_rakp_init(void);
434 int i_ipmi_aes_cbc_init(void);
435 int i_ipmi_hmac_init(void);
436 int i_ipmi_md5_init(void);
437 int i_ipmi_fru_init(void);
438 int i_ipmi_normal_fru_init(void);
439 int i_ipmi_fru_spd_decoder_init(void);
440 void i_ipmi_fru_shutdown(void);
441 void i_ipmi_normal_fru_shutdown(void);
442 void i_ipmi_fru_spd_decoder_shutdown(void);
443 int i_ipmi_sol_init(void);
444
445 void i_ipmi_rakp_shutdown(void);
446 void i_ipmi_aes_cbc_shutdown(void);
447 void i_ipmi_hmac_shutdown(void);
448 void i_ipmi_md5_shutdown(void);
449 void ipmi_oem_atca_conn_shutdown(void);
450 void ipmi_oem_intel_shutdown(void);
451 void ipmi_oem_kontron_conn_shutdown(void);
452 void ipmi_oem_atca_shutdown(void);
453 int i_ipmi_smi_shutdown(void);
454 int i_ipmi_lan_shutdown(void);
455 void i_ipmi_sol_shutdown(void);
456
457
458 static locked_list_t *con_type_list;
459 static int ipmi_initialized;
460
461 int
ipmi_init(os_handler_t * handler)462 ipmi_init(os_handler_t *handler)
463 {
464 int rv;
465
466 if (ipmi_initialized)
467 return 0;
468
469 ipmi_os_handler = handler;
470
471 /* Set up memory allocation first */
472 ipmi_malloc_init(handler);
473
474 /* Set up logging in malloc code. */
475 ipmi_malloc_log = ipmi_log;
476
477 con_type_list = locked_list_alloc(handler);
478
479 rv = i_ipmi_conn_init(handler);
480 if (rv)
481 return rv;
482
483 ipmi_initialized = 1;
484
485 if (handler->create_lock) {
486 rv = handler->create_lock(handler, &seq_lock);
487 if (rv)
488 goto out_err;
489 } else {
490 seq_lock = NULL;
491 }
492
493 #ifdef HAVE_OPENIPMI_SMI
494 rv = i_ipmi_smi_init(handler);
495 if (rv)
496 goto out_err;
497 #endif
498
499 rv = i_ipmi_lan_init(handler);
500 if (rv)
501 goto out_err;
502
503 i_ipmi_domain_init();
504 i_ipmi_mc_init();
505
506 rv = i_ipmi_rakp_init();
507 if (rv)
508 goto out_err;
509 rv = i_ipmi_aes_cbc_init();
510 if (rv)
511 goto out_err;
512 rv = i_ipmi_hmac_init();
513 if (rv)
514 goto out_err;
515 rv = i_ipmi_md5_init();
516 if (rv)
517 goto out_err;
518
519 rv = i_ipmi_fru_init();
520 if (rv)
521 goto out_err;
522
523 rv = i_ipmi_normal_fru_init();
524 if (rv)
525 goto out_err;
526
527 rv = i_ipmi_fru_spd_decoder_init();
528 if (rv)
529 goto out_err;
530
531 rv = i_ipmi_sol_init();
532 if (rv)
533 goto out_err;
534
535 /* Call the OEM handlers. */
536 ipmi_oem_force_conn_init();
537 ipmi_oem_motorola_mxp_init();
538 ipmi_oem_intel_init();
539 ipmi_oem_kontron_conn_init();
540 ipmi_oem_atca_conn_init();
541 ipmi_oem_atca_init();
542 init_oem_test();
543
544 return 0;
545
546 out_err:
547 ipmi_shutdown();
548 return rv;
549 }
550
551 void
ipmi_shutdown(void)552 ipmi_shutdown(void)
553 {
554 if (! ipmi_initialized)
555 return;
556
557 i_ipmi_rakp_shutdown();
558 i_ipmi_aes_cbc_shutdown();
559 i_ipmi_hmac_shutdown();
560 i_ipmi_md5_shutdown();
561 i_ipmi_sol_shutdown();
562 i_ipmi_lan_shutdown();
563 #ifdef HAVE_OPENIPMI_SMI
564 i_ipmi_smi_shutdown();
565 #endif
566 ipmi_oem_atca_shutdown();
567 ipmi_oem_atca_conn_shutdown();
568 ipmi_oem_intel_shutdown();
569 ipmi_oem_kontron_conn_shutdown();
570 i_ipmi_mc_shutdown();
571 i_ipmi_domain_shutdown();
572 i_ipmi_fru_spd_decoder_shutdown();
573 i_ipmi_conn_shutdown();
574 i_ipmi_normal_fru_shutdown();
575 i_ipmi_fru_shutdown();
576 if (seq_lock)
577 ipmi_os_handler->destroy_lock(ipmi_os_handler, seq_lock);
578 if (con_type_list)
579 locked_list_destroy(con_type_list);
580 ipmi_debug_malloc_cleanup();
581 ipmi_malloc_shutdown();
582
583 ipmi_os_handler = NULL;
584
585 ipmi_initialized = 0;
586 }
587
588 #define CHECK_ARG \
589 do { \
590 if (*curr_arg >= arg_count) { \
591 rv = EINVAL; \
592 goto out_err; \
593 } \
594 } while(0)
595
596 int
ipmi_parse_args(int * curr_arg,int arg_count,char * const * args,ipmi_args_t ** iargs)597 ipmi_parse_args(int *curr_arg,
598 int arg_count,
599 char * const *args,
600 ipmi_args_t **iargs)
601 {
602 int rv;
603 CHECK_ARG;
604
605 if (strcmp(args[*curr_arg], "smi") == 0) {
606 /* Format is unchanged. */
607 return ipmi_parse_args2(curr_arg, arg_count, args, iargs);
608 } else if (strcmp(args[*curr_arg], "lan") == 0) {
609 /* Convert the format over to the new one and call the new
610 handler. */
611 char *largs[16];
612 int c = 0;
613 int newcarg = 0;
614 char *addr, *addr2 = NULL;
615 char *port, *port2 = NULL;
616 char *auth;
617 char *priv;
618 char *username;
619 char *pw;
620
621 largs[c] = args[*curr_arg];
622 (*curr_arg)++; CHECK_ARG;
623 c++;
624
625 addr = args[*curr_arg];
626 (*curr_arg)++; CHECK_ARG;
627
628 port = args[*curr_arg];
629 (*curr_arg)++; CHECK_ARG;
630
631 if ((strcmp(args[*curr_arg], "none") != 0)
632 && (strcmp(args[*curr_arg], "md2") != 0)
633 && (strcmp(args[*curr_arg], "md5") != 0)
634 && (strcmp(args[*curr_arg], "straight") != 0)
635 && (strcmp(args[*curr_arg], "rmcp+") != 0))
636 {
637 addr2 = args[*curr_arg];
638 (*curr_arg)++; CHECK_ARG;
639
640 port2 = args[*curr_arg];
641 (*curr_arg)++; CHECK_ARG;
642 }
643
644 auth = args[*curr_arg];
645 (*curr_arg)++; CHECK_ARG;
646
647 priv = args[*curr_arg];
648 (*curr_arg)++; CHECK_ARG;
649
650 username = args[*curr_arg];
651 (*curr_arg)++; CHECK_ARG;
652
653 pw = args[*curr_arg];
654 (*curr_arg)++;
655
656 largs[c] = "-U"; c++; largs[c] = username; c++;
657 largs[c] = "-P"; c++; largs[c] = pw; c++;
658 largs[c] = "-A"; c++; largs[c] = auth; c++;
659 largs[c] = "-L"; c++; largs[c] = priv; c++;
660 if (addr2) {
661 largs[c] = "-s"; c++;
662 }
663 largs[c] = "-p"; c++; largs[c] = port; c++;
664 if (port2) {
665 largs[c] = "-p2"; c++; largs[c] = port2; c++;
666 }
667 largs[c] = addr; c++;
668 if (addr2) {
669 largs[c] = addr2; c++;
670 }
671
672 return ipmi_parse_args2(&newcarg, c, largs, iargs);
673 } else {
674 rv = EINVAL;
675 goto out_err;
676 }
677 return 0;
678
679 out_err:
680 return rv;
681 }
682
683 struct ipmi_args_s
684 {
685 ipmi_args_free_cb free;
686 ipmi_args_connect_cb connect;
687 ipmi_args_get_val_cb get_val;
688 ipmi_args_set_val_cb set_val;
689 ipmi_args_copy_cb copy;
690 ipmi_args_validate_cb validate;
691 ipmi_args_free_val_cb free_val;
692 ipmi_args_get_type_cb get_type;
693 };
694
695 struct ipmi_con_setup_s
696 {
697 ipmi_con_parse_args_cb parse;
698 ipmi_con_get_help_cb help;
699 ipmi_con_alloc_args_cb alloc;
700 };
701 ipmi_con_setup_t *
i_ipmi_alloc_con_setup(ipmi_con_parse_args_cb parse,ipmi_con_get_help_cb help,ipmi_con_alloc_args_cb alloc)702 i_ipmi_alloc_con_setup(ipmi_con_parse_args_cb parse,
703 ipmi_con_get_help_cb help,
704 ipmi_con_alloc_args_cb alloc)
705 {
706 ipmi_con_setup_t *rv;
707
708 rv = ipmi_mem_alloc(sizeof(*rv));
709 if (!rv)
710 return NULL;
711 memset(rv, 0, sizeof(*rv));
712 rv->parse = parse;
713 rv->help = help;
714 rv->alloc = alloc;
715 return rv;
716 }
717
718 void
i_ipmi_free_con_setup(ipmi_con_setup_t * v)719 i_ipmi_free_con_setup(ipmi_con_setup_t *v)
720 {
721 ipmi_mem_free(v);
722 }
723
724 typedef struct con_type_alloc_data_s
725 {
726 char *con_type;
727 ipmi_args_t *args;
728 int err;
729 } con_type_alloc_data_t;
730
731 static int
con_type_alloc_handler(void * cb_data,void * item1,void * item2)732 con_type_alloc_handler(void *cb_data, void *item1, void *item2)
733 {
734 ipmi_con_setup_t *setup = item2;
735 con_type_alloc_data_t *data = cb_data;
736
737 if (strcmp(data->con_type, item1) == 0) {
738 data->args = setup->alloc();
739 if (!data->args)
740 data->err = ENOMEM;
741 else
742 data->err = 0;
743 return LOCKED_LIST_ITER_STOP;
744 }
745 return LOCKED_LIST_ITER_CONTINUE;
746 }
747
748 int
ipmi_args_alloc(char * con_type,ipmi_args_t ** args)749 ipmi_args_alloc(char *con_type, ipmi_args_t **args)
750 {
751 con_type_alloc_data_t data;
752
753 data.con_type = con_type;
754 data.err = EINVAL;
755 locked_list_iterate(con_type_list, con_type_alloc_handler, &data);
756 if (!data.err)
757 *args = data.args;
758 return data.err;
759 }
760
761 typedef struct con_type_help_data_s
762 {
763 ipmi_iter_help_cb help_cb;
764 void *cb_data;
765 } con_type_help_data_t;
766
767 static int
con_type_help_handler(void * cb_data,void * item1,void * item2)768 con_type_help_handler(void *cb_data, void *item1, void *item2)
769 {
770 ipmi_con_setup_t *setup = item2;
771 con_type_help_data_t *data = cb_data;
772
773 data->help_cb(item1, setup->help(), data->cb_data);
774 return LOCKED_LIST_ITER_CONTINUE;
775 }
776
777 void
ipmi_parse_args_iter_help(ipmi_iter_help_cb help_cb,void * cb_data)778 ipmi_parse_args_iter_help(ipmi_iter_help_cb help_cb, void *cb_data)
779 {
780 con_type_help_data_t data;
781
782 data.help_cb = help_cb;
783 data.cb_data = cb_data;
784 locked_list_iterate(con_type_list, con_type_help_handler, &data);
785 }
786
787 typedef struct con_setup_data_s
788 {
789 const char *name;
790 int err;
791
792 int *curr_arg;
793 int arg_count;
794 char * const *args;
795 ipmi_args_t *iargs;
796 } con_setup_data_t;
797
798 static int
con_type_check_parse(void * cb_data,void * item1,void * item2)799 con_type_check_parse(void *cb_data, void *item1, void *item2)
800 {
801 con_setup_data_t *data = cb_data;
802
803 if (strcmp(item1, data->name) == 0) {
804 ipmi_con_setup_t *setup = item2;
805 data->err = setup->parse(data->curr_arg, data->arg_count, data->args,
806 &data->iargs);
807 return LOCKED_LIST_ITER_STOP;
808 }
809 return LOCKED_LIST_ITER_CONTINUE;
810 }
811
812 int
ipmi_parse_args2(int * curr_arg,int arg_count,char * const * args,ipmi_args_t ** iargs)813 ipmi_parse_args2(int *curr_arg,
814 int arg_count,
815 char * const *args,
816 ipmi_args_t **iargs)
817 {
818 con_setup_data_t data;
819 int rv;
820
821 CHECK_ARG;
822 data.err = EINVAL;
823 data.name = args[*curr_arg];
824 (*curr_arg)++;
825 data.curr_arg = curr_arg;
826 data.arg_count = arg_count;
827 data.args = args;
828 locked_list_iterate(con_type_list, con_type_check_parse, &data);
829 if (data.err) {
830 rv = data.err;
831 goto out_err;
832 }
833
834 *iargs = data.iargs;
835 return 0;
836
837 out_err:
838 return rv;
839 }
840
841 void
ipmi_free_args(ipmi_args_t * args)842 ipmi_free_args(ipmi_args_t *args)
843 {
844 if (args->free)
845 args->free(args);
846 ipmi_mem_free(args);
847 }
848
849 int
ipmi_args_setup_con(ipmi_args_t * args,os_handler_t * handlers,void * user_data,ipmi_con_t ** con)850 ipmi_args_setup_con(ipmi_args_t *args,
851 os_handler_t *handlers,
852 void *user_data,
853 ipmi_con_t **con)
854 {
855 return args->connect(args, handlers, user_data, con);
856 }
857
858 const char *
ipmi_args_get_type(ipmi_args_t * args)859 ipmi_args_get_type(ipmi_args_t *args)
860 {
861 return args->get_type(args);
862 }
863
864 int
ipmi_args_get_val(ipmi_args_t * args,unsigned int argnum,const char ** name,const char ** type,const char ** help,char ** value,const char *** range)865 ipmi_args_get_val(ipmi_args_t *args,
866 unsigned int argnum,
867 const char **name,
868 const char **type,
869 const char **help,
870 char **value,
871 const char ***range)
872 {
873 return args->get_val(args, argnum, name, type, help, value, range);
874 }
875
876 int
ipmi_args_set_val(ipmi_args_t * args,unsigned int argnum,const char * name,const char * value)877 ipmi_args_set_val(ipmi_args_t *args,
878 unsigned int argnum,
879 const char *name,
880 const char *value)
881 {
882 return args->set_val(args, argnum, name, value);
883 }
884
885 void
ipmi_args_free_str(ipmi_args_t * args,char * str)886 ipmi_args_free_str(ipmi_args_t *args, char *str)
887 {
888 args->free_val(args, str);
889 }
890
891 ipmi_args_t *
ipmi_args_copy(ipmi_args_t * args)892 ipmi_args_copy(ipmi_args_t *args)
893 {
894 return args->copy(args);
895 }
896
897 int
ipmi_args_validate(ipmi_args_t * args,int * argnum)898 ipmi_args_validate(ipmi_args_t *args, int *argnum)
899 {
900 return args->validate(args, argnum);
901 }
902
903 ipmi_args_t *
i_ipmi_args_alloc(ipmi_args_free_cb free,ipmi_args_connect_cb connect,ipmi_args_get_val_cb get_val,ipmi_args_set_val_cb set_val,ipmi_args_copy_cb copy,ipmi_args_validate_cb validate,ipmi_args_free_val_cb free_val,ipmi_args_get_type_cb get_type,unsigned int extra_data_len)904 i_ipmi_args_alloc(ipmi_args_free_cb free,
905 ipmi_args_connect_cb connect,
906 ipmi_args_get_val_cb get_val,
907 ipmi_args_set_val_cb set_val,
908 ipmi_args_copy_cb copy,
909 ipmi_args_validate_cb validate,
910 ipmi_args_free_val_cb free_val,
911 ipmi_args_get_type_cb get_type,
912 unsigned int extra_data_len)
913 {
914 ipmi_args_t *val;
915
916 val = ipmi_mem_alloc(sizeof(*val) + extra_data_len);
917 if (!val)
918 return NULL;
919 memset(val, 0, sizeof(*val) + extra_data_len);
920 val->free = free;
921 val->connect = connect;
922 val->get_val = get_val;
923 val->set_val = set_val;
924 val->copy = copy;
925 val->validate = validate;
926 val->free_val = free_val;
927 val->get_type = get_type;
928 return val;
929 }
930
931 void *
i_ipmi_args_get_extra_data(ipmi_args_t * args)932 i_ipmi_args_get_extra_data(ipmi_args_t *args)
933 {
934 return ((char *) args) + sizeof(*args);
935 }
936
937 int
i_ipmi_register_con_type(const char * name,ipmi_con_setup_t * setup)938 i_ipmi_register_con_type(const char *name, ipmi_con_setup_t *setup)
939 {
940 if (locked_list_add(con_type_list, (void *) name, setup))
941 return 0;
942 else
943 return ENOMEM;
944 }
945
946 typedef struct con_type_check_remover_s
947 {
948 const char *name;
949 int err;
950 } con_type_check_remover_t;
951
952 static int
con_type_check_remove(void * cb_data,void * item1,void * item2)953 con_type_check_remove(void *cb_data, void *item1, void *item2)
954 {
955 con_type_check_remover_t *data = cb_data;
956
957 if (strcmp(item1, data->name) == 0) {
958 locked_list_remove(con_type_list, item1, item2);
959 data->err = 0;
960 return LOCKED_LIST_ITER_STOP;
961 }
962 return LOCKED_LIST_ITER_CONTINUE;
963 }
964
965 int
i_ipmi_unregister_con_type(const char * name,ipmi_con_setup_t * setup)966 i_ipmi_unregister_con_type(const char *name, ipmi_con_setup_t *setup)
967 {
968 con_type_check_remover_t data;
969
970 data.err = EINVAL;
971 data.name = name;
972 locked_list_iterate(con_type_list, con_type_check_remove, &data);
973 return data.err;
974 }
975
976 int
ipmi_parse_options(ipmi_open_option_t * option,char * arg)977 ipmi_parse_options(ipmi_open_option_t *option,
978 char *arg)
979 {
980 if (strcmp(arg, "-noall") == 0) {
981 option->option = IPMI_OPEN_OPTION_ALL;
982 option->ival = 0;
983 } else if (strcmp(arg, "-all") == 0) {
984 option->option = IPMI_OPEN_OPTION_ALL;
985 option->ival = 1;
986 } else if (strcmp(arg, "-nosdrs") == 0) {
987 option->option = IPMI_OPEN_OPTION_SDRS;
988 option->ival = 0;
989 } else if (strcmp(arg, "-sdrs") == 0) {
990 option->option = IPMI_OPEN_OPTION_SDRS;
991 option->ival = 1;
992 } else if (strcmp(arg, "-nofrus") == 0) {
993 option->option = IPMI_OPEN_OPTION_FRUS;
994 option->ival = 0;
995 } else if (strcmp(arg, "-frus") == 0) {
996 option->option = IPMI_OPEN_OPTION_FRUS;
997 option->ival = 1;
998 } else if (strcmp(arg, "-nosel") == 0) {
999 option->option = IPMI_OPEN_OPTION_SEL;
1000 option->ival = 0;
1001 } else if (strcmp(arg, "-sel") == 0) {
1002 option->option = IPMI_OPEN_OPTION_SEL;
1003 option->ival = 1;
1004 } else if (strcmp(arg, "-noipmbscan") == 0) {
1005 option->option = IPMI_OPEN_OPTION_IPMB_SCAN;
1006 option->ival = 0;
1007 } else if (strcmp(arg, "-ipmbscan") == 0) {
1008 option->option = IPMI_OPEN_OPTION_IPMB_SCAN;
1009 option->ival = 1;
1010 } else if (strcmp(arg, "-nooeminit") == 0) {
1011 option->option = IPMI_OPEN_OPTION_OEM_INIT;
1012 option->ival = 0;
1013 } else if (strcmp(arg, "-oeminit") == 0) {
1014 option->option = IPMI_OPEN_OPTION_OEM_INIT;
1015 option->ival = 1;
1016 } else if (strcmp(arg, "-noseteventrcvr") == 0) {
1017 option->option = IPMI_OPEN_OPTION_SET_EVENT_RCVR;
1018 option->ival = 0;
1019 } else if (strcmp(arg, "-seteventrcvr") == 0) {
1020 option->option = IPMI_OPEN_OPTION_SET_EVENT_RCVR;
1021 option->ival = 1;
1022 } else if (strcmp(arg, "-noactivate") == 0) {
1023 option->option = IPMI_OPEN_OPTION_ACTIVATE_IF_POSSIBLE;
1024 option->ival = 0;
1025 } else if (strcmp(arg, "-activate") == 0) {
1026 option->option = IPMI_OPEN_OPTION_ACTIVATE_IF_POSSIBLE;
1027 option->ival = 1;
1028 } else if (strcmp(arg, "-nosetseltime") == 0) {
1029 option->option = IPMI_OPEN_OPTION_SET_SEL_TIME;
1030 option->ival = 0;
1031 } else if (strcmp(arg, "-setseltime") == 0) {
1032 option->option = IPMI_OPEN_OPTION_SET_SEL_TIME;
1033 option->ival = 1;
1034 } else if (strcmp(arg, "-nolocalonly") == 0) {
1035 option->option = IPMI_OPEN_OPTION_LOCAL_ONLY;
1036 option->ival = 0;
1037 } else if (strcmp(arg, "-localonly") == 0) {
1038 option->option = IPMI_OPEN_OPTION_LOCAL_ONLY;
1039 option->ival = 1;
1040 } else if (strcmp(arg, "-nocache") == 0) {
1041 option->option = IPMI_OPEN_OPTION_USE_CACHE;
1042 option->ival = 0;
1043 } else if (strcmp(arg, "-cache") == 0) {
1044 option->option = IPMI_OPEN_OPTION_USE_CACHE;
1045 option->ival = 1;
1046 } else
1047 return EINVAL;
1048
1049 return 0;
1050 }
1051
1052 const char *
ipmi_parse_options_help(void)1053 ipmi_parse_options_help(void)
1054 {
1055 return
1056 "-[no]all - all automatic handling\n"
1057 "-[no]sdrs - sdr fetching\n"
1058 "-[no]frus - FRU fetching\n"
1059 "-[no]sel - SEL fetching\n"
1060 "-[no]ipmbscan - IPMB bus scanning\n"
1061 "-[no]oeminit - special OEM processing (like ATCA)\n"
1062 "-[no]seteventrcvr - setting event receivers\n"
1063 "-[no]setseltime - setting the SEL clock\n"
1064 "-[no]activate - connection activation\n"
1065 "-[no]localonly - Just talk to the local BMC, (ATCA-only, for blades)\n"
1066 "-[no]cache - use the local cache for SDRs. On by default."
1067 "-wait_til_up - wait until the domain is up before returning";
1068 }
1069
1070 /* This is the number of seconds between 1/1/70 (IPMI event date) and
1071 1/1/98 (ipmi SNMP trap local timestamp). */
1072 #define IPMI_SNMP_DATE_OFFSET 883612800
1073
1074 int
ipmi_handle_snmp_trap_data(const void * src_addr,unsigned int src_addr_len,int src_addr_type,long specific,const unsigned char * data,unsigned int data_len)1075 ipmi_handle_snmp_trap_data(const void *src_addr,
1076 unsigned int src_addr_len,
1077 int src_addr_type,
1078 long specific,
1079 const unsigned char *data,
1080 unsigned int data_len)
1081 {
1082 int handled = 0;
1083 unsigned char pet_ack[12];
1084 ipmi_msg_t *msg = NULL;
1085
1086 if (DEBUG_RAWMSG) {
1087 ipmi_log(IPMI_LOG_DEBUG_START, "Got SNMP trap from:\n ");
1088 dump_hex(src_addr, src_addr_len);
1089 ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data is:\n ");
1090 dump_hex(data, data_len);
1091 ipmi_log(IPMI_LOG_DEBUG_END, " ");
1092 }
1093
1094 if (data_len < 46)
1095 return 0;
1096
1097 /* I will take this opportunity to note that the SNMP trap format
1098 from IPMI is insufficient to actually perform the job. It does
1099 not have:
1100 1 A guaranteed way to correlate the timestamp to the SEL.
1101 2 A guaranteed way to correlate the record id to the SEL.
1102 3 The channel or the LUN for the event generator.
1103
1104 Because of these, there is no guaranteed way to correlate the
1105 data from the SNMP trap to an SEL event. This can result in
1106 duplicate events, which is very bad. So we currently do not
1107 deliver the events this way, we pass a NULL in the event
1108 message to tell the domain code to rescan the SEL for this MC.
1109 In addition, item 3 above means that you cannot determine which
1110 sensor issued the event, since the channel and the LUN are
1111 required to find the sensor.
1112 */
1113
1114 /* Until we have some way to get full valid data from the trap, we
1115 just disable it. */
1116 #if 0
1117 ipmi_msg_t tmsg;
1118 unsigned char edata[17];
1119 unsigned long timestamp;
1120 int16_t utc_off;
1121 unsigned short record_id;
1122 timestamp = ntohl(*((uint32_t *) (data+18)));
1123 if (data[27] == 0xff)
1124 /* Can't handle unspecific event generator */
1125 return 0;
1126 if ((data[28] == 0xff) || (data[28] == 0x00))
1127 /* Can't handle unspecific sensor */
1128 return 0;
1129 if (timestamp == 0)
1130 /* Can't handle unspecified timestamp. */
1131 return 0;
1132 utc_off = ntohs(*((uint16_t *) (data+22)));
1133 if (utc_off == -1)
1134 /* If unspecified (0xffff), we assume zero (UTC). */
1135 utc_off = 0;
1136 timestamp -= utc_off; /* Remove timezone offset */
1137 timestamp += IPMI_SNMP_DATE_OFFSET; /* Convert to 1/1/70 offset */
1138
1139 /* We assume the record id is in the sequence # field, since that
1140 makes the most sense. */
1141 record_id = ntohs(*((uint16_t *) (data+16)));
1142
1143 tmsg.netfn = IPMI_APP_NETFN;
1144 tmsg.cmd = IPMI_READ_EVENT_MSG_BUFFER_CMD;
1145 tmsg.data = edata;
1146 tmsg.data_len = 17;
1147 msg = &tmsg;
1148 edata[0] = 0;
1149 edata[1] = record_id & 0xff;
1150 edata[2] = (record_id >> 8) & 0xff;
1151 edata[3] = 2; /* record type - system event */
1152 edata[4] = timestamp & 0xff;
1153 edata[5] = (timestamp >> 8) & 0xff;
1154 edata[6] = (timestamp >> 16) & 0xff;
1155 edata[7] = (timestamp >> 24) & 0xff;
1156 edata[8] = data[27]; /* Event generator */
1157 /* FIXME - is there a way to get the LUN? */
1158 edata[9] = 0; /* Assume channel 0, lun 0 */
1159 edata[10] = 0x04; /* IPMI 1.5 revision */
1160 edata[11] = (specific >> 16) & 0xff; /* Sensor type */
1161 edata[12] = data[28]; /* Sensor number */
1162 edata[13] = (specific >> 8) & 0xff; /* Event dir/type */
1163 memcpy(edata+14, data+31, 3); /* Event data 1-3 */
1164 #endif
1165
1166 pet_ack[0] = data[17]; /* Record id */
1167 pet_ack[1] = data[16];
1168 pet_ack[2] = data[21]; /* Timestamp */
1169 pet_ack[3] = data[20];
1170 pet_ack[4] = data[19];
1171 pet_ack[5] = data[18];
1172 pet_ack[6] = data[25]; /* Event source type */
1173 pet_ack[7] = data[27]; /* Sensor device */
1174 pet_ack[8] = data[28]; /* Sensor number */
1175 memcpy(pet_ack+9, data+31, 3); /* Event data 1-3 */
1176
1177 if (src_addr_type == IPMI_EXTERN_ADDR_IP)
1178 handled = ipmi_lan_handle_external_event(src_addr, msg, pet_ack);
1179
1180 return handled;
1181 }
1182
1183 char *
ipmi_openipmi_version(void)1184 ipmi_openipmi_version(void)
1185 {
1186 return OPENIPMI_VERSION;
1187 }
1188
1189 ipmi_msgi_t *
ipmi_alloc_msg_item(void)1190 ipmi_alloc_msg_item(void)
1191 {
1192 ipmi_msgi_t *rv;
1193
1194 rv = ipmi_mem_alloc(sizeof(ipmi_msgi_t));
1195 if (!rv)
1196 return NULL;
1197 memset(rv, 0, sizeof(*rv));
1198 rv->msg.data = rv->data;
1199 return rv;
1200 }
1201
1202 void
ipmi_free_msg_item(ipmi_msgi_t * item)1203 ipmi_free_msg_item(ipmi_msgi_t *item)
1204 {
1205 if (item->msg.data && (item->msg.data != item->data))
1206 ipmi_free_msg_item_data(item->msg.data);
1207 ipmi_mem_free(item);
1208 }
1209
1210 void *
ipmi_alloc_msg_item_data(unsigned int size)1211 ipmi_alloc_msg_item_data(unsigned int size)
1212 {
1213 return ipmi_mem_alloc(size);
1214 }
1215
1216 void
ipmi_free_msg_item_data(void * data)1217 ipmi_free_msg_item_data(void *data)
1218 {
1219 ipmi_mem_free(data);
1220 }
1221
1222 void
ipmi_move_msg_item(ipmi_msgi_t * new_item,ipmi_msgi_t * old_item)1223 ipmi_move_msg_item(ipmi_msgi_t *new_item, ipmi_msgi_t *old_item)
1224 {
1225 if (new_item->msg.data && (new_item->msg.data != new_item->data))
1226 ipmi_free_msg_item_data(new_item->msg.data);
1227 new_item->msg = old_item->msg;
1228
1229 if (!old_item->msg.data) {
1230 /* Nothing to do */
1231 } else if (old_item->msg.data != old_item->data) {
1232 /* Copied the actual data pointer. */
1233 old_item->msg.data = NULL;
1234 } else {
1235 memcpy(new_item->data, old_item->data, old_item->msg.data_len);
1236 new_item->msg.data = new_item->data;
1237 }
1238 }
1239
1240 void
ipmi_handle_rsp_item_copyall(ipmi_con_t * ipmi,ipmi_msgi_t * rspi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg,ipmi_ll_rsp_handler_t rsp_handler)1241 ipmi_handle_rsp_item_copyall(ipmi_con_t *ipmi,
1242 ipmi_msgi_t *rspi,
1243 const ipmi_addr_t *addr,
1244 unsigned int addr_len,
1245 const ipmi_msg_t *msg,
1246 ipmi_ll_rsp_handler_t rsp_handler)
1247 {
1248 int used = IPMI_MSG_ITEM_NOT_USED;
1249
1250 memcpy(&rspi->addr, addr, addr_len);
1251 rspi->addr_len = addr_len;
1252 rspi->msg = *msg;
1253 memcpy(rspi->data, msg->data, msg->data_len);
1254 rspi->msg.data = rspi->data;
1255
1256 /* call the user handler. */
1257 if (rsp_handler)
1258 used = rsp_handler(ipmi, rspi);
1259
1260 if (!used)
1261 ipmi_free_msg_item(rspi);
1262 }
1263
1264 void
ipmi_handle_rsp_item_copymsg(ipmi_con_t * ipmi,ipmi_msgi_t * rspi,const ipmi_msg_t * msg,ipmi_ll_rsp_handler_t rsp_handler)1265 ipmi_handle_rsp_item_copymsg(ipmi_con_t *ipmi,
1266 ipmi_msgi_t *rspi,
1267 const ipmi_msg_t *msg,
1268 ipmi_ll_rsp_handler_t rsp_handler)
1269 {
1270 int used = IPMI_MSG_ITEM_NOT_USED;
1271
1272 rspi->msg = *msg;
1273 memcpy(rspi->data, msg->data, msg->data_len);
1274 rspi->msg.data = rspi->data;
1275
1276 /* call the user handler. */
1277 if (rsp_handler)
1278 used = rsp_handler(ipmi, rspi);
1279
1280 if (!used)
1281 ipmi_free_msg_item(rspi);
1282 }
1283
1284 void
ipmi_handle_rsp_item(ipmi_con_t * ipmi,ipmi_msgi_t * rspi,ipmi_ll_rsp_handler_t rsp_handler)1285 ipmi_handle_rsp_item(ipmi_con_t *ipmi,
1286 ipmi_msgi_t *rspi,
1287 ipmi_ll_rsp_handler_t rsp_handler)
1288 {
1289 int used = IPMI_MSG_ITEM_NOT_USED;
1290
1291 /* call the user handler. */
1292 if (rsp_handler)
1293 used = rsp_handler(ipmi, rspi);
1294
1295 if (!used)
1296 ipmi_free_msg_item(rspi);
1297 }
1298
1299 os_handler_t *
ipmi_alloc_os_handler(void)1300 ipmi_alloc_os_handler(void)
1301 {
1302 os_handler_t *rv = ipmi_mem_alloc(sizeof(*rv));
1303 if (rv)
1304 memset(rv, 0, sizeof(*rv));
1305 return rv;
1306 }
1307
1308 void
ipmi_free_os_handler(os_handler_t * handler)1309 ipmi_free_os_handler(os_handler_t *handler)
1310 {
1311 ipmi_mem_free(handler);
1312 }
1313
1314