00001 /* 00002 * ipmi_conn.h 00003 * 00004 * MontaVista IPMI interface, definition for a low-level connection (like a 00005 * LAN interface, or system management interface, etc.). 00006 * 00007 * Author: MontaVista Software, Inc. 00008 * Corey Minyard <minyard@mvista.com> 00009 * source@mvista.com 00010 * 00011 * Copyright 2002,2003 MontaVista Software Inc. 00012 * 00013 * This program is free software; you can redistribute it and/or 00014 * modify it under the terms of the GNU Lesser General Public License 00015 * as published by the Free Software Foundation; either version 2 of 00016 * the License, or (at your option) any later version. 00017 * 00018 * 00019 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 00020 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00021 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00022 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00023 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00024 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00025 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 00027 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00028 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * You should have received a copy of the GNU Lesser General Public 00031 * License along with this program; if not, write to the Free 00032 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00033 */ 00034 00035 #ifndef _IPMI_CONN_H 00036 #define _IPMI_CONN_H 00037 00038 #include <OpenIPMI/ipmi_types.h> 00039 #include <OpenIPMI/ipmi_addr.h> 00040 #include <OpenIPMI/ipmiif.h> 00041 #include <OpenIPMI/os_handler.h> 00042 00043 #ifdef __cplusplus 00044 extern "C" { 00045 #endif 00046 00047 /* Called when an IPMI response to a command comes in from the BMC. */ 00048 typedef int (*ipmi_ll_rsp_handler_t)(ipmi_con_t *ipmi, 00049 ipmi_msgi_t *rspi); 00050 00051 /* Called when an IPMI event comes in from the BMC. Note that the 00052 event may be NULL, meaning that an event came in but did not have 00053 enough information to build a full event message. So this is just 00054 an indication that there is a new event in the event log. Note that 00055 if an event is delivered here, it's mcid might be invalid, so that 00056 may need to be established here. */ 00057 typedef void (*ipmi_ll_evt_handler_t)(ipmi_con_t *ipmi, 00058 const ipmi_addr_t *addr, 00059 unsigned int addr_len, 00060 ipmi_event_t *event, 00061 void *cb_data); 00062 00063 /* Called when an incoming command is received by the IPMI code. */ 00064 typedef void (*ipmi_ll_cmd_handler_t)(ipmi_con_t *ipmi, 00065 const ipmi_addr_t *addr, 00066 unsigned int addr_len, 00067 const ipmi_msg_t *cmd, 00068 long sequence, 00069 void *cmd_data, 00070 void *data2, 00071 void *data3); 00072 00073 /* Called when a low-level connection has failed or come up. If err 00074 is zero, the connection has come up after being failed. if err is 00075 non-zero, it's an error number to report why the failure occurred. 00076 Since some connections support multiple ports into the system, this 00077 is used to report partial failures as well as full failures. 00078 port_num will be the port number that has failed (if err is 00079 nonzero) or has just come up (if err is zero). What port_num that 00080 means depends on the connection type. any_port_up will be true if 00081 the system still has connectivity through other ports. */ 00082 typedef void (*ipmi_ll_con_changed_cb)(ipmi_con_t *ipmi, 00083 int err, 00084 unsigned int port_num, 00085 int any_port_up, 00086 void *cb_data); 00087 00088 /* Used when fetching the IPMB address of the connection. The active 00089 parm tells if the interface is active or not, this callback is also 00090 used to inform the upper layer when the connection becomes active 00091 or inactive. Note that there can be one IPMB address per channel, 00092 so this allows an array of IPMBs to be passed, one per channel. 00093 Set the IPMB to 0 if unknown. */ 00094 typedef void (*ipmi_ll_ipmb_addr_cb)(ipmi_con_t *ipmi, 00095 int err, 00096 const unsigned char ipmb_addr[], 00097 unsigned int num_ipmb_addr, 00098 int active, 00099 unsigned int hacks, 00100 void *cb_data); 00101 00102 /* Used to handle knowing when the connection shutdown is complete. */ 00103 typedef void (*ipmi_ll_con_closed_cb)(ipmi_con_t *ipmi, void *cb_data); 00104 00105 /* Set this bit in the hacks if, even though the connection is to a 00106 device not at 0x20, the first part of a LAN command should always 00107 use 0x20. */ 00108 #define IPMI_CONN_HACK_20_AS_MAIN_ADDR 0x00000001 00109 00110 /* Some systems (incorrectly, according to the spec) use only the 00111 bottom 4 bits or ROLE(m) for authentication in the RAKP3 message. 00112 The spec says to use all 8 bits, but enabling this hack makes 00113 OpenIPMI only use the bottom 4 bits. */ 00114 #define IPMI_CONN_HACK_RAKP3_WRONG_ROLEM 0x00000002 00115 00116 /* The spec is vague (perhaps wrong), but the default for RMCP+ seems 00117 to be to use K(1) as the integrity key. That is thus the default 00118 of OpenIPMI, but this hack lets you use SIK as it says in one part 00119 of the spec. */ 00120 #define IPMI_CONN_HACK_RMCPP_INTEG_SIK 0x00000004 00121 00122 /* 00123 * Used to pass special options for sending messages. 00124 */ 00125 typedef struct ipmi_con_option_s 00126 { 00127 int option; 00128 union { 00129 long ival; 00130 void *pval; 00131 }; 00132 } ipmi_con_option_t; 00133 00134 /* Used to mark the end of the option list. Must always be the last 00135 option. */ 00136 #define IPMI_CON_OPTION_LIST_END 0 00137 00138 /* Enable/disable authentication on the message (set by ival). 00139 Default is enabled. */ 00140 #define IPMI_CON_MSG_OPTION_AUTH 1 00141 00142 /* Enable/disable confidentiality (encryption) on the message (set by 00143 ival). Default is enabled. */ 00144 #define IPMI_CON_MSG_OPTION_CONF 2 00145 00146 00147 /* The data structure representing a connection. The low-level handler 00148 fills this out then calls ipmi_init_con() with the connection. */ 00149 struct ipmi_con_s 00150 { 00151 /* If this is zero, the domain handling code will not attempt to 00152 scan the system interface address of the connection. If 1, it 00153 will. Generally, if the system interface will respond on a 00154 IPMB address, you should set this to zero. If it does not 00155 respond on an IPMB, you should set this to one if it is a 00156 management controller. */ 00157 int scan_sysaddr; 00158 00159 /* The low-level handler should provide one of these for doing os-type 00160 things (locks, random numbers, etc.) */ 00161 os_handler_t *os_hnd; 00162 00163 /* This data can be fetched by the user and used for anything they 00164 like. */ 00165 void *user_data; 00166 00167 /* Connection-specific data for the underlying connection. */ 00168 void *con_data; 00169 00170 /* If OEM code want to attach some data, it can to it here. */ 00171 void *oem_data; 00172 void (*oem_data_cleanup)(ipmi_con_t *ipmi); 00173 00174 /* This allows the connection to tell the upper layer that broadcasting 00175 will not work on this interface. */ 00176 int broadcast_broken; 00177 00178 /* Calls for the interface. These should all return standard 00179 "errno" errors if they fail. */ 00180 00181 /* Start processing on a connection. Note that the handler *must* 00182 be called with the global read lock not held, because the 00183 handler must write lock the global lock in order to add the MC 00184 to the global list. This will report success/failure with the 00185 con_changed_handler, so set that up first. */ 00186 int (*start_con)(ipmi_con_t *ipmi); 00187 00188 /* Add a callback to call when the connection goes down or up. */ 00189 int (*add_con_change_handler)(ipmi_con_t *ipmi, 00190 ipmi_ll_con_changed_cb handler, 00191 void *cb_data); 00192 int (*remove_con_change_handler)(ipmi_con_t *ipmi, 00193 ipmi_ll_con_changed_cb handler, 00194 void *cb_data); 00195 00196 /* If OEM code discovers that an IPMB address has changed, it can 00197 use this to change it. The hacks are the same as the ones in 00198 the IPMB address handler. */ 00199 void (*set_ipmb_addr)(ipmi_con_t *ipmi, 00200 const unsigned char ipmb_addr[], 00201 unsigned int num_ipmb_addr, 00202 int active, 00203 unsigned int hacks); 00204 00205 /* Add a handler that will be called when the IPMB address changes. */ 00206 int (*add_ipmb_addr_handler)(ipmi_con_t *ipmi, 00207 ipmi_ll_ipmb_addr_cb handler, 00208 void *cb_data); 00209 int (*remove_ipmb_addr_handler)(ipmi_con_t *ipmi, 00210 ipmi_ll_ipmb_addr_cb handler, 00211 void *cb_data); 00212 00213 /* This call gets the IPMB address of the connection. It may be 00214 NULL if the connection does not support this. This call may be 00215 set or overridden by the OEM code. This is primarily for use 00216 by the connection code itself, the OEM code for the BMC 00217 connected to should set this. If it is not set, the IPMB 00218 address is assumed to be 0x20. This *should* send a message to 00219 the device, because connection code will assume that and use it 00220 to check for device function. This should also check if the 00221 device is active. If this is non-null, it will be called 00222 periodically. */ 00223 int (*get_ipmb_addr)(ipmi_con_t *ipmi, 00224 ipmi_ll_ipmb_addr_cb handler, 00225 void *cb_data); 00226 00227 /* Change the state of the connection to be active or inactive. 00228 This may be NULL if the connection does not support this. The 00229 interface code may set this, the OEM code should override this 00230 if necessary. */ 00231 int (*set_active_state)(ipmi_con_t *ipmi, 00232 int is_active, 00233 ipmi_ll_ipmb_addr_cb handler, 00234 void *cb_data); 00235 00236 /* Send an IPMI command (in "msg" on the "ipmi" connection to the 00237 given "addr". When the response comes in or the message times 00238 out, rsp_handler will be called with the following four data 00239 items. Note that the lower layer MUST guarantee that the 00240 reponse handler is called, even if it fails or the message is 00241 dropped. */ 00242 int (*send_command)(ipmi_con_t *ipmi, 00243 const ipmi_addr_t *addr, 00244 unsigned int addr_len, 00245 const ipmi_msg_t *msg, 00246 ipmi_ll_rsp_handler_t rsp_handler, 00247 ipmi_msgi_t *rspi); 00248 00249 /* Register to receive IPMI events from the interface. */ 00250 int (*add_event_handler)(ipmi_con_t *ipmi, 00251 ipmi_ll_evt_handler_t handler, 00252 void *cb_data); 00253 00254 /* Remove an event handler. */ 00255 int (*remove_event_handler)(ipmi_con_t *ipmi, 00256 ipmi_ll_evt_handler_t handler, 00257 void *cb_data); 00258 00259 /* Send a response message. This is not supported on all 00260 interfaces, primarily only on system management interfaces. If 00261 not supported, this should return ENOSYS. */ 00262 int (*send_response)(ipmi_con_t *ipmi, 00263 const ipmi_addr_t *addr, 00264 unsigned int addr_len, 00265 const ipmi_msg_t *msg, 00266 long sequence); 00267 00268 /* Register to receive incoming commands. This is not supported 00269 on all interfaces, primarily only on system management 00270 interfaces. If not supported, this should return ENOSYS. */ 00271 int (*register_for_command)(ipmi_con_t *ipmi, 00272 unsigned char netfn, 00273 unsigned char cmd, 00274 ipmi_ll_cmd_handler_t handler, 00275 void *cmd_data, 00276 void *data2, 00277 void *data3); 00278 00279 /* Deregister a command registration. This is not supported on 00280 all interfaces, primarily only on system management interfaces. 00281 If not supported, this should return ENOSYS. */ 00282 int (*deregister_for_command)(ipmi_con_t *ipmi, 00283 unsigned char netfn, 00284 unsigned char cmd); 00285 00286 /* Close an IPMI connection. */ 00287 int (*close_connection)(ipmi_con_t *ipmi); 00288 00289 /* This is set by OEM code to handle certain conditions when a 00290 send message fails. It is currently only used by the IPMI LAN 00291 code, if a send messages response is an error, this will be 00292 called first. If this function returns true, then the IPMI LAN 00293 code will not do anything with the message. */ 00294 int (*handle_send_rsp_err)(ipmi_con_t *con, ipmi_msg_t *msg); 00295 00296 /* Name the connection code can use for logging and instance names 00297 for statistics. Must be dynamically allocated with 00298 ipmi_mem_alloc(). The connection code will free this. May be 00299 NULL. */ 00300 char *name; 00301 00302 /* The connection code may put a string here to identify 00303 itself. */ 00304 char *con_type; 00305 00306 /* The privilege level of the connection */ 00307 unsigned int priv_level; 00308 00309 /* Close an IPMI connection and report that it is closed. */ 00310 int (*close_connection_done)(ipmi_con_t *ipmi, 00311 ipmi_ll_con_closed_cb handler, 00312 void *cb_data); 00313 00314 /* Hacks reported by OEM code. This should be set by the lower 00315 layer or by the user interface code. */ 00316 unsigned int hacks; 00317 00318 /* The IPMB address as reported by the lower layer. */ 00319 unsigned char ipmb_addr[MAX_IPMI_USED_CHANNELS]; 00320 00321 /* Handle an async event for the connection reported by something 00322 else. */ 00323 void (*handle_async_event)(ipmi_con_t *con, 00324 const ipmi_addr_t *addr, 00325 unsigned int addr_len, 00326 const ipmi_msg_t *msg); 00327 00328 /* Used by the connection attribute code. Don't do anything with 00329 this yourself!. The thing that creates this connection should 00330 call ipmi_con_attr_init() when the connection is created and 00331 ipmi_con_attr_cleanup() when the connection is destroyed. */ 00332 void *attr; 00333 00334 /* Statistics interfaces. These may be NULL if the user doesn't 00335 want statistics. They pass in the user data field. */ 00336 int (*register_stat)(void *user_data, char *name, 00337 char *instance, void **stat); 00338 void (*add_stat)(void *user_data, void *stat, int value); 00339 void (*finished_with_stat)(void *user_data, void *stat); 00340 00341 /* Return the arguments or the connection. */ 00342 ipmi_args_t *(*get_startup_args)(ipmi_con_t *con); 00343 00344 /* Increment the usecount of the connection; for each use, the 00345 connection must be closed. This may be NULL if the connection 00346 type does not support being reused. */ 00347 void (*use_connection)(ipmi_con_t *con); 00348 00349 /* Like send_command, but with options. options may be NULL if 00350 none. If options are passed in, they must be terminated with 00351 the proper option. This field may be NULL if the connection 00352 does not support options. */ 00353 int (*send_command_option)(ipmi_con_t *ipmi, 00354 const ipmi_addr_t *addr, 00355 unsigned int addr_len, 00356 const ipmi_msg_t *msg, 00357 const ipmi_con_option_t *options, 00358 ipmi_ll_rsp_handler_t rsp_handler, 00359 ipmi_msgi_t *rspi); 00360 00361 /* Returns the number of ports on the connection (one more than 00362 the max_port that can be reported by ipmi_ll_con_changed_cb(). 00363 If NULL, assume 1. */ 00364 unsigned int (*get_num_ports)(ipmi_con_t *ipmi); 00365 }; 00366 00367 #define IPMI_CONN_NAME(c) (c->name ? c->name : "") 00368 00369 /* Initialization code for the initialization the connection code. */ 00370 int _ipmi_conn_init(os_handler_t *os_hnd); 00371 void _ipmi_conn_shutdown(void); 00372 00373 00374 /* Address types for external addresses. */ 00375 #define IPMI_EXTERN_ADDR_IP 1 00376 00377 /* Handle a trap from an external SNMP source. It returns 1 if the 00378 event was handled an zero if it was not. */ 00379 int ipmi_handle_snmp_trap_data(const void *src_addr, 00380 unsigned int src_addr_len, 00381 int src_addr_type, 00382 long specific, 00383 const unsigned char *data, 00384 unsigned int data_len); 00385 00386 /* These calls deal with OEM-type handlers for connections. Certain 00387 connections can be detected with special means (beyond just the 00388 manufacturer and product id) and this allows handlers for these 00389 types of connections to be registered. At the very initial 00390 connection of every connection, the handler will be called and it 00391 must detect whether this is the specific type of connection or not, 00392 do any setup for that connection type, and then call the done 00393 routine passed in. Note that the done routine may be called later, 00394 (allowing this handler to send messages and the like) but it *must* 00395 be called. Note that this has no cancellation handler. It relies 00396 on the lower levels returning responses for all the commands with 00397 NULL connections. */ 00398 typedef void (*ipmi_conn_oem_check_done)(ipmi_con_t *conn, 00399 void *cb_data); 00400 typedef int (*ipmi_conn_oem_check)(ipmi_con_t *conn, 00401 void *check_cb_data, 00402 ipmi_conn_oem_check_done done, 00403 void *done_cb_data); 00404 int ipmi_register_conn_oem_check(ipmi_conn_oem_check check, 00405 void *cb_data); 00406 int ipmi_deregister_conn_oem_check(ipmi_conn_oem_check check, 00407 void *cb_data); 00408 /* Should be called by the connection code for any new connection. */ 00409 int ipmi_conn_check_oem_handlers(ipmi_con_t *conn, 00410 ipmi_conn_oem_check_done done, 00411 void *cb_data); 00412 00413 /* Generic message handling */ 00414 void ipmi_handle_rsp_item(ipmi_con_t *ipmi, 00415 ipmi_msgi_t *rspi, 00416 ipmi_ll_rsp_handler_t rsp_handler); 00417 00418 void ipmi_handle_rsp_item_copymsg(ipmi_con_t *ipmi, 00419 ipmi_msgi_t *rspi, 00420 const ipmi_msg_t *msg, 00421 ipmi_ll_rsp_handler_t rsp_handler); 00422 00423 void ipmi_handle_rsp_item_copyall(ipmi_con_t *ipmi, 00424 ipmi_msgi_t *rspi, 00425 const ipmi_addr_t *addr, 00426 unsigned int addr_len, 00427 const ipmi_msg_t *msg, 00428 ipmi_ll_rsp_handler_t rsp_handler); 00429 00430 /* You should use these for allocating and freeing mesage items. Note 00431 that if you set item->msg.data to a non-NULL value that is not 00432 item->data, the system will free it with ipmi_free_msg_item_data(). 00433 So you should allocate it with ipmi_alloc_msg_item_data9). */ 00434 ipmi_msgi_t *ipmi_alloc_msg_item(void); 00435 void ipmi_free_msg_item(ipmi_msgi_t *item); 00436 void *ipmi_alloc_msg_item_data(unsigned int size); 00437 void ipmi_free_msg_item_data(void *data); 00438 /* Move the data from the old message item to the new one, NULL-ing 00439 out the old item's data. This will free the new_item's original 00440 data if necessary. This will *not* copy the data items, just the 00441 address and message. */ 00442 void ipmi_move_msg_item(ipmi_msgi_t *new_item, ipmi_msgi_t *old_item); 00443 00444 /* 00445 * Connection attributes. These are named items that code may create 00446 * to attach a void data item to a connection by name. It can then 00447 * look up the data item by name. Note that you can call 00448 * ipmi_con_register_attribute multiple times. The first time will 00449 * create the item, the rest of the times will return the existing 00450 * item. 00451 * 00452 * When the connection is destroyed, the destroy function will be 00453 * called on the attribute so the memory (or anything else) can be 00454 * cleaned up. 00455 * 00456 * This is especially for use by RMCP+ payloads so they may attach 00457 * data to the connection they are associated with. 00458 */ 00459 typedef struct ipmi_con_attr_s ipmi_con_attr_t; 00460 00461 /* Attr init function. Return the data item in the data field. Returns 00462 an error value. Will only be called once for the attribute. */ 00463 typedef int (*ipmi_con_attr_init_cb)(ipmi_con_t *con, void *cb_data, 00464 void **data); 00465 00466 /* Called when the attribute is destroyed. Note that this may happen 00467 after connection destruction, so the connection may not exist any 00468 more. */ 00469 typedef void (*ipmi_con_attr_kill_cb)(void *cb_data, void *data); 00470 00471 int ipmi_con_register_attribute(ipmi_con_t *con, 00472 char *name, 00473 ipmi_con_attr_init_cb init, 00474 ipmi_con_attr_kill_cb destroy, 00475 void *cb_data, 00476 ipmi_con_attr_t **attr); 00477 int ipmi_con_find_attribute(ipmi_con_t *con, 00478 char *name, 00479 ipmi_con_attr_t **attr); 00480 void *ipmi_con_attr_get_data(ipmi_con_attr_t *attr); 00481 /* You must call the put operation of every attribute returned by 00482 register or find. */ 00483 void ipmi_con_attr_put(ipmi_con_attr_t *attr); 00484 int ipmi_con_attr_init(ipmi_con_t *con); 00485 void ipmi_con_attr_cleanup(ipmi_con_t *con); 00486 00487 #ifdef __cplusplus 00488 } 00489 #endif 00490 00491 #endif /* _IPMI_CONN_H */