1 /*
2  * ipmi_lan.c
3  *
4  * MontaVista IPMI code for handling IPMI LAN connections
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2002,2003,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 <config.h>
35 
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <sys/stat.h>
40 #include <sys/poll.h>
41 #include <sys/time.h>
42 #include <fcntl.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <netdb.h>
48 #include <arpa/inet.h>
49 
50 #include <OpenIPMI/ipmi_conn.h>
51 #include <OpenIPMI/ipmi_msgbits.h>
52 #include <OpenIPMI/ipmi_auth.h>
53 #include <OpenIPMI/ipmi_err.h>
54 #include <OpenIPMI/ipmi_lan.h>
55 
56 #include <OpenIPMI/internal/ipmi_event.h>
57 #include <OpenIPMI/internal/ipmi_int.h>
58 #include <OpenIPMI/internal/locked_list.h>
59 
60 #if defined(DEBUG_MSG) || defined(DEBUG_RAWMSG)
61 static void
dump_hex(void * vdata,int len)62 dump_hex(void *vdata, int len)
63 {
64     unsigned char *data = vdata;
65     int i;
66     for (i=0; i<len; i++) {
67 	if ((i != 0) && ((i % 16) == 0)) {
68 	    ipmi_log(IPMI_LOG_DEBUG_CONT, "\n  ");
69 	}
70 	ipmi_log(IPMI_LOG_DEBUG_CONT, " %2.2x", data[i]);
71     }
72 }
73 #endif
74 
75 #define LAN_AUDIT_TIMEOUT 10000000
76 
77 /* Timeout to wait for IPMI responses, in microseconds.  For commands
78    with side effects, we wait 5 seconds, not one. */
79 #define LAN_RSP_TIMEOUT 1000000
80 #define LAN_RSP_TIMEOUT_SIDEEFF 5000000
81 
82 /* # of times to try a message before we fail it. */
83 #define LAN_RSP_RETRIES 6
84 
85 /* Number of microseconds of consecutive failures allowed on an IP
86    before it is considered failed. */
87 #define IP_FAIL_TIME 7000000
88 
89 /* Number of consecutive failures that must occur before an IP is
90    considered failed. */
91 #define IP_FAIL_COUNT 4
92 
93 /* The default for the maximum number of messages that are allowed to be
94    outstanding.  This is a pretty conservative number. */
95 #define DEFAULT_MAX_OUTSTANDING_MSG_COUNT 2
96 #define MAX_POSSIBLE_OUTSTANDING_MSG_COUNT 63
97 
98 typedef struct lan_data_s lan_data_t;
99 
100 typedef struct audit_timer_info_s
101 {
102     int        cancelled;
103     ipmi_con_t *ipmi;
104 } audit_timer_info_t;
105 
106 typedef struct lan_timer_info_s
107 {
108     int               cancelled;
109     ipmi_con_t        *ipmi;
110     os_hnd_timer_id_t *timer;
111     unsigned int      seq;
112 } lan_timer_info_t;
113 
114 typedef struct lan_wait_queue_s
115 {
116     lan_timer_info_t      *info;
117     ipmi_addr_t           addr;
118     unsigned int          addr_len;
119     ipmi_msg_t            msg;
120     unsigned char         data[IPMI_MAX_MSG_LENGTH];
121     ipmi_ll_rsp_handler_t rsp_handler;
122     ipmi_msgi_t           *rsp_item;
123     int                   side_effects;
124 
125     struct lan_wait_queue_s *next;
126 } lan_wait_queue_t;
127 
128 #define MAX_IP_ADDR 2
129 
130 /* We must keep this number small, if it's too big and a failure
131    occurs, we will be outside the sequence number before we switch. */
132 #define SENDS_BETWEEN_IP_SWITCHES 3
133 
134 /* Because sizeof(sockaddr_in6) > sizeof(sockaddr_in), this structure
135  * is used as a replacement of struct sockaddr. */
136 typedef struct sockaddr_ip_s {
137     union
138         {
139 	    struct sockaddr	s_addr0;
140             struct sockaddr_in  s_addr4;
141 #ifdef PF_INET6
142             struct sockaddr_in6 s_addr6;
143 #endif
144         } s_ipsock;
145     socklen_t ip_addr_len;
146 } sockaddr_ip_t;
147 
148 struct ipmi_rmcpp_auth_s
149 {
150     lan_data_t *lan;
151     int        addr_num;
152 
153     uint8_t       role;
154 
155     /* Filled in by the auth algorithm. */
156     unsigned char my_rand[16];
157     unsigned int  my_rand_len;
158     unsigned char mgsys_rand[16];
159     unsigned int  mgsys_rand_len;
160     unsigned char mgsys_guid[16];
161     unsigned int  mgsys_guid_len;
162     unsigned char sik[20];
163     unsigned int  sik_len;
164     unsigned char k1[20];
165     unsigned int  k1_len;
166     unsigned char k2[20];
167     unsigned int  k2_len;
168 };
169 
170 typedef struct lan_conn_parms_s
171 {
172     unsigned int  num_ip_addr;
173     char          *ip_addr_str[MAX_IP_ADDR];
174     char          *ip_port_str[MAX_IP_ADDR];
175     sockaddr_ip_t ip_addr[MAX_IP_ADDR];
176     unsigned int  authtype;
177     unsigned int  privilege;
178     unsigned char username[IPMI_USERNAME_MAX];
179     unsigned int  username_len;
180     unsigned char password[IPMI_PASSWORD_MAX];
181     unsigned int  password_len;
182     unsigned int  conf;
183     unsigned int  integ;
184     unsigned int  auth;
185     unsigned int  name_lookup_only;
186     unsigned char bmc_key[IPMI_PASSWORD_MAX];
187     unsigned int  bmc_key_len;
188 } lan_conn_parms_t;
189 
190 typedef struct lan_link_s lan_link_t;
191 struct lan_link_s
192 {
193     lan_link_t *next, *prev;
194     lan_data_t *lan;
195 };
196 
197 typedef struct lan_fd_s lan_fd_t;
198 
199 typedef struct lan_stat_info_s
200 {
201 #define STAT_RECV_PACKETS	0
202 #define STAT_XMIT_PACKETS	1
203 #define STAT_REXMITS		2
204 #define STAT_TIMED_OUT		3
205 #define STAT_INVALID_RMCP	4
206 #define STAT_TOO_SHORT		5
207 #define STAT_INVALID_AUTH	6
208 #define STAT_BAD_SESSION_ID	7
209 #define STAT_AUTH_FAIL		8
210 #define STAT_DUPLICATES		9
211 #define STAT_SEQ_OUT_OF_RANGE	10
212 #define STAT_ASYNC_EVENTS	11
213 #define STAT_CONN_DOWN		12
214 #define STAT_CONN_UP		13
215 #define STAT_BAD_SIZE		14
216 #define STAT_DECRYPT_FAIL	15
217 #define STAT_INVALID_PAYLOAD	16
218 #define STAT_SEQ_ERR		17
219 #define STAT_RSP_NO_CMD		18
220 #define NUM_STATS 19
221     /* Statistics */
222     void *stats[NUM_STATS];
223 } lan_stat_info_t;
224 
225 static const char *lan_stat_names[NUM_STATS] =
226 {
227     "lan_recv_packets",
228     "lan_xmit_packets",
229     "lan_rexmits",
230     "lan_timed_out",
231     "lan_invalid_rmcp",
232     "lan_too_short",
233     "lan_invalid_auth",
234     "lan_bad_session_id",
235     "lan_auth_fail",
236     "lan_duplicates",
237     "lan_seq_out_of_range",
238     "lan_async_events",
239     "lan_conn_down",
240     "lan_conn_up",
241     "lan_bad_size",
242     "lan_decrypt_fail",
243     "lan_invalid_payload",
244     "lan_seq_err",
245     "lan_rsp_no_cmd"
246 };
247 
248 
249 /* Per-IP specific information. */
250 typedef struct lan_ip_data_s
251 {
252     int                        working;
253     unsigned int               consecutive_failures;
254     struct timeval             failure_time;
255 
256     /* For both RMCP and RMCP+.  For RMCP+, the session id is the one
257        I receive and the sequence numbers are the authenticated
258        ones. */
259     unsigned char              working_authtype;
260     uint32_t                   session_id;
261     uint32_t                   outbound_seq_num;
262     uint32_t                   inbound_seq_num;
263     uint32_t                   recv_msg_map;
264 
265     /* RMCP+ specific info */
266     uint32_t                   unauth_out_seq_num;
267     uint32_t                   unauth_in_seq_num;
268     uint32_t                   unauth_recv_msg_map;
269     unsigned char              working_integ;
270     unsigned char              working_conf;
271     uint32_t                   mgsys_session_id;
272     ipmi_rmcpp_auth_t          ainfo;
273 
274     /* Used to hold the session id before the connection is up. */
275     uint32_t                   precon_session_id;
276     uint32_t                   precon_mgsys_session_id;
277 
278     ipmi_rmcpp_confidentiality_t *conf_info;
279     void                         *conf_data;
280 
281     ipmi_rmcpp_integrity_t       *integ_info;
282     void                         *integ_data;
283 
284     /* Use for linked-lists of IP addresses. */
285     lan_link_t                 ip_link;
286 } lan_ip_data_t;
287 
288 
289 #if IPMI_MAX_MSG_LENGTH > 80
290 # define LAN_MAX_RAW_MSG IPMI_MAX_MSG_LENGTH
291 #else
292 # define LAN_MAX_RAW_MSG 80 /* Enough to hold the rmcp+ session messages */
293 #endif
294 struct lan_data_s
295 {
296     unsigned int	       refcount;
297     unsigned int	       users;
298 
299     ipmi_con_t                 *ipmi;
300     lan_fd_t                   *fd;
301     int                        fd_slot;
302 
303     unsigned char              slave_addr[MAX_IPMI_USED_CHANNELS];
304     int                        is_active;
305     int			       disabled;
306 
307     /* Have we already been started? */
308     int                        started;
309 
310     /* Are we currently in cleanup?  Don't allow any outgoing messages. */
311     int                        in_cleanup;
312 
313     /* Protects modifiecations to working, curr_ip_addr, RMCP
314        sequence numbers, the con_change_handler, and other
315        connection-related data.  Note that if the seq_num_lock must
316        also be held, it must be locked before this lock.  */
317     ipmi_lock_t                *ip_lock;
318 
319     /* If 0, we don't have a connection to the BMC right now. */
320     int                        connected;
321 
322     /* If 0, we have not yet initialized */
323     int                        initialized;
324 
325     /* If 0, the OEM handlers have not been called. */
326     int                        oem_conn_handlers_called;
327 
328     /* Number of packets sent on the connection.  Used to track when
329        to switch between IP addresses. */
330     unsigned int               num_sends;
331 
332     /* The IP address we are currently using. */
333     unsigned int               curr_ip_addr;
334 
335     /* Data about each IP address */
336     lan_ip_data_t              ip[MAX_IP_ADDR];
337 
338     /* We keep a session on each LAN connection.  I don't think all
339        systems require that, but it's safer. */
340 
341     /* From the get channel auth */
342     unsigned char              oem_iana[3];
343     unsigned char              oem_aux;
344 
345     /* Parms we were configured with. */
346     lan_conn_parms_t           cparm;
347 
348     /* IPMI LAN 1.5 specific info. */
349     unsigned char              chosen_authtype;
350     unsigned char              challenge_string[16];
351     ipmi_authdata_t            authdata;
352 
353     /* RMCP+ specific info */
354     unsigned int               use_two_keys : 1;
355 
356     struct {
357 	unsigned int          inuse : 1;
358 	ipmi_addr_t           addr;
359 	unsigned int          addr_len;
360 
361 	ipmi_msg_t            msg;
362 	unsigned char         data[LAN_MAX_RAW_MSG];
363 	ipmi_ll_rsp_handler_t rsp_handler;
364 	ipmi_msgi_t           *rsp_item;
365 	int                   use_orig_addr;
366 	ipmi_addr_t           orig_addr;
367 	unsigned int          orig_addr_len;
368 	os_hnd_timer_id_t     *timer;
369 	lan_timer_info_t      *timer_info;
370 	int                   retries_left;
371 	int                   side_effects;
372 
373 	/* If -1, just use the normal algorithm.  If not -1, force to
374            this address. */
375 	int                   addr_num;
376 
377 	/* The number of the last IP address sent on. */
378 	int                   last_ip_num;
379     } seq_table[64];
380     ipmi_lock_t               *seq_num_lock;
381 
382     /* The current sequence number.  Note that we reserve sequence
383        number 0 for our own neferous purposes. */
384     unsigned int              last_seq;
385 
386     /* The number of messages that are outstanding with the remote
387        MC. */
388     unsigned int outstanding_msg_count;
389 
390     /* The maximum number of outstanding messages.  This must NEVER be
391        larger than 63 (64 sequence numbers minus 1 for our reserved
392        sequence zero. */
393     unsigned int max_outstanding_msg_count;
394 
395     /* Address family specified at startup. */
396     unsigned int addr_family;
397 
398     /* List of messages waiting to be sent. */
399     lan_wait_queue_t *wait_q, *wait_q_tail;
400 
401     locked_list_t              *event_handlers;
402 
403     os_hnd_timer_id_t          *audit_timer;
404     audit_timer_info_t         *audit_info;
405 
406     /* Handles connection shutdown reporting. */
407     ipmi_ll_con_closed_cb close_done;
408     void                  *close_cb_data;
409 
410     /* This lock is used to assure that the conn changes occur in
411        proper order.  The user code is called with this lock held, but
412        it should be harmless to the user as this is the only use for
413        it.  But the user cannot do a wait on I/O in the handler. */
414     ipmi_lock_t            *con_change_lock;
415     locked_list_t          *con_change_handlers;
416 
417     locked_list_t          *ipmb_change_handlers;
418 
419     lan_link_t link;
420 
421     locked_list_t *lan_stat_list;
422 };
423 
424 
425 /************************************************************************
426  *
427  * Authentication and encryption information and functions.
428  *
429  ***********************************************************************/
430 extern ipmi_payload_t i_ipmi_payload;
431 
432 static int
open_format_msg(ipmi_con_t * ipmi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg,unsigned char * out_data,unsigned int * out_data_len,int * out_of_session,unsigned char seq)433 open_format_msg(ipmi_con_t        *ipmi,
434 		const ipmi_addr_t *addr,
435 		unsigned int      addr_len,
436 		const ipmi_msg_t  *msg,
437 		unsigned char     *out_data,
438 		unsigned int      *out_data_len,
439 		int               *out_of_session,
440 		unsigned char     seq)
441 {
442     unsigned char *tmsg = out_data;
443 
444     if (msg->data_len > *out_data_len)
445 	return E2BIG;
446 
447     memcpy(tmsg, msg->data, msg->data_len);
448     tmsg[0] = seq; /* We use the message tag for the sequence # */
449     *out_of_session = 1;
450     *out_data_len = msg->data_len;
451     return 0;
452 }
453 
454 static int
open_get_recv_seq(ipmi_con_t * ipmi,unsigned char * data,unsigned int data_len,unsigned char * seq)455 open_get_recv_seq(ipmi_con_t    *ipmi,
456 		  unsigned char *data,
457 		  unsigned int  data_len,
458 		  unsigned char *seq)
459 {
460     if (data_len < 1) { /* Minimum size of an IPMI msg. */
461 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
462 	    ipmi_log(IPMI_LOG_DEBUG,
463 		     "%sDropped message because too small(7)",
464 		     IPMI_CONN_NAME(ipmi));
465 	return EINVAL;
466     }
467     *seq = data[0];
468     return 0;
469 }
470 
471 static int
open_handle_recv(ipmi_con_t * ipmi,ipmi_msgi_t * rspi,ipmi_addr_t * orig_addr,unsigned int orig_addr_len,ipmi_msg_t * orig_msg,unsigned char * data,unsigned int data_len)472 open_handle_recv(ipmi_con_t    *ipmi,
473 		 ipmi_msgi_t   *rspi,
474 		 ipmi_addr_t   *orig_addr,
475 		 unsigned int  orig_addr_len,
476 		 ipmi_msg_t    *orig_msg,
477 		 unsigned char *data,
478 		 unsigned int  data_len)
479 {
480     ipmi_msg_t *msg = &(rspi->msg);
481     if (data_len > sizeof(rspi->data))
482 	return E2BIG;
483     memcpy(rspi->data, data, data_len);
484     msg->data = rspi->data;
485     msg->data_len = data_len;
486     return 0;
487 }
488 
489 static void
open_handle_recv_async(ipmi_con_t * ipmi,unsigned char * tmsg,unsigned int data_len)490 open_handle_recv_async(ipmi_con_t    *ipmi,
491 		       unsigned char *tmsg,
492 		       unsigned int  data_len)
493 {
494 }
495 
496 static int
open_get_msg_tag(unsigned char * tmsg,unsigned int data_len,unsigned char * tag)497 open_get_msg_tag(unsigned char *tmsg,
498 		 unsigned int  data_len,
499 		 unsigned char *tag)
500 {
501     if (data_len < 8)
502 	return EINVAL;
503     *tag = ipmi_get_uint32(tmsg+4) - 1; /* session id */
504     return 0;
505 }
506 
507 static ipmi_payload_t open_payload =
508 { open_format_msg, open_get_recv_seq, open_handle_recv,
509   open_handle_recv_async, open_get_msg_tag };
510 
511 static ipmi_payload_t *payloads[64] =
512 {
513     &i_ipmi_payload,
514     [IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST] = &open_payload,
515     [IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE] = &open_payload
516 };
517 
518 typedef struct payload_entry_s payload_entry_t;
519 struct payload_entry_s
520 {
521     unsigned int   payload_type;
522     unsigned char  iana[3];
523     unsigned int   payload_id;
524     ipmi_payload_t *payload;
525 
526     payload_entry_t *next;
527 };
528 
529 /* Note that we only add payloads to the head, so no lock is required
530    except for addition. */
531 static ipmi_lock_t *lan_payload_lock = NULL;
532 payload_entry_t *oem_payload_list = NULL;
533 
534 int
ipmi_rmcpp_register_payload(unsigned int payload_type,ipmi_payload_t * payload)535 ipmi_rmcpp_register_payload(unsigned int   payload_type,
536 			    ipmi_payload_t *payload)
537 {
538     if ((payload_type == IPMI_RMCPP_PAYLOAD_TYPE_IPMI)
539 	|| (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
540 	|| (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST)
541 	|| (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE)
542 	|| (payload_type >= 64)
543 	|| ((payload_type >= 0x20) && (payload_type <= 0x27))) /* No OEM here*/
544     {
545 	return EINVAL;
546     }
547     ipmi_lock(lan_payload_lock);
548     if (payloads[payload_type] && payload) {
549 	ipmi_unlock(lan_payload_lock);
550 	return EAGAIN;
551     }
552 
553     payloads[payload_type] = payload;
554     ipmi_unlock(lan_payload_lock);
555     return 0;
556 }
557 
558 int
ipmi_rmcpp_register_oem_payload(unsigned int payload_type,unsigned char iana[3],unsigned int payload_id,ipmi_payload_t * payload)559 ipmi_rmcpp_register_oem_payload(unsigned int   payload_type,
560 				unsigned char  iana[3],
561 				unsigned int   payload_id,
562 				ipmi_payload_t *payload)
563 {
564     payload_entry_t *e;
565     payload_entry_t *c;
566 
567     e = ipmi_mem_alloc(sizeof(*e));
568     if (!e)
569 	return ENOMEM;
570     e->payload_type = payload_type;
571     memcpy(e->iana, iana, 3);
572     if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
573 	e->payload_id = payload_id;
574     else
575 	e->payload_id = 0;
576     e->payload = payload;
577 
578     ipmi_lock(lan_payload_lock);
579     c = oem_payload_list;
580     while (c) {
581 	if ((c->payload_type == payload_type)
582 	    && (memcmp(c->iana, iana, 3) == 0)
583 	    && (c->payload_id == payload_id))
584 	{
585 	    ipmi_unlock(lan_payload_lock);
586 	    ipmi_mem_free(e);
587 	    return EAGAIN;
588 	}
589 	c = c->next;
590     }
591     e->next = oem_payload_list;
592     oem_payload_list = e;
593     ipmi_unlock(lan_payload_lock);
594     return 0;
595 }
596 
597 static ipmi_lock_t *lan_auth_lock = NULL;
598 
599 typedef struct auth_entry_s auth_entry_t;
600 struct auth_entry_s
601 {
602     unsigned int  auth_num;
603     unsigned char iana[3];
604     ipmi_rmcpp_authentication_t *auth;
605     auth_entry_t  *next;
606 };
607 static auth_entry_t *oem_auth_list = NULL;
608 
609 static ipmi_rmcpp_authentication_t *auths[64];
610 
611 int
ipmi_rmcpp_register_authentication(unsigned int auth_num,ipmi_rmcpp_authentication_t * auth)612 ipmi_rmcpp_register_authentication(unsigned int                auth_num,
613 				   ipmi_rmcpp_authentication_t *auth)
614 {
615     if (auth_num >= 64)
616 	return EINVAL;
617     if (auths[auth_num] && auth)
618 	return EAGAIN;
619 
620     auths[auth_num] = auth;
621     return 0;
622 }
623 
624 int
ipmi_rmcpp_register_oem_authentication(unsigned int auth_num,unsigned char iana[3],ipmi_rmcpp_authentication_t * auth)625 ipmi_rmcpp_register_oem_authentication(unsigned int                auth_num,
626 				       unsigned char               iana[3],
627 				       ipmi_rmcpp_authentication_t *auth)
628 {
629     auth_entry_t *e;
630     auth_entry_t *c;
631 
632     e = ipmi_mem_alloc(sizeof(*e));
633     if (!e)
634 	return ENOMEM;
635     e->auth_num = auth_num;
636     memcpy(e->iana, iana, 3);
637     e->auth = auth;
638 
639     ipmi_lock(lan_auth_lock);
640     c = oem_auth_list;
641     while (c) {
642 	if ((c->auth_num == auth_num)
643 	    && (memcmp(c->iana, iana, 3) == 0))
644 	{
645 	    ipmi_unlock(lan_auth_lock);
646 	    ipmi_mem_free(e);
647 	    return EAGAIN;
648 	}
649     }
650     e->next = oem_auth_list;
651     oem_auth_list = e;
652     ipmi_unlock(lan_auth_lock);
653     return 0;
654 }
655 
656 typedef struct conf_entry_s conf_entry_t;
657 struct conf_entry_s
658 {
659     unsigned int  conf_num;
660     unsigned char iana[3];
661     ipmi_rmcpp_confidentiality_t *conf;
662     conf_entry_t  *next;
663 };
664 static conf_entry_t *oem_conf_list = NULL;
665 
666 static int
conf_none_init(ipmi_con_t * ipmi,ipmi_rmcpp_auth_t * ainfo,void ** conf_data)667 conf_none_init(ipmi_con_t *ipmi, ipmi_rmcpp_auth_t *ainfo, void **conf_data)
668 {
669     *conf_data = NULL;
670     return 0;
671 }
672 
673 static void
conf_none_free(ipmi_con_t * ipmi,void * conf_data)674 conf_none_free(ipmi_con_t *ipmi, void *conf_data)
675 {
676 }
677 
678 static int
conf_none_encrypt(ipmi_con_t * ipmi,void * conf_data,unsigned char ** payload,unsigned int * header_len,unsigned int * payload_len,unsigned int * max_payload_len)679 conf_none_encrypt(ipmi_con_t    *ipmi,
680 		  void          *conf_data,
681 		  unsigned char **payload,
682 		  unsigned int  *header_len,
683 		  unsigned int  *payload_len,
684 		  unsigned int  *max_payload_len)
685 {
686     return 0;
687 }
688 
689 static int
conf_none_decrypt(ipmi_con_t * ipmi,void * conf_data,unsigned char ** payload,unsigned int * payload_len)690 conf_none_decrypt(ipmi_con_t    *ipmi,
691 		  void          *conf_data,
692 		  unsigned char **payload,
693 		  unsigned int  *payload_len)
694 {
695     return 0;
696 }
697 static ipmi_rmcpp_confidentiality_t conf_none =
698 { conf_none_init, conf_none_free, conf_none_encrypt, conf_none_decrypt};
699 
700 static ipmi_rmcpp_confidentiality_t *confs[64] =
701 {
702     &conf_none
703 };
704 
ipmi_rmcpp_register_confidentiality(unsigned int conf_num,ipmi_rmcpp_confidentiality_t * conf)705 int ipmi_rmcpp_register_confidentiality(unsigned int                 conf_num,
706 					ipmi_rmcpp_confidentiality_t *conf)
707 {
708     if ((conf_num == 0) || (conf_num >= 64))
709 	return EINVAL;
710     if (confs[conf_num] && conf)
711 	return EAGAIN;
712 
713     confs[conf_num] = conf;
714     return 0;
715 }
716 
717 int
ipmi_rmcpp_register_oem_confidentiality(unsigned int conf_num,unsigned char iana[3],ipmi_rmcpp_confidentiality_t * conf)718 ipmi_rmcpp_register_oem_confidentiality(unsigned int                 conf_num,
719 					unsigned char                iana[3],
720 					ipmi_rmcpp_confidentiality_t *conf)
721 {
722     conf_entry_t *e;
723     conf_entry_t *c;
724 
725     e = ipmi_mem_alloc(sizeof(*e));
726     if (!e)
727 	return ENOMEM;
728     e->conf_num = conf_num;
729     memcpy(e->iana, iana, 3);
730     e->conf = conf;
731 
732     ipmi_lock(lan_auth_lock);
733     c = oem_conf_list;
734     while (c) {
735 	if ((c->conf_num == conf_num)
736 	    && (memcmp(c->iana, iana, 3) == 0))
737 	{
738 	    ipmi_unlock(lan_auth_lock);
739 	    ipmi_mem_free(e);
740 	    return EAGAIN;
741 	}
742     }
743     e->next = oem_conf_list;
744     oem_conf_list = e;
745     ipmi_unlock(lan_auth_lock);
746     return 0;
747 }
748 
749 typedef struct integ_entry_s integ_entry_t;
750 struct integ_entry_s
751 {
752     unsigned int  integ_num;
753     unsigned char iana[3];
754     ipmi_rmcpp_integrity_t *integ;
755     integ_entry_t  *next;
756 };
757 static integ_entry_t *oem_integ_list = NULL;
758 
759 static int
integ_none_init(ipmi_con_t * ipmi,ipmi_rmcpp_auth_t * ainfo,void ** integ_data)760 integ_none_init(ipmi_con_t       *ipmi,
761 		ipmi_rmcpp_auth_t *ainfo,
762 		void             **integ_data)
763 {
764     *integ_data = NULL;
765     return 0;
766 }
767 
768 static void
integ_none_free(ipmi_con_t * ipmi,void * integ_data)769 integ_none_free(ipmi_con_t *ipmi,
770 		void       *integ_data)
771 {
772 }
773 
774 static int
integ_none_pad(ipmi_con_t * ipmi,void * integ_data,unsigned char * payload,unsigned int * payload_len,unsigned int max_payload_len)775 integ_none_pad(ipmi_con_t    *ipmi,
776 	       void          *integ_data,
777 	       unsigned char *payload,
778 	       unsigned int  *payload_len,
779 	       unsigned int  max_payload_len)
780 {
781     return 0;
782 }
783 
784 static int
integ_none_add(ipmi_con_t * ipmi,void * integ_data,unsigned char * payload,unsigned int * payload_len,unsigned int max_payload_len)785 integ_none_add(ipmi_con_t    *ipmi,
786 	       void          *integ_data,
787 	       unsigned char *payload,
788 	       unsigned int  *payload_len,
789 	       unsigned int  max_payload_len)
790 {
791     return 0;
792 }
793 
794 static int
integ_none_check(ipmi_con_t * ipmi,void * integ_data,unsigned char * payload,unsigned int payload_len,unsigned int total_len)795 integ_none_check(ipmi_con_t    *ipmi,
796 		 void          *integ_data,
797 		 unsigned char *payload,
798 		 unsigned int  payload_len,
799 		 unsigned int  total_len)
800 {
801     return 0;
802 }
803 
804 static ipmi_rmcpp_integrity_t integ_none =
805 { integ_none_init, integ_none_free, integ_none_pad, integ_none_add,
806   integ_none_check };
807 
808 static ipmi_rmcpp_integrity_t *integs[64] =
809 {
810     &integ_none
811 };
812 
ipmi_rmcpp_register_integrity(unsigned int integ_num,ipmi_rmcpp_integrity_t * integ)813 int ipmi_rmcpp_register_integrity(unsigned int           integ_num,
814 				  ipmi_rmcpp_integrity_t *integ)
815 {
816     if ((integ_num == 0) || (integ_num >= 64))
817 	return EINVAL;
818     if (integs[integ_num] && integ)
819 	return EAGAIN;
820 
821     integs[integ_num] = integ;
822     return 0;
823 }
824 
825 int
ipmi_rmcpp_register_oem_integrity(unsigned int integ_num,unsigned char iana[3],ipmi_rmcpp_integrity_t * integ)826 ipmi_rmcpp_register_oem_integrity(unsigned int           integ_num,
827 				  unsigned char          iana[3],
828 				  ipmi_rmcpp_integrity_t *integ)
829 {
830     integ_entry_t *e;
831     integ_entry_t *c;
832 
833     e = ipmi_mem_alloc(sizeof(*e));
834     if (!e)
835 	return ENOMEM;
836     e->integ_num = integ_num;
837     memcpy(e->iana, iana, 3);
838     e->integ = integ;
839 
840     ipmi_lock(lan_auth_lock);
841     c = oem_integ_list;
842     while (c) {
843 	if ((c->integ_num == integ_num)
844 	    && (memcmp(c->iana, iana, 3) == 0))
845 	{
846 	    ipmi_unlock(lan_auth_lock);
847 	    ipmi_mem_free(e);
848 	    return EAGAIN;
849 	}
850     }
851     e->next = oem_integ_list;
852     oem_integ_list = e;
853     ipmi_unlock(lan_auth_lock);
854     return 0;
855 }
856 
857 uint32_t
ipmi_rmcpp_auth_get_my_session_id(ipmi_rmcpp_auth_t * ainfo)858 ipmi_rmcpp_auth_get_my_session_id(ipmi_rmcpp_auth_t *ainfo)
859 {
860     return ainfo->lan->ip[ainfo->addr_num].precon_session_id;
861 }
862 
863 uint32_t
ipmi_rmcpp_auth_get_mgsys_session_id(ipmi_rmcpp_auth_t * ainfo)864 ipmi_rmcpp_auth_get_mgsys_session_id(ipmi_rmcpp_auth_t *ainfo)
865 {
866     return ainfo->lan->ip[ainfo->addr_num].precon_mgsys_session_id;
867 }
868 
869 uint8_t
ipmi_rmcpp_auth_get_role(ipmi_rmcpp_auth_t * ainfo)870 ipmi_rmcpp_auth_get_role(ipmi_rmcpp_auth_t *ainfo)
871 {
872     return ainfo->role;
873 }
874 
875 const unsigned char *
ipmi_rmcpp_auth_get_username(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)876 ipmi_rmcpp_auth_get_username(ipmi_rmcpp_auth_t *ainfo,
877 			     unsigned int      *max_len)
878 {
879     *max_len = 16;
880     return ainfo->lan->cparm.username;
881 }
882 
883 unsigned int
ipmi_rmcpp_auth_get_username_len(ipmi_rmcpp_auth_t * ainfo)884 ipmi_rmcpp_auth_get_username_len(ipmi_rmcpp_auth_t *ainfo)
885 {
886     return ainfo->lan->cparm.username_len;
887 }
888 
889 const unsigned char *
ipmi_rmcpp_auth_get_password(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)890 ipmi_rmcpp_auth_get_password(ipmi_rmcpp_auth_t *ainfo,
891 			     unsigned int      *max_len)
892 {
893     *max_len = 20;
894     return ainfo->lan->cparm.password;
895 }
896 
897 unsigned int
ipmi_rmcpp_auth_get_password_len(ipmi_rmcpp_auth_t * ainfo)898 ipmi_rmcpp_auth_get_password_len(ipmi_rmcpp_auth_t *ainfo)
899 {
900     return ainfo->lan->cparm.password_len;
901 }
902 
903 int
ipmi_rmcpp_auth_get_use_two_keys(ipmi_rmcpp_auth_t * ainfo)904 ipmi_rmcpp_auth_get_use_two_keys(ipmi_rmcpp_auth_t *ainfo)
905 {
906     return ainfo->lan->use_two_keys;
907 }
908 
909 const unsigned char *
ipmi_rmcpp_auth_get_bmc_key(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)910 ipmi_rmcpp_auth_get_bmc_key(ipmi_rmcpp_auth_t *ainfo,
911 			    unsigned int      *max_len)
912 {
913     *max_len = 20;
914     if (ainfo->lan->use_two_keys)
915 	return ainfo->lan->cparm.bmc_key;
916     else
917 	return ainfo->lan->cparm.password;
918 }
919 
920 unsigned int
ipmi_rmcpp_auth_get_bmc_key_len(ipmi_rmcpp_auth_t * ainfo)921 ipmi_rmcpp_auth_get_bmc_key_len(ipmi_rmcpp_auth_t *ainfo)
922 {
923     if (ainfo->lan->use_two_keys)
924 	return ainfo->lan->cparm.bmc_key_len;
925     else
926 	return ainfo->lan->cparm.password_len;
927 }
928 
929 /* From the get channel auth. */
930 const unsigned char *
ipmi_rmcpp_auth_get_oem_iana(ipmi_rmcpp_auth_t * ainfo,unsigned int * len)931 ipmi_rmcpp_auth_get_oem_iana(ipmi_rmcpp_auth_t *ainfo,
932 			     unsigned int      *len)
933 {
934     *len = 3;
935     return ainfo->lan->oem_iana;
936 }
937 
938 unsigned char
ipmi_rmcpp_auth_get_oem_aux(ipmi_rmcpp_auth_t * ainfo)939 ipmi_rmcpp_auth_get_oem_aux(ipmi_rmcpp_auth_t *ainfo)
940 {
941     return ainfo->lan->oem_aux;
942 }
943 
944 /* Should be filled in by the auth algorithm. */
945 unsigned char *
ipmi_rmcpp_auth_get_my_rand(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)946 ipmi_rmcpp_auth_get_my_rand(ipmi_rmcpp_auth_t *ainfo,
947 			    unsigned int      *max_len)
948 {
949     *max_len = 16;
950     return ainfo->my_rand;
951 }
952 
953 unsigned int
ipmi_rmcpp_auth_get_my_rand_len(ipmi_rmcpp_auth_t * ainfo)954 ipmi_rmcpp_auth_get_my_rand_len(ipmi_rmcpp_auth_t *ainfo)
955 {
956     return ainfo->my_rand_len;
957 }
958 
959 void
ipmi_rmcpp_auth_set_my_rand_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)960 ipmi_rmcpp_auth_set_my_rand_len(ipmi_rmcpp_auth_t *ainfo,
961 				unsigned int      length)
962 {
963     ainfo->my_rand_len = length;
964 }
965 
966 unsigned char *
ipmi_rmcpp_auth_get_mgsys_rand(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)967 ipmi_rmcpp_auth_get_mgsys_rand(ipmi_rmcpp_auth_t *ainfo,
968 			       unsigned int      *max_len)
969 {
970     *max_len = 16;
971     return ainfo->mgsys_rand;
972 }
973 
974 unsigned int
ipmi_rmcpp_auth_get_mgsys_rand_len(ipmi_rmcpp_auth_t * ainfo)975 ipmi_rmcpp_auth_get_mgsys_rand_len(ipmi_rmcpp_auth_t *ainfo)
976 {
977     return ainfo->mgsys_rand_len;
978 }
979 
980 void
ipmi_rmcpp_auth_set_mgsys_rand_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)981 ipmi_rmcpp_auth_set_mgsys_rand_len(ipmi_rmcpp_auth_t *ainfo,
982 				   unsigned int      length)
983 {
984     ainfo->mgsys_rand_len = length;
985 }
986 
987 unsigned char *
ipmi_rmcpp_auth_get_mgsys_guid(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)988 ipmi_rmcpp_auth_get_mgsys_guid(ipmi_rmcpp_auth_t *ainfo,
989 			       unsigned int      *max_len)
990 {
991     *max_len = 16;
992     return ainfo->mgsys_guid;
993 }
994 
995 unsigned int
ipmi_rmcpp_auth_get_mgsys_guid_len(ipmi_rmcpp_auth_t * ainfo)996 ipmi_rmcpp_auth_get_mgsys_guid_len(ipmi_rmcpp_auth_t *ainfo)
997 {
998     return ainfo->mgsys_guid_len;
999 }
1000 
1001 void
ipmi_rmcpp_auth_set_mgsys_guid_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)1002 ipmi_rmcpp_auth_set_mgsys_guid_len(ipmi_rmcpp_auth_t *ainfo,
1003 				   unsigned int      length)
1004 {
1005     ainfo->mgsys_guid_len = length;
1006 }
1007 
1008 unsigned char *
ipmi_rmcpp_auth_get_sik(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)1009 ipmi_rmcpp_auth_get_sik(ipmi_rmcpp_auth_t *ainfo,
1010 			unsigned int      *max_len)
1011 {
1012     *max_len = 20;
1013     return ainfo->sik;
1014 }
1015 
1016 unsigned int
ipmi_rmcpp_auth_get_sik_len(ipmi_rmcpp_auth_t * ainfo)1017 ipmi_rmcpp_auth_get_sik_len(ipmi_rmcpp_auth_t *ainfo)
1018 {
1019     return ainfo->sik_len;
1020 }
1021 
1022 void
ipmi_rmcpp_auth_set_sik_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)1023 ipmi_rmcpp_auth_set_sik_len(ipmi_rmcpp_auth_t *ainfo,
1024 			    unsigned int      length)
1025 {
1026     ainfo->sik_len = length;
1027 }
1028 
1029 unsigned char *
ipmi_rmcpp_auth_get_k1(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)1030 ipmi_rmcpp_auth_get_k1(ipmi_rmcpp_auth_t *ainfo,
1031 		       unsigned int      *max_len)
1032 {
1033     *max_len = 20;
1034     return ainfo->k1;
1035 }
1036 
1037 unsigned int
ipmi_rmcpp_auth_get_k1_len(ipmi_rmcpp_auth_t * ainfo)1038 ipmi_rmcpp_auth_get_k1_len(ipmi_rmcpp_auth_t *ainfo)
1039 {
1040     return ainfo->k1_len;
1041 }
1042 
1043 void
ipmi_rmcpp_auth_set_k1_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)1044 ipmi_rmcpp_auth_set_k1_len(ipmi_rmcpp_auth_t *ainfo,
1045 			   unsigned int      length)
1046 {
1047     ainfo->k1_len = length;
1048 }
1049 
1050 unsigned char *
ipmi_rmcpp_auth_get_k2(ipmi_rmcpp_auth_t * ainfo,unsigned int * max_len)1051 ipmi_rmcpp_auth_get_k2(ipmi_rmcpp_auth_t *ainfo,
1052 		       unsigned int      *max_len)
1053 {
1054     *max_len = 20;
1055     return ainfo->k2;
1056 }
1057 
1058 unsigned int
ipmi_rmcpp_auth_get_k2_len(ipmi_rmcpp_auth_t * ainfo)1059 ipmi_rmcpp_auth_get_k2_len(ipmi_rmcpp_auth_t *ainfo)
1060 {
1061     return ainfo->k2_len;
1062 }
1063 
1064 void
ipmi_rmcpp_auth_set_k2_len(ipmi_rmcpp_auth_t * ainfo,unsigned int length)1065 ipmi_rmcpp_auth_set_k2_len(ipmi_rmcpp_auth_t *ainfo,
1066 			   unsigned int      length)
1067 {
1068     ainfo->k2_len = length;
1069 }
1070 
1071 
1072 static void check_command_queue(ipmi_con_t *ipmi, lan_data_t *lan);
1073 static int send_auth_cap(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
1074 			 int force_ipmiv15);
1075 
1076 static os_handler_t *lan_os_hnd;
1077 
1078 #define MAX_CONS_PER_FD	32
1079 struct lan_fd_s
1080 {
1081     int            fd;
1082     os_hnd_fd_id_t *fd_wait_id;
1083     unsigned int   cons_in_use;
1084     lan_data_t     *lan[MAX_CONS_PER_FD];
1085     lan_fd_t       *next, *prev;
1086     ipmi_lock_t    *con_lock;
1087 
1088     /* Main list info. */
1089     ipmi_lock_t    *lock;
1090     lan_fd_t       **free_list;
1091     lan_fd_t       *list;
1092 };
1093 
1094 /* This is a list, but the only searching is to find an fd with a free
1095    slot (when creating a new lan).  This is O(1) because the first
1096    entry is guaranteed to have a free slot if any have free slots.
1097    Note that once one of these is created, it is never destroyed
1098    (destruction is very difficult because of the race conditions). */
1099 static ipmi_lock_t *fd_list_lock = NULL;
1100 static lan_fd_t fd_list;
1101 static lan_fd_t *fd_free_list;
1102 #ifdef PF_INET6
1103 static ipmi_lock_t *fd6_list_lock = NULL;
1104 static lan_fd_t fd6_list;
1105 static lan_fd_t *fd6_free_list;
1106 #endif
1107 
1108 static void data_handler(int            fd,
1109 			 void           *cb_data,
1110 			 os_hnd_fd_id_t *id);
1111 
1112 static int
lan_addr_same(sockaddr_ip_t * a1,sockaddr_ip_t * a2)1113 lan_addr_same(sockaddr_ip_t *a1, sockaddr_ip_t *a2)
1114 {
1115     if (a1->ip_addr_len != a2->ip_addr_len)
1116 	return 0;
1117 
1118     if (a1->s_ipsock.s_addr0.sa_family != a2->s_ipsock.s_addr0.sa_family) {
1119 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
1120 	    ipmi_log(IPMI_LOG_DEBUG, "Address family mismatch: %d %d",
1121 		     a1->s_ipsock.s_addr0.sa_family,
1122 		     a2->s_ipsock.s_addr0.sa_family);
1123 	return 0;
1124     }
1125 
1126     switch (a1->s_ipsock.s_addr0.sa_family) {
1127     case PF_INET:
1128 	{
1129 	    struct sockaddr_in *ip1 = &a1->s_ipsock.s_addr4;
1130 	    struct sockaddr_in *ip2 = &a2->s_ipsock.s_addr4;
1131 
1132 	    if ((ip1->sin_port == ip2->sin_port)
1133 		&& (ip1->sin_addr.s_addr == ip2->sin_addr.s_addr))
1134 		return 1;
1135 	}
1136 	break;
1137 
1138 #ifdef PF_INET6
1139     case PF_INET6:
1140 	{
1141 	    struct sockaddr_in6 *ip1 = &a1->s_ipsock.s_addr6;
1142 	    struct sockaddr_in6 *ip2 = &a2->s_ipsock.s_addr6;
1143 	    if ((ip1->sin6_port == ip2->sin6_port)
1144 		&& (memcmp(ip1->sin6_addr.s6_addr, ip2->sin6_addr.s6_addr,
1145 			   sizeof(struct in6_addr)) == 0))
1146 		return 1;
1147 	}
1148 	break;
1149 #endif
1150     default:
1151 	ipmi_log(IPMI_LOG_ERR_INFO,
1152 		 "ipmi_lan: Unknown protocol family: 0x%x",
1153 		 a1->s_ipsock.s_addr0.sa_family);
1154 	break;
1155     }
1156 
1157     return 0;
1158 }
1159 
1160 static void
move_to_lan_list_end(lan_fd_t * item)1161 move_to_lan_list_end(lan_fd_t *item)
1162 {
1163     lan_fd_t *list = item->list;
1164 
1165     item->next->prev = item->prev;
1166     item->prev->next = item->next;
1167     item->next = list;
1168     item->prev = list->prev;
1169     list->prev->next = item;
1170     list->prev = item;
1171 }
1172 
1173 static void
move_to_lan_list_head(lan_fd_t * item)1174 move_to_lan_list_head(lan_fd_t *item)
1175 {
1176     lan_fd_t *list = item->list;
1177 
1178     item->next->prev = item->prev;
1179     item->prev->next = item->next;
1180     item->next = list->next;
1181     item->prev = list;
1182     list->next->prev = item;
1183     list->next = item;
1184 }
1185 
1186 static lan_fd_t *
find_free_lan_fd(int family,lan_data_t * lan,int * slot)1187 find_free_lan_fd(int family, lan_data_t *lan, int *slot)
1188 {
1189     ipmi_lock_t *lock;
1190     lan_fd_t    *list, *item;
1191     lan_fd_t    **free_list;
1192     int         rv;
1193     int         i;
1194 
1195     if (family == PF_INET) {
1196 	lock = fd_list_lock;
1197 	list = &fd_list;
1198 	free_list = &fd_free_list;
1199     }
1200 #ifdef PF_INET6
1201     else if (family == PF_INET6) {
1202 	lock = fd6_list_lock;
1203 	list = &fd6_list;
1204 	free_list = &fd6_free_list;
1205     }
1206 #endif
1207     else {
1208 	return NULL;
1209     }
1210 
1211     ipmi_lock(lock);
1212     item = list->next;
1213  retry:
1214     if (item->cons_in_use < MAX_CONS_PER_FD) {
1215 	int tslot = -1;
1216 	/* Got an entry with a slot, just reuse it. */
1217 	for (i=0; i<MAX_CONS_PER_FD; i++) {
1218 	    if (item->lan[i]) {
1219 		/* Check for a matching IP address.  Can't have two
1220 		   systems with the same address in the same fd entry. */
1221 		unsigned int j, k;
1222 		lan_data_t   *l = item->lan[i];
1223 
1224 		for (j=0; j<l->cparm.num_ip_addr; j++) {
1225 		    for (k=0; k<lan->cparm.num_ip_addr; k++) {
1226 			if (lan_addr_same(&l->cparm.ip_addr[j],
1227 					  &lan->cparm.ip_addr[k]))
1228 			{
1229 			    /* Found the same address in the same
1230 			       lan_data file.  Try another one. */
1231 			    item = item->next;
1232 			    goto retry;
1233 			}
1234 		    }
1235 		}
1236 	    } else if (tslot < 0)
1237 		tslot = i;
1238 	}
1239 	if (tslot < 0) {
1240 	    lan_fd_t *next = item->next;
1241 	    /* Can't happen, but log and fix it up. */
1242 	    ipmi_log(IPMI_LOG_SEVERE, "ipmi_lan.c: Internal error, count"
1243 		     " in lan fd list item incorrect, but we can recover.");
1244 	    item->cons_in_use = MAX_CONS_PER_FD;
1245 	    move_to_lan_list_end(item);
1246 	    item = next;
1247 	    goto retry;
1248 	}
1249 	item->cons_in_use++;
1250 	item->lan[tslot] = lan;
1251 	*slot = tslot;
1252 
1253 	if (item->cons_in_use == MAX_CONS_PER_FD)
1254 	    /* Out of connections in this item, move it to the end of
1255 	       the list. */
1256 	    move_to_lan_list_end(item);
1257     } else {
1258 	/* No free entries, create one */
1259 	if (*free_list) {
1260 	    /* Pull them off the free list first. */
1261 	    item = *free_list;
1262 	    *free_list = item->next;
1263 	} else {
1264 	    item = ipmi_mem_alloc(sizeof(*item));
1265 	    if (item) {
1266 		memset(item, 0, sizeof(*item));
1267 		rv = ipmi_create_global_lock(&item->con_lock);
1268 		if (rv) {
1269 		    ipmi_mem_free(item);
1270 		    goto out_unlock;
1271 		}
1272 		item->lock = lock;
1273 		item->free_list = free_list;
1274 		item->list = list;
1275 	    }
1276 	}
1277 	if (!item)
1278 	    goto out_unlock;
1279 
1280 	item->next = item;
1281 	item->prev = item;
1282 
1283 	item->fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
1284 	if (item->fd == -1) {
1285 	    item->next = *free_list;
1286 	    *free_list = item;
1287 	    item = NULL;
1288 	    goto out_unlock;
1289 	}
1290 
1291 	/* Bind is not necessary, we don't care what port we are. */
1292 
1293 	/* We want it to be non-blocking. */
1294 	rv = fcntl(item->fd, F_SETFL, O_NONBLOCK);
1295 	if (rv) {
1296 	    close(item->fd);
1297 	    item->next = *free_list;
1298 	    *free_list = item;
1299 	    item = NULL;
1300 	    goto out_unlock;
1301 	}
1302 
1303 	rv = lan_os_hnd->add_fd_to_wait_for(lan_os_hnd,
1304 					    item->fd,
1305 					    data_handler,
1306 					    item,
1307 					    NULL,
1308 					    &(item->fd_wait_id));
1309 	if (rv) {
1310 	    close(item->fd);
1311 	    item->next = *free_list;
1312 	    *free_list = item;
1313 	    item = NULL;
1314 	    goto out_unlock;
1315 	}
1316 
1317 	item->cons_in_use++;
1318 	item->lan[0] = lan;
1319 	*slot = 0;
1320 
1321 	/* This will have free items, put it at the head of the list. */
1322 	move_to_lan_list_head(item);
1323     }
1324  out_unlock:
1325     ipmi_unlock(lock);
1326     return item;
1327 }
1328 
1329 static void
release_lan_fd(lan_fd_t * item,int slot)1330 release_lan_fd(lan_fd_t *item, int slot)
1331 {
1332     ipmi_lock(item->lock);
1333     item->lan[slot] = NULL;
1334     item->cons_in_use--;
1335     if (item->cons_in_use == 0) {
1336 	lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, item->fd_wait_id);
1337 	close(item->fd);
1338 	item->next->prev = item->prev;
1339 	item->prev->next = item->next;
1340 	item->next = *(item->free_list);
1341 	*(item->free_list) = item;
1342     } else {
1343 	/* This has free connections, move it to the head of the
1344 	   list. */
1345 	move_to_lan_list_head(item);
1346     }
1347     ipmi_unlock(item->lock);
1348 }
1349 
1350 /*
1351  * We keep two hash tables, one by IP address and one by connection
1352  * address.
1353  */
1354 #define LAN_HASH_SIZE 256
1355 #define LAN_HASH_SHIFT 6
1356 static ipmi_lock_t *lan_list_lock = NULL;
1357 static lan_link_t lan_list[LAN_HASH_SIZE];
1358 static lan_link_t lan_ip_list[LAN_HASH_SIZE];
1359 
1360 static unsigned int
hash_lan(const ipmi_con_t * ipmi)1361 hash_lan(const ipmi_con_t *ipmi)
1362 {
1363     unsigned int idx;
1364 
1365     idx = (((unsigned long) ipmi)
1366 	   >> (sizeof(unsigned long) + LAN_HASH_SHIFT));
1367     idx %= LAN_HASH_SIZE;
1368     return idx;
1369 }
1370 
1371 static unsigned int
hash_lan_addr(const struct sockaddr * addr)1372 hash_lan_addr(const struct sockaddr *addr)
1373 {
1374     unsigned int idx;
1375     switch (addr->sa_family)
1376     {
1377     case PF_INET:
1378 	{
1379 	    struct sockaddr_in *iaddr = (struct sockaddr_in *) addr;
1380 	    idx = ntohl(iaddr->sin_addr.s_addr) % LAN_HASH_SIZE;
1381 	    break;
1382 	}
1383 #ifdef PF_INET6
1384     case PF_INET6:
1385 	{
1386 	    /* Use the lower 4 bytes of the IPV6 address. */
1387 	    struct sockaddr_in6 *iaddr = (struct sockaddr_in6 *) addr;
1388 	    idx = iaddr->sin6_addr.s6_addr[12];
1389 	    idx |= iaddr->sin6_addr.s6_addr[13] << 8;
1390 	    idx |= iaddr->sin6_addr.s6_addr[14] << 16;
1391 	    idx |= iaddr->sin6_addr.s6_addr[15] << 24;
1392 	    break;
1393 	}
1394 #endif
1395     default:
1396 	idx = 0;
1397     }
1398     idx %= LAN_HASH_SIZE;
1399     return idx;
1400 }
1401 
1402 static void
lan_add_con(lan_data_t * lan)1403 lan_add_con(lan_data_t *lan)
1404 {
1405     unsigned int idx;
1406     lan_link_t   *head;
1407     unsigned int i;
1408 
1409     ipmi_lock(lan_list_lock);
1410     idx = hash_lan(lan->ipmi);
1411     head = &lan_list[idx];
1412     lan->link.lan = lan;
1413     lan->link.next = head;
1414     lan->link.prev = head->prev;
1415     head->prev->next = &lan->link;
1416     head->prev = &lan->link;
1417 
1418     for (i=0; i<lan->cparm.num_ip_addr; i++) {
1419 	struct sockaddr *addr = &lan->cparm.ip_addr[i].s_ipsock.s_addr0;
1420 
1421 	idx = hash_lan_addr(addr);
1422 
1423 	head = &lan_ip_list[idx];
1424 	lan->ip[i].ip_link.lan = lan;
1425 	lan->ip[i].ip_link.next = head;
1426 	lan->ip[i].ip_link.prev = head->prev;
1427 	head->prev->next = &lan->ip[i].ip_link;
1428 	head->prev = &lan->ip[i].ip_link;
1429     }
1430     ipmi_unlock(lan_list_lock);
1431 }
1432 
1433 /* Must be called with the lan list lock held. */
1434 static void
lan_remove_con_nolock(lan_data_t * lan)1435 lan_remove_con_nolock(lan_data_t *lan)
1436 {
1437     unsigned int i;
1438     if (!lan->link.lan)
1439 	/* Hasn't been initialized. */
1440 	return;
1441     lan->link.prev->next = lan->link.next;
1442     lan->link.next->prev = lan->link.prev;
1443     lan->link.lan = NULL;
1444     for (i=0; i<lan->cparm.num_ip_addr; i++) {
1445 	lan->ip[i].ip_link.prev->next = lan->ip[i].ip_link.next;
1446 	lan->ip[i].ip_link.next->prev = lan->ip[i].ip_link.prev;
1447 	lan->ip[i].ip_link.lan = NULL;
1448     }
1449 }
1450 
1451 static lan_data_t *
lan_find_con(ipmi_con_t * ipmi)1452 lan_find_con(ipmi_con_t *ipmi)
1453 {
1454     unsigned int idx;
1455     lan_link_t   *l;
1456 
1457     ipmi_lock(lan_list_lock);
1458     idx = hash_lan(ipmi);
1459     l = lan_list[idx].next;
1460     while (l->lan) {
1461 	if (l->lan->ipmi == ipmi)
1462 	    break;
1463 	l = l->next;
1464     }
1465     if (l->lan)
1466 	l->lan->refcount++;
1467     ipmi_unlock(lan_list_lock);
1468 
1469     return l->lan;
1470 }
1471 
1472 static inline int
cmp_timeval(struct timeval * tv1,struct timeval * tv2)1473 cmp_timeval(struct timeval *tv1, struct timeval *tv2)
1474 {
1475     if (tv1->tv_sec < tv2->tv_sec)
1476         return -1;
1477 
1478     if (tv1->tv_sec > tv2->tv_sec)
1479         return 1;
1480 
1481     if (tv1->tv_usec < tv2->tv_usec)
1482         return -1;
1483 
1484     if (tv1->tv_usec > tv2->tv_usec)
1485         return 1;
1486 
1487     return 0;
1488 }
1489 
1490 typedef struct lan_add_stat_info_s
1491 {
1492     int statnum;
1493     int count;
1494 } lan_add_stat_info_t;
1495 
1496 int
add_stat_cb(void * cb_data,void * item1,void * item2)1497 add_stat_cb(void *cb_data, void *item1, void *item2)
1498 {
1499     ipmi_ll_stat_info_t *info = item2;
1500     lan_stat_info_t     *stat = item1;
1501     lan_add_stat_info_t *sinfo = cb_data;
1502 
1503     if (stat->stats[sinfo->statnum])
1504 	ipmi_ll_con_stat_call_adder(info, stat->stats[sinfo->statnum],
1505 				    sinfo->count);
1506     return LOCKED_LIST_ITER_CONTINUE;
1507 }
1508 
1509 static inline void
add_stat(ipmi_con_t * ipmi,int stat,int count)1510 add_stat(ipmi_con_t *ipmi, int stat, int count)
1511 {
1512     lan_data_t          *lan = ipmi->con_data;
1513     lan_add_stat_info_t sinfo;
1514 
1515     sinfo.statnum = stat;
1516     sinfo.count = count;
1517     locked_list_iterate(lan->lan_stat_list, add_stat_cb, &sinfo);
1518 }
1519 
1520 /* Must be called with the ipmi read or write lock. */
lan_valid_ipmi(ipmi_con_t * ipmi)1521 static int lan_valid_ipmi(ipmi_con_t *ipmi)
1522 {
1523     return (lan_find_con(ipmi) != NULL);
1524 }
1525 
1526 static void lan_cleanup(ipmi_con_t *ipmi);
1527 
1528 static void
lan_put(ipmi_con_t * ipmi)1529 lan_put(ipmi_con_t *ipmi)
1530 {
1531     lan_data_t *lan = ipmi->con_data;
1532     int        done;
1533 
1534     ipmi_lock(lan_list_lock);
1535     lan->refcount--;
1536     done = lan->refcount == 0;
1537 
1538     /* If done, remove it before we release the lock. */
1539     if (done)
1540 	lan_remove_con_nolock(lan);
1541     ipmi_unlock(lan_list_lock);
1542 
1543     if (done)
1544 	lan_cleanup(ipmi);
1545 }
1546 
1547 static int
auth_gen(lan_data_t * lan,unsigned char * out,uint8_t * ses_id,uint8_t * seq,unsigned char * data,unsigned int data_len,int addr_num)1548 auth_gen(lan_data_t    *lan,
1549 	 unsigned char *out,
1550 	 uint8_t       *ses_id,
1551 	 uint8_t       *seq,
1552 	 unsigned char *data,
1553 	 unsigned int  data_len,
1554 	 int           addr_num)
1555 {
1556     int rv;
1557     ipmi_auth_sg_t l[] =
1558     { { ses_id, 4 },
1559       { data,   data_len },
1560       { seq,    4 },
1561       { NULL,   0 }};
1562 
1563     rv = ipmi_auths[lan->ip[addr_num].working_authtype]
1564 	.authcode_gen(lan->authdata, l, out);
1565     return rv;
1566 }
1567 
1568 static int
auth_check(lan_data_t * lan,uint8_t * ses_id,uint8_t * seq,unsigned char * data,unsigned int data_len,unsigned char * code,int addr_num)1569 auth_check(lan_data_t    *lan,
1570 	   uint8_t       *ses_id,
1571 	   uint8_t       *seq,
1572 	   unsigned char *data,
1573 	   unsigned int  data_len,
1574 	   unsigned char *code,
1575 	   int           addr_num)
1576 {
1577     int rv;
1578     ipmi_auth_sg_t l[] =
1579     { { ses_id, 4  },
1580       { data,   data_len },
1581       { seq,    4 },
1582       { NULL,   0 }};
1583 
1584     rv = ipmi_auths[lan->ip[addr_num].working_authtype]
1585 	.authcode_check(lan->authdata, l, code);
1586     return rv;
1587 }
1588 
1589 #define IPMI_MAX_LAN_LEN    (IPMI_MAX_MSG_LENGTH + 128)
1590 #define IPMI_LAN_MAX_HEADER 128
1591 
1592 static int
rmcpp_format_msg(lan_data_t * lan,int addr_num,unsigned int payload_type,int in_session,unsigned char ** msgdata,unsigned int * data_len,unsigned int max_data_len,unsigned int header_len,unsigned char * oem_iana,unsigned int oem_payload_id,const ipmi_con_option_t * options)1593 rmcpp_format_msg(lan_data_t *lan, int addr_num,
1594 		 unsigned int payload_type, int in_session,
1595 		 unsigned char **msgdata, unsigned int *data_len,
1596 		 unsigned int  max_data_len, unsigned int header_len,
1597 		 unsigned char *oem_iana, unsigned int oem_payload_id,
1598 		 const ipmi_con_option_t *options)
1599 {
1600     unsigned char *tmsg;
1601     int           rv;
1602     unsigned int  header_used;
1603     unsigned char *data;
1604     unsigned int  payload_len;
1605     uint32_t      *seqp;
1606     int           do_auth = 1;
1607     int           do_conf = 1;
1608 
1609     if (options) {
1610 	while (options->option != IPMI_CON_OPTION_LIST_END) {
1611 	    switch (options->option) {
1612 	    case IPMI_CON_MSG_OPTION_AUTH:
1613 		do_auth = options->ival;
1614 		break;
1615 
1616 	    case IPMI_CON_MSG_OPTION_CONF:
1617 		do_conf = options->ival;
1618 		break;
1619 
1620 	    default:
1621 		/* Ignore unknown options. */
1622 		break;
1623 	    }
1624 	    options++;
1625 	}
1626     }
1627 
1628     do_conf = (do_conf && in_session
1629 	       && (lan->ip[addr_num].working_conf
1630 		   != IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE));
1631     do_auth = (do_auth && in_session
1632 	       && (lan->ip[addr_num].working_integ
1633 		   != IPMI_LANP_INTEGRITY_ALGORITHM_NONE));
1634 
1635     if (do_conf) {
1636 #if 0
1637 	if (! lan->ip[addr_num].working)
1638 	    return EAGAIN;
1639 #endif
1640 
1641 	/* Note: This may encrypt the data, the old data will be lost. */
1642 	rv = lan->ip[addr_num].conf_info->conf_encrypt
1643 	    (lan->ipmi,
1644 	     lan->ip[addr_num].conf_data,
1645 	     msgdata,
1646 	     &header_len, data_len,
1647 	     &max_data_len);
1648 	if (rv)
1649 	    return rv;
1650     }
1651 
1652     payload_len = *data_len;
1653 
1654     if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
1655 	header_used = 22;
1656     else
1657 	header_used = 16;
1658 
1659     if (header_used > header_len)
1660 	return E2BIG;
1661 
1662     data = *msgdata - header_used;
1663     *data_len += header_used;
1664     max_data_len += header_used;
1665 
1666     data[0] = 6; /* RMCP version 1.0. */
1667     data[1] = 0;
1668     data[2] = 0xff;
1669     data[3] = 0x07;
1670     data[4] = lan->ip[addr_num].working_authtype;
1671     data[5] = payload_type;
1672     tmsg = data+6;
1673     if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
1674 	memcpy(tmsg, oem_iana, 3);
1675 	tmsg += 3;
1676 	*tmsg = 0;
1677 	tmsg++;
1678 	ipmi_set_uint16(tmsg, oem_payload_id);
1679 	tmsg += 2;
1680     }
1681     if (in_session) {
1682 	if (do_conf)
1683 	    data[5] |= 0x80;
1684 	if (do_auth) {
1685 	    seqp = &(lan->ip[addr_num].outbound_seq_num);
1686 	    data[5] |= 0x40;
1687 	} else {
1688 	    seqp = &(lan->ip[addr_num].unauth_out_seq_num);
1689 	}
1690 	ipmi_set_uint32(tmsg, lan->ip[addr_num].mgsys_session_id);
1691 	tmsg += 4;
1692 	ipmi_set_uint32(tmsg, *seqp);
1693 	tmsg += 4;
1694     } else {
1695 	ipmi_set_uint32(tmsg, 0); /* session id */
1696 	tmsg += 4;
1697 	ipmi_set_uint32(tmsg, 0); /* session sequence number */
1698 	tmsg += 4;
1699 	seqp = NULL;
1700     }
1701 
1702     /* Payload length doesn't include the padding. */
1703     ipmi_set_uint16(tmsg, payload_len);
1704 
1705     if (do_auth) {
1706 	rv = lan->ip[addr_num].integ_info->integ_pad
1707 	    (lan->ipmi,
1708 	     lan->ip[addr_num].integ_data,
1709 	     data, data_len,
1710 	     max_data_len);
1711 	if (rv)
1712 	    return rv;
1713 
1714 	rv = lan->ip[addr_num].integ_info->integ_add
1715 	    (lan->ipmi,
1716 	     lan->ip[addr_num].integ_data,
1717 	     data, data_len,
1718 	     max_data_len);
1719 	if (rv)
1720 	    return rv;
1721     }
1722 
1723     if (seqp) {
1724 	(*seqp)++;
1725 	if (*seqp == 0)
1726 	    *seqp = 1;
1727     }
1728 
1729     *msgdata = data;
1730 
1731     return 0;
1732 }
1733 
1734 static int
lan15_format_msg(lan_data_t * lan,int addr_num,unsigned char ** msgdata,unsigned int * data_len)1735 lan15_format_msg(lan_data_t *lan, int addr_num,
1736 		 unsigned char **msgdata, unsigned int *data_len)
1737 {
1738     unsigned char *data;
1739     int           rv;
1740 
1741     if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_NONE)
1742 	data = *msgdata - 14;
1743     else
1744 	data = *msgdata - 30;
1745 
1746     data[0] = 6; /* RMCP version 1.0. */
1747     data[1] = 0;
1748     data[2] = 0xff;
1749     data[3] = 0x07;
1750     data[4] = lan->ip[addr_num].working_authtype;
1751     ipmi_set_uint32(data+5, lan->ip[addr_num].outbound_seq_num);
1752     ipmi_set_uint32(data+9, lan->ip[addr_num].session_id);
1753 
1754     /* FIXME - need locks for the sequence numbers. */
1755 
1756     /* Increment the outbound number, but make sure it's not zero.  If
1757        it's already zero, ignore it, we are in pre-setup. */
1758     if (lan->ip[addr_num].outbound_seq_num != 0) {
1759 	(lan->ip[addr_num].outbound_seq_num)++;
1760 	if (lan->ip[addr_num].outbound_seq_num == 0)
1761 	    (lan->ip[addr_num].outbound_seq_num)++;
1762     }
1763 
1764     if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_NONE) {
1765 	/* No authentication, so no authcode. */
1766 	data[13] = *data_len;
1767 	*data_len += 14;
1768     } else {
1769 	data[29] = *data_len;
1770 	rv = auth_gen(lan, data+13, data+9, data+5, *msgdata, *data_len,
1771 		      addr_num);
1772 	if (rv)
1773 	    return rv;
1774 	*data_len += 30;
1775     }
1776     *msgdata = data;
1777 
1778     return 0;
1779 }
1780 
1781 static int
lan_send_addr(lan_data_t * lan,const ipmi_addr_t * addr,int addr_len,const ipmi_msg_t * msg,uint8_t seq,int addr_num,const ipmi_con_option_t * options)1782 lan_send_addr(lan_data_t              *lan,
1783 	      const ipmi_addr_t       *addr,
1784 	      int                     addr_len,
1785 	      const ipmi_msg_t        *msg,
1786 	      uint8_t                 seq,
1787 	      int                     addr_num,
1788 	      const ipmi_con_option_t *options)
1789 {
1790     unsigned char  data[IPMI_MAX_LAN_LEN+IPMI_LAN_MAX_HEADER];
1791     unsigned char  *tmsg;
1792     unsigned int   pos;
1793     int            rv;
1794     unsigned int   payload_type;
1795     int            out_of_session = 0;
1796     ipmi_payload_t *payload = NULL;
1797     unsigned char  oem_iana[3] = {0, 0, 0};
1798     unsigned int   oem_payload_id = 0;
1799 
1800     if ((addr->addr_type >= IPMI_RMCPP_ADDR_START)
1801 	&& (addr->addr_type <= IPMI_RMCPP_ADDR_END))
1802     {
1803 	/*
1804 	 * Let through the dodgy IPMI 1.5 Serial-over-LAN packets, but block
1805 	 * anything else that tries to send an RMCP+ packet to a non-RMCP+
1806 	 * host.
1807 	 */
1808 	if ((addr->addr_type != IPMI_RMCPP_ADDR_SOL)
1809 		&& (lan->ip[addr_num].working_authtype != IPMI_AUTHTYPE_RMCP_PLUS))
1810 	    return EINVAL;
1811 	payload_type = addr->addr_type - IPMI_RMCPP_ADDR_START;
1812     } else {
1813 	switch (addr->addr_type) {
1814 	case IPMI_SYSTEM_INTERFACE_ADDR_TYPE:
1815 	case IPMI_IPMB_ADDR_TYPE:
1816 	case IPMI_IPMB_BROADCAST_ADDR_TYPE:
1817 	    payload_type = IPMI_RMCPP_PAYLOAD_TYPE_IPMI;
1818 	    break;
1819 	default:
1820 	    return EINVAL;
1821 	}
1822     }
1823 
1824     if ((payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT)
1825 	|| ((payload_type >= 0x20) && (payload_type <= 0x27)))
1826     {
1827 	ipmi_rmcpp_addr_t *rmcpp_addr = (ipmi_rmcpp_addr_t *) addr;
1828 	payload_entry_t *e;
1829 
1830 	if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
1831 	    memcpy(oem_iana, rmcpp_addr->oem_iana, 3);
1832 	    oem_payload_id = rmcpp_addr->oem_payload_id;
1833 	} else {
1834 	    memcpy(oem_iana, lan->oem_iana, 3);
1835 	    oem_payload_id = 0;
1836 	}
1837 
1838 	/* No lock required, only payload additions are allowed. */
1839 	e = oem_payload_list;
1840 	while (e) {
1841 	    if ((e->payload_type == payload_type)
1842 		&& (memcmp(e->iana, oem_iana, 3) == 0)
1843 		&& (e->payload_id == oem_payload_id))
1844 	    {
1845 		payload = e->payload;
1846 		break;
1847 	    }
1848 	    e = e->next;
1849 	}
1850     } else {
1851 	payload = payloads[payload_type];
1852     }
1853 
1854     tmsg = data + IPMI_LAN_MAX_HEADER;
1855     if (!payload) {
1856 	return ENOSYS;
1857     } else {
1858 	pos = IPMI_MAX_LAN_LEN;
1859 	rv = payload->format_for_xmit(lan->ipmi, addr, addr_len,
1860 				      msg, tmsg, &pos,
1861 				      &out_of_session, seq);
1862 	if (rv)
1863 	    return rv;
1864     }
1865 
1866     if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
1867 	rv = rmcpp_format_msg(lan, addr_num,
1868 			      payload_type, !out_of_session,
1869 			      &tmsg, &pos,
1870 			      IPMI_MAX_LAN_LEN, IPMI_LAN_MAX_HEADER,
1871 			      oem_iana, oem_payload_id, options);
1872     } else {
1873 	rv = lan15_format_msg(lan, addr_num, &tmsg, &pos);
1874 	if (addr->addr_type == IPMI_RMCPP_ADDR_SOL)
1875 		/*
1876 		 * We're sending SoL over IPMI 1.5, which requires that we set
1877 		 * a "reserved" bit.  This is dodgy.
1878 		 */
1879 		tmsg[4] |= 0x80;
1880     }
1881     if (rv)
1882 	return rv;
1883 
1884     if (DEBUG_RAWMSG) {
1885 	char buf1[32], buf2[32];
1886 	ipmi_log(IPMI_LOG_DEBUG_START, "%soutgoing seq %d\n addr =",
1887 		 IPMI_CONN_NAME(lan->ipmi), seq);
1888 	dump_hex((unsigned char *) &(lan->cparm.ip_addr[addr_num]),
1889 		 sizeof(sockaddr_ip_t));
1890         ipmi_log(IPMI_LOG_DEBUG_CONT,
1891                  "\n msg  = netfn=%s cmd=%s data_len=%d.",
1892 		 ipmi_get_netfn_string(msg->netfn, buf1, 32),
1893                  ipmi_get_command_string(msg->netfn, msg->cmd, buf2, 32),
1894 		 msg->data_len);
1895 	if (pos) {
1896 	    ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data =\n  ");
1897 	    dump_hex(tmsg, pos);
1898 	}
1899 	ipmi_log(IPMI_LOG_DEBUG_END, " ");
1900     }
1901 
1902     add_stat(lan->ipmi, STAT_XMIT_PACKETS, 1);
1903 
1904     rv = sendto(lan->fd->fd, tmsg, pos, 0,
1905 		(struct sockaddr *) &(lan->cparm.ip_addr[addr_num].s_ipsock),
1906 		lan->cparm.ip_addr[addr_num].ip_addr_len);
1907     if (rv == -1)
1908 	rv = errno;
1909     else
1910 	rv = 0;
1911 
1912     return rv;
1913 }
1914 
1915 static int
lan_send(lan_data_t * lan,const ipmi_addr_t * addr,int addr_len,const ipmi_msg_t * msg,uint8_t seq,int * send_ip_num,const ipmi_con_option_t * options)1916 lan_send(lan_data_t              *lan,
1917 	 const ipmi_addr_t       *addr,
1918 	 int                     addr_len,
1919 	 const ipmi_msg_t        *msg,
1920 	 uint8_t                 seq,
1921 	 int                     *send_ip_num,
1922 	 const ipmi_con_option_t *options)
1923 {
1924     int curr_ip_addr;
1925 
1926     ipmi_lock(lan->ip_lock);
1927     if (msg->netfn & 1) {
1928 	/* For unacknowledged packets, don't switch addresses.  They
1929 	   don't contribute to detecting that the link is down. */
1930 	curr_ip_addr = lan->curr_ip_addr;
1931     } else if (lan->connected) {
1932 	lan->num_sends++;
1933 
1934 	/* We periodically switch between IP addresses, just to make sure
1935 	   they are all operational. */
1936 	if ((lan->num_sends % SENDS_BETWEEN_IP_SWITCHES) == 0) {
1937 	    unsigned int addr_num = lan->curr_ip_addr + 1;
1938 	    if (addr_num >= lan->cparm.num_ip_addr)
1939 		addr_num = 0;
1940 	    while (addr_num != lan->curr_ip_addr) {
1941 		if (lan->ip[addr_num].working)
1942 		    break;
1943 		addr_num++;
1944 		if (addr_num >= lan->cparm.num_ip_addr)
1945 		    addr_num = 0;
1946 	    }
1947 	    lan->curr_ip_addr = addr_num;
1948 	}
1949     } else {
1950 	/* Just rotate between IP addresses if we are not yet connected */
1951 	unsigned int addr_num = lan->curr_ip_addr + 1;
1952 	if (addr_num >= lan->cparm.num_ip_addr)
1953 	    addr_num = 0;
1954 	lan->curr_ip_addr = addr_num;
1955     }
1956     curr_ip_addr = lan->curr_ip_addr;
1957     ipmi_unlock(lan->ip_lock);
1958 
1959     *send_ip_num = curr_ip_addr;
1960 
1961     return lan_send_addr(lan, addr, addr_len, msg, seq, curr_ip_addr, options);
1962 }
1963 
1964 typedef struct call_ipmb_change_handler_s
1965 {
1966     lan_data_t   *lan;
1967     int           err;
1968     const unsigned char *ipmb_addr;
1969     unsigned int  num_ipmb_addr;
1970     int           active;
1971     unsigned int  hacks;
1972 } call_ipmb_change_handler_t;
1973 
1974 static int
call_ipmb_change_handler(void * cb_data,void * item1,void * item2)1975 call_ipmb_change_handler(void *cb_data, void *item1, void *item2)
1976 {
1977     call_ipmb_change_handler_t *info = cb_data;
1978     ipmi_ll_ipmb_addr_cb       handler = item1;
1979 
1980     handler(info->lan->ipmi, info->err, info->ipmb_addr, info->num_ipmb_addr,
1981 	    info->active, info->hacks, item2);
1982     return LOCKED_LIST_ITER_CONTINUE;
1983 }
1984 
1985 static void
call_ipmb_change_handlers(lan_data_t * lan,int err,const unsigned char ipmb_addr[],unsigned int num_ipmb_addr,int active,unsigned int hacks)1986 call_ipmb_change_handlers(lan_data_t *lan, int err,
1987 			  const unsigned char ipmb_addr[],
1988 			  unsigned int num_ipmb_addr,
1989 			  int active, unsigned int hacks)
1990 {
1991     call_ipmb_change_handler_t info;
1992 
1993     info.lan = lan;
1994     info.err = err;
1995     info.ipmb_addr = ipmb_addr;
1996     info.num_ipmb_addr = num_ipmb_addr;
1997     info.active = active;
1998     info.hacks = hacks;
1999     locked_list_iterate(lan->ipmb_change_handlers, call_ipmb_change_handler,
2000 			&info);
2001 }
2002 
2003 static int
lan_add_ipmb_addr_handler(ipmi_con_t * ipmi,ipmi_ll_ipmb_addr_cb handler,void * cb_data)2004 lan_add_ipmb_addr_handler(ipmi_con_t           *ipmi,
2005 			  ipmi_ll_ipmb_addr_cb handler,
2006 			  void                 *cb_data)
2007 {
2008     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2009 
2010     if (locked_list_add(lan->ipmb_change_handlers, handler, cb_data))
2011 	return 0;
2012     else
2013 	return ENOMEM;
2014 }
2015 
2016 static int
lan_remove_ipmb_addr_handler(ipmi_con_t * ipmi,ipmi_ll_ipmb_addr_cb handler,void * cb_data)2017 lan_remove_ipmb_addr_handler(ipmi_con_t           *ipmi,
2018 			     ipmi_ll_ipmb_addr_cb handler,
2019 			     void                 *cb_data)
2020 {
2021     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2022 
2023     if (locked_list_remove(lan->ipmb_change_handlers, handler, cb_data))
2024 	return 0;
2025     else
2026 	return EINVAL;
2027 }
2028 
2029 static void
ipmb_handler(ipmi_con_t * ipmi,int err,const unsigned char ipmb_addr[],unsigned int num_ipmb_addr,int active,unsigned int hacks,void * cb_data)2030 ipmb_handler(ipmi_con_t   *ipmi,
2031 	     int          err,
2032 	     const unsigned char ipmb_addr[],
2033 	     unsigned int num_ipmb_addr,
2034 	     int          active,
2035 	     unsigned int hacks,
2036 	     void         *cb_data)
2037 {
2038     lan_data_t *lan;
2039     int        changed = 0;
2040     int        i;
2041 
2042     if (err)
2043 	return;
2044 
2045     lan = (lan_data_t *) ipmi->con_data;
2046 
2047     for (i=0; i<MAX_IPMI_USED_CHANNELS; i++) {
2048 	if (! ipmb_addr[i])
2049 	    continue;
2050 	if (ipmb_addr[i] != lan->slave_addr[i]) {
2051 	    lan->slave_addr[i] = ipmb_addr[i];
2052 	    ipmi->ipmb_addr[i] = ipmb_addr[i];
2053 	    changed = 1;
2054 	}
2055     }
2056     if (changed || (lan->is_active != active))  {
2057 	lan->is_active = active;
2058 	ipmi->hacks = hacks;
2059 	call_ipmb_change_handlers(lan, err, ipmb_addr, num_ipmb_addr,
2060 				  active, hacks);
2061     }
2062 }
2063 
2064 static void
audit_timeout_handler(void * cb_data,os_hnd_timer_id_t * id)2065 audit_timeout_handler(void              *cb_data,
2066 		      os_hnd_timer_id_t *id)
2067 {
2068     audit_timer_info_t           *info = cb_data;
2069     ipmi_con_t                   *ipmi = info->ipmi;
2070     lan_data_t                   *lan;
2071     struct timeval               timeout;
2072     ipmi_msg_t                   msg;
2073     unsigned int                 i;
2074     ipmi_system_interface_addr_t si;
2075     int                          start_up[MAX_IP_ADDR];
2076 
2077 
2078     /* If we were cancelled, just free the data and ignore the call. */
2079     if (info->cancelled)
2080 	goto out_done;
2081 
2082     if (!lan_valid_ipmi(ipmi))
2083 	goto out_done;
2084 
2085     lan = ipmi->con_data;
2086 
2087     /* Send message to all addresses we think are down.  If the
2088        connection is down, this will bring it up, otherwise it
2089        will keep it alive. */
2090     ipmi_lock(lan->ip_lock);
2091     for (i=0; i<lan->cparm.num_ip_addr; i++)
2092 	    start_up[i] = ! lan->ip[i].working;
2093     ipmi_unlock(lan->ip_lock);
2094 
2095     for (i=0; i<lan->cparm.num_ip_addr; i++) {
2096 	if (start_up[i])
2097 	    send_auth_cap(ipmi, lan, i, 0);
2098     }
2099 
2100     msg.netfn = IPMI_APP_NETFN;
2101     msg.cmd = IPMI_GET_DEVICE_ID_CMD;
2102     msg.data = NULL;
2103     msg.data_len = 0;
2104 
2105     /* Send a message to check the working of the interface. */
2106     if (ipmi->get_ipmb_addr) {
2107 	/* If we have a way to query the IPMB address, do so
2108            periodically. */
2109 	ipmi->get_ipmb_addr(ipmi, ipmb_handler, NULL);
2110     } else {
2111 	si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2112 	si.channel = 0xf;
2113 	si.lun = 0;
2114 	ipmi->send_command(ipmi, (ipmi_addr_t *) &si, sizeof(si),
2115 			   &msg, NULL, NULL);
2116     }
2117 
2118     timeout.tv_sec = LAN_AUDIT_TIMEOUT / 1000000;
2119     timeout.tv_usec = LAN_AUDIT_TIMEOUT % 1000000;
2120     ipmi->os_hnd->start_timer(ipmi->os_hnd,
2121 			      id,
2122 			      &timeout,
2123 			      audit_timeout_handler,
2124 			      cb_data);
2125 
2126     /* Make sure the timer info doesn't get freed. */
2127     info = NULL;
2128 
2129     lan_put(ipmi);
2130 
2131  out_done:
2132     if (info) {
2133 	ipmi->os_hnd->free_timer(ipmi->os_hnd, id);
2134 	ipmi_mem_free(info);
2135     }
2136     return;
2137 }
2138 
2139 typedef struct call_con_change_handler_s
2140 {
2141     lan_data_t  *lan;
2142     int          err;
2143     unsigned int port;
2144     int          any_port_up;
2145 } call_con_change_handler_t;
2146 
2147 static int
call_con_change_handler(void * cb_data,void * item1,void * item2)2148 call_con_change_handler(void *cb_data, void *item1, void *item2)
2149 {
2150     call_con_change_handler_t  *info = cb_data;
2151     ipmi_ll_con_changed_cb     handler = item1;
2152 
2153     handler(info->lan->ipmi, info->err, info->port, info->any_port_up, item2);
2154     return LOCKED_LIST_ITER_CONTINUE;
2155 }
2156 
2157 static void
call_con_change_handlers(lan_data_t * lan,int err,unsigned int port,int any_port_up)2158 call_con_change_handlers(lan_data_t *lan, int err, unsigned int port,
2159 			 int any_port_up)
2160 {
2161     call_con_change_handler_t info;
2162 
2163     info.lan = lan;
2164     info.err = err;
2165     info.port = port;
2166     info.any_port_up = any_port_up;
2167     locked_list_iterate(lan->con_change_handlers, call_con_change_handler,
2168 			&info);
2169 }
2170 
2171 void
i_ipmi_lan_con_change_lock(ipmi_con_t * ipmi)2172 i_ipmi_lan_con_change_lock(ipmi_con_t *ipmi)
2173 {
2174     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2175     ipmi_lock(lan->ip_lock);
2176     ipmi_lock(lan->con_change_lock);
2177     ipmi_unlock(lan->ip_lock);
2178 }
2179 
2180 void
i_ipmi_lan_con_change_unlock(ipmi_con_t * ipmi)2181 i_ipmi_lan_con_change_unlock(ipmi_con_t *ipmi)
2182 {
2183     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2184     ipmi_unlock(lan->con_change_lock);
2185 }
2186 
2187 void
i_ipmi_lan_call_con_change_handlers(ipmi_con_t * ipmi,int err,unsigned int port)2188 i_ipmi_lan_call_con_change_handlers(ipmi_con_t   *ipmi,
2189 				   int          err,
2190 				   unsigned int port)
2191 {
2192     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2193 
2194     call_con_change_handlers(lan, err, port, lan->connected);
2195 }
2196 
2197 static int
lan_add_con_change_handler(ipmi_con_t * ipmi,ipmi_ll_con_changed_cb handler,void * cb_data)2198 lan_add_con_change_handler(ipmi_con_t             *ipmi,
2199 			   ipmi_ll_con_changed_cb handler,
2200 			   void                   *cb_data)
2201 {
2202     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2203 
2204     if (locked_list_add(lan->con_change_handlers, handler, cb_data))
2205 	return 0;
2206     else
2207 	return ENOMEM;
2208 }
2209 
2210 static int
lan_remove_con_change_handler(ipmi_con_t * ipmi,ipmi_ll_con_changed_cb handler,void * cb_data)2211 lan_remove_con_change_handler(ipmi_con_t             *ipmi,
2212 			      ipmi_ll_con_changed_cb handler,
2213 			      void                   *cb_data)
2214 {
2215     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2216 
2217     if (locked_list_remove(lan->con_change_handlers, handler, cb_data))
2218 	return 0;
2219     else
2220 	return EINVAL;
2221 }
2222 
2223 static void
connection_up(lan_data_t * lan,int addr_num,int new_con)2224 connection_up(lan_data_t *lan, int addr_num, int new_con)
2225 {
2226     add_stat(lan->ipmi, STAT_CONN_UP, 1);
2227 
2228     ipmi_lock(lan->ip_lock);
2229     if ((! lan->ip[addr_num].working) && new_con) {
2230 	lan->ip[addr_num].working = 1;
2231 
2232 	ipmi_log(IPMI_LOG_INFO,
2233 		 "%sipmi_lan.c(connection_up): "
2234 		 "Connection %d to the BMC is up",
2235 		 IPMI_CONN_NAME(lan->ipmi), addr_num);
2236     }
2237 
2238     if (new_con) {
2239 	ipmi_log(IPMI_LOG_INFO,
2240 		 "%sipmi_lan.c(connection_up): "
2241 		 "Connection to the BMC restored",
2242 		 IPMI_CONN_NAME(lan->ipmi));
2243 	lan->curr_ip_addr = addr_num;
2244     }
2245 
2246     if (lan->connected) {
2247 	ipmi_lock(lan->con_change_lock);
2248 	ipmi_unlock(lan->ip_lock);
2249 	call_con_change_handlers(lan, 0, addr_num, 1);
2250 	ipmi_unlock(lan->con_change_lock);
2251     } else {
2252 	ipmi_unlock(lan->ip_lock);
2253     }
2254 }
2255 
2256 static void
reset_session_data(lan_data_t * lan,int addr_num)2257 reset_session_data(lan_data_t *lan, int addr_num)
2258 {
2259     lan_ip_data_t *ip = &lan->ip[addr_num];
2260 
2261     ip->outbound_seq_num = 0;
2262     ip->inbound_seq_num = 0;
2263     ip->session_id = 0;
2264     ip->mgsys_session_id = 0;
2265     ip->precon_session_id = 0;
2266     ip->precon_mgsys_session_id = 0;
2267     ip->recv_msg_map = 0;
2268     ip->unauth_recv_msg_map = 0;
2269     ip->working_authtype = 0;
2270     ip->unauth_out_seq_num = 0;
2271     ip->unauth_in_seq_num = 0;
2272     if (ip->conf_data) {
2273 	ip->conf_info->conf_free(lan->ipmi, ip->conf_data);
2274 	ip->conf_data = NULL;
2275     }
2276     ip->conf_info = NULL;
2277     if (ip->integ_data) {
2278 	ip->integ_info->integ_free(lan->ipmi, ip->integ_data);
2279 	ip->integ_data = NULL;
2280     }
2281     ip->integ_info = NULL;
2282     ip->working_conf = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
2283     ip->working_integ = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
2284 }
2285 
2286 static void
lost_connection(lan_data_t * lan,unsigned int addr_num)2287 lost_connection(lan_data_t *lan, unsigned int addr_num)
2288 {
2289     unsigned int i;
2290 
2291     ipmi_lock(lan->ip_lock);
2292     if (! lan->ip[addr_num].working) {
2293 	ipmi_unlock(lan->ip_lock);
2294 	return;
2295     }
2296 
2297     add_stat(lan->ipmi, STAT_CONN_DOWN, 1);
2298 
2299     lan->ip[addr_num].working = 0;
2300 
2301     reset_session_data(lan, addr_num);
2302 
2303     ipmi_log(IPMI_LOG_WARNING,
2304 	     "%sipmi_lan.c(lost_connection): "
2305 	     "Connection %d to the BMC is down",
2306 	     IPMI_CONN_NAME(lan->ipmi), addr_num);
2307 
2308     if (lan->curr_ip_addr == addr_num) {
2309 	/* Scan to see if any address is operational. */
2310 	for (i=0; i<lan->cparm.num_ip_addr; i++) {
2311 	    if (lan->ip[i].working) {
2312 		lan->curr_ip_addr = i;
2313 		break;
2314 	    }
2315 	}
2316 
2317 	if (i >= lan->cparm.num_ip_addr) {
2318 	    /* There were no operational connections, report that. */
2319 	    ipmi_log(IPMI_LOG_SEVERE,
2320 		     "%sipmi_lan.c(lost_connection): "
2321 		     "All connections to the BMC are down",
2322 		     IPMI_CONN_NAME(lan->ipmi));
2323 
2324 	    lan->connected = 0;
2325 	}
2326     }
2327 
2328     {
2329 	int connected = lan->connected;
2330 
2331 	ipmi_lock(lan->con_change_lock);
2332 	ipmi_unlock(lan->ip_lock);
2333 	call_con_change_handlers(lan, ETIMEDOUT, addr_num, connected);
2334 	ipmi_unlock(lan->con_change_lock);
2335     }
2336 }
2337 
2338 static void
rsp_timeout_handler(void * cb_data,os_hnd_timer_id_t * id)2339 rsp_timeout_handler(void              *cb_data,
2340 		    os_hnd_timer_id_t *id)
2341 {
2342     lan_timer_info_t      *info = cb_data;
2343     ipmi_con_t            *ipmi = info->ipmi;
2344     lan_data_t            *lan;
2345     int                   seq;
2346     ipmi_ll_rsp_handler_t handler;
2347     ipmi_msgi_t           *rspi;
2348     int                   ip_num = 0;
2349     int                   call_lost_con = 0;
2350 
2351     if (!lan_valid_ipmi(ipmi))
2352 	return;
2353 
2354     lan = ipmi->con_data;
2355     seq = info->seq;
2356 
2357     ipmi_lock(lan->seq_num_lock);
2358 
2359     /* If we were cancelled, just free the data and ignore it. */
2360     if (info->cancelled) {
2361 	ipmi_unlock(lan->seq_num_lock);
2362 	goto out;
2363     }
2364 
2365     if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2366 	ipmi_log(IPMI_LOG_DEBUG, "%sTimeout for seq #%d",
2367 		 IPMI_CONN_NAME(ipmi), seq);
2368 
2369     if (! lan->seq_table[seq].inuse) {
2370 	ipmi_unlock(lan->seq_num_lock);
2371 	goto out;
2372     }
2373 
2374     if (DEBUG_RAWMSG) {
2375 	ip_num = lan->seq_table[seq].last_ip_num;
2376 	ipmi_log(IPMI_LOG_DEBUG,
2377 		 "%sSeq #%d\n"
2378 		 "  addr_type=%d, ip_num=%d, fails=%d\n"
2379 		 "  fail_start_time=%ld.%6.6ld",
2380 		 IPMI_CONN_NAME(ipmi),
2381 		 seq, lan->seq_table[seq].addr.addr_type,
2382 		 lan->seq_table[seq].last_ip_num,
2383 		 lan->ip[ip_num].consecutive_failures,
2384 		 lan->ip[ip_num].failure_time.tv_sec,
2385 		 lan->ip[ip_num].failure_time.tv_usec);
2386     }
2387 
2388     if (lan->seq_table[seq].addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
2389     {
2390 	/* We only count timeouts on messages to the system interface.
2391            Otherwise, if we sent a bunch of messages to the IPMB that
2392            timed out, we might trigger this code accidentally. */
2393 	ip_num = lan->seq_table[seq].last_ip_num;
2394 	ipmi_lock(lan->ip_lock);
2395 	if (lan->ip[ip_num].working) {
2396 	    if (lan->ip[ip_num].consecutive_failures == 0) {
2397 		/* Set the time when the connection will be considered
2398                    failed. */
2399 		ipmi->os_hnd->get_monotonic_time(ipmi->os_hnd,
2400 					       &(lan->ip[ip_num].failure_time));
2401 		lan->ip[ip_num].failure_time.tv_sec += IP_FAIL_TIME / 1000000;
2402 		lan->ip[ip_num].failure_time.tv_usec += IP_FAIL_TIME % 1000000;
2403 		if (lan->ip[ip_num].failure_time.tv_usec > 1000000) {
2404 		    lan->ip[ip_num].failure_time.tv_sec += 1;
2405 		    lan->ip[ip_num].failure_time.tv_usec -= 1000000;
2406 		}
2407 		lan->ip[ip_num].consecutive_failures = 1;
2408 	    } else if (!lan->seq_table[seq].side_effects) {
2409 		/* Don't use messages with side effects for failure
2410 		   detection. */
2411 		lan->ip[ip_num].consecutive_failures++;
2412 		if (lan->ip[ip_num].consecutive_failures >= IP_FAIL_COUNT) {
2413 		    /* Consider this for a failure, check after unlocking */
2414 		    call_lost_con = 1;
2415 		}
2416 	    }
2417 	}
2418 	ipmi_unlock(lan->ip_lock);
2419 
2420 	if (call_lost_con) {
2421 	    struct timeval now;
2422 	    ipmi->os_hnd->get_monotonic_time(ipmi->os_hnd, &now);
2423 	    if (cmp_timeval(&now, &lan->ip[ip_num].failure_time) <= 0) {
2424 		/* Not a failure yet. */
2425 		call_lost_con = 0;
2426 	    }
2427 	}
2428     }
2429 
2430     rspi = lan->seq_table[seq].rsp_item;
2431 
2432     if (lan->seq_table[seq].retries_left > 0)
2433     {
2434 	struct timeval timeout;
2435 	int            rv;
2436 
2437 	lan->seq_table[seq].retries_left--;
2438 
2439 	add_stat(ipmi, STAT_REXMITS, 1);
2440 
2441 	/* Note that we will need a new session seq # here, we can't reuse
2442 	   the old one.  If the message got lost on the way back, the other
2443 	   end would silently ignore resends of the seq #. */
2444 	if (lan->seq_table[seq].addr_num >= 0)
2445 	    rv = lan_send_addr(lan,
2446 			       &(lan->seq_table[seq].addr),
2447 			       lan->seq_table[seq].addr_len,
2448 			       &(lan->seq_table[seq].msg),
2449 			       seq,
2450 			       lan->seq_table[seq].addr_num,
2451 			       NULL);
2452 	else
2453 	    rv = lan_send(lan,
2454 			  &(lan->seq_table[seq].addr),
2455 			  lan->seq_table[seq].addr_len,
2456 			  &(lan->seq_table[seq].msg),
2457 			  seq,
2458 			  &(lan->seq_table[seq].last_ip_num),
2459 			  NULL);
2460 
2461 	if (rv) {
2462 	    /* If we get an error resending the message, report an unknown
2463 	       error. */
2464 	    rspi->data[0] = IPMI_UNKNOWN_ERR_CC;
2465 	} else {
2466 	    if (!lan->seq_table[seq].side_effects) {
2467 		timeout.tv_sec = LAN_RSP_TIMEOUT / 1000000;
2468 		timeout.tv_usec = LAN_RSP_TIMEOUT % 1000000;
2469 	    } else {
2470 		timeout.tv_sec = LAN_RSP_TIMEOUT_SIDEEFF / 1000000;
2471 		timeout.tv_usec = LAN_RSP_TIMEOUT_SIDEEFF % 1000000;
2472 	    }
2473 	    ipmi->os_hnd->start_timer(ipmi->os_hnd,
2474 				      id,
2475 				      &timeout,
2476 				      rsp_timeout_handler,
2477 				      cb_data);
2478 
2479 	    ipmi_unlock(lan->seq_num_lock);
2480 	    if (call_lost_con)
2481 		lost_connection(lan, ip_num);
2482 	    lan_put(ipmi);
2483 	    return;
2484 	}
2485     } else {
2486 	add_stat(ipmi, STAT_TIMED_OUT, 1);
2487 
2488 	rspi->data[0] = IPMI_TIMEOUT_CC;
2489     }
2490 
2491     rspi->msg.netfn = lan->seq_table[seq].msg.netfn | 1;
2492     rspi->msg.cmd = lan->seq_table[seq].msg.cmd;
2493     rspi->msg.data = rspi->data;
2494     rspi->msg.data_len = 1;
2495 
2496     if (lan->seq_table[seq].use_orig_addr) {
2497 	/* We did an address translation, so translate back. */
2498 	memcpy(&rspi->addr, &lan->seq_table[seq].orig_addr,
2499 	       lan->seq_table[seq].orig_addr_len);
2500 	rspi->addr_len = lan->seq_table[seq].orig_addr_len;
2501     } else {
2502 	memcpy(&rspi->addr,
2503 	       &(lan->seq_table[seq].addr),
2504 	       lan->seq_table[seq].addr_len);
2505 	rspi->addr_len = lan->seq_table[seq].addr_len;
2506     }
2507 
2508     handler = lan->seq_table[seq].rsp_handler;
2509 
2510     lan->seq_table[seq].inuse = 0;
2511 
2512     check_command_queue(ipmi, lan);
2513     ipmi_unlock(lan->seq_num_lock);
2514 
2515     ipmi->os_hnd->free_timer(ipmi->os_hnd, id);
2516 
2517     /* Convert broadcasts back into normal sends. */
2518     if (rspi->addr.addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
2519 	rspi->addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2520 
2521     if (call_lost_con)
2522 	lost_connection(lan, ip_num);
2523 
2524     ipmi_handle_rsp_item(ipmi, rspi, handler);
2525 
2526  out:
2527     lan_put(ipmi);
2528     ipmi_mem_free(info);
2529 }
2530 
2531 typedef struct call_event_handler_s
2532 {
2533     lan_data_t        *lan;
2534     const ipmi_addr_t *addr;
2535     unsigned int      addr_len;
2536     ipmi_event_t      *event;
2537 } call_event_handler_t;
2538 
2539 static int
call_event_handler(void * cb_data,void * item1,void * item2)2540 call_event_handler(void *cb_data, void *item1, void *item2)
2541 {
2542     call_event_handler_t  *info = cb_data;
2543     ipmi_ll_evt_handler_t handler = item1;
2544 
2545     handler(info->lan->ipmi, info->addr, info->addr_len, info->event, item2);
2546     return LOCKED_LIST_ITER_CONTINUE;
2547 }
2548 
2549 static int
lan_add_event_handler(ipmi_con_t * ipmi,ipmi_ll_evt_handler_t handler,void * cb_data)2550 lan_add_event_handler(ipmi_con_t            *ipmi,
2551 		      ipmi_ll_evt_handler_t handler,
2552 		      void                  *cb_data)
2553 {
2554     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2555 
2556     if (locked_list_add(lan->event_handlers, handler, cb_data))
2557 	return 0;
2558     else
2559 	return ENOMEM;
2560 }
2561 
2562 static int
lan_remove_event_handler(ipmi_con_t * ipmi,ipmi_ll_evt_handler_t handler,void * cb_data)2563 lan_remove_event_handler(ipmi_con_t            *ipmi,
2564 			 ipmi_ll_evt_handler_t handler,
2565 			 void                  *cb_data)
2566 {
2567     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
2568 
2569     if (locked_list_remove(lan->event_handlers, handler, cb_data))
2570 	return 0;
2571     else
2572 	return EINVAL;
2573 }
2574 
2575 static ipmi_mcid_t invalid_mcid = IPMI_MCID_INVALID;
2576 
2577 static void
handle_async_event(ipmi_con_t * ipmi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg)2578 handle_async_event(ipmi_con_t        *ipmi,
2579 		   const ipmi_addr_t *addr,
2580 		   unsigned int      addr_len,
2581 		   const ipmi_msg_t  *msg)
2582 {
2583     lan_data_t           *lan = (lan_data_t *) ipmi->con_data;
2584     ipmi_event_t         *event = NULL;
2585     ipmi_time_t          timestamp;
2586     call_event_handler_t info;
2587 
2588     add_stat(ipmi, STAT_ASYNC_EVENTS, 1);
2589 
2590     if (msg) {
2591 	unsigned int type = msg->data[2];
2592 	unsigned int record_id = ipmi_get_uint16(msg->data);
2593 
2594 	if (type < 0xe0)
2595 	    timestamp = ipmi_seconds_to_time(ipmi_get_uint32(msg->data+3));
2596 	else
2597 	    timestamp = -1;
2598 	event = ipmi_event_alloc(invalid_mcid,
2599 				 record_id,
2600 				 type,
2601 				 timestamp,
2602 				 msg->data+3, 13);
2603 	if (!event)
2604 	    /* We missed it here, but the SEL fetch should catch it later. */
2605 	    return;
2606     }
2607 
2608     info.lan = lan;
2609     info.addr = addr;
2610     info.addr_len = addr_len;
2611     info.event = event;
2612     locked_list_iterate(lan->event_handlers, call_event_handler, &info);
2613 
2614     if (event)
2615 	ipmi_event_free(event);
2616 }
2617 
2618 /* Must be called with the message sequence lock held. */
2619 static int
handle_msg_send(lan_timer_info_t * info,int addr_num,const ipmi_addr_t * iaddr,unsigned int addr_len,const ipmi_msg_t * msg,ipmi_ll_rsp_handler_t rsp_handler,ipmi_msgi_t * rspi,int side_effects)2620 handle_msg_send(lan_timer_info_t      *info,
2621 		int                   addr_num,
2622 		const ipmi_addr_t     *iaddr,
2623 		unsigned int          addr_len,
2624 		const ipmi_msg_t      *msg,
2625 		ipmi_ll_rsp_handler_t rsp_handler,
2626 		ipmi_msgi_t           *rspi,
2627 		int                   side_effects)
2628 {
2629     ipmi_con_t        *ipmi = info->ipmi;
2630     lan_data_t        *lan = ipmi->con_data;
2631     unsigned int      seq;
2632     struct timeval    timeout;
2633     int               rv;
2634     char              addr_data[sizeof(ipmi_addr_t)];
2635     char              addr_data2[sizeof(ipmi_addr_t)];
2636     ipmi_addr_t       *addr = (ipmi_addr_t *) addr_data;
2637     const ipmi_addr_t *orig_addr = NULL;
2638     unsigned int      orig_addr_len = 0;
2639 
2640     *addr = *iaddr;
2641 
2642     seq = (lan->last_seq + 1) % 64;
2643     if (seq == 0)
2644 	seq++;
2645     while (lan->seq_table[seq].inuse) {
2646 	if (seq == lan->last_seq) {
2647 	    /* This cannot really happen if max_outstanding_msg_count <= 63. */
2648 	    ipmi_log(IPMI_LOG_FATAL,
2649 		     "%sipmi_lan.c(handle_msg_send): "
2650 		     "ipmi_lan: Attempted to start too many messages",
2651 		     IPMI_CONN_NAME(ipmi));
2652 	    abort();
2653 	}
2654 
2655 	seq = (seq + 1) % 64;
2656 	if (seq == 0)
2657 	    seq++;
2658     }
2659 
2660     if (DEBUG_MSG) {
2661 	char buf1[32], buf2[32];
2662 	ipmi_log(IPMI_LOG_DEBUG_START, "%soutgoing msg to IPMI addr =",
2663 		 IPMI_CONN_NAME(ipmi));
2664 	dump_hex((unsigned char *) addr, addr_len);
2665 	ipmi_log(IPMI_LOG_DEBUG_CONT,
2666 		 "\n msg  = netfn=%s cmd=%s data_len=%d",
2667 		 ipmi_get_netfn_string(msg->netfn, buf1, 32),
2668 		 ipmi_get_command_string(msg->netfn, msg->cmd, buf2, 32),
2669 		 msg->data_len);
2670 	if (msg->data_len) {
2671 	    ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data(len=%d.) =\n  ",
2672 		     msg->data_len);
2673 	    dump_hex(msg->data, msg->data_len);
2674 	}
2675 	ipmi_log(IPMI_LOG_DEBUG_END, " ");
2676     }
2677 
2678     if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
2679 	|| (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
2680     {
2681 	ipmi_ipmb_addr_t *ipmb = (ipmi_ipmb_addr_t *) addr;
2682 
2683 	if (ipmb->channel >= MAX_IPMI_USED_CHANNELS) {
2684 	    ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
2685 	    ipmi_mem_free(info);
2686 	    rv = EINVAL;
2687 	    goto out;
2688 	}
2689 
2690 	if (ipmb->slave_addr == lan->slave_addr[ipmb->channel]) {
2691 	    ipmi_system_interface_addr_t *si = (void *) addr_data2;
2692 	    /* Most systems don't handle sending to your own slave
2693                address, so we have to translate here. */
2694 
2695 	    si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2696 	    si->channel = IPMI_BMC_CHANNEL;
2697 	    si->lun = ipmb->lun;
2698 	    orig_addr = addr;
2699 	    orig_addr_len = addr_len;
2700 	    addr = (ipmi_addr_t *) si;
2701 	    addr_len = sizeof(*si);
2702 	}
2703     }
2704 
2705     info->seq = seq;
2706     lan->seq_table[seq].inuse = 1;
2707     lan->seq_table[seq].side_effects = side_effects;
2708     lan->seq_table[seq].addr_num = addr_num;
2709     lan->seq_table[seq].rsp_handler = rsp_handler;
2710     lan->seq_table[seq].rsp_item = rspi;
2711     memcpy(&(lan->seq_table[seq].addr), addr, addr_len);
2712     lan->seq_table[seq].addr_len = addr_len;
2713     lan->seq_table[seq].msg = *msg;
2714     lan->seq_table[seq].msg.data = lan->seq_table[seq].data;
2715     memcpy(lan->seq_table[seq].data, msg->data, msg->data_len);
2716     lan->seq_table[seq].timer_info = info;
2717     if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
2718 	lan->seq_table[seq].retries_left = 0;
2719     else
2720 	lan->seq_table[seq].retries_left = LAN_RSP_RETRIES;
2721     if (orig_addr) {
2722 	lan->seq_table[seq].use_orig_addr = 1;
2723 	memcpy(&(lan->seq_table[seq].orig_addr), orig_addr, orig_addr_len);
2724 	lan->seq_table[seq].orig_addr_len = orig_addr_len;
2725 
2726 	/* In case it's a broadcast. */
2727 	lan->seq_table[seq].orig_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2728     } else {
2729 	lan->seq_table[seq].use_orig_addr = 0;
2730     }
2731 
2732     if (!side_effects) {
2733 	timeout.tv_sec = LAN_RSP_TIMEOUT / 1000000;
2734 	timeout.tv_usec = LAN_RSP_TIMEOUT % 1000000;
2735     } else {
2736 	timeout.tv_sec = LAN_RSP_TIMEOUT_SIDEEFF / 1000000;
2737 	timeout.tv_usec = LAN_RSP_TIMEOUT_SIDEEFF % 1000000;
2738     }
2739     lan->seq_table[seq].timer = info->timer;
2740     rv = ipmi->os_hnd->start_timer(ipmi->os_hnd,
2741 				   lan->seq_table[seq].timer,
2742 				   &timeout,
2743 				   rsp_timeout_handler,
2744 				   info);
2745     if (rv) {
2746 	lan->seq_table[seq].inuse = 0;
2747 	ipmi->os_hnd->free_timer(ipmi->os_hnd,
2748 				 lan->seq_table[seq].timer);
2749 	lan->seq_table[seq].timer = NULL;
2750 	ipmi_mem_free(info);
2751 	goto out;
2752     }
2753 
2754     lan->last_seq = seq;
2755 
2756     if (addr_num >= 0) {
2757 	rv = lan_send_addr(lan, addr, addr_len, msg, seq, addr_num, NULL);
2758 	lan->seq_table[seq].last_ip_num = addr_num;
2759     } else {
2760 	rv = lan_send(lan, addr, addr_len, msg, seq,
2761 		      &(lan->seq_table[seq].last_ip_num),
2762 		      NULL);
2763     }
2764     if (rv) {
2765 	int err;
2766 
2767 	lan->seq_table[seq].inuse = 0;
2768 	err = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
2769 				       lan->seq_table[seq].timer);
2770 	/* Special handling, if we can't remove the timer, then it
2771            will time out on us, so we need to not free the command and
2772            instead let the timeout handle freeing it. */
2773 	if (err) {
2774 	    info->cancelled = 1;
2775 	} else {
2776 	    ipmi->os_hnd->free_timer(ipmi->os_hnd,
2777 				     lan->seq_table[seq].timer);
2778 	    lan->seq_table[seq].timer = NULL;
2779 	    ipmi_mem_free(info);
2780 	}
2781     }
2782  out:
2783     return rv;
2784 }
2785 
2786 static void
check_command_queue(ipmi_con_t * ipmi,lan_data_t * lan)2787 check_command_queue(ipmi_con_t *ipmi, lan_data_t *lan)
2788 {
2789     int              rv;
2790     lan_wait_queue_t *q_item;
2791     int              started = 0;
2792 
2793     while (!started && (lan->wait_q != NULL)) {
2794 	/* Commands are waiting to be started, remove the queue item
2795            and start it. */
2796 	q_item = lan->wait_q;
2797 	lan->wait_q = q_item->next;
2798 	if (lan->wait_q == NULL)
2799 	    lan->wait_q_tail = NULL;
2800 
2801 	rv = handle_msg_send(q_item->info, -1, &q_item->addr, q_item->addr_len,
2802 			     &(q_item->msg), q_item->rsp_handler,
2803 			     q_item->rsp_item, q_item->side_effects);
2804 	if (rv) {
2805 	    ipmi_unlock(lan->seq_num_lock);
2806 
2807 	    /* Send an error response to the user. */
2808 	    ipmi_log(IPMI_LOG_ERR_INFO,
2809 		     "%sipmi_lan.c(check_command_queue): "
2810 		     "Command was not able to be sent due to error 0x%x",
2811 		     IPMI_CONN_NAME(ipmi), rv);
2812 
2813 	    q_item->msg.netfn |= 1; /* Convert it to a response. */
2814 	    q_item->msg.data[0] = IPMI_UNKNOWN_ERR_CC;
2815 	    q_item->msg.data_len = 1;
2816 	    q_item->info = NULL;
2817 	    ipmi_handle_rsp_item_copyall(ipmi, q_item->rsp_item,
2818 					 &q_item->addr, q_item->addr_len,
2819 					 &q_item->msg, q_item->rsp_handler);
2820 	    ipmi_lock(lan->seq_num_lock);
2821 	} else {
2822 	    /* We successfully sent a message, break out of the loop. */
2823 	    started = 1;
2824 	}
2825 	ipmi_mem_free(q_item);
2826     }
2827 
2828     if (!started)
2829 	lan->outstanding_msg_count--;
2830 }
2831 
2832 /* Per the spec, RMCP and RMCP+ have different allowed sequence number
2833    ranges, so adjust for this. */
2834 static int
check_session_seq_num(lan_data_t * lan,uint32_t seq,uint32_t * in_seq,uint32_t * map,int gt_allowed,int lt_allowed)2835 check_session_seq_num(lan_data_t *lan, uint32_t seq,
2836 		      uint32_t *in_seq, uint32_t *map,
2837 		      int gt_allowed, int lt_allowed)
2838 {
2839     /* Check the sequence number. */
2840     if ((int) (seq - *in_seq) >= 0 && (int) (seq - *in_seq) <= gt_allowed) {
2841 	/* It's after the current sequence number, but within gt_allowed.
2842 	   We move the sequence number forward. */
2843 	*map <<= seq - *in_seq;
2844 	*map |= 1;
2845 	*in_seq = seq;
2846     } else if ((int) (*in_seq - seq) >= 0 && (int) (*in_seq - seq) <= lt_allowed) {
2847 	/* It's before the current sequence number, but within lt_allowed. */
2848 	uint32_t bit = 1 << (*in_seq - seq);
2849 	if (*map & bit) {
2850 	    /* We've already received the message, so discard it. */
2851 	    add_stat(lan->ipmi, STAT_DUPLICATES, 1);
2852 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2853 		ipmi_log(IPMI_LOG_DEBUG, "%sDropped message duplicate",
2854 			 IPMI_CONN_NAME(lan->ipmi));
2855 	    return EINVAL;
2856 	}
2857 
2858 	*map |= bit;
2859     } else {
2860 	/* It's outside the current sequence number range, discard
2861 	   the packet. */
2862 	add_stat(lan->ipmi, STAT_SEQ_OUT_OF_RANGE, 1);
2863 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2864 	    ipmi_log(IPMI_LOG_DEBUG, "%sDropped message out of seq range",
2865 		     IPMI_CONN_NAME(lan->ipmi));
2866 	return EINVAL;
2867     }
2868 
2869     return 0;
2870 }
2871 
2872 static int
check_15_session_seq_num(lan_data_t * lan,uint32_t seq,uint32_t * in_seq,uint32_t * map)2873 check_15_session_seq_num(lan_data_t *lan, uint32_t seq,
2874 			 uint32_t *in_seq, uint32_t *map)
2875 {
2876     return check_session_seq_num(lan, seq, in_seq, map, 8, 8);
2877 }
2878 
2879 static int
check_20_session_seq_num(lan_data_t * lan,uint32_t seq,uint32_t * in_seq,uint32_t * map)2880 check_20_session_seq_num(lan_data_t *lan, uint32_t seq,
2881 			 uint32_t *in_seq, uint32_t *map)
2882 {
2883     return check_session_seq_num(lan, seq, in_seq, map, 15, 16);
2884 }
2885 
2886 static void
handle_payload(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,int payload_type,unsigned char * tmsg,unsigned int payload_len)2887 handle_payload(ipmi_con_t    *ipmi,
2888 	       lan_data_t    *lan,
2889 	       int           addr_num,
2890 	       int           payload_type,
2891 	       unsigned char *tmsg,
2892 	       unsigned int  payload_len)
2893 {
2894     ipmi_ll_rsp_handler_t handler;
2895     ipmi_msgi_t           *rspi;
2896     unsigned char         seq;
2897     int                   rv;
2898     int                   (*handle_send_rsp)(ipmi_con_t *con, ipmi_msg_t *msg);
2899 
2900     handle_send_rsp = NULL;
2901 
2902     if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_RESPONSE) {
2903 	if (payload_len < 1) {
2904 	    add_stat(ipmi, STAT_TOO_SHORT, 1);
2905 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2906 		ipmi_log(IPMI_LOG_DEBUG, "%sPayload length to short",
2907 			 IPMI_CONN_NAME(ipmi));
2908 	    goto out;
2909 	}
2910 
2911 	/* We use the message tag field to store the sequence #. */
2912 	seq = tmsg[0] & 0x3f;
2913     } else if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
2914 #if 0
2915 	/* FIXME - add handling of OEM payloads. */
2916 	handle_oem_payload(ipmi, lan, oem_iana, oem_payload_id,
2917 			   tmsg, payload_len);
2918 #else
2919 	goto out;
2920 #endif
2921     } else if (! payloads[payload_type]) {
2922 	add_stat(ipmi, STAT_INVALID_PAYLOAD, 1);
2923 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2924 	    ipmi_log(IPMI_LOG_DEBUG, "%sUnhandled payload: 0x%x",
2925 		     IPMI_CONN_NAME(ipmi), payload_type);
2926 	goto out;
2927     } else {
2928 	rv = payloads[payload_type]->get_recv_seq(ipmi, tmsg,
2929 						  payload_len, &seq);
2930 	if (rv == ENOSYS) {
2931 	    payloads[payload_type]->handle_recv_async(ipmi, tmsg, payload_len);
2932 	    goto out;
2933 	} else if (rv) {
2934 	    add_stat(ipmi, STAT_SEQ_ERR, 1);
2935 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2936 		ipmi_log(IPMI_LOG_DEBUG, "%sError getting sequence: 0x%x",
2937 			 IPMI_CONN_NAME(ipmi), rv);
2938 	    goto out;
2939 	}
2940     }
2941 
2942     ipmi_lock(lan->seq_num_lock);
2943     if (! lan->seq_table[seq].inuse) {
2944 	add_stat(ipmi, STAT_RSP_NO_CMD, 1);
2945 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
2946 	    ipmi_log(IPMI_LOG_DEBUG,
2947 		     "%sDropped message seq not in use: 0x%x",
2948 		     IPMI_CONN_NAME(ipmi), seq);
2949 	goto out_unlock;
2950     }
2951 
2952     rv = payloads[payload_type]->handle_recv_rsp
2953 	(ipmi,
2954 	 lan->seq_table[seq].rsp_item,
2955 	 &lan->seq_table[seq].addr,
2956 	 lan->seq_table[seq].addr_len,
2957 	 &lan->seq_table[seq].msg,
2958 	 tmsg,
2959 	 payload_len);
2960     if (rv) {
2961 	if (rv == -1)
2962 	    handle_send_rsp = ipmi->handle_send_rsp_err;
2963 	else
2964 	    goto out_unlock;
2965     }
2966 
2967     /* We got a response from the connection, so reset the failure
2968        count. */
2969     lan->ip[addr_num].consecutive_failures = 0;
2970 
2971     /* The command matches up, cancel the timer and deliver it */
2972     rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
2973 				  lan->seq_table[seq].timer);
2974     if (rv)
2975 	/* Couldn't cancel the timer, make sure the timer
2976 	   doesn't do the callback. */
2977 	lan->seq_table[seq].timer_info->cancelled = 1;
2978     else {
2979 	/* Timer is cancelled, free its data. */
2980 	ipmi->os_hnd->free_timer(ipmi->os_hnd,
2981 				 lan->seq_table[seq].timer);
2982 	ipmi_mem_free(lan->seq_table[seq].timer_info);
2983     }
2984 
2985     handler = lan->seq_table[seq].rsp_handler;
2986     rspi = lan->seq_table[seq].rsp_item;
2987     lan->seq_table[seq].inuse = 0;
2988 
2989     if (lan->seq_table[seq].use_orig_addr) {
2990 	/* We did an address translation, so translate back. */
2991 	memcpy(&rspi->addr, &lan->seq_table[seq].orig_addr,
2992 	       lan->seq_table[seq].orig_addr_len);
2993 	rspi->addr_len = lan->seq_table[seq].orig_addr_len;
2994     }
2995 
2996     check_command_queue(ipmi, lan);
2997     ipmi_unlock(lan->seq_num_lock);
2998 
2999     if (handle_send_rsp)
3000 	handle_send_rsp(ipmi, &rspi->msg);
3001 
3002     ipmi_handle_rsp_item(ipmi, rspi, handler);
3003 
3004  out:
3005     return;
3006 
3007  out_unlock:
3008     ipmi_unlock(lan->seq_num_lock);
3009 }
3010 
3011 static void
handle_rmcpp_recv(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,unsigned char * data,unsigned int len)3012 handle_rmcpp_recv(ipmi_con_t    *ipmi,
3013 		  lan_data_t    *lan,
3014 		  int           addr_num,
3015 		  unsigned char *data,
3016 		  unsigned int  len)
3017 {
3018     unsigned char oem_iana[3] = { 0, 0, 0 };
3019 #if 0
3020     /* FIXME - add handling of OEM payloads. */
3021     unsigned int  oem_payload_id = 0;
3022 #endif
3023     unsigned char *tmsg;
3024     int           encrypted;
3025     int           authenticated;
3026     unsigned int  payload_type;
3027     uint32_t      session_id;
3028     uint32_t      session_seq;
3029     int           rv;
3030     unsigned int  payload_len;
3031     unsigned int  header_len;
3032 
3033     if (len < 16) { /* Minimum size of an RMCP+ msg. */
3034 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3035 	    ipmi_log(IPMI_LOG_DEBUG,
3036 		     "%sDropped message because too small(5)",
3037 		     IPMI_CONN_NAME(ipmi));
3038 	goto out;
3039     }
3040 
3041     encrypted = data[5] & 0x80;
3042     authenticated = data[5] & 0x40;
3043     payload_type = data[5] & 0x3f;
3044 
3045     tmsg = data+6;
3046     if (payload_type == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
3047 	if (len < 22) { /* Minimum size of an RMCP+ type 2 msg. */
3048 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3049 		ipmi_log(IPMI_LOG_DEBUG,
3050 			 "%sDropped message because too small(6)",
3051 			 IPMI_CONN_NAME(ipmi));
3052 	    goto out;
3053 	}
3054 	memcpy(oem_iana, tmsg, 3);
3055 	tmsg += 4;
3056 #if 0
3057 	/* FIXME - add handling of OEM payloads. */
3058 	oem_payload_id = ipmi_get_uint16(tmsg);
3059 #endif
3060 	tmsg += 2;
3061     }
3062 
3063     session_id = ipmi_get_uint32(tmsg);
3064     tmsg += 4;
3065     if (session_id != lan->ip[addr_num].session_id) {
3066 	add_stat(ipmi, STAT_BAD_SESSION_ID, 1);
3067 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3068 	    ipmi_log(IPMI_LOG_DEBUG,
3069 		     "%sDropped message not valid session id (2)",
3070 		     IPMI_CONN_NAME(ipmi));
3071 	goto out;
3072     }
3073 
3074     session_seq = ipmi_get_uint32(tmsg);
3075     tmsg += 4;
3076 
3077     payload_len = ipmi_get_uint16(tmsg);
3078     tmsg += 2;
3079 
3080     header_len = tmsg - data;
3081     if ((header_len + payload_len) > len) {
3082 	add_stat(ipmi, STAT_BAD_SIZE, 1);
3083 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3084 	    ipmi_log(IPMI_LOG_DEBUG,
3085 		     "%sDropped message payload length doesn't match up",
3086 		     IPMI_CONN_NAME(ipmi));
3087 	goto out;
3088     }
3089 
3090     /* Authenticate the message before we do anything else. */
3091     if (authenticated) {
3092 	unsigned int  pad_len;
3093 	unsigned int  integ_len;
3094 
3095 	if (lan->ip[addr_num].working_integ
3096 	    == IPMI_LANP_INTEGRITY_ALGORITHM_NONE)
3097 	{
3098 	    add_stat(ipmi, STAT_INVALID_AUTH, 1);
3099 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3100 		ipmi_log(IPMI_LOG_DEBUG,
3101 			 "%sGot authenticated msg but authentication"
3102 			 " not available", IPMI_CONN_NAME(ipmi));
3103 	    goto out;
3104 	}
3105 
3106 	/* Increase the length to include the padding; this eases the
3107 	   handling for the payload integrity check. */
3108 	integ_len = header_len + payload_len;
3109 	while ((integ_len < len) && (data[integ_len] == 0xff))
3110 	    integ_len++;
3111 	if (integ_len < len)
3112 	    integ_len++;
3113 
3114 	rv = lan->ip[addr_num].integ_info->integ_check
3115 	    (ipmi,
3116 	     lan->ip[addr_num].integ_data,
3117 	     data,
3118 	     integ_len,
3119 	     len);
3120 	if (rv) {
3121 	    add_stat(ipmi, STAT_AUTH_FAIL, 1);
3122 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3123 		ipmi_log(IPMI_LOG_DEBUG, "%sIntegrity failed",
3124 			 IPMI_CONN_NAME(ipmi));
3125 	    goto out;
3126 	}
3127 
3128 	/* Remove the integrity padding. */
3129 	pad_len = data[integ_len-1] + 1;
3130 	if ((integ_len - header_len - pad_len) != payload_len) {
3131 	    add_stat(ipmi, STAT_BAD_SIZE, 1);
3132 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3133 		ipmi_log(IPMI_LOG_DEBUG, "%sPadding size not valid: %d",
3134 			 IPMI_CONN_NAME(ipmi), pad_len);
3135 	    goto out;
3136 	}
3137     }
3138 
3139     /* The packet is good, we can trust the data in it now. */
3140 
3141     /* If it's from a down connection, report it as up. */
3142     ipmi_lock(lan->ip_lock);
3143     if (! lan->ip[addr_num].working) {
3144 	ipmi_unlock(lan->ip_lock);
3145 	connection_up(lan, addr_num, 0);
3146 	ipmi_lock(lan->ip_lock);
3147     }
3148 
3149     if (authenticated)
3150 	rv = check_20_session_seq_num(lan, session_seq,
3151 				      &(lan->ip[addr_num].inbound_seq_num),
3152 				      &(lan->ip[addr_num].recv_msg_map));
3153     else if (session_id == 0)
3154 	rv = 0; /* seq num not used for out-of-session messages. */
3155     else
3156 	rv = check_20_session_seq_num(lan, session_seq,
3157 				      &(lan->ip[addr_num].unauth_in_seq_num),
3158 				      &(lan->ip[addr_num].unauth_recv_msg_map));
3159     ipmi_unlock(lan->ip_lock);
3160     if (rv) {
3161 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3162 	    ipmi_log(IPMI_LOG_DEBUG, "%sInvalid sequence number",
3163 		     IPMI_CONN_NAME(ipmi));
3164 	add_stat(ipmi, STAT_SEQ_OUT_OF_RANGE, 1);
3165 	goto out;
3166     }
3167 
3168     /* Message is in sequence, so it's good to deliver after we
3169        decrypt it. */
3170 
3171     if (encrypted) {
3172 	if (lan->ip[addr_num].working_conf
3173 	    == IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE)
3174 	{
3175 	    add_stat(ipmi, STAT_INVALID_AUTH, 1);
3176 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3177 		ipmi_log(IPMI_LOG_DEBUG,
3178 			 "%sGot encrypted msg but encryption not available",
3179 			 IPMI_CONN_NAME(ipmi));
3180 	    goto out;
3181 	}
3182 
3183 	rv = lan->ip[addr_num].conf_info->conf_decrypt
3184 	    (ipmi, lan->ip[addr_num].conf_data, &tmsg, &payload_len);
3185 	if (rv) {
3186 	    add_stat(ipmi, STAT_DECRYPT_FAIL, 1);
3187 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3188 		ipmi_log(IPMI_LOG_DEBUG, "%sDecryption failed",
3189 			 IPMI_CONN_NAME(ipmi));
3190 	    goto out;
3191 	}
3192     }
3193 
3194     handle_payload(ipmi, lan, addr_num, payload_type, tmsg, payload_len);
3195 
3196  out:
3197     return;
3198 }
3199 
3200 static void
handle_lan15_recv(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,unsigned char * data,unsigned int len)3201 handle_lan15_recv(ipmi_con_t    *ipmi,
3202 		  lan_data_t    *lan,
3203 		  int           addr_num,
3204 		  unsigned char *data,
3205 		  unsigned int  len)
3206 {
3207     uint32_t      seq, sess_id;
3208     unsigned char *tmsg = NULL;
3209     unsigned int  data_len;
3210     int           rv;
3211 
3212     if ((data[4] & 0x0f) == IPMI_AUTHTYPE_NONE) {
3213 	if (len < 14) { /* Minimum size of an IPMI msg. */
3214 	    add_stat(ipmi, STAT_TOO_SHORT, 1);
3215 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3216 		ipmi_log(IPMI_LOG_DEBUG,
3217 			 "%sDropped message because too small(1)",
3218 			 IPMI_CONN_NAME(ipmi));
3219 	    goto out;
3220 	}
3221 
3222 	/* No authentication. */
3223 	if (len < (unsigned int) (data[13] + 14)) {
3224 	    /* Not enough data was supplied, reject the message. */
3225 	    add_stat(ipmi, STAT_TOO_SHORT, 1);
3226 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3227 		ipmi_log(IPMI_LOG_DEBUG,
3228 			 "%sDropped message because too small(2)",
3229 			 IPMI_CONN_NAME(ipmi));
3230 	    goto out;
3231 	}
3232 	data_len = data[13];
3233     } else {
3234 	if (len < 30) { /* Minimum size of an authenticated IPMI msg. */
3235 	    add_stat(ipmi, STAT_TOO_SHORT, 1);
3236 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3237 		ipmi_log(IPMI_LOG_DEBUG,
3238 			 "%sDropped message because too small(3)",
3239 			 IPMI_CONN_NAME(ipmi));
3240 	    goto out;
3241 	}
3242 	/* authcode in message, add 16 to the above checks. */
3243 	if (len < (unsigned int) (data[29] + 30)) {
3244 	    add_stat(ipmi, STAT_TOO_SHORT, 1);
3245 	    /* Not enough data was supplied, reject the message. */
3246 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3247 		ipmi_log(IPMI_LOG_DEBUG,
3248 			 "%sDropped message because too small(4)",
3249 			 IPMI_CONN_NAME(ipmi));
3250 	    goto out;
3251 	}
3252 	data_len = data[29];
3253     }
3254 
3255     /* FIXME - need a lock on the session data. */
3256 
3257     /* Drop if the authtypes are incompatible. */
3258     if (lan->ip[addr_num].working_authtype != (data[4] & 0x0f)) {
3259 	add_stat(ipmi, STAT_INVALID_AUTH, 1);
3260 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3261 	    ipmi_log(IPMI_LOG_DEBUG, "%sDropped message not valid authtype,"
3262 		     " expected %d, got %d",
3263 		     IPMI_CONN_NAME(ipmi),
3264 		     lan->ip[addr_num].working_authtype,
3265 		     data[4] & 0x0f);
3266 	goto out;
3267     }
3268 
3269     /* Drop if sessions ID's don't match. */
3270     sess_id = ipmi_get_uint32(data+9);
3271     if (sess_id != lan->ip[addr_num].session_id) {
3272 	add_stat(ipmi, STAT_BAD_SESSION_ID, 1);
3273 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3274 	    ipmi_log(IPMI_LOG_DEBUG,
3275 		     "%sDropped message not valid session id",
3276 		     IPMI_CONN_NAME(ipmi));
3277 	goto out;
3278     }
3279 
3280     seq = ipmi_get_uint32(data+5);
3281 
3282     if ((data[4] & 0x0f) != 0) {
3283 	/* Validate the message's authcode.  Do this before checking
3284            the session seq num so we know the data is valid. */
3285 	rv = auth_check(lan, data+9, data+5, data+30, data[29], data+13,
3286 			addr_num);
3287 	if (rv) {
3288 	    add_stat(ipmi, STAT_AUTH_FAIL, 1);
3289 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3290 		ipmi_log(IPMI_LOG_DEBUG, "%sDropped message auth fail",
3291 			 IPMI_CONN_NAME(ipmi));
3292 	    goto out;
3293 	}
3294 	tmsg = data + 30;
3295     } else {
3296 	tmsg = data + 14;
3297     }
3298 
3299     /* If it's from a down connection, report it as up. */
3300     ipmi_lock(lan->ip_lock);
3301     if (! lan->ip[addr_num].working) {
3302 	ipmi_unlock(lan->ip_lock);
3303 	connection_up(lan, addr_num, 0);
3304 	ipmi_lock(lan->ip_lock);
3305     }
3306 
3307     rv = check_15_session_seq_num(lan, seq,
3308 				  &(lan->ip[addr_num].inbound_seq_num),
3309 				  &(lan->ip[addr_num].recv_msg_map));
3310     ipmi_unlock(lan->ip_lock);
3311     if (rv)
3312 	goto out;
3313 
3314     /*
3315      * Special case for Serial-over-LAN IPMI 1.5 packets, which use the
3316      * "reserved" nybble to identify the SoL payload.
3317      */
3318     if ((data[4] & 0xf0) == 0x80)
3319 	    handle_payload(ipmi, lan, addr_num,
3320 			   IPMI_RMCPP_PAYLOAD_TYPE_SOL, tmsg, data_len);
3321     else
3322 	    handle_payload(ipmi, lan, addr_num,
3323 			   IPMI_RMCPP_PAYLOAD_TYPE_IPMI, tmsg, data_len);
3324 
3325  out:
3326     return;
3327 }
3328 
3329 static int
addr_match_lan(lan_data_t * lan,uint32_t sid,sockaddr_ip_t * addr,int * raddr_num)3330 addr_match_lan(lan_data_t *lan, uint32_t sid, sockaddr_ip_t *addr,
3331 	       int *raddr_num)
3332 {
3333     unsigned int addr_num;
3334 
3335     /* Make sure the source address matches one we expect from
3336        this system. */
3337     for (addr_num = 0; addr_num < lan->cparm.num_ip_addr; addr_num++) {
3338 	if ((!sid || (lan->ip[addr_num].session_id == sid))
3339 	    && lan_addr_same(&(lan->cparm.ip_addr[addr_num]), addr))
3340 	{
3341 	    *raddr_num = addr_num;
3342 	    return 1;
3343 	}
3344     }
3345     return 0;
3346 }
3347 
3348 static ipmi_con_t *
rmcpp_find_ipmi(lan_fd_t * item,unsigned char * data,unsigned int len,sockaddr_ip_t * addr,int * addr_num)3349 rmcpp_find_ipmi(lan_fd_t      *item,
3350 		unsigned char *data,
3351 		unsigned int  len,
3352 		sockaddr_ip_t *addr,
3353 		int           *addr_num)
3354 {
3355     /* This is easy, the session id is our slot in the fd or is a
3356        message tag. */
3357     unsigned char payload;
3358     uint32_t      tag;
3359     uint32_t      sid;
3360     unsigned char ctag;
3361     unsigned int  mlen;
3362     unsigned char *d;
3363     ipmi_con_t    *ipmi = NULL;
3364     lan_data_t    *lan;
3365 
3366     /* We need to find the sessions id; it's position depends on
3367        the payload type. */
3368     if (len < 16) {
3369 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3370 	    ipmi_log(IPMI_LOG_DEBUG, "Message too short(2): %d", len);
3371 	return NULL;
3372     }
3373     payload = data[5] & 0x3f;
3374     if (payload == IPMI_RMCPP_PAYLOAD_TYPE_OEM_EXPLICIT) {
3375 	if (len < 22) {
3376 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3377 		ipmi_log(IPMI_LOG_DEBUG, "Message too short(3): %d", len);
3378 	    return NULL;
3379 	}
3380 	d = data+12;
3381     } else {
3382 	d = data+6;
3383     }
3384 
3385     mlen = ipmi_get_uint16(d+8);
3386     if ((mlen + 10 + (d-data)) > len) {
3387 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3388 	    ipmi_log(IPMI_LOG_DEBUG,
3389 		     "Dropped message payload length doesn't match up");
3390 	return NULL;
3391     }
3392 
3393     sid = ipmi_get_uint32(d);
3394     if ((sid == 0) && payloads[payload]->get_msg_tag) {
3395 	int rv = payloads[payload]->get_msg_tag(d+10, mlen, &ctag);
3396 	if (rv) {
3397 	    if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3398 		ipmi_log(IPMI_LOG_DEBUG, "Error getting message tag: %d", rv);
3399 	    return NULL;
3400 	}
3401 	tag = ctag;
3402     } else
3403 	tag = sid - 1;
3404 
3405     if (tag >= MAX_CONS_PER_FD) {
3406 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3407 	    ipmi_log(IPMI_LOG_DEBUG, "tag is out of range: %d", tag);
3408 	return NULL;
3409     }
3410 
3411     ipmi_lock(item->con_lock);
3412     lan = item->lan[tag];
3413     if (lan && addr_match_lan(lan, sid, addr, addr_num))
3414 	ipmi = lan->ipmi;
3415     else if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3416 	ipmi_log(IPMI_LOG_DEBUG, "tag doesn't match: %d", tag);
3417     ipmi_unlock(item->con_lock);
3418 
3419     return ipmi;
3420 }
3421 
3422 static ipmi_con_t *
rmcp_find_ipmi(lan_fd_t * item,unsigned char * data,unsigned int len,sockaddr_ip_t * addr,int * addr_num)3423 rmcp_find_ipmi(lan_fd_t      *item,
3424 	       unsigned char *data,
3425 	       unsigned int  len,
3426 	       sockaddr_ip_t *addr,
3427 	       int           *addr_num)
3428 {
3429     /* Old RMCP is harder, we have to hunt. */
3430     uint32_t   sid;
3431     lan_data_t *lan;
3432     int        i;
3433     ipmi_con_t *ipmi = NULL;
3434 
3435     if (len < 13) {
3436 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3437 	    ipmi_log(IPMI_LOG_DEBUG, "Message too short(4): %d", len);
3438 	return NULL;
3439     }
3440 
3441     sid = ipmi_get_uint32(data+9);
3442     ipmi_lock(item->con_lock);
3443     for (i=0; i<MAX_CONS_PER_FD; i++) {
3444 	lan = item->lan[i];
3445 	if (lan && addr_match_lan(lan, sid, addr, addr_num)) {
3446 	    ipmi = lan->ipmi;
3447 	    break;
3448 	}
3449     }
3450     ipmi_unlock(item->con_lock);
3451 
3452     return ipmi;
3453 }
3454 
3455 static void
data_handler(int fd,void * cb_data,os_hnd_fd_id_t * id)3456 data_handler(int            fd,
3457 	     void           *cb_data,
3458 	     os_hnd_fd_id_t *id)
3459 {
3460     lan_fd_t           *item = cb_data;
3461     ipmi_con_t         *ipmi;
3462     lan_data_t         *lan;
3463     unsigned char      data[IPMI_MAX_LAN_LEN];
3464     sockaddr_ip_t      ipaddrd;
3465     socklen_t          from_len;
3466     int                len;
3467     int                addr_num = 0; /* Keep gcc happy and initialize */
3468 
3469     from_len = sizeof(ipaddrd.s_ipsock);
3470     len = recvfrom(fd, data, sizeof(data), 0, (struct sockaddr *)&ipaddrd,
3471 		   &from_len);
3472 
3473     if (len < 0)
3474 	/* Got an error, probably no data, just return. */
3475 	return;
3476 
3477     ipaddrd.ip_addr_len = from_len;
3478     if (DEBUG_RAWMSG) {
3479 	ipmi_log(IPMI_LOG_DEBUG_START, "incoming\n addr = ");
3480 	dump_hex((unsigned char *) &ipaddrd, from_len);
3481 	if (len) {
3482 	    ipmi_log(IPMI_LOG_DEBUG_CONT, "\n data =\n  ");
3483 	    dump_hex(data, len);
3484 	}
3485 	ipmi_log(IPMI_LOG_DEBUG_END, " ");
3486     }
3487 
3488     if (len < 5) {
3489 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3490 	    ipmi_log(IPMI_LOG_DEBUG, "Message too short(1): %d", len);
3491 	return;
3492     }
3493 
3494     /* Validate the RMCP portion of the message. */
3495     if ((data[0] != 6)
3496 	|| (data[2] != 0xff)
3497 	|| (data[3] != 0x07))
3498     {
3499 	if (DEBUG_RAWMSG || DEBUG_MSG_ERR)
3500 	    ipmi_log(IPMI_LOG_DEBUG, "Dropped message not valid IPMI/RMCP");
3501 	return;
3502     }
3503 
3504     if ((data[4] & 0x0f) == IPMI_AUTHTYPE_RMCP_PLUS) {
3505 	ipmi = rmcpp_find_ipmi(item, data, len, &ipaddrd, &addr_num);
3506     } else {
3507 	ipmi = rmcp_find_ipmi(item, data, len, &ipaddrd, &addr_num);
3508     }
3509 
3510     if (!lan_valid_ipmi(ipmi))
3511 	/* This can fail due to a race condition, just return and
3512            everything should be fine. */
3513 	return;
3514 
3515     lan = ipmi->con_data;
3516 
3517     add_stat(ipmi, STAT_RECV_PACKETS, 1);
3518 
3519     if ((data[4] & 0x0f) == IPMI_AUTHTYPE_RMCP_PLUS) {
3520 	handle_rmcpp_recv(ipmi, lan, addr_num, data, len);
3521     } else {
3522 	handle_lan15_recv(ipmi, lan, addr_num, data, len);
3523     }
3524 
3525     lan_put(ipmi);
3526     return;
3527 }
3528 
3529 /* Note that this puts the address number in data4 of the rspi. */
3530 int
ipmi_lan_send_command_forceip(ipmi_con_t * ipmi,int addr_num,ipmi_addr_t * addr,unsigned int addr_len,ipmi_msg_t * msg,ipmi_ll_rsp_handler_t rsp_handler,ipmi_msgi_t * rspi)3531 ipmi_lan_send_command_forceip(ipmi_con_t            *ipmi,
3532 			      int                   addr_num,
3533 			      ipmi_addr_t           *addr,
3534 			      unsigned int          addr_len,
3535 			      ipmi_msg_t            *msg,
3536 			      ipmi_ll_rsp_handler_t rsp_handler,
3537 			      ipmi_msgi_t           *rspi)
3538 {
3539     lan_timer_info_t *info;
3540     lan_data_t       *lan;
3541     int              rv;
3542     /* We store the address number in data4. */
3543 
3544     if (addr_num >= MAX_IP_ADDR)
3545 	return EINVAL;
3546 
3547     if (addr_len > sizeof(ipmi_addr_t))
3548 	return EINVAL;
3549 
3550     if (msg->data_len > IPMI_MAX_MSG_LENGTH)
3551 	return EINVAL;
3552 
3553     lan = (lan_data_t *) ipmi->con_data;
3554 
3555     if (lan->in_cleanup)
3556 	return ECANCELED;
3557 
3558     /* Odd netfns are responses or unacknowledged data.  Just send
3559        them. */
3560     if (msg->netfn & 1)
3561 	return lan_send_addr(lan, addr, addr_len, msg, 0, addr_num, NULL);
3562 
3563     info = ipmi_mem_alloc(sizeof(*info));
3564     if (!info)
3565 	return ENOMEM;
3566     memset(info, 0, sizeof(*info));
3567 
3568     /* Put it in the list first. */
3569     info->ipmi = ipmi;
3570     info->cancelled = 0;
3571 
3572     rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(info->timer));
3573     if (rv) {
3574 	ipmi_mem_free(info);
3575 	return rv;
3576     }
3577 
3578     ipmi_lock(lan->seq_num_lock);
3579 
3580     if (lan->outstanding_msg_count >= 60) {
3581 	rv = EAGAIN;
3582 	goto out_unlock;
3583     }
3584 
3585     rspi->data4 = (void *) (long) addr_num;
3586     rv = handle_msg_send(info, addr_num, addr, addr_len, msg,
3587 			 rsp_handler, rspi, 0);
3588     /* handle_msg_send handles freeing the timer and info on an error */
3589     info = NULL;
3590     if (! rv)
3591 	lan->outstanding_msg_count++;
3592     ipmi_unlock(lan->seq_num_lock);
3593     return rv;
3594 
3595  out_unlock:
3596     ipmi_unlock(lan->seq_num_lock);
3597     if (rv) {
3598 	if (info) {
3599 	    if (info->timer)
3600 		ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
3601 	    ipmi_mem_free(info);
3602 	}
3603     }
3604     return rv;
3605 }
3606 
3607 static int
lan_send_command_option(ipmi_con_t * ipmi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg,const ipmi_con_option_t * options,ipmi_ll_rsp_handler_t rsp_handler,ipmi_msgi_t * trspi)3608 lan_send_command_option(ipmi_con_t              *ipmi,
3609 			const ipmi_addr_t       *addr,
3610 			unsigned int            addr_len,
3611 			const ipmi_msg_t        *msg,
3612 			const ipmi_con_option_t *options,
3613 			ipmi_ll_rsp_handler_t   rsp_handler,
3614 			ipmi_msgi_t             *trspi)
3615 {
3616     lan_timer_info_t *info;
3617     lan_data_t       *lan;
3618     int              rv;
3619     ipmi_msgi_t      *rspi = trspi;
3620     int              side_effects = 0;
3621     int              i;
3622 
3623 
3624     if (addr_len > sizeof(ipmi_addr_t))
3625 	return EINVAL;
3626 
3627     if (msg->data_len > IPMI_MAX_MSG_LENGTH)
3628 	return EINVAL;
3629 
3630     lan = (lan_data_t *) ipmi->con_data;
3631 
3632     /* Odd netfns are responses or unacknowledged data.  Just send
3633        them. */
3634     if (msg->netfn & 1) {
3635 	int dummy_send_ip;
3636 	return lan_send(lan, addr, addr_len, msg, 0, &dummy_send_ip, options);
3637     }
3638 
3639     if (options) {
3640 	for (i=0; options[i].option != IPMI_CON_OPTION_LIST_END; i++) {
3641 	    if (options[i].option == IPMI_CON_MSG_OPTION_SIDE_EFFECTS)
3642 		side_effects = options[i].ival;
3643 	}
3644     }
3645 
3646     if (!rspi) {
3647 	rspi = ipmi_mem_alloc(sizeof(*rspi));
3648 	if (!rspi)
3649 	    return ENOMEM;
3650     }
3651 
3652     info = ipmi_mem_alloc(sizeof(*info));
3653     if (!info) {
3654 	rv = ENOMEM;
3655 	goto out_unlock2;
3656     }
3657     memset(info, 0, sizeof(*info));
3658 
3659     /* Put it in the list first. */
3660     info->ipmi = ipmi;
3661     info->cancelled = 0;
3662 
3663     rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(info->timer));
3664     if (rv)
3665 	goto out_unlock;
3666 
3667     ipmi_lock(lan->seq_num_lock);
3668 
3669     if (lan->outstanding_msg_count >= lan->max_outstanding_msg_count) {
3670 	lan_wait_queue_t *q_item;
3671 
3672 	q_item = ipmi_mem_alloc(sizeof(*q_item));
3673 	if (!q_item) {
3674 	    ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
3675 	    rv = ENOMEM;
3676 	    goto out_unlock;
3677 	}
3678 
3679 	q_item->info = info;
3680 	memcpy(&(q_item->addr), addr, addr_len);
3681 	q_item->addr_len = addr_len;
3682 	memcpy(&q_item->msg, msg, sizeof(q_item->msg));
3683 	q_item->msg.data = q_item->data;
3684 	memcpy(q_item->data, msg->data, msg->data_len);
3685 	q_item->rsp_handler = rsp_handler;
3686 	q_item->rsp_item = rspi;
3687 	q_item->side_effects = side_effects;
3688 
3689 	/* Add it to the end of the queue. */
3690 	q_item->next = NULL;
3691 	if (lan->wait_q_tail == NULL) {
3692 	    lan->wait_q_tail = q_item;
3693 	    lan->wait_q = q_item;
3694 	} else {
3695 	    lan->wait_q_tail->next = q_item;
3696 	    lan->wait_q_tail = q_item;
3697 	}
3698 	goto out_unlock;
3699     }
3700 
3701     rv = handle_msg_send(info, -1, addr, addr_len, msg,
3702 			 rsp_handler, rspi, side_effects);
3703     /* handle_msg_send handles freeing the timer and info on an error */
3704     info = NULL;
3705     if (!rv)
3706 	lan->outstanding_msg_count++;
3707     else if (!trspi && rspi)
3708 	/* If we allocated an rspi, free it on error. */
3709 	ipmi_mem_free(rspi);
3710     ipmi_unlock(lan->seq_num_lock);
3711     return rv;
3712 
3713  out_unlock:
3714     ipmi_unlock(lan->seq_num_lock);
3715     if (rv) {
3716 	if (info) {
3717 	    if (info->timer)
3718 		ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
3719 	    ipmi_mem_free(info);
3720 	}
3721     }
3722  out_unlock2:
3723     if (rv) {
3724 	/* If we allocated an rspi, free it. */
3725 	if (!trspi && rspi)
3726 	    ipmi_mem_free(rspi);
3727     }
3728     return rv;
3729 }
3730 
3731 static int
lan_send_command(ipmi_con_t * ipmi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg,ipmi_ll_rsp_handler_t rsp_handler,ipmi_msgi_t * trspi)3732 lan_send_command(ipmi_con_t            *ipmi,
3733 		 const ipmi_addr_t     *addr,
3734 		 unsigned int          addr_len,
3735 		 const ipmi_msg_t      *msg,
3736 		 ipmi_ll_rsp_handler_t rsp_handler,
3737 		 ipmi_msgi_t           *trspi)
3738 {
3739     return lan_send_command_option(ipmi, addr, addr_len, msg, NULL,
3740 				   rsp_handler, trspi);
3741 }
3742 
3743 static int
lan_send_response(ipmi_con_t * ipmi,const ipmi_addr_t * addr,unsigned int addr_len,const ipmi_msg_t * msg,long sequence)3744 lan_send_response(ipmi_con_t        *ipmi,
3745 		  const ipmi_addr_t *addr,
3746 		  unsigned int      addr_len,
3747 		  const ipmi_msg_t  *msg,
3748 		  long              sequence)
3749 {
3750     return ENOSYS;
3751 }
3752 
3753 static int
lan_register_for_command(ipmi_con_t * ipmi,unsigned char netfn,unsigned char cmd,ipmi_ll_cmd_handler_t handler,void * cmd_data,void * data2,void * data3)3754 lan_register_for_command(ipmi_con_t            *ipmi,
3755 			 unsigned char         netfn,
3756 			 unsigned char         cmd,
3757 			 ipmi_ll_cmd_handler_t handler,
3758 			 void                  *cmd_data,
3759 			 void                  *data2,
3760 			 void                  *data3)
3761 {
3762     return ENOSYS;
3763 }
3764 
3765 static int
lan_deregister_for_command(ipmi_con_t * ipmi,unsigned char netfn,unsigned char cmd)3766 lan_deregister_for_command(ipmi_con_t    *ipmi,
3767 			   unsigned char netfn,
3768 			   unsigned char cmd)
3769 {
3770     return ENOSYS;
3771 }
3772 
3773 static unsigned int
lan_get_num_ports(ipmi_con_t * ipmi)3774 lan_get_num_ports(ipmi_con_t *ipmi)
3775 {
3776     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
3777 
3778     return lan->cparm.num_ip_addr;
3779 }
3780 
3781 static int
lan_get_port_info(ipmi_con_t * ipmi,unsigned int port,char * info,int * info_len)3782 lan_get_port_info(ipmi_con_t *ipmi, unsigned int port,
3783 		  char *info, int *info_len)
3784 {
3785     lan_data_t    *lan = (lan_data_t *) ipmi->con_data;
3786     sockaddr_ip_t *a;
3787     int           count = 0;
3788     int           len = *info_len;
3789 
3790     if (port > lan->cparm.num_ip_addr)
3791 	return EINVAL;
3792 
3793     a = &(lan->cparm.ip_addr[port]);
3794 
3795     if (lan->ip[port].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS)
3796 	count = snprintf(info, len, "rmcp+: ");
3797     else
3798 	count = snprintf(info, len, "rmcp: ");
3799 
3800     switch (a->s_ipsock.s_addr0.sa_family) {
3801     case PF_INET:
3802 	{
3803 	    struct sockaddr_in *ip = &a->s_ipsock.s_addr4;
3804 	    char buf[INET_ADDRSTRLEN];
3805 
3806 	    inet_ntop(AF_INET, &ip->sin_addr, buf, sizeof(buf));
3807 	    count += snprintf(info+count, len-count, "inet:%s:%d",
3808 			      buf, ntohs(ip->sin_port));
3809 	}
3810 	break;
3811 
3812 #ifdef PF_INET6
3813     case PF_INET6:
3814 	{
3815 	    struct sockaddr_in6 *ip = &a->s_ipsock.s_addr6;
3816 	    char buf[INET6_ADDRSTRLEN];
3817 
3818 	    inet_ntop(AF_INET6, &ip->sin6_addr, buf, sizeof(buf));
3819 	    count += snprintf(info+count, len-count, "inet6:%s:%d",
3820 			      buf, ntohs(ip->sin6_port));
3821 	}
3822 	break;
3823 #endif
3824     default:
3825 	count += snprintf(info+count, len-count, "invalid");
3826 	break;
3827     }
3828 
3829     *info_len = count;
3830     return 0;
3831 }
3832 
3833 static void *
auth_alloc(void * info,int size)3834 auth_alloc(void *info, int size)
3835 {
3836     return ipmi_mem_alloc(size);
3837 }
3838 
3839 static void
auth_free(void * info,void * data)3840 auth_free(void *info, void *data)
3841 {
3842     ipmi_mem_free(data);
3843 }
3844 
3845 /* Send the final close session to shut the connection down. */
3846 static void
send_close_session(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num)3847 send_close_session(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num)
3848 {
3849     ipmi_msg_t                   msg;
3850     unsigned char                data[4];
3851     ipmi_system_interface_addr_t si;
3852 
3853     si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
3854     si.channel = 0xf;
3855     si.lun = 0;
3856     msg.netfn = IPMI_APP_NETFN;
3857     msg.cmd = IPMI_CLOSE_SESSION_CMD;
3858     msg.data_len = 4;
3859     msg.data = data;
3860     if (lan->ip[addr_num].working_authtype == IPMI_AUTHTYPE_RMCP_PLUS)
3861 	ipmi_set_uint32(data, lan->ip[addr_num].mgsys_session_id);
3862     else
3863 	ipmi_set_uint32(data, lan->ip[addr_num].session_id);
3864     lan_send_addr(lan, (ipmi_addr_t *) &si, sizeof(si), &msg, 0, addr_num,
3865 		  NULL);
3866 }
3867 
3868 typedef struct lan_unreg_stat_info_s
3869 {
3870     lan_data_t          *lan;
3871     ipmi_ll_stat_info_t *cmpinfo;
3872     int                 found;
3873 } lan_unreg_stat_info_t;
3874 
3875 static int
lan_unreg_stat_info(void * cb_data,void * item1,void * item2)3876 lan_unreg_stat_info(void *cb_data, void *item1, void *item2)
3877 {
3878     ipmi_ll_stat_info_t   *info = item2;
3879     lan_stat_info_t       *stat = item1;
3880     lan_unreg_stat_info_t *sinfo = cb_data;
3881     int                   i;
3882 
3883     if (!sinfo->cmpinfo || (sinfo->cmpinfo == info)) {
3884 	locked_list_remove(sinfo->lan->lan_stat_list, stat, info);
3885 	for (i=0; i<NUM_STATS; i++)
3886 	    if (stat->stats[i]) {
3887 		ipmi_ll_con_stat_call_unregister(info, stat->stats[i]);
3888 		stat->stats[i] = NULL;
3889 	    }
3890 	ipmi_mem_free(stat);
3891 	sinfo->found = 1;
3892     }
3893     return LOCKED_LIST_ITER_CONTINUE;
3894 }
3895 
3896 static void
cleanup_con(ipmi_con_t * ipmi)3897 cleanup_con(ipmi_con_t *ipmi)
3898 {
3899     lan_data_t   *lan = NULL;
3900     unsigned int i;
3901 
3902     if (ipmi) {
3903 	lan = (lan_data_t *) ipmi->con_data;
3904 	ipmi_con_attr_cleanup(ipmi);
3905 	if (ipmi->name) {
3906 	    ipmi_mem_free(ipmi->name);
3907 	    ipmi->name = NULL;
3908 	}
3909 	ipmi_mem_free(ipmi);
3910     }
3911 
3912     if (lan) {
3913 	/* This is only called in the case of an error at startup, so
3914 	   there is no need to remove it from the LAN lists (hashes),
3915 	   because it won't be there yet. */
3916 
3917 	for (i=0; i<lan->cparm.num_ip_addr; i++) {
3918 	    if (lan->cparm.ip_addr_str[i])
3919 		ipmi_mem_free(lan->cparm.ip_addr_str[i]);
3920 	    if (lan->cparm.ip_port_str[i])
3921 		ipmi_mem_free(lan->cparm.ip_port_str[i]);
3922 	}
3923 
3924 	if (lan->lan_stat_list) {
3925 	    lan_unreg_stat_info_t sinfo;
3926 	    sinfo.lan = lan;
3927 	    sinfo.cmpinfo = NULL;
3928 	    sinfo.found = 0;
3929 	    locked_list_iterate(lan->lan_stat_list, lan_unreg_stat_info,
3930 				&sinfo);
3931 	    locked_list_destroy(lan->lan_stat_list);
3932 	}
3933 	if (lan->con_change_lock)
3934 	    ipmi_destroy_lock(lan->con_change_lock);
3935 	if (lan->ip_lock)
3936 	    ipmi_destroy_lock(lan->ip_lock);
3937 	if (lan->con_change_handlers)
3938 	    locked_list_destroy(lan->con_change_handlers);
3939 	if (lan->event_handlers)
3940 	    locked_list_destroy(lan->event_handlers);
3941 	if (lan->ipmb_change_handlers)
3942 	    locked_list_destroy(lan->ipmb_change_handlers);
3943 	if (lan->seq_num_lock)
3944 	    ipmi_destroy_lock(lan->seq_num_lock);
3945 	if (lan->fd)
3946 	    release_lan_fd(lan->fd, lan->fd_slot);
3947 	if (lan->authdata)
3948 	    ipmi_auths[lan->chosen_authtype].authcode_cleanup(lan->authdata);
3949 	for (i=0; i<MAX_IP_ADDR; i++) {
3950 	    if (lan->ip[i].conf_data)
3951 		lan->ip[i].conf_info->conf_free(ipmi, lan->ip[i].conf_data);
3952 	    if (lan->ip[i].integ_data)
3953 		lan->ip[i].integ_info->integ_free(ipmi, lan->ip[i].integ_data);
3954 	}
3955 	/* paranoia */
3956 	memset(lan->cparm.password, 0, sizeof(lan->cparm.password));
3957 	memset(lan->cparm.bmc_key, 0, sizeof(lan->cparm.bmc_key));
3958 	ipmi_mem_free(lan);
3959     }
3960 }
3961 
3962 static void
lan_cleanup(ipmi_con_t * ipmi)3963 lan_cleanup(ipmi_con_t *ipmi)
3964 {
3965     lan_data_t   *lan = ipmi->con_data;
3966     int          rv;
3967     unsigned int i;
3968 
3969     /* After this point no other operations can occur on this ipmi
3970        interface, so it's safe. */
3971 
3972     if (!lan->disabled) {
3973 	for (i=0; i<lan->cparm.num_ip_addr; i++)
3974 	    send_close_session(ipmi, lan, i);
3975     }
3976 
3977     lan->in_cleanup = 1;
3978 
3979     ipmi_lock(lan->seq_num_lock);
3980     for (i=0; i<64; i++) {
3981 	if (lan->seq_table[i].inuse) {
3982 	    ipmi_ll_rsp_handler_t handler;
3983 	    ipmi_msgi_t           *rspi;
3984 	    lan_timer_info_t      *info;
3985 
3986 	    rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd,
3987 					  lan->seq_table[i].timer);
3988 
3989 	    rspi = lan->seq_table[i].rsp_item;
3990 
3991 	    if (lan->seq_table[i].use_orig_addr) {
3992 		/* We did an address translation, so translate back. */
3993 		memcpy(&rspi->addr, &lan->seq_table[i].orig_addr,
3994 		       lan->seq_table[i].orig_addr_len);
3995 		rspi->addr_len = lan->seq_table[i].orig_addr_len;
3996 	    } else {
3997 		memcpy(&rspi->addr, &(lan->seq_table[i].addr),
3998 		       lan->seq_table[i].addr_len);
3999 		rspi->addr_len = lan->seq_table[i].addr_len;
4000 	    }
4001 	    handler = lan->seq_table[i].rsp_handler;
4002 	    info = lan->seq_table[i].timer_info;
4003 
4004 	    rspi->msg.netfn = lan->seq_table[i].msg.netfn | 1;
4005 	    rspi->msg.cmd = lan->seq_table[i].msg.cmd;
4006 	    rspi->msg.data = rspi->data;
4007 	    rspi->data[0] = IPMI_UNKNOWN_ERR_CC;
4008 	    rspi->msg.data_len = 1;
4009 
4010 	    lan->seq_table[i].inuse = 0;
4011 
4012 	    /* Wait until here to free the info, as we use it above.
4013 	       But we must be holding the lock while we do this. */
4014 	    if (rv)
4015 		info->cancelled = 1;
4016 	    else {
4017 		ipmi->os_hnd->free_timer(ipmi->os_hnd, info->timer);
4018 		ipmi_mem_free(info);
4019 	    }
4020 
4021 	    ipmi_unlock(lan->seq_num_lock);
4022 
4023 	    /* The unlock is safe here because the connection is no
4024                longer valid and thus nothing else can really happen on
4025                this connection.  Sends will fail and receives will not
4026                validate. */
4027 
4028 	    ipmi_handle_rsp_item(NULL, rspi, handler);
4029 
4030 	    ipmi_lock(lan->seq_num_lock);
4031 	}
4032     }
4033     while (lan->wait_q != NULL) {
4034 	lan_wait_queue_t *q_item;
4035 
4036 	q_item = lan->wait_q;
4037 	lan->wait_q = q_item->next;
4038 
4039 	ipmi->os_hnd->free_timer(ipmi->os_hnd, q_item->info->timer);
4040 
4041 	if (!lan->disabled) {
4042 	    ipmi_unlock(lan->seq_num_lock);
4043 
4044 	    q_item->msg.netfn |= 1; /* Convert it to a response. */
4045 	    q_item->msg.data[0] = IPMI_UNKNOWN_ERR_CC;
4046 	    q_item->msg.data_len = 1;
4047 	    ipmi_handle_rsp_item_copyall(ipmi, q_item->rsp_item,
4048 					 &q_item->addr, q_item->addr_len,
4049 					 &q_item->msg, q_item->rsp_handler);
4050 
4051 	    ipmi_lock(lan->seq_num_lock);
4052 	}
4053 
4054 	ipmi_mem_free(q_item->info);
4055 	ipmi_mem_free(q_item);
4056     }
4057     if (lan->audit_info) {
4058 	rv = ipmi->os_hnd->stop_timer(ipmi->os_hnd, lan->audit_timer);
4059 	if (rv)
4060 	    lan->audit_info->cancelled = 1;
4061 	else {
4062 	    ipmi->os_hnd->free_timer(ipmi->os_hnd, lan->audit_timer);
4063 	    ipmi_mem_free(lan->audit_info);
4064 	}
4065     }
4066     ipmi_unlock(lan->seq_num_lock);
4067 
4068     if (lan->close_done)
4069 	lan->close_done(ipmi, lan->close_cb_data);
4070 
4071     if (ipmi->oem_data_cleanup)
4072 	ipmi->oem_data_cleanup(ipmi);
4073 
4074     cleanup_con(ipmi);
4075 }
4076 
4077 static int
lan_close_connection_done(ipmi_con_t * ipmi,ipmi_ll_con_closed_cb handler,void * cb_data)4078 lan_close_connection_done(ipmi_con_t            *ipmi,
4079 			  ipmi_ll_con_closed_cb handler,
4080 			  void                  *cb_data)
4081 {
4082     lan_data_t *lan;
4083 
4084     if (! lan_valid_ipmi(ipmi))
4085 	return EINVAL;
4086 
4087     lan = (lan_data_t *) ipmi->con_data;
4088 
4089     ipmi_lock(lan_list_lock);
4090     if (lan->users > 1) {
4091 	/* The connection has been reused, just report it going
4092 	   down. */
4093 	lan->users--;
4094 	ipmi_unlock(lan_list_lock);
4095 	if (handler)
4096 	    handler(ipmi, cb_data);
4097 	lan_put(ipmi);
4098 	return 0;
4099     }
4100 
4101     /* Once we begin the shutdown process, we don't want anyone else
4102        reusing the connection. */
4103     lan_remove_con_nolock(lan);
4104     ipmi_unlock(lan_list_lock);
4105 
4106     lan->close_done = handler;
4107     lan->close_cb_data = cb_data;
4108 
4109     /* Put it once for the lan_valid_ipmi() call, then once to
4110        actually destroy it. */
4111     lan_put(ipmi);
4112     lan_put(ipmi);
4113     return 0;
4114 }
4115 
4116 static int
lan_close_connection(ipmi_con_t * ipmi)4117 lan_close_connection(ipmi_con_t *ipmi)
4118 {
4119     return lan_close_connection_done(ipmi, NULL, NULL);
4120 }
4121 
4122 static void
handle_connected(ipmi_con_t * ipmi,int err,int addr_num)4123 handle_connected(ipmi_con_t *ipmi, int err, int addr_num)
4124 {
4125     lan_data_t *lan;
4126 
4127     if (!ipmi)
4128 	return;
4129 
4130     lan = (lan_data_t *) ipmi->con_data;
4131 
4132     /* This should be occurring single-threaded (the IP is down and is
4133        being brought back up or is initially coming up), so no need
4134        for a lock here. */
4135 
4136     /* Make sure session data is reset on an error. */
4137     if (err)
4138 	reset_session_data(lan, addr_num);
4139 
4140     ipmi_lock(lan->ip_lock);
4141     ipmi_lock(lan->con_change_lock);
4142     ipmi_unlock(lan->ip_lock);
4143     call_con_change_handlers(lan, err, addr_num, lan->connected);
4144     ipmi_unlock(lan->con_change_lock);
4145 }
4146 
4147 static void
finish_connection(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num)4148 finish_connection(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num)
4149 {
4150     lan->connected = 1;
4151     connection_up(lan, addr_num, 1);
4152     if (! lan->initialized) {
4153 	lan->initialized = 1;
4154 	handle_connected(ipmi, 0, addr_num);
4155     }
4156 }
4157 
4158 static void
lan_set_ipmb_addr(ipmi_con_t * ipmi,const unsigned char ipmb_addr[],unsigned int num_ipmb_addr,int active,unsigned int hacks)4159 lan_set_ipmb_addr(ipmi_con_t    *ipmi,
4160 		  const unsigned char ipmb_addr[],
4161 		  unsigned int  num_ipmb_addr,
4162 		  int           active,
4163 		  unsigned int  hacks)
4164 {
4165     lan_data_t   *lan = (lan_data_t *) ipmi->con_data;
4166     int          changed = 0;
4167     unsigned int i;
4168 
4169     for (i=0; i<num_ipmb_addr && i<MAX_IPMI_USED_CHANNELS; i++) {
4170 	if (! ipmb_addr[i])
4171 	    continue;
4172 	if (lan->slave_addr[i] != ipmb_addr[i]) {
4173 	    lan->slave_addr[i] = ipmb_addr[i];
4174 	    ipmi->ipmb_addr[i] = ipmb_addr[i];
4175 	    changed = 1;
4176 	}
4177     }
4178 
4179     if (changed || (lan->is_active != active))  {
4180 	lan->is_active = active;
4181 	ipmi->hacks = hacks;
4182 	call_ipmb_change_handlers(lan, 0, ipmb_addr, num_ipmb_addr,
4183 				  active, hacks);
4184     }
4185 }
4186 
4187 static void
handle_ipmb_addr(ipmi_con_t * ipmi,int err,const unsigned char ipmb_addr[],unsigned int num_ipmb_addr,int active,unsigned int hacks,void * cb_data)4188 handle_ipmb_addr(ipmi_con_t   *ipmi,
4189 		 int          err,
4190 		 const unsigned char ipmb_addr[],
4191 		 unsigned int  num_ipmb_addr,
4192 		 int          active,
4193 		 unsigned int hacks,
4194 		 void         *cb_data)
4195 {
4196     lan_data_t   *lan;
4197     unsigned int addr_num = (unsigned long) cb_data;
4198     unsigned int i;
4199 
4200     if (err) {
4201 	handle_connected(ipmi, err, addr_num);
4202 	return;
4203     }
4204 
4205     if (!ipmi) {
4206 	handle_connected(ipmi, ECANCELED, addr_num);
4207 	return;
4208     }
4209 
4210     lan = (lan_data_t *) ipmi->con_data;
4211 
4212     for (i=0; i<num_ipmb_addr && i<MAX_IPMI_USED_CHANNELS; i++) {
4213 	if (! ipmb_addr[i])
4214 	    continue;
4215 	lan->slave_addr[i] = ipmb_addr[i];
4216 	ipmi->ipmb_addr[i] = ipmb_addr[i];
4217     }
4218 
4219     lan->is_active = active;
4220     ipmi->hacks = hacks;
4221     finish_connection(ipmi, lan, addr_num);
4222     call_ipmb_change_handlers(lan, err, ipmb_addr, num_ipmb_addr,
4223 			      active, hacks);
4224 }
4225 
4226 static int
handle_dev_id(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4227 handle_dev_id(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
4228 {
4229     ipmi_msg_t   *msg = &rspi->msg;
4230     lan_data_t   *lan = NULL;
4231     int          err;
4232     unsigned int manufacturer_id;
4233     unsigned int product_id;
4234     int          addr_num = (long) rspi->data4;
4235 
4236     if (!ipmi) {
4237 	err = ECANCELED;
4238 	goto out_err;
4239     }
4240 
4241     lan = (lan_data_t *) ipmi->con_data;
4242 
4243     if (msg->data[0] != 0) {
4244 	err = IPMI_IPMI_ERR_VAL(msg->data[0]);
4245 	goto out_err;
4246     }
4247 
4248     if (msg->data_len < 12) {
4249 	err = EINVAL;
4250 	goto out_err;
4251     }
4252 
4253     manufacturer_id = (msg->data[7]
4254 		       | (msg->data[8] << 8)
4255 		       | (msg->data[9] << 16));
4256     product_id = msg->data[10] | (msg->data[11] << 8);
4257 
4258     if (!lan->oem_conn_handlers_called) {
4259 	lan->oem_conn_handlers_called = 1;
4260 	err = ipmi_check_oem_conn_handlers(ipmi, manufacturer_id, product_id);
4261 	if (err)
4262 	    goto out_err;
4263 
4264 	if (ipmi->get_ipmb_addr) {
4265 	    /* We have a way to fetch the IPMB address, do so. */
4266 	    err = ipmi->get_ipmb_addr(ipmi, handle_ipmb_addr,
4267 				      (void *) (long) addr_num);
4268 	    if (err)
4269 		goto out_err;
4270 	} else
4271 	    finish_connection(ipmi, lan, addr_num);
4272     } else {
4273 	finish_connection(ipmi, lan, addr_num);
4274     }
4275     return IPMI_MSG_ITEM_NOT_USED;
4276 
4277  out_err:
4278     handle_connected(ipmi, err, addr_num);
4279     return IPMI_MSG_ITEM_NOT_USED;
4280 }
4281 
4282 static int
send_get_dev_id(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,ipmi_msgi_t * rspi)4283 send_get_dev_id(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
4284 		ipmi_msgi_t *rspi)
4285 {
4286     ipmi_msg_t			 msg;
4287     int				 rv;
4288     ipmi_system_interface_addr_t addr;
4289 
4290     addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
4291     addr.channel = 0xf;
4292     addr.lun = 0;
4293 
4294     msg.cmd = IPMI_GET_DEVICE_ID_CMD;
4295     msg.netfn = IPMI_APP_NETFN;
4296     msg.data = NULL;
4297     msg.data_len = 0;
4298 
4299     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
4300 				       (ipmi_addr_t *) &addr, sizeof(addr),
4301 				       &msg, handle_dev_id, rspi);
4302     return rv;
4303 }
4304 
4305 static void
lan_oem_done(ipmi_con_t * ipmi,void * cb_data)4306 lan_oem_done(ipmi_con_t *ipmi, void *cb_data)
4307 {
4308     lan_data_t  *lan;
4309     int         rv;
4310     ipmi_msgi_t *rspi = cb_data;
4311     int         addr_num = (long) rspi->data4;
4312 
4313     if (! ipmi) {
4314 	ipmi_mem_free(rspi);
4315 	return;
4316     }
4317 
4318     lan = (lan_data_t *) ipmi->con_data;
4319     rv = send_get_dev_id(ipmi, lan, addr_num, rspi);
4320     if (rv) {
4321         handle_connected(ipmi, rv, addr_num);
4322 	ipmi_mem_free(rspi);
4323     }
4324 }
4325 
4326 static int
session_privilege_set(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4327 session_privilege_set(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
4328 {
4329     ipmi_msg_t *msg = &rspi->msg;
4330     lan_data_t *lan;
4331     int        rv;
4332     int        addr_num = (long) rspi->data4;
4333 
4334     if (!ipmi) {
4335 	handle_connected(ipmi, ECANCELED, addr_num);
4336 	goto out;
4337     }
4338 
4339     lan = (lan_data_t *) ipmi->con_data;
4340 
4341     if (msg->data[0] != 0) {
4342         handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
4343 	goto out;
4344     }
4345 
4346     if (msg->data_len < 2) {
4347         handle_connected(ipmi, EINVAL, addr_num);
4348 	goto out;
4349     }
4350 
4351     if (lan->cparm.privilege != (unsigned int) (msg->data[1] & 0xf)) {
4352 	/* Requested privilege level did not match. */
4353         handle_connected(ipmi, EINVAL, addr_num);
4354 	goto out;
4355     }
4356 
4357     rv = ipmi_conn_check_oem_handlers(ipmi, lan_oem_done, rspi);
4358     if (rv) {
4359         handle_connected(ipmi, rv, addr_num);
4360 	goto out;
4361     }
4362 
4363     return IPMI_MSG_ITEM_USED;
4364 
4365  out:
4366     return IPMI_MSG_ITEM_NOT_USED;
4367 }
4368 
4369 static int
send_set_session_privilege(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,ipmi_msgi_t * rspi)4370 send_set_session_privilege(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
4371 			   ipmi_msgi_t *rspi)
4372 {
4373     unsigned char		 data[1];
4374     ipmi_msg_t			 msg;
4375     int				 rv;
4376     ipmi_system_interface_addr_t addr;
4377 
4378     addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
4379     addr.channel = 0xf;
4380     addr.lun = 0;
4381 
4382     data[0] = lan->cparm.privilege;
4383 
4384     msg.cmd = IPMI_SET_SESSION_PRIVILEGE_CMD;
4385     msg.netfn = IPMI_APP_NETFN;
4386     msg.data = data;
4387     msg.data_len = 1;
4388 
4389     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
4390 				       (ipmi_addr_t *) &addr, sizeof(addr),
4391 				       &msg, session_privilege_set, rspi);
4392     return rv;
4393 }
4394 
4395 static int
check_rakp_rsp(ipmi_con_t * ipmi,ipmi_msg_t * msg,char * caller,unsigned int min_length,int addr_num)4396 check_rakp_rsp(ipmi_con_t   *ipmi,
4397 	       ipmi_msg_t   *msg,
4398 	       char         *caller,
4399 	       unsigned int min_length,
4400 	       int          addr_num)
4401 {
4402     if (!ipmi) {
4403 	handle_connected(ipmi, ECANCELED, addr_num);
4404 	return ECANCELED;
4405     }
4406 
4407     if (msg->data_len < 2) {
4408 	ipmi_log(IPMI_LOG_ERR_INFO,
4409 		 "%sipmi_lan.c(%s): Message data too short: %d",
4410 		 IPMI_CONN_NAME(ipmi), caller, msg->data_len);
4411 	handle_connected(ipmi, EINVAL, addr_num);
4412 	return EINVAL;
4413     }
4414 
4415     if (msg->data[1]) {
4416 	/* Got an RMCP+ error. */
4417 	handle_connected(ipmi, IPMI_RMCPP_ERR_VAL(msg->data[1]), addr_num);
4418 	return EINVAL;
4419     }
4420 
4421     if (msg->data_len < min_length) {
4422 	ipmi_log(IPMI_LOG_ERR_INFO,
4423 		 "%sipmi_lan.c(%s): Message data too short: %d",
4424 		 IPMI_CONN_NAME(ipmi), caller, msg->data_len);
4425 	handle_connected(ipmi, EINVAL, addr_num);
4426 	return EINVAL;
4427     }
4428 
4429     return 0;
4430 }
4431 
4432 typedef struct auth_info_s
4433 {
4434     ipmi_msgi_t *rspi;
4435     lan_data_t  *lan;
4436 } auth_info_t;
4437 
4438 static void
rmcpp_auth_finished(ipmi_con_t * ipmi,int err,int addr_num,void * cb_data)4439 rmcpp_auth_finished(ipmi_con_t    *ipmi,
4440 		    int           err,
4441 		    int           addr_num,
4442 		    void          *cb_data)
4443 {
4444     auth_info_t *info = cb_data;
4445     lan_data_t  *lan = info->lan;
4446     int         rv = EINVAL;
4447 
4448     if (!ipmi) {
4449 	handle_connected(lan->ipmi, ECANCELED, addr_num);
4450 	goto out;
4451     }
4452 
4453     if (err) {
4454 	handle_connected(lan->ipmi, err, addr_num);
4455 	goto out;
4456     }
4457 
4458     lan->ip[addr_num].session_id = lan->ip[addr_num].precon_session_id;
4459     lan->ip[addr_num].mgsys_session_id
4460 	= lan->ip[addr_num].precon_mgsys_session_id;
4461     lan->ip[addr_num].inbound_seq_num = 1;
4462     lan->ip[addr_num].outbound_seq_num = 1;
4463     lan->ip[addr_num].unauth_in_seq_num = 1;
4464     lan->ip[addr_num].unauth_out_seq_num = 1;
4465 
4466     /* We're up!.  Start the session stuff. */
4467     rv = send_set_session_privilege(ipmi, lan, addr_num, info->rspi);
4468     if (rv) {
4469         handle_connected(ipmi, rv, addr_num);
4470 	goto out;
4471     }
4472 
4473  out:
4474     if (rv)
4475 	ipmi_free_msg_item(info->rspi);
4476     ipmi_mem_free(info);
4477     return;
4478 }
4479 
4480 static int
rmcpp_set_info(ipmi_con_t * ipmi,int addr_num,ipmi_rmcpp_auth_t * ainfo,void * cb_data)4481 rmcpp_set_info(ipmi_con_t        *ipmi,
4482 	       int               addr_num,
4483 	       ipmi_rmcpp_auth_t *ainfo,
4484 	       void              *cb_data)
4485 {
4486     auth_info_t *info = cb_data;
4487     lan_data_t  *lan = info->lan;
4488     int         rv;
4489 
4490     rv = lan->ip[addr_num].conf_info->conf_init
4491 	(ipmi, ainfo, &(lan->ip[addr_num].conf_data));
4492     if (rv)
4493 	goto out;
4494 
4495     rv = lan->ip[addr_num].integ_info->integ_init
4496 	(ipmi, ainfo, &(lan->ip[addr_num].integ_data));
4497     if (rv)
4498 	goto out;
4499 
4500  out:
4501     return rv;
4502 }
4503 
4504 static int
got_rmcpp_open_session_rsp(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4505 got_rmcpp_open_session_rsp(ipmi_con_t *ipmi, ipmi_msgi_t  *rspi)
4506 {
4507     ipmi_msg_t   *msg = &rspi->msg;
4508     lan_data_t   *lan;
4509     int          addr_num = (long) rspi->data4;
4510     uint32_t     session_id;
4511     uint32_t     mgsys_session_id;
4512     unsigned int privilege;
4513     unsigned int auth, integ, conf;
4514     ipmi_rmcpp_authentication_t *authp = NULL;
4515     ipmi_rmcpp_confidentiality_t *confp = NULL;
4516     ipmi_rmcpp_integrity_t *integp = NULL;
4517     auth_info_t  *info;
4518     int          rv;
4519 
4520     if (check_rakp_rsp(ipmi, msg, "got_rmcpp_open_session_rsp", 36, addr_num))
4521 	goto out;
4522 
4523     lan = (lan_data_t *) ipmi->con_data;
4524 
4525     privilege = msg->data[2] & 0xf;
4526     if (privilege < lan->cparm.privilege) {
4527 	ipmi_log(IPMI_LOG_WARNING,
4528 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4529 		 "Expected privilege %d, got %d",
4530 		 IPMI_CONN_NAME(ipmi), lan->cparm.privilege, privilege);
4531     }
4532 
4533     session_id = ipmi_get_uint32(msg->data+4);
4534     if (session_id != lan->ip[addr_num].precon_session_id) {
4535 	ipmi_log(IPMI_LOG_ERR_INFO,
4536 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4537 		 " Got wrong session id: 0x%x",
4538 		 IPMI_CONN_NAME(ipmi), session_id);
4539 	handle_connected(ipmi, EINVAL, addr_num);
4540 	goto out;
4541     }
4542 
4543     mgsys_session_id = ipmi_get_uint32(msg->data+8);
4544     if (mgsys_session_id == 0) {
4545 	ipmi_log(IPMI_LOG_ERR_INFO,
4546 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4547 		 "Got NULL mgd system session id", IPMI_CONN_NAME(ipmi));
4548 	handle_connected(ipmi, EINVAL, addr_num);
4549 	goto out;
4550     }
4551     lan->ip[addr_num].precon_mgsys_session_id = mgsys_session_id;
4552 
4553     if ((msg->data[12] != 0) || (msg->data[15] != 8)) {
4554 	ipmi_log(IPMI_LOG_ERR_INFO,
4555 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4556 		 "Got NULL or invalid authentication payload",
4557 		 IPMI_CONN_NAME(ipmi));
4558 	handle_connected(ipmi, EINVAL, addr_num);
4559 	goto out;
4560     }
4561     auth = msg->data[16] & 0x3f;
4562 
4563     if ((msg->data[20] != 1) || (msg->data[23] != 8)) {
4564 	ipmi_log(IPMI_LOG_ERR_INFO,
4565 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4566 		 "Got NULL or invalid integrity payload",
4567 		 IPMI_CONN_NAME(ipmi));
4568 	handle_connected(ipmi, EINVAL, addr_num);
4569 	goto out;
4570     }
4571     integ = msg->data[24] & 0x3f;
4572 
4573     if ((msg->data[28] != 2) || (msg->data[31] != 8)) {
4574 	ipmi_log(IPMI_LOG_ERR_INFO,
4575 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4576 		 "Got NULL or invalid confidentiality payload",
4577 		 IPMI_CONN_NAME(ipmi));
4578 	handle_connected(ipmi, EINVAL, addr_num);
4579 	goto out;
4580     }
4581     conf = msg->data[32] & 0x3f;
4582 
4583     if (auth >= 0x30) {
4584 	auth_entry_t *e = oem_auth_list;
4585 	while (e) {
4586 	    if ((e->auth_num == auth)
4587 		&& (memcmp(e->iana, lan->oem_iana, 3) == 0))
4588 	    {
4589 		authp = e->auth;
4590 		break;
4591 	    }
4592 	    e = e->next;
4593 	}
4594     } else
4595 	authp = auths[auth];
4596 
4597     if (!authp) {
4598 	ipmi_log(IPMI_LOG_ERR_INFO,
4599 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4600 		 "BMC returned an auth algorithm that wasn't supported: %d",
4601 		 IPMI_CONN_NAME(ipmi), auth);
4602 	handle_connected(ipmi, EINVAL, addr_num);
4603 	goto out;
4604     }
4605 
4606     if (conf >= 0x30) {
4607 	conf_entry_t *e = oem_conf_list;
4608 	while (e) {
4609 	    if ((e->conf_num == conf)
4610 		&& (memcmp(e->iana, lan->oem_iana, 3) == 0))
4611 	    {
4612 		confp = e->conf;
4613 		break;
4614 	    }
4615 	    e = e->next;
4616 	}
4617     } else
4618 	confp = confs[conf];
4619 
4620     if (!confp) {
4621 	ipmi_log(IPMI_LOG_ERR_INFO,
4622 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4623 		 "BMC returned a conf algorithm that wasn't supported: %d",
4624 		 IPMI_CONN_NAME(ipmi), conf);
4625 	handle_connected(ipmi, EINVAL, addr_num);
4626 	goto out;
4627     }
4628 
4629     if (integ >= 0x30) {
4630 	integ_entry_t *e = oem_integ_list;
4631 	while (e) {
4632 	    if ((e->integ_num == integ)
4633 		&& (memcmp(e->iana, lan->oem_iana, 3) == 0))
4634 	    {
4635 		integp = e->integ;
4636 		break;
4637 	    }
4638 	    e = e->next;
4639 	}
4640     } else
4641 	integp = integs[integ];
4642 
4643     if (!integp) {
4644 	ipmi_log(IPMI_LOG_ERR_INFO,
4645 		 "%sipmi_lan.c(got_rmcpp_open_session_rsp): "
4646 		 "BMC returned an integ algorithm that wasn't supported: %d",
4647 		 IPMI_CONN_NAME(ipmi), integ);
4648 	handle_connected(ipmi, EINVAL, addr_num);
4649 	goto out;
4650     }
4651 
4652     info = ipmi_mem_alloc(sizeof(*info));
4653     if (!info) {
4654 	handle_connected(ipmi, ENOMEM, addr_num);
4655 	goto out;
4656     }
4657 
4658     lan->ip[addr_num].working_conf = conf;
4659     lan->ip[addr_num].working_integ = integ;
4660     lan->ip[addr_num].conf_info = confp;
4661     lan->ip[addr_num].integ_info = integp;
4662 
4663     lan->ip[addr_num].ainfo.lan = lan;
4664     lan->ip[addr_num].ainfo.role = ((lan->cparm.name_lookup_only << 4)
4665 				    | lan->cparm.privilege);
4666 
4667     info->lan = lan;
4668     info->rspi = rspi;
4669 
4670     rv = authp->start_auth(ipmi, addr_num, lan->fd_slot,
4671 			   &(lan->ip[addr_num].ainfo),
4672 			   rmcpp_set_info, rmcpp_auth_finished,
4673 			   info);
4674     if (rv) {
4675 	ipmi_mem_free(info);
4676 	handle_connected(ipmi, rv, addr_num);
4677 	goto out;
4678     }
4679 
4680     return IPMI_MSG_ITEM_USED;
4681 
4682  out:
4683     return IPMI_MSG_ITEM_NOT_USED;
4684 }
4685 
4686 static int
send_rmcpp_open_session(ipmi_con_t * ipmi,lan_data_t * lan,ipmi_msgi_t * rspi,int addr_num)4687 send_rmcpp_open_session(ipmi_con_t *ipmi, lan_data_t *lan, ipmi_msgi_t *rspi,
4688 			int addr_num)
4689 {
4690     int               rv;
4691     unsigned char     data[32];
4692     ipmi_msg_t        msg;
4693     ipmi_rmcpp_addr_t addr;
4694 
4695     memset(data, 0, sizeof(data));
4696     data[0] = 0; /* Set to seq# by the formatting code. */
4697     data[1] = lan->cparm.privilege;
4698     ipmi_set_uint32(data+4, lan->ip[addr_num].precon_session_id);
4699     data[8] = 0; /* auth algorithm */
4700     if ((int) lan->cparm.auth == IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK)
4701 	data[11] = 0; /* Let the BMC pick */
4702     else {
4703 	data[11] = 8;
4704 	data[12] = lan->cparm.auth;
4705     }
4706     data[16] = 1; /* integrity algorithm */
4707     if ((int) lan->cparm.integ == IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK)
4708 	data[19] = 0; /* Let the BMC pick */
4709     else {
4710 	data[19] = 8;
4711 	data[20] = lan->cparm.integ;
4712     }
4713     data[24] = 2; /* confidentiality algorithm */
4714     if ((int) lan->cparm.conf == IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK)
4715 	data[27] = 0; /* Let the BMC pick */
4716     else {
4717 	data[27] = 8;
4718 	data[28] = lan->cparm.conf;
4719     }
4720 
4721     msg.netfn = IPMI_RMCPP_DUMMY_NETFN;
4722     msg.cmd = IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST;
4723     msg.data = data;
4724     msg.data_len = 32;
4725     addr.addr_type = (IPMI_RMCPP_ADDR_START
4726 		      + IPMI_RMCPP_PAYLOAD_TYPE_OPEN_SESSION_REQUEST);
4727 
4728     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
4729 				       (ipmi_addr_t *) &addr, sizeof(addr),
4730 				       &msg, got_rmcpp_open_session_rsp, rspi);
4731     return rv;
4732 }
4733 
4734 static int
start_rmcpp(ipmi_con_t * ipmi,lan_data_t * lan,ipmi_msgi_t * rspi,int addr_num)4735 start_rmcpp(ipmi_con_t *ipmi, lan_data_t *lan, ipmi_msgi_t *rspi, int addr_num)
4736 {
4737     int rv;
4738 
4739     /* We don't really need to get the cipher suites, the user
4740        requests them (or defaults them to the mandatory ones). */
4741 
4742     lan->ip[addr_num].working_authtype = IPMI_AUTHTYPE_RMCP_PLUS;
4743     lan->ip[addr_num].outbound_seq_num = 0;
4744     lan->ip[addr_num].unauth_out_seq_num = 0;
4745     lan->ip[addr_num].inbound_seq_num = 0;
4746     lan->ip[addr_num].unauth_in_seq_num = 0;
4747     /* Use our fd_slot in the fd for the session id, so we can look it
4748        up quickly. */
4749     lan->ip[addr_num].precon_session_id = lan->fd_slot + 1;
4750     lan->ip[addr_num].working_conf = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
4751     lan->ip[addr_num].working_integ = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
4752 
4753     rv = send_rmcpp_open_session(ipmi, lan, rspi, addr_num);
4754     if (rv) {
4755 	handle_connected(ipmi, rv, addr_num);
4756 	goto out;
4757     }
4758 
4759     return IPMI_MSG_ITEM_USED;
4760 
4761  out:
4762     return IPMI_MSG_ITEM_NOT_USED;
4763 }
4764 
4765 static int
session_activated(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4766 session_activated(ipmi_con_t *ipmi, ipmi_msgi_t  *rspi)
4767 {
4768     ipmi_msg_t *msg = &rspi->msg;
4769     lan_data_t *lan;
4770     int        rv;
4771     int        addr_num = (long) rspi->data4;
4772 
4773 
4774     if (!ipmi) {
4775 	handle_connected(ipmi, ECANCELED, addr_num);
4776 	goto out;
4777     }
4778 
4779     lan = (lan_data_t *) ipmi->con_data;
4780 
4781     if (msg->data[0] != 0) {
4782         handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
4783 	goto out;
4784     }
4785 
4786     if (msg->data_len < 11) {
4787         handle_connected(ipmi, EINVAL, addr_num);
4788 	goto out;
4789     }
4790 
4791     lan->ip[addr_num].working_authtype = msg->data[1] & 0xf;
4792     if ((lan->ip[addr_num].working_authtype != 0)
4793 	&& (lan->ip[addr_num].working_authtype != lan->chosen_authtype))
4794     {
4795 	/* Eh?  It didn't return a valid authtype. */
4796         handle_connected(ipmi, EINVAL, addr_num);
4797 	goto out;
4798     }
4799 
4800     lan->ip[addr_num].session_id = ipmi_get_uint32(msg->data+2);
4801     lan->ip[addr_num].outbound_seq_num = ipmi_get_uint32(msg->data+6);
4802 
4803     rv = send_set_session_privilege(ipmi, lan, addr_num, rspi);
4804     if (rv) {
4805         handle_connected(ipmi, rv, addr_num);
4806 	goto out;
4807     }
4808 
4809     return IPMI_MSG_ITEM_USED;
4810 
4811  out:
4812     return IPMI_MSG_ITEM_NOT_USED;
4813 }
4814 
4815 static int
send_activate_session(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,ipmi_msgi_t * rspi)4816 send_activate_session(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
4817 		      ipmi_msgi_t *rspi)
4818 {
4819     unsigned char                data[IPMI_MAX_MSG_LENGTH];
4820     ipmi_msg_t                   msg;
4821     int                          rv;
4822     ipmi_system_interface_addr_t addr;
4823 
4824     addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
4825     addr.channel = 0xf;
4826     addr.lun = 0;
4827 
4828     data[0] = lan->chosen_authtype;
4829     data[1] = lan->cparm.privilege;
4830     memcpy(data+2, lan->challenge_string, 16);
4831     ipmi_set_uint32(data+18, lan->ip[addr_num].inbound_seq_num);
4832 
4833     msg.cmd = IPMI_ACTIVATE_SESSION_CMD;
4834     msg.netfn = IPMI_APP_NETFN;
4835     msg.data = data;
4836     msg.data_len = 22;
4837 
4838     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
4839 				       (ipmi_addr_t *) &addr, sizeof(addr),
4840 				       &msg, session_activated, rspi);
4841     return rv;
4842 }
4843 
4844 static int
challenge_done(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4845 challenge_done(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
4846 {
4847     ipmi_msg_t *msg = &rspi->msg;
4848     lan_data_t *lan;
4849     int        rv;
4850     int        addr_num = (long) rspi->data4;
4851 
4852 
4853     if (!ipmi) {
4854 	handle_connected(ipmi, ECANCELED, addr_num);
4855 	goto out;
4856     }
4857 
4858     lan = (lan_data_t *) ipmi->con_data;
4859 
4860     if (msg->data[0] != 0) {
4861         handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
4862 	goto out;
4863     }
4864 
4865     if (msg->data_len < 21) {
4866         handle_connected(ipmi, EINVAL, addr_num);
4867 	goto out;
4868     }
4869 
4870     /* Get the temporary session id. */
4871     lan->ip[addr_num].session_id = ipmi_get_uint32(msg->data+1);
4872 
4873     lan->ip[addr_num].outbound_seq_num = 0;
4874     lan->ip[addr_num].working_authtype = lan->chosen_authtype;
4875     memcpy(lan->challenge_string, msg->data+5, 16);
4876 
4877     /* Get a random number of the other end to start sending me sequence
4878        numbers at, but don't let it be zero. */
4879     while (lan->ip[addr_num].inbound_seq_num == 0) {
4880 	rv = ipmi->os_hnd->get_random(ipmi->os_hnd,
4881 				      &(lan->ip[addr_num].inbound_seq_num), 4);
4882 	if (rv) {
4883 	    handle_connected(ipmi, rv, addr_num);
4884 	    goto out;
4885 	}
4886     }
4887 
4888     rv = send_activate_session(ipmi, lan, addr_num, rspi);
4889     if (rv) {
4890         handle_connected(ipmi, rv, addr_num);
4891 	goto out;
4892     }
4893 
4894     return IPMI_MSG_ITEM_USED;
4895 
4896  out:
4897     return IPMI_MSG_ITEM_NOT_USED;
4898 }
4899 
4900 static int
send_challenge(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,ipmi_msgi_t * rspi)4901 send_challenge(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
4902 	       ipmi_msgi_t *rspi)
4903 {
4904     unsigned char                data[IPMI_MAX_MSG_LENGTH];
4905     ipmi_msg_t                   msg;
4906     ipmi_system_interface_addr_t addr;
4907     int                          rv;
4908 
4909     addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
4910     addr.channel = 0xf;
4911     addr.lun = 0;
4912 
4913     data[0] = lan->chosen_authtype;
4914     msg.cmd = IPMI_GET_SESSION_CHALLENGE_CMD;
4915     msg.netfn = IPMI_APP_NETFN;
4916     msg.data = data;
4917     msg.data_len = 1;
4918     memcpy(data+1, lan->cparm.username, IPMI_USERNAME_MAX);
4919     msg.data_len += IPMI_USERNAME_MAX;
4920 
4921     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
4922 				       (ipmi_addr_t *) &addr, sizeof(addr),
4923 				       &msg, challenge_done, rspi);
4924     return rv;
4925 }
4926 
4927 static int
auth_cap_done(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)4928 auth_cap_done(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
4929 {
4930     ipmi_msg_t *msg = &rspi->msg;
4931     lan_data_t *lan;
4932     int        rv;
4933     int        addr_num = (long) rspi->data4;
4934     int        supports_ipmi2;
4935     int        extended_capabilities_reported;
4936 
4937     if (!ipmi) {
4938 	handle_connected(ipmi, ECANCELED, addr_num);
4939 	goto out;
4940     }
4941 
4942     lan = (lan_data_t *) ipmi->con_data;
4943 
4944     if (msg->data[0] != 0) {
4945         handle_connected(ipmi, IPMI_IPMI_ERR_VAL(msg->data[0]), addr_num);
4946 	goto out;
4947     }
4948 
4949     if (msg->data_len < 9) {
4950 	handle_connected(ipmi, EINVAL, addr_num);
4951 	goto out;
4952     }
4953 
4954     extended_capabilities_reported = (msg->data[2] & 0x80);
4955     supports_ipmi2 = (msg->data[4] & 0x02);
4956     if (extended_capabilities_reported && supports_ipmi2) {
4957 	/* We have RMCP+ support!  Use it. */
4958 	lan->use_two_keys = (msg->data[3] >> 5) & 1;
4959 	memcpy(lan->oem_iana, msg->data+5, 3);
4960 	lan->oem_aux = msg->data[8];
4961 	return start_rmcpp(ipmi, lan, rspi, addr_num);
4962     }
4963     else if (supports_ipmi2)
4964     {
4965 	/*
4966 	 * The BMC has said that it supports RMCP+/IPMI 2.0 in the
4967 	 * extended response fields, but has not indicated that we
4968 	 * should USE the extended response fields!  The SuperMicro
4969 	 * AOC-IPMI20-E currently does this (April 2005), and will do
4970 	 * so until they provide BMC firmware that supports RMCP+.
4971 	 */
4972 	ipmi_log(IPMI_LOG_WARNING,
4973 		"%sipmi_lan.c(auth_cap_done): "
4974 		"BMC confused about RMCP+ support. Disabling RMCP+.",
4975 		IPMI_CONN_NAME(lan->ipmi));
4976     }
4977     if (lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
4978 	/* The user specified RMCP+, but the system doesn't have it. */
4979 	ipmi_log(IPMI_LOG_ERR_INFO,
4980 		"%sipmi_lan.c(auth_cap_done): "
4981 		"User requested RMCP+, but not supported",
4982 		IPMI_CONN_NAME(lan->ipmi));
4983 	handle_connected(ipmi, ENOENT, addr_num);
4984 	goto out;
4985     }
4986 
4987     memcpy(lan->oem_iana, msg->data+5, 3);
4988     lan->oem_aux = msg->data[8];
4989 
4990     if (lan->authdata) {
4991 	ipmi_auths[lan->chosen_authtype].authcode_cleanup(lan->authdata);
4992 	lan->authdata = NULL;
4993     }
4994 
4995     if ((int) lan->cparm.authtype == IPMI_AUTHTYPE_DEFAULT) {
4996 	/* Pick the most secure authentication type. */
4997 	if (msg->data[2] & (1 << IPMI_AUTHTYPE_MD5)) {
4998 	    lan->chosen_authtype = IPMI_AUTHTYPE_MD5;
4999 	} else if (msg->data[2] & (1 << IPMI_AUTHTYPE_MD2)) {
5000 	    lan->chosen_authtype = IPMI_AUTHTYPE_MD2;
5001 	} else if (msg->data[2] & (1 << IPMI_AUTHTYPE_STRAIGHT)) {
5002 	    lan->chosen_authtype = IPMI_AUTHTYPE_STRAIGHT;
5003 	} else if (msg->data[2] & (1 << IPMI_AUTHTYPE_NONE)) {
5004 	    lan->chosen_authtype = IPMI_AUTHTYPE_NONE;
5005 	} else {
5006 	    ipmi_log(IPMI_LOG_ERR_INFO,
5007 		     "%sipmi_lan.c(auth_cap_done): "
5008 		     "No valid authentication supported",
5009 		     IPMI_CONN_NAME(lan->ipmi));
5010 	    handle_connected(ipmi, EINVAL, addr_num);
5011 	    goto out;
5012 	}
5013     } else {
5014 	if (!(msg->data[2] & (1 << lan->cparm.authtype))) {
5015 	    ipmi_log(IPMI_LOG_ERR_INFO,
5016 		     "%sipmi_lan.c(auth_cap_done): "
5017 		     "Requested authentication not supported",
5018 		     IPMI_CONN_NAME(lan->ipmi));
5019 	    handle_connected(ipmi, EINVAL, addr_num);
5020 	    goto out;
5021 	}
5022 	lan->chosen_authtype = lan->cparm.authtype;
5023     }
5024 
5025     rv = ipmi_auths[lan->chosen_authtype].authcode_init(lan->cparm.password,
5026 							&(lan->authdata),
5027 							NULL, auth_alloc,
5028 							auth_free);
5029     if (rv) {
5030         ipmi_log(IPMI_LOG_ERR_INFO,
5031 		 "%sipmi_lan.c(auth_cap_done): "
5032 		 "Unable to initialize authentication data: 0x%x",
5033 		 IPMI_CONN_NAME(lan->ipmi), rv);
5034         handle_connected(ipmi, rv, addr_num);
5035 	goto out;
5036     }
5037 
5038     rv = send_challenge(ipmi, lan, addr_num, rspi);
5039     if (rv) {
5040         ipmi_log(IPMI_LOG_ERR_INFO,
5041 		 "%sipmi_lan.c(auth_cap_done): "
5042 		 "Unable to send challenge command: 0x%x",
5043 		 IPMI_CONN_NAME(lan->ipmi), rv);
5044         handle_connected(ipmi, rv, addr_num);
5045 	goto out;
5046     }
5047 
5048     return IPMI_MSG_ITEM_USED;
5049 
5050  out:
5051     return IPMI_MSG_ITEM_NOT_USED;
5052 }
5053 
5054 static int
auth_cap_done_p(ipmi_con_t * ipmi,ipmi_msgi_t * rspi)5055 auth_cap_done_p(ipmi_con_t *ipmi, ipmi_msgi_t *rspi)
5056 {
5057     ipmi_msg_t *msg = &rspi->msg;
5058     lan_data_t *lan;
5059     int        addr_num = (long) rspi->data4;
5060     int        rv;
5061 
5062     if (!ipmi) {
5063 	handle_connected(ipmi, ECANCELED, addr_num);
5064 	goto out;
5065     }
5066 
5067     lan = (lan_data_t *) ipmi->con_data;
5068 
5069     if ((msg->data[0] != 0) || (msg->data_len < 9)) {
5070 	/* Got an error, try it without the RMCP+ bit set.  Some
5071 	   systems incorrectly return errors when reserved data is
5072 	   set. */
5073 
5074 	if (lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS) {
5075 	    /* The user specified RMCP+, but the system doesn't have it. */
5076 	    ipmi_log(IPMI_LOG_ERR_INFO,
5077 		     "%sipmi_lan.c(auth_cap_done_p): "
5078 		     "Use requested RMCP+, but not supported",
5079 		     IPMI_CONN_NAME(lan->ipmi));
5080 	    handle_connected(ipmi, ENOENT, addr_num);
5081 	    goto out;
5082 	}
5083 
5084 	rv = send_auth_cap(ipmi, lan, addr_num, 1);
5085 	if (rv) {
5086 	    handle_connected(ipmi, rv, addr_num);
5087 	}
5088 	goto out;
5089     }
5090 
5091 
5092     return auth_cap_done(ipmi, rspi);
5093 
5094  out:
5095     return IPMI_MSG_ITEM_NOT_USED;
5096 }
5097 
5098 static int
send_auth_cap(ipmi_con_t * ipmi,lan_data_t * lan,int addr_num,int force_ipmiv15)5099 send_auth_cap(ipmi_con_t *ipmi, lan_data_t *lan, int addr_num,
5100 	      int force_ipmiv15)
5101 {
5102     unsigned char                data[2];
5103     ipmi_msg_t                   msg;
5104     ipmi_system_interface_addr_t addr;
5105     int                          rv;
5106     ipmi_msgi_t                  *rspi;
5107     ipmi_ll_rsp_handler_t        rsp_handler;
5108 
5109     /* FIXME - a system may only support RMCP+ and not RMCP.  We need
5110        a way to detect and handle that.  */
5111 
5112     rspi = ipmi_mem_alloc(sizeof(*rspi));
5113     if (!rspi)
5114 	return ENOMEM;
5115 
5116     addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
5117     addr.channel = 0xf;
5118     addr.lun = 0;
5119 
5120     data[0] = 0xe;
5121     data[1] = lan->cparm.privilege;
5122     msg.cmd = IPMI_GET_CHANNEL_AUTH_CAPABILITIES_CMD;
5123     msg.netfn = IPMI_APP_NETFN;
5124     msg.data = data;
5125     msg.data_len = 2;
5126     if ((((int) lan->cparm.authtype == IPMI_AUTHTYPE_DEFAULT)
5127 	 || ((int) lan->cparm.authtype == IPMI_AUTHTYPE_RMCP_PLUS))
5128 	&& !force_ipmiv15)
5129     {
5130 	rsp_handler = auth_cap_done_p;
5131 	data[0] |= 0x80; /* Get RMCP data. */
5132     } else {
5133 	rsp_handler = auth_cap_done;
5134     }
5135 
5136     rv = ipmi_lan_send_command_forceip(ipmi, addr_num,
5137 				       (ipmi_addr_t *) &addr, sizeof(addr),
5138 				       &msg, rsp_handler, rspi);
5139     if (rv)
5140 	ipmi_mem_free(rspi);
5141     return rv;
5142 }
5143 
5144 static int
lan_start_con(ipmi_con_t * ipmi)5145 lan_start_con(ipmi_con_t *ipmi)
5146 {
5147     lan_data_t     *lan = (lan_data_t *) ipmi->con_data;
5148     int            rv;
5149     struct timeval timeout;
5150     unsigned int   i;
5151 
5152     ipmi_lock(lan->ip_lock);
5153     if (lan->started) {
5154 	/* Only allow started to be called once, but make sure the
5155 	   connected callback gets called if started is called again
5156 	   (assuming the connection is up).  This lets multiple users
5157 	   use the same connection.  If the LAN is not connected, this
5158 	   doesn't matter, the callback will be called properly
5159 	   later. */
5160 	if (lan->connected) {
5161 	    unsigned int i;
5162 	    int          port_err[MAX_IP_ADDR];
5163 
5164 	    for (i=0; i<lan->cparm.num_ip_addr; i++)
5165 		port_err[i] = lan->ip[i].working ? 0 : EINVAL;
5166 
5167 	    ipmi_lock(lan->con_change_lock);
5168 	    ipmi_unlock(lan->ip_lock);
5169 
5170 	    for (i=0; i<lan->cparm.num_ip_addr; i++)
5171 		call_con_change_handlers(lan, port_err[i], i, 1);
5172 	    ipmi_unlock(lan->con_change_lock);
5173 	} else
5174 	    ipmi_unlock(lan->ip_lock);
5175 	return 0;
5176     }
5177 
5178     /* Start the timer to audit the connections. */
5179     lan->audit_info = ipmi_mem_alloc(sizeof(*(lan->audit_info)));
5180     if (!lan->audit_info) {
5181 	rv = ENOMEM;
5182 	goto out_err;
5183     }
5184 
5185     lan->audit_info->cancelled = 0;
5186     lan->audit_info->ipmi = ipmi;
5187     rv = ipmi->os_hnd->alloc_timer(ipmi->os_hnd, &(lan->audit_timer));
5188     if (rv)
5189 	goto out_err;
5190     timeout.tv_sec = LAN_AUDIT_TIMEOUT / 1000000;
5191     timeout.tv_usec = LAN_AUDIT_TIMEOUT % 1000000;
5192     rv = ipmi->os_hnd->start_timer(ipmi->os_hnd,
5193 				   lan->audit_timer,
5194 				   &timeout,
5195 				   audit_timeout_handler,
5196 				   lan->audit_info);
5197     if (rv) {
5198 	ipmi_mem_free(lan->audit_info);
5199 	lan->audit_info = NULL;
5200 	ipmi->os_hnd->free_timer(ipmi->os_hnd, lan->audit_timer);
5201 	lan->audit_timer = NULL;
5202 	goto out_err;
5203     }
5204 
5205     lan->started = 1;
5206     ipmi_unlock(lan->ip_lock);
5207 
5208     for (i=0; i<lan->cparm.num_ip_addr; i++)
5209 	/* Ignore failures, this gets retried. */
5210 	send_auth_cap(ipmi, lan, i, 0);
5211 
5212     return 0;
5213 
5214  out_err:
5215     ipmi_unlock(lan->ip_lock);
5216     return rv;
5217 }
5218 
5219 int
ipmi_lan_setup_con(struct in_addr * ip_addrs,int * ports,unsigned int num_ip_addrs,unsigned int authtype,unsigned int privilege,void * username,unsigned int username_len,void * password,unsigned int password_len,os_handler_t * handlers,void * user_data,ipmi_con_t ** new_con)5220 ipmi_lan_setup_con(struct in_addr            *ip_addrs,
5221 		   int                       *ports,
5222 		   unsigned int              num_ip_addrs,
5223 		   unsigned int              authtype,
5224 		   unsigned int              privilege,
5225 		   void                      *username,
5226 		   unsigned int              username_len,
5227 		   void                      *password,
5228 		   unsigned int              password_len,
5229 		   os_handler_t              *handlers,
5230 		   void                      *user_data,
5231 		   ipmi_con_t                **new_con)
5232 {
5233     char s_ip_addrs[MAX_IP_ADDR][20];
5234     char s_ports[MAX_IP_ADDR][10];
5235     char *paddrs[MAX_IP_ADDR], *pports[MAX_IP_ADDR];
5236     unsigned char *p;
5237     unsigned int  i;
5238     int           rv;
5239 
5240     if ((num_ip_addrs < 1) || (num_ip_addrs > MAX_IP_ADDR))
5241 	return EINVAL;
5242     for (i=0; i<num_ip_addrs; i++) {
5243 	p = (unsigned char *)&(ip_addrs[i]);
5244 	sprintf(s_ip_addrs[i], "%u.%u.%u.%u", *p, *(p+1), *(p+2), *(p+3));
5245 	sprintf(s_ports[i], "%u", ports[i]);
5246 	paddrs[i] = s_ip_addrs[i];
5247 	pports[i]= s_ports[i];
5248     }
5249     rv = ipmi_ip_setup_con(paddrs,
5250 			   pports,
5251 			   num_ip_addrs,
5252 			   authtype,
5253 			   privilege,
5254 			   username,
5255 			   username_len,
5256 			   password,
5257 			   password_len,
5258 			   handlers,
5259 			   user_data,
5260 			   new_con);
5261     return rv;
5262 }
5263 
5264 int
ipmi_ip_setup_con(char * const ip_addrs[],char * const ports[],unsigned int num_ip_addrs,unsigned int authtype,unsigned int privilege,void * username,unsigned int username_len,void * password,unsigned int password_len,os_handler_t * handlers,void * user_data,ipmi_con_t ** new_con)5265 ipmi_ip_setup_con(char         * const ip_addrs[],
5266 		  char         * const ports[],
5267 		  unsigned int num_ip_addrs,
5268 		  unsigned int authtype,
5269 		  unsigned int privilege,
5270 		  void         *username,
5271 		  unsigned int username_len,
5272 		  void         *password,
5273 		  unsigned int password_len,
5274 		  os_handler_t *handlers,
5275 		  void         *user_data,
5276 		  ipmi_con_t   **new_con)
5277 {
5278     ipmi_lanp_parm_t parms[6];
5279 
5280     parms[0].parm_id = IPMI_LANP_PARMID_ADDRS;
5281     parms[0].parm_data = (void *) ip_addrs;
5282     parms[0].parm_data_len = num_ip_addrs;
5283     parms[1].parm_id = IPMI_LANP_PARMID_PORTS;
5284     parms[1].parm_data = (void *) ports;
5285     parms[1].parm_data_len = num_ip_addrs;
5286     parms[2].parm_id = IPMI_LANP_PARMID_AUTHTYPE;
5287     parms[2].parm_val = authtype;
5288     parms[3].parm_id = IPMI_LANP_PARMID_PRIVILEGE;
5289     parms[3].parm_val = privilege;
5290     parms[4].parm_id = IPMI_LANP_PARMID_USERNAME;
5291     parms[4].parm_data = username;
5292     parms[4].parm_data_len = username_len;
5293     parms[5].parm_id = IPMI_LANP_PARMID_PASSWORD;
5294     parms[5].parm_data = password;
5295     parms[5].parm_data_len = password_len;
5296     return ipmi_lanp_setup_con(parms, 6, handlers, user_data, new_con);
5297 }
5298 
5299 static lan_data_t *
find_matching_lan(lan_conn_parms_t * cparm)5300 find_matching_lan(lan_conn_parms_t *cparm)
5301 {
5302     lan_link_t   *l;
5303     lan_data_t   *lan;
5304     unsigned int idx;
5305 
5306     /* Look in the first IP addresses list. */
5307     idx = hash_lan_addr(&cparm->ip_addr[0].s_ipsock.s_addr0);
5308     ipmi_lock(lan_list_lock);
5309     l = lan_ip_list[idx].next;
5310     while (l->lan) {
5311 	lan = l->lan;
5312 	if (memcmp(&lan->cparm, cparm, sizeof(*cparm)) == 0) {
5313 	    /* Parms match up, use it */
5314 	    lan->users++;
5315 	    ipmi_unlock(lan_list_lock);
5316 	    return lan;
5317 	}
5318 	l = l->next;
5319     }
5320     ipmi_unlock(lan_list_lock);
5321     return NULL;
5322 }
5323 
5324 static void
lan_use_connection(ipmi_con_t * ipmi)5325 lan_use_connection(ipmi_con_t *ipmi)
5326 {
5327     lan_data_t *lan = ipmi->con_data;
5328 
5329     ipmi_lock(lan_list_lock);
5330     lan->users++;
5331     ipmi_unlock(lan_list_lock);
5332 }
5333 
5334 static int
lan_register_stat_handler(ipmi_con_t * ipmi,ipmi_ll_stat_info_t * info)5335 lan_register_stat_handler(ipmi_con_t          *ipmi,
5336 			  ipmi_ll_stat_info_t *info)
5337 {
5338     lan_stat_info_t *nstat;
5339     lan_data_t      *lan = ipmi->con_data;
5340     int             i;
5341 
5342     nstat = ipmi_mem_alloc(sizeof(*nstat));
5343     if (!nstat)
5344 	return ENOMEM;
5345     memset(nstat, 0, sizeof(*nstat));
5346 
5347     for (i=0; i<NUM_STATS; i++)
5348 	ipmi_ll_con_stat_call_register(info, lan_stat_names[i],
5349 				       ipmi->name, &(nstat->stats[i]));
5350 
5351     if (!locked_list_add(lan->lan_stat_list, nstat, info)) {
5352 	for (i=0; i<NUM_STATS; i++)
5353 	    if (nstat->stats[i]) {
5354 		ipmi_ll_con_stat_call_unregister(info, nstat->stats[i]);
5355 		nstat->stats[i] = NULL;
5356 	    }
5357 	ipmi_mem_free(nstat);
5358 	return ENOMEM;
5359     }
5360 
5361     return 0;
5362 }
5363 
5364 static int
lan_unregister_stat_handler(ipmi_con_t * ipmi,ipmi_ll_stat_info_t * info)5365 lan_unregister_stat_handler(ipmi_con_t          *ipmi,
5366 			    ipmi_ll_stat_info_t *info)
5367 {
5368     lan_unreg_stat_info_t sinfo;
5369     lan_data_t            *lan = ipmi->con_data;
5370 
5371     sinfo.lan = lan;
5372     sinfo.cmpinfo = info;
5373     sinfo.found = 0;
5374     locked_list_iterate(lan->lan_stat_list, lan_unreg_stat_info,
5375 			&sinfo);
5376     if (sinfo.found)
5377 	return 0;
5378     else
5379 	return EINVAL;
5380 }
5381 
5382 static ipmi_args_t *get_startup_args(ipmi_con_t *ipmi);
5383 
5384 static unsigned int conf_order[] = {
5385     IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128
5386 };
5387 
5388 static unsigned int
most_secure_lanp_conf(void)5389 most_secure_lanp_conf(void)
5390 {
5391     unsigned int i, v;
5392     for (i=0; i<(sizeof(conf_order)/sizeof(unsigned int)); i++) {
5393 	v = conf_order[i];
5394 	if (confs[v])
5395 	    return v;
5396     }
5397 
5398     return IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
5399 }
5400 
5401 static unsigned int integ_order[] = {
5402     IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96,
5403     IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128,
5404     IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128
5405 };
5406 
5407 static unsigned int
most_secure_lanp_integ(void)5408 most_secure_lanp_integ(void)
5409 {
5410     unsigned int i, v;
5411     for (i=0; i<(sizeof(integ_order)/sizeof(unsigned int)); i++) {
5412 	v = integ_order[i];
5413 	if (integs[v])
5414 	    return v;
5415     }
5416 
5417     return IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
5418 }
5419 
5420 static unsigned int auth_order[] = {
5421     IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1,
5422     IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
5423 };
5424 
5425 static unsigned int
most_secure_lanp_auth(void)5426 most_secure_lanp_auth(void)
5427 {
5428     unsigned int i, v;
5429     for (i=0; i<(sizeof(auth_order)/sizeof(unsigned int)); i++) {
5430 	v = auth_order[i];
5431 	if (auths[v])
5432 	    return v;
5433     }
5434 
5435     return IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE;
5436 }
5437 
5438 static void
lan_disable(ipmi_con_t * ipmi)5439 lan_disable(ipmi_con_t *ipmi)
5440 {
5441     lan_data_t *lan = (lan_data_t *) ipmi->con_data;
5442 
5443     lan->disabled = 1;
5444 }
5445 
5446 int
ipmi_lanp_setup_con(ipmi_lanp_parm_t * parms,unsigned int num_parms,os_handler_t * handlers,void * user_data,ipmi_con_t ** new_con)5447 ipmi_lanp_setup_con(ipmi_lanp_parm_t *parms,
5448 		    unsigned int     num_parms,
5449 		    os_handler_t     *handlers,
5450 		    void             *user_data,
5451 		    ipmi_con_t       **new_con)
5452 {
5453     ipmi_con_t         *ipmi = NULL;
5454     lan_data_t         *lan = NULL;
5455     int                rv;
5456     unsigned int       i;
5457     unsigned int       count;
5458     struct sockaddr_in *pa;
5459     char               **ip_addrs = NULL;
5460     char               *tports[MAX_IP_ADDR];
5461     char               **ports = NULL;
5462     lan_conn_parms_t   cparm;
5463     int max_outstanding_msg_count = DEFAULT_MAX_OUTSTANDING_MSG_COUNT;
5464     unsigned int addr_family = AF_UNSPEC;
5465     unsigned int set_addr_family = AF_UNSPEC;
5466 
5467     memset(&cparm, 0, sizeof(cparm));
5468 
5469     /* Pick some secure defaults. */
5470     cparm.authtype = IPMI_AUTHTYPE_DEFAULT;
5471     cparm.privilege = IPMI_PRIVILEGE_ADMIN;
5472     cparm.conf = most_secure_lanp_conf();
5473     cparm.integ = most_secure_lanp_integ();
5474     cparm.auth = most_secure_lanp_auth();
5475     cparm.name_lookup_only = 1;
5476 
5477     for (i=0; i<num_parms; i++) {
5478 	switch (parms[i].parm_id) {
5479 	case IPMI_LANP_PARMID_AUTHTYPE:
5480 	    cparm.authtype = parms[i].parm_val;
5481 	    break;
5482 
5483 	case IPMI_LANP_PARMID_PRIVILEGE:
5484 	    cparm.privilege = parms[i].parm_val;
5485 	    break;
5486 
5487 	case IPMI_LANP_PARMID_PASSWORD:
5488 	    if (parms[i].parm_data_len > sizeof(cparm.password))
5489 		return EINVAL;
5490 	    memcpy(cparm.password, parms[i].parm_data, parms[i].parm_data_len);
5491 	    cparm.password_len = parms[i].parm_data_len;
5492 	    break;
5493 
5494 	case IPMI_LANP_PARMID_USERNAME:
5495 	    if (parms[i].parm_data_len > sizeof(cparm.username))
5496 		return EINVAL;
5497 	    memcpy(cparm.username, parms[i].parm_data, parms[i].parm_data_len);
5498 	    cparm.username_len = parms[i].parm_data_len;
5499 	    break;
5500 
5501 	case IPMI_LANP_PARMID_ADDRS:
5502 	    if (cparm.num_ip_addr
5503 		&& (cparm.num_ip_addr != parms[i].parm_data_len))
5504 		return EINVAL;
5505 	    if (parms[i].parm_data_len > MAX_IP_ADDR)
5506 		return EINVAL;
5507 	    ip_addrs = parms[i].parm_data;
5508 	    cparm.num_ip_addr = parms[i].parm_data_len;
5509 	    break;
5510 
5511 	case IPMI_LANP_PARMID_PORTS:
5512 	    if (cparm.num_ip_addr
5513 		&& (cparm.num_ip_addr != parms[i].parm_data_len))
5514 		return EINVAL;
5515 	    if (parms[i].parm_data_len > MAX_IP_ADDR)
5516 		return EINVAL;
5517 	    ports = parms[i].parm_data;
5518 	    cparm.num_ip_addr = parms[i].parm_data_len;
5519 	    break;
5520 
5521 	case IPMI_LANP_AUTHENTICATION_ALGORITHM:
5522 	    cparm.auth = parms[i].parm_val;
5523 	    if ((int) cparm.auth != IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK)
5524 	    {
5525 		if (cparm.auth >= 64)
5526 		    return EINVAL;
5527 		if ((cparm.auth < 0x30) && (!auths[cparm.auth]))
5528 		    return ENOSYS;
5529 	    }
5530 	    break;
5531 
5532 	case IPMI_LANP_INTEGRITY_ALGORITHM:
5533 	    cparm.integ = parms[i].parm_val;
5534 	    if ((int) cparm.integ != IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK)
5535 	    {
5536 		if (cparm.integ >= 64)
5537 		    return EINVAL;
5538 		if (cparm.integ
5539 		    && ((cparm.integ < 0x30) && (!integs[cparm.integ])))
5540 		    return ENOSYS;
5541 	    }
5542 	    break;
5543 
5544 	case IPMI_LANP_CONFIDENTIALITY_ALGORITHM:
5545 	    cparm.conf = parms[i].parm_val;
5546 	    if ((int)cparm.conf != IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK)
5547 	    {
5548 		if (cparm.conf >= 64)
5549 		    return EINVAL;
5550 		if (cparm.conf
5551 		    && ((cparm.conf < 0x30) && (!confs[cparm.conf])))
5552 		    return ENOSYS;
5553 	    }
5554 	    break;
5555 
5556 	case IPMI_LANP_NAME_LOOKUP_ONLY:
5557 	    cparm.name_lookup_only = parms[i].parm_val != 0;
5558 	    break;
5559 
5560 	case IPMI_LANP_BMC_KEY:
5561 	    if (parms[i].parm_data_len > sizeof(cparm.bmc_key))
5562 		return EINVAL;
5563 	    memcpy(cparm.bmc_key, parms[i].parm_data, parms[i].parm_data_len);
5564 	    cparm.bmc_key_len = parms[i].parm_data_len;
5565 	    break;
5566 
5567 	case IPMI_LANP_MAX_OUTSTANDING_MSG_COUNT:
5568 	    if ((parms[i].parm_val < 1)
5569 		|| (parms[i].parm_val > MAX_POSSIBLE_OUTSTANDING_MSG_COUNT))
5570 		return EINVAL;
5571 	    max_outstanding_msg_count = parms[i].parm_val;
5572 	    break;
5573 
5574 	case IPMI_LANP_ADDRESS_FAMILY:
5575 	    set_addr_family = addr_family = parms[i].parm_val;
5576 	    break;
5577 
5578 	default:
5579 	    return EINVAL;
5580 	}
5581     }
5582 
5583     if ((cparm.num_ip_addr == 0) || (ip_addrs == NULL))
5584 	return EINVAL;
5585     if (((int) cparm.authtype != IPMI_AUTHTYPE_DEFAULT)
5586 	&& (cparm.authtype != IPMI_AUTHTYPE_RMCP_PLUS)
5587 	&& ((cparm.authtype >= MAX_IPMI_AUTHS)
5588 	    || (ipmi_auths[cparm.authtype].authcode_init == NULL)))
5589 	return EINVAL;
5590     if ((cparm.num_ip_addr < 1) || (cparm.num_ip_addr > MAX_IP_ADDR))
5591 	return EINVAL;
5592 
5593     if (ports) {
5594 	for (i=0; i<MAX_IP_ADDR; i++)
5595 	    tports[i] = ports[i];
5596 	ports = tports;
5597     } else {
5598 	ports = tports;
5599 	for (i=0; i<MAX_IP_ADDR; i++)
5600 	    ports[i] = NULL;
5601     }
5602     for (i=0; i<MAX_IP_ADDR; i++) {
5603 	if (!ports[i])
5604 	    ports[i] = IPMI_LAN_STD_PORT_STR;
5605     }
5606 
5607     count = 0;
5608 #ifdef HAVE_GETADDRINFO
5609     for (i=0; i<cparm.num_ip_addr; i++) {
5610         struct addrinfo hints, *res0;
5611 
5612         memset(&hints, 0, sizeof(hints));
5613         if (count == 0)
5614             hints.ai_family = addr_family;
5615         else {
5616             /* Make sure all ip address are in the same protocol family*/
5617 	    struct sockaddr_in *paddr;
5618 	    paddr = (struct sockaddr_in *)&(cparm.ip_addr[0]);
5619             hints.ai_family = paddr->sin_family;
5620 	}
5621         hints.ai_socktype = SOCK_DGRAM;
5622         rv = getaddrinfo(ip_addrs[i], ports[i], &hints, &res0);
5623 	if (rv)
5624 	    return EINVAL;
5625 
5626 	if (res0->ai_addrlen > sizeof(cparm.ip_addr[count].s_ipsock)) {
5627 	    freeaddrinfo(res0);
5628 	    return EFBIG;
5629 	}
5630 
5631 	/* Only get the first choices */
5632 	memcpy(&(cparm.ip_addr[count].s_ipsock), res0->ai_addr,
5633 	       res0->ai_addrlen);
5634 	cparm.ip_addr[count].ip_addr_len = res0->ai_addrlen;
5635 	count++;
5636 	freeaddrinfo(res0);
5637     }
5638 #else
5639     /* System does not support getaddrinfo, just for IPv4 */
5640     if (addr_family == AF_UNSPEC)
5641 	addr_family = AF_INET;
5642     else if (addr_family != AF_INET)
5643 	return EINVAL;
5644     for (i=0; i<cparm.num_ip_addr; i++) {
5645 	struct hostent *ent;
5646 	struct sockaddr_in *paddr;
5647 	ent = gethostbyname(ip_addrs[i]);
5648 	if (!ent)
5649 	    return EINVAL;
5650 	paddr = (struct sockaddr_in *)&(cparm.ip_addr[i]);
5651         paddr->sin_family = AF_INET;
5652         paddr->sin_port = htons(atoi(ports[i]));
5653 	if (ent->h_length > sizeof(paddr->sin_addr))
5654 	    return EFBIG;
5655 
5656 	memcpy(&(paddr->sin_addr), ent->h_addr_list[0], ent->h_length);
5657 	cparm.ip_addr[count].ip_addr_len = ent->h_length;
5658 	count++;
5659     }
5660 #endif
5661     if (count == 0)
5662 	return EINVAL;
5663     cparm.num_ip_addr = count;
5664 
5665     /* At this point we have a validated set of parms in cparm.  See
5666        if we alreay have one that matches. */
5667     lan = find_matching_lan(&cparm);
5668     if (lan) {
5669 	*new_con = lan->ipmi;
5670 	return 0;
5671     }
5672 
5673     ipmi = ipmi_mem_alloc(sizeof(*ipmi));
5674     if (!ipmi)
5675 	return ENOMEM;
5676     memset(ipmi, 0, sizeof(*ipmi));
5677 
5678     ipmi->user_data = user_data;
5679     ipmi->os_hnd = handlers;
5680     ipmi->con_type = "rmcp";
5681     ipmi->priv_level = cparm.privilege;
5682     for (i=0; i<MAX_IPMI_USED_CHANNELS; i++)
5683 	ipmi->ipmb_addr[i] = 0x20; /* Assume this until told otherwise */
5684 
5685     rv = ipmi_con_attr_init(ipmi);
5686     if (rv)
5687 	goto out_err;
5688 
5689     lan = ipmi_mem_alloc(sizeof(*lan));
5690     if (!lan) {
5691 	rv = ENOMEM;
5692 	goto out_err;
5693     }
5694     memset(lan, 0, sizeof(*lan));
5695     ipmi->con_data = lan;
5696     lan->cparm = cparm;
5697     for (i=0; i<cparm.num_ip_addr; i++) {
5698 	lan->cparm.ip_addr_str[i] = ipmi_strdup(ip_addrs[i]);
5699 	if (!lan->cparm.ip_addr_str[i]) {
5700 	    rv = ENOMEM;
5701 	    goto out_err;
5702 	}
5703 	lan->cparm.ip_port_str[i] = ipmi_strdup(ports[i]);
5704 	if (!lan->cparm.ip_port_str[i]) {
5705 	    rv = ENOMEM;
5706 	    goto out_err;
5707 	}
5708     }
5709 
5710     lan->refcount = 1;
5711     lan->users = 1;
5712     lan->ipmi = ipmi;
5713     for (i=0; i<MAX_IPMI_USED_CHANNELS; i++)
5714 	lan->slave_addr[i] = 0x20; /* Assume this until told otherwise */
5715     lan->is_active = 1;
5716     lan->chosen_authtype = IPMI_AUTHTYPE_DEFAULT;
5717     lan->curr_ip_addr = 0;
5718     lan->num_sends = 0;
5719     lan->connected = 0;
5720     lan->initialized = 0;
5721 
5722     lan->outstanding_msg_count = 0;
5723     lan->max_outstanding_msg_count = max_outstanding_msg_count;
5724     lan->addr_family = set_addr_family;
5725     lan->wait_q = NULL;
5726     lan->wait_q_tail = NULL;
5727 
5728     pa = (struct sockaddr_in *)&(lan->cparm.ip_addr[0]);
5729     lan->fd = find_free_lan_fd(pa->sin_family, lan, &lan->fd_slot);
5730     if (! lan->fd) {
5731 	rv = errno;
5732 	goto out_err;
5733     }
5734 
5735     /* Create the locks if they are available. */
5736     rv = ipmi_create_lock_os_hnd(handlers, &lan->seq_num_lock);
5737     if (rv)
5738 	goto out_err;
5739 
5740     rv = ipmi_create_lock_os_hnd(handlers, &lan->ip_lock);
5741     if (rv)
5742 	goto out_err;
5743 
5744     lan->con_change_handlers = locked_list_alloc(handlers);
5745     if (!lan->con_change_handlers) {
5746 	rv = ENOMEM;
5747 	goto out_err;
5748     }
5749 
5750     lan->event_handlers = locked_list_alloc(handlers);
5751     if (!lan->event_handlers) {
5752 	rv = ENOMEM;
5753 	goto out_err;
5754     }
5755 
5756     lan->ipmb_change_handlers = locked_list_alloc(handlers);
5757     if (!lan->ipmb_change_handlers) {
5758 	rv = ENOMEM;
5759 	goto out_err;
5760     }
5761 
5762     rv = ipmi_create_lock_os_hnd(handlers, &lan->con_change_lock);
5763     if (rv)
5764 	goto out_err;
5765 
5766     lan->lan_stat_list = locked_list_alloc(handlers);
5767     if (!lan->lan_stat_list) {
5768 	rv = ENOMEM;
5769 	goto out_err;
5770     }
5771 
5772     ipmi->start_con = lan_start_con;
5773     ipmi->set_ipmb_addr = lan_set_ipmb_addr;
5774     ipmi->add_ipmb_addr_handler = lan_add_ipmb_addr_handler;
5775     ipmi->remove_ipmb_addr_handler = lan_remove_ipmb_addr_handler;
5776     ipmi->add_con_change_handler = lan_add_con_change_handler;
5777     ipmi->remove_con_change_handler = lan_remove_con_change_handler;
5778     ipmi->send_command = lan_send_command;
5779     ipmi->add_event_handler = lan_add_event_handler;
5780     ipmi->remove_event_handler = lan_remove_event_handler;
5781     ipmi->send_response = lan_send_response;
5782     ipmi->register_for_command = lan_register_for_command;
5783     ipmi->deregister_for_command = lan_deregister_for_command;
5784     ipmi->close_connection = lan_close_connection;
5785     ipmi->close_connection_done = lan_close_connection_done;
5786     ipmi->handle_async_event = handle_async_event;
5787     ipmi->get_startup_args = get_startup_args;
5788     ipmi->use_connection = lan_use_connection;
5789     ipmi->send_command_option = lan_send_command_option;
5790     ipmi->get_num_ports = lan_get_num_ports;
5791     ipmi->get_port_info = lan_get_port_info;
5792     ipmi->register_stat_handler = lan_register_stat_handler;
5793     ipmi->unregister_stat_handler = lan_unregister_stat_handler;
5794     ipmi->disable = lan_disable;
5795 
5796     /* Add it to the list of valid IPMIs so it will validate.  This
5797        must be done last, after a point where it cannot fail. */
5798     lan_add_con(lan);
5799 
5800     *new_con = ipmi;
5801 
5802     return 0;
5803 
5804  out_err:
5805     cleanup_con(ipmi);
5806     return rv;
5807 }
5808 
5809 static void
snmp_got_match(lan_data_t * lan,const ipmi_msg_t * msg,const unsigned char * pet_ack)5810 snmp_got_match(lan_data_t          *lan,
5811 	       const ipmi_msg_t    *msg,
5812 	       const unsigned char *pet_ack)
5813 {
5814     ipmi_system_interface_addr_t si;
5815     ipmi_msg_t                   ack;
5816     int                          dummy_send_ip;
5817 
5818     si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
5819     si.channel = 0xf;
5820     si.lun = 0;
5821     handle_async_event(lan->ipmi, (ipmi_addr_t *) &si, sizeof(si), msg);
5822 
5823     /* Send the ack directly. */
5824     ack.netfn = IPMI_SENSOR_EVENT_NETFN;
5825     ack.cmd = IPMI_PET_ACKNOWLEDGE_CMD;
5826     ack.data = (unsigned char *) pet_ack;
5827     ack.data_len = 12;
5828     lan_send(lan, (ipmi_addr_t *) &si, sizeof(si), &ack, 0, &dummy_send_ip,
5829 	     NULL);
5830 }
5831 
5832 typedef struct lan_do_evt_s
5833 {
5834     lan_data_t          *lan;
5835     struct lan_do_evt_s *next;
5836 } lan_do_evt_t;
5837 
5838 int
ipmi_lan_handle_external_event(const struct sockaddr * src_addr,const ipmi_msg_t * msg,const unsigned char * pet_ack)5839 ipmi_lan_handle_external_event(const struct sockaddr *src_addr,
5840 			       const ipmi_msg_t      *msg,
5841 			       const unsigned char   *pet_ack)
5842 {
5843     lan_link_t   *l;
5844     lan_data_t   *lan;
5845     unsigned int i;
5846     unsigned int idx;
5847     lan_do_evt_t *found = NULL;
5848     lan_do_evt_t *next = NULL;
5849 
5850     idx = hash_lan_addr(src_addr);
5851     ipmi_lock(lan_list_lock);
5852     l = lan_ip_list[idx].next;
5853     /* Note that we call all the connections with the given IP
5854        address, not just the first one we find.  There may be more
5855        than one. */
5856     while (l->lan) {
5857 	lan = NULL;
5858 	for (i=0; i<l->lan->cparm.num_ip_addr; i++) {
5859 	    if (l->lan->cparm.ip_addr[i].s_ipsock.s_addr0.sa_family
5860 		!= src_addr->sa_family)
5861 	    {
5862 		continue;
5863 	    }
5864 	    switch (src_addr->sa_family)
5865 	    {
5866 	    case PF_INET:
5867 	    {
5868 		struct sockaddr_in *src, *dst;
5869 		src = (struct sockaddr_in *) src_addr;
5870 		dst = &(l->lan->cparm.ip_addr[i].s_ipsock.s_addr4);
5871 		if (dst->sin_addr.s_addr == src->sin_addr.s_addr) {
5872 		    /* We have a match, handle it */
5873 		    lan = l->lan;
5874 		    lan->refcount++;
5875 		}
5876 	    }
5877 	    break;
5878 #ifdef PF_INET6
5879 	    case PF_INET6:
5880 	    {
5881 		struct sockaddr_in6 *src, *dst;
5882 		src = (struct sockaddr_in6 *) src_addr;
5883 		dst = &(l->lan->cparm.ip_addr[i].s_ipsock.s_addr6);
5884 		if (memcmp(dst->sin6_addr.s6_addr,
5885 			   src->sin6_addr.s6_addr,
5886 			   sizeof(struct in6_addr))
5887 		    == 0)
5888 		{
5889 		    /* We have a match, handle it */
5890 		    lan = l->lan;
5891 		    lan->refcount++;
5892 		}
5893 	    }
5894 	    break;
5895 #endif
5896 	    }
5897 
5898 	    if (lan) {
5899 		next = ipmi_mem_alloc(sizeof(*next));
5900 		if (!next)
5901 		    /* Can't do anything, just go on.  It's not
5902 		       fatal, it just delays things. */
5903 		    continue;
5904 		next->lan = lan;
5905 		next->next = found;
5906 		found = next;
5907 	    }
5908 	}
5909 	l = l->next;
5910     }
5911     ipmi_unlock(lan_list_lock);
5912 
5913     while (found) {
5914 	next = found;
5915 	found = found->next;
5916 	snmp_got_match(next->lan, msg, pet_ack);
5917 	lan_put(next->lan->ipmi);
5918 	ipmi_mem_free(next);
5919     }
5920 
5921     /* Next will be left non-NULL if something was delivered, it will
5922        be NULL if nothing was delivered. */
5923     return next != NULL;
5924 }
5925 
5926 typedef struct lan_args_s
5927 {
5928     char            *str_addr[2];	/* parms 0, 1 */
5929     char            *str_port[2];	/* parms 2, 3 */
5930     int             num_addr;
5931     unsigned int    authtype;		/* parm 4 */
5932     unsigned int    privilege;		/* parm 5 */
5933     int             username_set;
5934     char            username[16];	/* parm 6 */
5935     unsigned int    username_len;
5936     int             password_set;
5937     char            password[20];	/* parm 7 */
5938     unsigned int    password_len;
5939 
5940     unsigned int    auth_alg;		/* parm 8 */
5941     unsigned int    integ_alg;		/* parm 9 */
5942     unsigned int    conf_alg;		/* parm 10 */
5943     unsigned int    name_lookup_only;	/* parm 11 */
5944     int             bmc_key_set;
5945     char            bmc_key[20];	/* parm 12 */
5946     unsigned int    bmc_key_len;
5947 
5948     unsigned int    hacks;		/* parms 13, 14 */
5949     unsigned int    max_outstanding_msgs;/* parm 15 */
5950 
5951     unsigned int    addr_family;	/* parm 16 */
5952 } lan_args_t;
5953 
5954 static const char *auth_range[] = { "default", "none", "md2", "md5",
5955 				    "straight", "oem", "rmcp+", NULL };
5956 static int auth_vals[] = { IPMI_AUTHTYPE_DEFAULT,
5957 			   IPMI_AUTHTYPE_NONE,
5958 			   IPMI_AUTHTYPE_MD2,
5959 			   IPMI_AUTHTYPE_MD5,
5960 			   IPMI_AUTHTYPE_STRAIGHT,
5961 			   IPMI_AUTHTYPE_OEM,
5962 			   IPMI_AUTHTYPE_RMCP_PLUS };
5963 
5964 static const char *priv_range[] = { "callback", "user", "operator", "admin",
5965 				    "oem", NULL };
5966 static int priv_vals[] = { IPMI_PRIVILEGE_CALLBACK,
5967 			   IPMI_PRIVILEGE_USER,
5968 			   IPMI_PRIVILEGE_OPERATOR,
5969 			   IPMI_PRIVILEGE_ADMIN,
5970 			   IPMI_PRIVILEGE_OEM };
5971 
5972 static const char *auth_alg_range[] = { "bmcpick", "rakp_none",
5973 					"rakp_hmac_sha1", "rakp_hmac_md5",
5974 					NULL };
5975 static int auth_alg_vals[] = { IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK,
5976 			       IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE,
5977 			       IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1,
5978 			       IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 };
5979 static const char *integ_alg_range[] = { "bmcpick", "none", "hmac_sha1",
5980 					"hmac_md5", "md5", NULL };
5981 static int integ_alg_vals[] = { IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK,
5982 				IPMI_LANP_INTEGRITY_ALGORITHM_NONE,
5983 				IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96,
5984 				IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128,
5985 				IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128 };
5986 
5987 static const char *conf_alg_range[] = { "bmcpick", "none", "aes_cbc_128",
5988 					"xrc4_128", "xrc4_40", NULL };
5989 static int conf_alg_vals[] = { IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK,
5990 			       IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE,
5991 			       IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128,
5992 			       IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_128,
5993 			       IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_40 };
5994 
5995 static const char *addr_family_range[] = { "af_unspec", "af_inet",
5996 #ifdef AF_INET6
5997 					   "af_inet6",
5998 #endif
5999 					   NULL };
6000 static int addr_family_vals[] = { AF_UNSPEC, AF_INET
6001 #ifdef AF_INET6
6002 	, AF_INET6
6003 #endif
6004 };
6005 
6006 
6007 static struct lan_argnum_info_s
6008 {
6009     const char *name;
6010     const char *type;
6011     const char *help;
6012     const char **range;
6013     const int  *values;
6014 } lan_argnum_info[18] =
6015 {
6016     { "Address",	"str",
6017       "*IP name or address of the MC",
6018       NULL, NULL },
6019     { "Port",		"str",
6020       "*IP port or port name for the MC",
6021       NULL, NULL },
6022     { "Address2",	"str",
6023       "IP name or address of a second connection to the same MC",
6024       NULL, NULL },
6025     { "Port2",		"str",
6026       "IP port or portname for a second connection to the same MC",
6027       NULL, NULL },
6028     { "Authtype",	"enum",
6029       "Authentication to use for the connection",
6030       auth_range, auth_vals },
6031     { "Privilege",	"enum",
6032       "Privilege level to use for the connection",
6033       priv_range, priv_vals },
6034     { "Username",	"str",
6035       "The user name to use for the connection",
6036       NULL, NULL },
6037     { "Password",	"str",
6038       "!The password to use for the connection",
6039       NULL, NULL },
6040     { "Authentication_Algorithm",	"enum",
6041       "Authentication algorithm to use for the connection, for RMCP+ only",
6042       auth_alg_range, auth_alg_vals },
6043     { "Integrity_Algorithm",	"enum",
6044       "Integrity algorithm to use for the connection, for RMCP+ only",
6045       integ_alg_range, integ_alg_vals },
6046     { "Confidentiality_Algorithm",	"enum",
6047       "Confidentiality algorithm to use for the connection, for RMCP+ only",
6048       conf_alg_range, conf_alg_vals },
6049     { "Name_Lookup_Only",	"bool",
6050       "Use only the name, not the privilege, for selecting the password",
6051       NULL, NULL },
6052     { "BMC_Key",		"str",
6053       "The key to use for connecting to the BMC, may or may not be required",
6054       NULL, NULL },
6055     { "RAKP3_Wrong_RoleM",	"bool",
6056       "Some systems use the wrong RoleM value for RAKP3, a common problem",
6057       NULL, NULL },
6058     { "RMCP_Integ_SIK",		"bool",
6059       "The IPMI 2.0 Spec was unclear which integrity key to use",
6060       NULL, NULL },
6061     { "Max_Outstanding_Msgs",	"int",
6062       "How many outstanding messages on the connection, range 1-63",
6063       NULL, NULL },
6064     { "Address_Family",	"enum",
6065       "Specified address family (AF_INET or AF_INET6) or AF_UNSPEC",
6066       addr_family_range, addr_family_vals },
6067 
6068     { NULL },
6069 };
6070 
6071 static ipmi_args_t *lan_con_alloc_args(void);
6072 
6073 static void
lan_free_args(ipmi_args_t * args)6074 lan_free_args(ipmi_args_t *args)
6075 {
6076     lan_args_t *largs = i_ipmi_args_get_extra_data(args);
6077 
6078     if (largs->str_addr[0])
6079 	ipmi_mem_free(largs->str_addr[0]);
6080     if (largs->str_addr[1])
6081 	ipmi_mem_free(largs->str_addr[1]);
6082     if (largs->str_port[0])
6083 	ipmi_mem_free(largs->str_port[0]);
6084     if (largs->str_port[1])
6085 	ipmi_mem_free(largs->str_port[1]);
6086     /* paranoia */
6087     memset(largs->password, 0, sizeof(largs->password));
6088     memset(largs->bmc_key, 0, sizeof(largs->bmc_key));
6089 }
6090 
6091 static ipmi_args_t *
get_startup_args(ipmi_con_t * ipmi)6092 get_startup_args(ipmi_con_t *ipmi)
6093 {
6094     ipmi_args_t      *args;
6095     lan_args_t       *largs;
6096     lan_data_t       *lan;
6097     lan_conn_parms_t *cparm;
6098 
6099     args = lan_con_alloc_args();
6100     if (! args)
6101 	return NULL;
6102     largs = i_ipmi_args_get_extra_data(args);
6103     lan = (lan_data_t *) ipmi->con_data;
6104     cparm = &lan->cparm;
6105     largs->str_addr[0] = ipmi_strdup(cparm->ip_addr_str[0]);
6106     if (!largs->str_addr[0])
6107 	goto out_err;
6108     largs->str_port[0] = ipmi_strdup(cparm->ip_port_str[0]);
6109     if (!largs->str_port[0])
6110 	goto out_err;
6111     if (cparm->num_ip_addr > 1) {
6112 	largs->str_addr[1] = ipmi_strdup(cparm->ip_addr_str[1]);
6113 	if (!largs->str_addr[1])
6114 	    goto out_err;
6115 	largs->str_port[1] = ipmi_strdup(cparm->ip_port_str[1]);
6116 	if (!largs->str_port[1])
6117 	    goto out_err;
6118     }
6119     largs->num_addr = cparm->num_ip_addr;
6120     largs->authtype = cparm->authtype;
6121     largs->privilege = cparm->privilege;
6122     if (cparm->username_len) {
6123 	largs->username_len = cparm->username_len ;
6124 	memcpy(largs->username, cparm->username, cparm->username_len);
6125 	largs->username_set = 1;
6126     }
6127     if (cparm->password_len) {
6128 	largs->password_len = cparm->password_len ;
6129 	memcpy(largs->password, cparm->password, cparm->password_len);
6130 	largs->password_set = 1;
6131     }
6132     largs->conf_alg = cparm->conf;
6133     largs->auth_alg = cparm->auth;
6134     largs->integ_alg = cparm->integ;
6135     largs->name_lookup_only = cparm->name_lookup_only;
6136     largs->hacks = ipmi->hacks;
6137     if (cparm->bmc_key_len) {
6138 	largs->bmc_key_len = cparm->bmc_key_len ;
6139 	memcpy(largs->bmc_key, cparm->bmc_key, cparm->bmc_key_len);
6140 	largs->bmc_key_set = 1;
6141     }
6142     largs->max_outstanding_msgs = lan->max_outstanding_msg_count;
6143     largs->addr_family = lan->addr_family;
6144     return args;
6145 
6146  out_err:
6147     lan_free_args(args);
6148     return NULL;
6149 }
6150 
6151 static int
lan_connect_args(ipmi_args_t * args,os_handler_t * handlers,void * user_data,ipmi_con_t ** con)6152 lan_connect_args(ipmi_args_t  *args,
6153 		 os_handler_t *handlers,
6154 		 void         *user_data,
6155 		 ipmi_con_t   **con)
6156 {
6157     lan_args_t       *largs = i_ipmi_args_get_extra_data(args);
6158     int              i;
6159     ipmi_lanp_parm_t parms[13];
6160     int              rv;
6161 
6162     i = 0;
6163     parms[i].parm_id = IPMI_LANP_PARMID_ADDRS;
6164     parms[i].parm_data = largs->str_addr;
6165     parms[i].parm_data_len = largs->num_addr;
6166     i++;
6167     parms[i].parm_id = IPMI_LANP_PARMID_PORTS;
6168     parms[i].parm_data = largs->str_port;
6169     parms[i].parm_data_len = largs->num_addr;
6170     i++;
6171     parms[i].parm_id = IPMI_LANP_PARMID_AUTHTYPE;
6172     parms[i].parm_val = largs->authtype;
6173     i++;
6174     parms[i].parm_id = IPMI_LANP_PARMID_PRIVILEGE;
6175     parms[i].parm_val = largs->privilege;
6176     i++;
6177     if (largs->username_set) {
6178 	parms[i].parm_id = IPMI_LANP_PARMID_USERNAME;
6179 	parms[i].parm_data = largs->username;
6180 	parms[i].parm_data_len = largs->username_len;
6181 	i++;
6182     }
6183     if (largs->password_set) {
6184 	parms[i].parm_id = IPMI_LANP_PARMID_PASSWORD;
6185 	parms[i].parm_data = largs->password;
6186 	parms[i].parm_data_len = largs->password_len;
6187 	i++;
6188     }
6189     parms[i].parm_id = IPMI_LANP_AUTHENTICATION_ALGORITHM;
6190     parms[i].parm_val = largs->auth_alg;
6191     i++;
6192     parms[i].parm_id = IPMI_LANP_INTEGRITY_ALGORITHM;
6193     parms[i].parm_val = largs->integ_alg;
6194     i++;
6195     parms[i].parm_id = IPMI_LANP_CONFIDENTIALITY_ALGORITHM;
6196     parms[i].parm_val = largs->conf_alg;
6197     i++;
6198     parms[i].parm_id = IPMI_LANP_NAME_LOOKUP_ONLY;
6199     parms[i].parm_val = largs->name_lookup_only;
6200     i++;
6201     if (largs->bmc_key_set) {
6202 	parms[i].parm_id = IPMI_LANP_BMC_KEY;
6203 	parms[i].parm_data = largs->bmc_key;
6204 	parms[i].parm_data_len = largs->bmc_key_len;
6205 	i++;
6206     }
6207     parms[i].parm_id = IPMI_LANP_MAX_OUTSTANDING_MSG_COUNT;
6208     parms[i].parm_val = largs->max_outstanding_msgs;
6209     i++;
6210     parms[i].parm_id = IPMI_LANP_ADDRESS_FAMILY;
6211     parms[i].parm_val = largs->addr_family;
6212     i++;
6213     rv = ipmi_lanp_setup_con(parms, i, handlers, user_data, con);
6214     if (!rv)
6215 	(*con)->hacks = largs->hacks;
6216     return rv;
6217 }
6218 
6219 static int
get_str_val(char ** dest,const char * data,int * is_set,unsigned int * len)6220 get_str_val(char **dest, const char *data, int *is_set, unsigned int *len)
6221 {
6222     char *rval = NULL;
6223     if (!dest)
6224 	return 0;
6225     if (is_set && (! *is_set)) {
6226 	*dest = NULL;
6227 	return 0;
6228     }
6229     if (data) {
6230 	if (len) {
6231 	    rval = ipmi_mem_alloc(*len+1);
6232 	    if (!rval)
6233 		return ENOMEM;
6234 	    memcpy(rval, data, *len);
6235 	    rval[*len] = '\0';
6236 	} else {
6237 	    rval = ipmi_strdup(data);
6238 	    if (!rval)
6239 		return ENOMEM;
6240 	}
6241 	*dest = rval;
6242     } else {
6243 	*dest = NULL;
6244     }
6245     return 0;
6246 }
6247 
6248 static int
get_enum_val(int argnum,char ** dest,int data,const char *** rrange)6249 get_enum_val(int argnum, char **dest, int data, const char ***rrange)
6250 {
6251     char       *rval = NULL;
6252     const int  *values;
6253     const char **range;
6254     int        i;
6255 
6256     if (rrange)
6257 	*rrange = lan_argnum_info[argnum].range;
6258 
6259     if (!dest)
6260 	return 0;
6261 
6262     values = lan_argnum_info[argnum].values;
6263     range = lan_argnum_info[argnum].range;
6264     for (i=0; range[i]; i++) {
6265 	if (values[i] == data) {
6266 	    rval = ipmi_strdup(lan_argnum_info[argnum].range[i]);
6267 	    if (!rval)
6268 		return ENOMEM;
6269 	    *dest = rval;
6270 	    return 0;
6271 	}
6272     }
6273     return EINVAL;
6274 }
6275 
6276 static int
get_bool_val(char ** dest,int data,unsigned int bit)6277 get_bool_val(char **dest, int data, unsigned int bit)
6278 {
6279     char *rval = NULL;
6280 
6281     if (!dest)
6282 	return 0;
6283     if (data & bit)
6284 	rval = ipmi_strdup("true");
6285     else
6286 	rval = ipmi_strdup("false");
6287     if (!rval)
6288 	return ENOMEM;
6289     *dest = rval;
6290     return 0;
6291 }
6292 
6293 static int
get_int_val(char ** dest,int data)6294 get_int_val(char **dest, int data)
6295 {
6296     char *rval = NULL;
6297     int len;
6298 
6299     if (!dest)
6300 	return 0;
6301     len = snprintf(NULL, 0, "%d", data);
6302     rval = malloc(len+1);
6303     if (!rval)
6304 	return ENOMEM;
6305     snprintf(rval, len+1, "%d", data);
6306     *dest = rval;
6307     return 0;
6308 }
6309 
6310 static const char *
lan_args_get_type(ipmi_args_t * args)6311 lan_args_get_type(ipmi_args_t *args)
6312 {
6313     return "lan";
6314 }
6315 
6316 static int
lan_args_get_val(ipmi_args_t * args,unsigned int argnum,const char ** name,const char ** type,const char ** help,char ** value,const char *** range)6317 lan_args_get_val(ipmi_args_t  *args,
6318 		 unsigned int argnum,
6319 		 const char   **name,
6320 		 const char   **type,
6321 		 const char   **help,
6322 		 char         **value,
6323 		 const char   ***range)
6324 {
6325     lan_args_t *largs = i_ipmi_args_get_extra_data(args);
6326     int        rv;
6327 
6328     switch(argnum) {
6329     case 0:
6330 	rv = get_str_val(value, largs->str_addr[0], NULL, NULL);
6331 	break;
6332 
6333     case 1:
6334 	rv = get_str_val(value, largs->str_port[0], NULL, NULL);
6335 	break;
6336 
6337     case 2:
6338 	rv = get_str_val(value, largs->str_addr[1], NULL, NULL);
6339 	break;
6340 
6341     case 3:
6342 	rv = get_str_val(value, largs->str_port[1], NULL, NULL);
6343 	break;
6344 
6345     case 4:
6346 	rv = get_enum_val(argnum, value, largs->authtype, range);
6347 	break;
6348 
6349     case 5:
6350 	rv = get_enum_val(argnum, value, largs->privilege, range);
6351 	break;
6352 
6353     case 6:
6354 	rv = get_str_val(value, largs->username, &largs->username_set,
6355 			 &largs->username_len);
6356 	break;
6357 
6358     case 7:
6359 	rv = get_str_val(value, largs->password, &largs->password_set,
6360 			 &largs->password_len);
6361 	break;
6362 
6363     case 8:
6364 	rv = get_enum_val(argnum, value, largs->auth_alg, range);
6365 	break;
6366 
6367     case 9:
6368 	rv = get_enum_val(argnum, value, largs->integ_alg, range);
6369 	break;
6370 
6371     case 10:
6372 	rv = get_enum_val(argnum, value, largs->conf_alg, range);
6373 	break;
6374 
6375     case 11:
6376 	rv = get_bool_val(value, largs->name_lookup_only, 1);
6377 	break;
6378 
6379     case 12:
6380 	rv = get_str_val(value, largs->bmc_key, &largs->bmc_key_set,
6381 			 &largs->bmc_key_len);
6382 	break;
6383 
6384     case 13:
6385 	rv = get_bool_val(value, largs->hacks,
6386 			  IPMI_CONN_HACK_RAKP3_WRONG_ROLEM);
6387 	break;
6388 
6389     case 14:
6390 	rv = get_bool_val(value, largs->hacks,
6391 			  IPMI_CONN_HACK_RMCPP_INTEG_SIK);
6392 	break;
6393 
6394     case 15:
6395 	rv = get_int_val(value, largs->max_outstanding_msgs);
6396 	break;
6397 
6398     case 16:
6399 	rv = get_enum_val(argnum, value, largs->addr_family, range);
6400 	break;
6401 
6402     default:
6403 	return E2BIG;
6404     }
6405 
6406     if (rv)
6407 	return rv;
6408 
6409     if (name)
6410 	*name = lan_argnum_info[argnum].name;
6411     if (type)
6412 	*type = lan_argnum_info[argnum].type;
6413     if (help)
6414 	*help = lan_argnum_info[argnum].help;
6415 
6416     return 0;
6417 }
6418 
6419 static int
set_str_val(char ** dest,const char * value,int null_ok,int * is_set,unsigned int * len,unsigned int max_len)6420 set_str_val(char **dest, const char *value, int null_ok, int *is_set,
6421 	    unsigned int *len, unsigned int max_len)
6422 {
6423     char *rval;
6424 
6425     if (! value) {
6426 	if (! null_ok)
6427 	    return EINVAL;
6428 	*dest = NULL;
6429 	if (is_set)
6430 	    *is_set = 0;
6431 	return 0;
6432     }
6433 
6434     if (len) {
6435 	unsigned int nlen = strlen(value);
6436 	if (nlen > max_len)
6437 	    return EINVAL;
6438 	memcpy(*dest, value, nlen);
6439 	*len = nlen;
6440     } else {
6441 	rval = ipmi_strdup(value);
6442 	if (!rval)
6443 	    return ENOMEM;
6444 	if (*dest)
6445 	    ipmi_mem_free(*dest);
6446 	*dest = rval;
6447     }
6448     if (is_set)
6449 	*is_set = 1;
6450     return 0;
6451 }
6452 
6453 static int
set_enum_val(int argnum,unsigned int * dest,const char * value)6454 set_enum_val(int argnum, unsigned int *dest, const char *value)
6455 {
6456     const char **range;
6457     int        i;
6458 
6459     if (! value)
6460 	return EINVAL;
6461 
6462     range = lan_argnum_info[argnum].range;
6463     for (i=0; range[i]; i++) {
6464 	if (strcmp(range[i], value) == 0) {
6465 	    *dest = lan_argnum_info[argnum].values[i];
6466 	    return 0;
6467 	}
6468     }
6469     return EINVAL;
6470 }
6471 
6472 static int
set_bool_val(unsigned int * dest,const char * value,unsigned int bit)6473 set_bool_val(unsigned int *dest, const char *value, unsigned int bit)
6474 {
6475     if (! value)
6476 	return EINVAL;
6477 
6478     if (strcmp(value, "true") == 0)
6479 	*dest |= bit;
6480     else if (strcmp(value, "false") == 0)
6481 	*dest &= ~bit;
6482     else
6483 	return EINVAL;
6484     return 0;
6485 }
6486 
6487 static int
set_uint_val(unsigned int * dest,const char * value)6488 set_uint_val(unsigned int *dest, const char *value)
6489 {
6490     int val;
6491     char *end;
6492 
6493     if (! value)
6494 	return EINVAL;
6495     if (*value == '\0')
6496 	return EINVAL;
6497 
6498     val = strtoul(value, &end, 0);
6499     if (*end != '\0')
6500 	return EINVAL;
6501     *dest = val;
6502     return 0;
6503 }
6504 
6505 static int
lan_args_set_val(ipmi_args_t * args,unsigned int argnum,const char * name,const char * value)6506 lan_args_set_val(ipmi_args_t  *args,
6507 		 unsigned int argnum,
6508 		 const char   *name,
6509 		 const char   *value)
6510 {
6511     lan_args_t   *largs = i_ipmi_args_get_extra_data(args);
6512     int          rv;
6513     char         *sval;
6514 
6515     if (name) {
6516 	int i;
6517 	for (i=0; lan_argnum_info[i].name; i++) {
6518 	    if (strcmp(lan_argnum_info[i].name, name) == 0)
6519 		break;
6520 	}
6521 	if (! lan_argnum_info[i].name)
6522 	    return EINVAL;
6523 	argnum = i;
6524     }
6525 
6526     switch (argnum) {
6527     case 0:
6528 	rv = set_str_val(&(largs->str_addr[0]), value, 0, NULL, NULL, 0);
6529 	if (!rv && (largs->num_addr == 0))
6530 	    largs->num_addr = 1;
6531 	break;
6532 
6533     case 1:
6534 	rv = set_str_val(&(largs->str_port[0]), value, 1, NULL, NULL, 0);
6535 	break;
6536 
6537     case 2:
6538 	rv = set_str_val(&(largs->str_addr[1]), value, 1, NULL, NULL, 0);
6539 	if (!rv) {
6540 	    if (largs->str_addr[1]) {
6541 		if (largs->num_addr < 2)
6542 		    largs->num_addr = 2;
6543 	    } else {
6544 		if (largs->str_addr[0])
6545 		    largs->num_addr = 1;
6546 		else
6547 		    largs->num_addr = 0;
6548 	    }
6549 	}
6550 	break;
6551 
6552     case 3:
6553 	rv = set_str_val(&(largs->str_port[1]), value, 1, NULL, NULL, 0);
6554 	break;
6555 
6556     case 4:
6557 	rv = set_enum_val(argnum, &largs->authtype, value);
6558 	break;
6559 
6560     case 5:
6561 	rv = set_enum_val(argnum, &largs->privilege, value);
6562 	break;
6563 
6564     case 6:
6565 	sval = largs->username;
6566 	rv = set_str_val(&sval, value, 1, &largs->username_set,
6567 			 &largs->username_len, 16);
6568 	break;
6569 
6570     case 7:
6571 	sval = largs->password;
6572 	rv = set_str_val(&sval, value, 1, &largs->password_set,
6573 			 &largs->password_len, 20);
6574 	break;
6575 
6576     case 8:
6577 	rv = set_enum_val(argnum, &largs->auth_alg, value);
6578 	break;
6579 
6580     case 9:
6581 	rv = set_enum_val(argnum, &largs->integ_alg, value);
6582 	break;
6583 
6584     case 10:
6585 	rv = set_enum_val(argnum, &largs->conf_alg, value);
6586 	break;
6587 
6588     case 11:
6589 	rv = set_bool_val(&largs->name_lookup_only, value, 1);
6590 	break;
6591 
6592     case 12:
6593 	sval = largs->bmc_key;
6594 	rv = set_str_val(&sval, value, 1, &largs->bmc_key_set,
6595 			 &largs->bmc_key_len, 20);
6596 	break;
6597 
6598     case 13:
6599 	rv = set_bool_val(&largs->hacks, value,
6600 			  IPMI_CONN_HACK_RAKP3_WRONG_ROLEM);
6601 	break;
6602 
6603     case 14:
6604 	rv = set_bool_val(&largs->hacks, value,
6605 			  IPMI_CONN_HACK_RMCPP_INTEG_SIK);
6606 	break;
6607 
6608     case 15:
6609 	rv = set_uint_val(&largs->max_outstanding_msgs, value);
6610 	break;
6611 
6612     case 16:
6613 	rv = set_enum_val(argnum, &largs->addr_family, value);
6614 	break;
6615 
6616     default:
6617 	rv = E2BIG;
6618     }
6619 
6620     return rv;
6621 }
6622 
6623 static ipmi_args_t *
lan_args_copy(ipmi_args_t * args)6624 lan_args_copy(ipmi_args_t *args)
6625 {
6626     ipmi_args_t *nargs;
6627     lan_args_t  *largs = i_ipmi_args_get_extra_data(args);
6628     lan_args_t  *nlargs;
6629 
6630     nargs = lan_con_alloc_args();
6631     if (!nargs)
6632 	return NULL;
6633     nlargs = i_ipmi_args_get_extra_data(nargs);
6634     *nlargs = *largs;
6635 
6636     nlargs->str_addr[0] = NULL;
6637     nlargs->str_addr[1] = NULL;
6638     nlargs->str_port[0] = NULL;
6639     nlargs->str_port[1] = NULL;
6640 
6641     nlargs->str_addr[0] = ipmi_strdup(largs->str_addr[0]);
6642     if (! nlargs->str_addr[0])
6643 	goto out_err;
6644     nlargs->str_addr[1] = ipmi_strdup(largs->str_addr[1]);
6645     if (! nlargs->str_addr[1])
6646 	goto out_err;
6647     nlargs->str_port[0] = ipmi_strdup(largs->str_port[0]);
6648     if (! nlargs->str_port[0])
6649 	goto out_err;
6650     nlargs->str_port[1] = ipmi_strdup(largs->str_port[1]);
6651     if (! nlargs->str_port[1])
6652 	goto out_err;
6653 
6654     return nargs;
6655 
6656  out_err:
6657     lan_free_args(nargs);
6658     return NULL;
6659 }
6660 
6661 static int
lan_args_validate(ipmi_args_t * args,int * argnum)6662 lan_args_validate(ipmi_args_t *args, int *argnum)
6663 {
6664     return 1; /* Can't be invalid */
6665 }
6666 
6667 static void
lan_args_free_val(ipmi_args_t * args,char * value)6668 lan_args_free_val(ipmi_args_t *args, char *value)
6669 {
6670     ipmi_mem_free(value);
6671 }
6672 
6673 #define CHECK_ARG \
6674     do { \
6675         if (*curr_arg >= arg_count) { \
6676 	    rv = EINVAL; \
6677 	    goto out_err; \
6678         } \
6679     } while(0)
6680 
6681 static int
lan_parse_args(int * curr_arg,int arg_count,char * const * args,ipmi_args_t ** iargs)6682 lan_parse_args(int         *curr_arg,
6683 	       int         arg_count,
6684 	       char        * const *args,
6685 	       ipmi_args_t **iargs)
6686 {
6687     int         rv;
6688     ipmi_args_t *p = NULL;
6689     lan_args_t  *largs;
6690     int         i;
6691     int         len;
6692 
6693     CHECK_ARG;
6694 
6695     p = lan_con_alloc_args();
6696     if (!p)
6697 	return ENOMEM;
6698 
6699     largs = i_ipmi_args_get_extra_data(p);
6700     largs->num_addr = 1;
6701 
6702     while (*curr_arg < arg_count) {
6703 	if (args[*curr_arg][0] != '-') {
6704 	    break;
6705 	}
6706 
6707 	if (strcmp(args[*curr_arg], "-U") == 0) {
6708 	    (*curr_arg)++; CHECK_ARG;
6709 	    len = strlen(args[*curr_arg]);
6710 	    if (len > 16)
6711 		len = 16;
6712 	    memcpy(largs->username, args[*curr_arg], len);
6713 	    largs->username_set = 1;
6714 	    largs->username_len = len;
6715 	} else if (strcmp(args[*curr_arg], "-P") == 0) {
6716 	    (*curr_arg)++; CHECK_ARG;
6717 	    len = strlen(args[*curr_arg]);
6718 	    if (len > 20)
6719 		len = 20;
6720 	    memcpy(largs->password, args[*curr_arg], len);
6721 	    largs->password_set = 1;
6722 	    largs->password_len = len;
6723 	} else if (strcmp(args[*curr_arg], "-H") == 0) {
6724 	    (*curr_arg)++; CHECK_ARG;
6725 	    if (strcmp(args[*curr_arg], "intelplus") == 0)
6726 		largs->hacks |= IPMI_CONN_HACK_RAKP3_WRONG_ROLEM;
6727 	    else if (strcmp(args[*curr_arg], "rakp3_wrong_rolem") == 0)
6728 		largs->hacks |= IPMI_CONN_HACK_RAKP3_WRONG_ROLEM;
6729 	    else if (strcmp(args[*curr_arg], "rmcpp_integ_sik") == 0)
6730 		largs->hacks |= IPMI_CONN_HACK_RMCPP_INTEG_SIK;
6731 	    /* Ignore unknown hacks. */
6732 	} else if (strcmp(args[*curr_arg], "-4") == 0) {
6733 		largs->addr_family = AF_INET;
6734 #ifdef AF_INET6
6735 	} else if (strcmp(args[*curr_arg], "-6") == 0) {
6736 		largs->addr_family = AF_INET6;
6737 #endif
6738 	} else if (strcmp(args[*curr_arg], "-s") == 0) {
6739 	    largs->num_addr = 2;
6740 	} else if (strcmp(args[*curr_arg], "-A") == 0) {
6741 	    (*curr_arg)++; CHECK_ARG;
6742 	    if (strcmp(args[*curr_arg], "none") == 0) {
6743 		largs->authtype = IPMI_AUTHTYPE_NONE;
6744 	    } else if (strcmp(args[*curr_arg], "md2") == 0) {
6745 		largs->authtype = IPMI_AUTHTYPE_MD2;
6746 	    } else if (strcmp(args[*curr_arg], "md5") == 0) {
6747 		largs->authtype = IPMI_AUTHTYPE_MD5;
6748 	    } else if (strcmp(args[*curr_arg], "straight") == 0) {
6749 		largs->authtype = IPMI_AUTHTYPE_STRAIGHT;
6750 	    } else if (strcmp(args[*curr_arg], "rmcp+") == 0) {
6751 		largs->authtype = IPMI_AUTHTYPE_RMCP_PLUS;
6752 	    } else {
6753 		rv = EINVAL;
6754 		goto out_err;
6755 	    }
6756 	} else if (strcmp(args[*curr_arg], "-L") == 0) {
6757 	    (*curr_arg)++; CHECK_ARG;
6758 
6759 	    if (strcmp(args[*curr_arg], "callback") == 0) {
6760 		largs->privilege = IPMI_PRIVILEGE_CALLBACK;
6761 	    } else if (strcmp(args[*curr_arg], "user") == 0) {
6762 		largs->privilege = IPMI_PRIVILEGE_USER;
6763 	    } else if (strcmp(args[*curr_arg], "operator") == 0) {
6764 		largs->privilege = IPMI_PRIVILEGE_OPERATOR;
6765 	    } else if (strcmp(args[*curr_arg], "admin") == 0) {
6766 		largs->privilege = IPMI_PRIVILEGE_ADMIN;
6767 	    } else if (strcmp(args[*curr_arg], "oem") == 0) {
6768 		largs->privilege = IPMI_PRIVILEGE_OEM;
6769 	    } else {
6770 		rv = EINVAL;
6771 		goto out_err;
6772 	    }
6773 	} else if (strcmp(args[*curr_arg], "-p") == 0) {
6774 	    (*curr_arg)++; CHECK_ARG;
6775 	    largs->str_port[0] = ipmi_strdup(args[*curr_arg]);
6776 	    if (largs->str_port[0] == NULL) {
6777 		rv = ENOMEM;
6778 		goto out_err;
6779 	    }
6780 	} else if (strcmp(args[*curr_arg], "-p2") == 0) {
6781 	    (*curr_arg)++; CHECK_ARG;
6782 	    largs->str_port[1] = ipmi_strdup(args[*curr_arg]);
6783 	    if (largs->str_port[1] == NULL) {
6784 		rv = ENOMEM;
6785 		goto out_err;
6786 	    }
6787 	} else if (strcmp(args[*curr_arg], "-Ra") == 0) {
6788 	    (*curr_arg)++; CHECK_ARG;
6789 
6790 	    if (strcmp(args[*curr_arg], "bmcpick") == 0) {
6791 		largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_BMCPICK;
6792 	    } else if (strcmp(args[*curr_arg], "rakp_none") == 0) {
6793 		largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_NONE;
6794 	    } else if (strcmp(args[*curr_arg], "rakp_hmac_sha1") == 0) {
6795 		largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1;
6796 	    } else if (strcmp(args[*curr_arg], "rakp_hmac_md5") == 0) {
6797 		largs->auth_alg = IPMI_LANP_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5;
6798 	    } else {
6799 		rv = EINVAL;
6800 		goto out_err;
6801 	    }
6802 	} else if (strcmp(args[*curr_arg], "-Ri") == 0) {
6803 	    (*curr_arg)++; CHECK_ARG;
6804 
6805 	    if (strcmp(args[*curr_arg], "bmcpick") == 0) {
6806 		largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_BMCPICK;
6807 	    } else if (strcmp(args[*curr_arg], "none") == 0) {
6808 		largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_NONE;
6809 	    } else if (strcmp(args[*curr_arg], "hmac_sha1") == 0) {
6810 		largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_SHA1_96;
6811 	    } else if (strcmp(args[*curr_arg], "hmac_md5") == 0) {
6812 		largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_HMAC_MD5_128;
6813 	    } else if (strcmp(args[*curr_arg], "md5") == 0) {
6814 		largs->integ_alg = IPMI_LANP_INTEGRITY_ALGORITHM_MD5_128;
6815 	    } else {
6816 		rv = EINVAL;
6817 		goto out_err;
6818 	    }
6819 	} else if (strcmp(args[*curr_arg], "-Rc") == 0) {
6820 	    (*curr_arg)++; CHECK_ARG;
6821 
6822 	    if (strcmp(args[*curr_arg], "bmcpick") == 0) {
6823 		largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_BMCPICK;
6824 	    } else if (strcmp(args[*curr_arg], "none") == 0) {
6825 		largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_NONE;
6826 	    } else if (strcmp(args[*curr_arg], "aes_cbc_128") == 0) {
6827 		largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_AES_CBC_128;
6828 	    } else if (strcmp(args[*curr_arg], "xrc4_128") == 0) {
6829 		largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_128;
6830 	    } else if (strcmp(args[*curr_arg], "xrc4_40") == 0) {
6831 		largs->conf_alg = IPMI_LANP_CONFIDENTIALITY_ALGORITHM_xRC4_40;
6832 	    } else {
6833 		rv = EINVAL;
6834 		goto out_err;
6835 	    }
6836 	} else if (strcmp(args[*curr_arg], "-Rl") == 0) {
6837 	    largs->name_lookup_only = 0;
6838 	} else if (strcmp(args[*curr_arg], "-Rk") == 0) {
6839 	    (*curr_arg)++; CHECK_ARG;
6840 	    len = strlen(args[*curr_arg]);
6841 	    if (len > 20)
6842 		len = 20;
6843 	    memcpy(largs->bmc_key, args[*curr_arg], len);
6844 	    largs->bmc_key_set = 1;
6845 	    largs->bmc_key_len = len;
6846 	} else if (strcmp(args[*curr_arg], "-M") == 0) {
6847 	    char *end;
6848 	    int val;
6849 	    (*curr_arg)++; CHECK_ARG;
6850 	    if (args[*curr_arg][0] == '\0') {
6851 		rv = EINVAL;
6852 		goto out_err;
6853 	    }
6854 	    val = strtol(args[*curr_arg], &end, 0);
6855 	    if (*end != '\0') {
6856 		rv = EINVAL;
6857 		goto out_err;
6858 	    }
6859 	    largs->max_outstanding_msgs = val;
6860 	}
6861 	(*curr_arg)++;
6862     }
6863 
6864     for (i=0; i<largs->num_addr; i++) {
6865 	CHECK_ARG;
6866 	largs->str_addr[i] = ipmi_strdup(args[*curr_arg]);
6867 	if (largs->str_addr[i] == NULL) {
6868 	    rv = ENOMEM;
6869 	    goto out_err;
6870 	}
6871 	(*curr_arg)++;
6872 	if (! largs->str_port[i]) {
6873 	    largs->str_port[i] = ipmi_strdup("623");
6874 	    if (largs->str_port[i] == NULL) {
6875 		rv = ENOMEM;
6876 		goto out_err;
6877 	    }
6878 	}
6879     }
6880 
6881     *iargs = p;
6882     return 0;
6883 
6884  out_err:
6885     if (p)
6886 	ipmi_free_args(p);
6887     return rv;
6888 }
6889 
6890 static const char *
lan_parse_help(void)6891 lan_parse_help(void)
6892 {
6893     return
6894 	"\n"
6895 	" lan [-U <username>] [-P <password>] [-p[2] port] [-A <authtype>]\n"
6896 	"     [-L <privilege>] [-s] [-Ra <auth alg>] [-Ri <integ alg>]\n"
6897 	"     [-Rc <conf algo>] [-Rl] [-Rk <bmc key>] [-H <hackname>]\n"
6898 	"     [-4] [-6] [-M <max outstanding msgs>] <host1> [<host2>]\n"
6899 	"If -s is supplied, then two host names are taken (the second port\n"
6900 	"may be specified with -p2).  Otherwise, only one hostname is\n"
6901 	"taken.  The defaults are an empty username and password (anonymous),\n"
6902 	"port 623, admin privilege, and authtype defaulting to the most\n"
6903 	"secure one available.\n"
6904 	"privilege is one of: callback, user, operator, admin, or oem.  These\n"
6905 	"select the specific commands that are available to the connection.\n"
6906 	"Higher privileges (ones further to the right in the above list) have\n"
6907 	"more commands available to them.\n"
6908 	"authtype is one of the following: rmcp+, md5, md2, straight, or none.\n"
6909 	"Setting this to anything but rmcp+ forces normal rmcp\n"
6910 	"authentication.  By default the most secure method available is\n"
6911 	"chosen, in the order given above.\n"
6912 	"For RMCP+ connections, the authentication algorithms supported (-Ra)\n"
6913 	"are: bmcpick, rakp_none, rakp_hmac_sha1, and rakp_hmac_md5.  The\n"
6914 	"integrity algorithms (-Ri) supported are: bmcpick, none, hmac_sha1,\n"
6915 	"hmac_md5, and md5.  The confidentiality algorithms (-Rc) are: bmcpick,\n"
6916 	"aes_cbc_128, xrc4_128, and xrc_40.  The defaults are\n"
6917 	"rackp_hmac_sha1, hmac_sha1, and aes_cb_128.  -Rl turns on lookup up\n"
6918 	"names by the name and the privilege level (allowing the same name with\n"
6919 	"different privileges and different passwords), the default is straight\n"
6920 	"name lookup.  -Rk sets the BMC key, needed if the system does two-key\n"
6921 	"lookups.  The -M option sets the maximum outstanding messages.\n"
6922 	"The default is 2, ranges 1-63.\n"
6923 	"-4 and -6 force IPv4 and IPv6.  The default is unspecified.\n"
6924 	"The -H option enables certain hacks for broken platforms.  This may\n"
6925 	"be listed multiple times to enable multiple hacks.  The currently\n"
6926 	"available hacks are:\n"
6927 	"  intelplus - For Intel platforms that have broken RMCP+.\n"
6928 	"  rakp3_wrong_rolem - For systems that truncate role(m) in the RAKP3"
6929 	" msg.\n"
6930 	"  rmcpp_integ_sik - For systems that use SIK instead of K(1) for"
6931 	" integrity.";
6932 }
6933 
6934 static ipmi_args_t *
lan_con_alloc_args(void)6935 lan_con_alloc_args(void)
6936 {
6937     ipmi_args_t *args;
6938     lan_args_t  *largs;
6939     args = i_ipmi_args_alloc(lan_free_args, lan_connect_args,
6940 			     lan_args_get_val, lan_args_set_val,
6941 			     lan_args_copy, lan_args_validate,
6942 			     lan_args_free_val, lan_args_get_type,
6943 			     sizeof(lan_args_t));
6944     if (!args)
6945 	return NULL;
6946 
6947     largs = i_ipmi_args_get_extra_data(args);
6948 
6949     /* Set defaults */
6950     largs->authtype = IPMI_AUTHTYPE_DEFAULT;
6951     largs->privilege = IPMI_PRIVILEGE_ADMIN;
6952     largs->conf_alg = most_secure_lanp_conf();
6953     largs->integ_alg = most_secure_lanp_integ();
6954     largs->auth_alg = most_secure_lanp_auth();
6955     largs->name_lookup_only = 1;
6956     largs->max_outstanding_msgs = DEFAULT_MAX_OUTSTANDING_MSG_COUNT;
6957     /* largs->hacks = IPMI_CONN_HACK_RAKP3_WRONG_ROLEM; */
6958     largs->addr_family = AF_UNSPEC;
6959     return args;
6960 }
6961 
6962 static ipmi_con_setup_t *lan_setup;
6963 
6964 int
i_ipmi_lan_init(os_handler_t * os_hnd)6965 i_ipmi_lan_init(os_handler_t *os_hnd)
6966 {
6967     int rv;
6968     int i;
6969 
6970     rv = ipmi_create_global_lock(&lan_list_lock);
6971     if (rv)
6972 	return rv;
6973 
6974     rv = ipmi_create_global_lock(&fd_list_lock);
6975     if (rv)
6976 	return rv;
6977     memset(&fd_list, 0, sizeof(fd_list));
6978     fd_list.next = &fd_list;
6979     fd_list.prev = &fd_list;
6980     fd_list.cons_in_use = MAX_CONS_PER_FD;
6981 
6982 #ifdef PF_INET6
6983     rv = ipmi_create_global_lock(&fd6_list_lock);
6984     if (rv)
6985 	return rv;
6986     memset(&fd6_list, 0, sizeof(fd6_list));
6987     fd6_list.next = &fd6_list;
6988     fd6_list.prev = &fd6_list;
6989     fd6_list.cons_in_use = MAX_CONS_PER_FD;
6990 #endif
6991 
6992     for (i=0; i<LAN_HASH_SIZE; i++) {
6993 	lan_list[i].next = &(lan_list[i]);
6994 	lan_list[i].prev = &(lan_list[i]);
6995 	lan_list[i].lan = NULL;
6996 	lan_ip_list[i].next = &(lan_ip_list[i]);
6997 	lan_ip_list[i].prev = &(lan_ip_list[i]);
6998 	lan_ip_list[i].lan = NULL;
6999     }
7000 
7001     rv = ipmi_create_global_lock(&lan_payload_lock);
7002     if (rv)
7003 	return rv;
7004 
7005     rv = ipmi_create_global_lock(&lan_auth_lock);
7006     if (rv)
7007 	return rv;
7008 
7009     lan_setup = i_ipmi_alloc_con_setup(lan_parse_args, lan_parse_help,
7010 				       lan_con_alloc_args);
7011     if (! lan_setup)
7012 	return ENOMEM;
7013 
7014     rv = i_ipmi_register_con_type("lan", lan_setup);
7015     if (rv)
7016 	return rv;
7017 
7018     lan_os_hnd = os_hnd;
7019 
7020     return 0;
7021 }
7022 
7023 void
i_ipmi_lan_shutdown(void)7024 i_ipmi_lan_shutdown(void)
7025 {
7026     i_ipmi_unregister_con_type("lan", lan_setup);
7027     i_ipmi_free_con_setup(lan_setup);
7028     lan_setup = NULL;
7029 
7030     if (lan_list_lock) {
7031 	ipmi_destroy_lock(lan_list_lock);
7032 	lan_list_lock = NULL;
7033     }
7034     if (lan_payload_lock) {
7035 	ipmi_destroy_lock(lan_payload_lock);
7036 	lan_payload_lock = NULL;
7037     }
7038     while (oem_payload_list) {
7039 	payload_entry_t *e = oem_payload_list;
7040 	oem_payload_list = e->next;
7041 	ipmi_mem_free(e);
7042     }
7043     if (lan_auth_lock) {
7044 	ipmi_destroy_lock(lan_auth_lock);
7045 	lan_auth_lock = NULL;
7046     }
7047     while (oem_auth_list) {
7048 	auth_entry_t *e = oem_auth_list;
7049 	oem_auth_list = e->next;
7050 	ipmi_mem_free(e);
7051     }
7052     while (oem_conf_list) {
7053 	conf_entry_t *e = oem_conf_list;
7054 	oem_conf_list = e->next;
7055 	ipmi_mem_free(e);
7056     }
7057     while (oem_integ_list) {
7058 	integ_entry_t *e = oem_integ_list;
7059 	oem_integ_list = e->next;
7060 	ipmi_mem_free(e);
7061     }
7062     if (fd_list_lock) {
7063 	ipmi_destroy_lock(fd_list_lock);
7064 	fd_list_lock = NULL;
7065     }
7066     while (fd_list.next != &fd_list) {
7067 	lan_fd_t *e = fd_list.next;
7068 	e->next->prev = e->prev;
7069 	e->prev->next = e->next;
7070 	lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, e->fd_wait_id);
7071 	close(e->fd);
7072 	ipmi_destroy_lock(e->con_lock);
7073 	ipmi_mem_free(e);
7074     }
7075     while (fd_free_list) {
7076 	lan_fd_t *e = fd_free_list;
7077 	fd_free_list = e->next;
7078 	ipmi_destroy_lock(e->con_lock);
7079 	ipmi_mem_free(e);
7080     }
7081 #ifdef PF_INET6
7082     if (fd6_list_lock) {
7083 	ipmi_destroy_lock(fd6_list_lock);
7084 	fd6_list_lock = NULL;
7085     }
7086     while (fd6_list.next != &fd6_list) {
7087 	lan_fd_t *e = fd6_list.next;
7088 	e->next->prev = e->prev;
7089 	e->prev->next = e->next;
7090 	lan_os_hnd->remove_fd_to_wait_for(lan_os_hnd, e->fd_wait_id);
7091 	close(e->fd);
7092 	ipmi_destroy_lock(e->con_lock);
7093 	ipmi_mem_free(e);
7094     }
7095     while (fd6_free_list) {
7096 	lan_fd_t *e = fd6_free_list;
7097 	fd6_free_list = e->next;
7098 	ipmi_destroy_lock(e->con_lock);
7099 	ipmi_mem_free(e);
7100     }
7101 #endif
7102     lan_os_hnd = NULL;
7103 }
7104