xref: /openbmc/ipmitool/src/plugins/lan/lan.c (revision 30becb35)
1 /*
2  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistribution of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistribution in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * Neither the name of Sun Microsystems, Inc. or the names of
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * This software is provided "AS IS," without a warranty of any kind.
20  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  */
32 #define _GNU_SOURCE
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <inttypes.h>
37 #include <string.h>
38 #include <sys/time.h>
39 #include <sys/types.h>
40 #include <sys/select.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <errno.h>
45 #include <unistd.h>
46 #include <netdb.h>
47 #include <fcntl.h>
48 
49 #include <ipmitool/helper.h>
50 #include <ipmitool/log.h>
51 #include <ipmitool/bswap.h>
52 #include <ipmitool/ipmi.h>
53 #include <ipmitool/ipmi_sel.h>
54 #include <ipmitool/ipmi_intf.h>
55 #include <ipmitool/ipmi_oem.h>
56 #include <ipmitool/ipmi_strings.h>
57 #include <ipmitool/ipmi_constants.h>
58 #include <ipmitool/hpm2.h>
59 
60 #if HAVE_CONFIG_H
61 # include <config.h>
62 #endif
63 
64 #include "lan.h"
65 #include "rmcp.h"
66 #include "asf.h"
67 #include "auth.h"
68 
69 #define IPMI_LAN_TIMEOUT	2
70 #define IPMI_LAN_RETRY		4
71 #define IPMI_LAN_PORT		0x26f
72 #define IPMI_LAN_CHANNEL_E	0x0e
73 
74 /*
75  * LAN interface is required to support 45 byte request transactions and
76  * 42 byte response transactions.
77  */
78 #define IPMI_LAN_MAX_REQUEST_SIZE	38	/* 45 - 7 */
79 #define IPMI_LAN_MAX_RESPONSE_SIZE	34	/* 42 - 8 */
80 
81 extern const struct valstr ipmi_privlvl_vals[];
82 extern const struct valstr ipmi_authtype_session_vals[];
83 extern int verbose;
84 
85 struct ipmi_rq_entry * ipmi_req_entries;
86 static struct ipmi_rq_entry * ipmi_req_entries_tail;
87 static uint8_t bridge_possible = 0;
88 
89 static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len);
90 static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf);
91 static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf);
92 static int ipmi_lan_setup(struct ipmi_intf * intf);
93 static int ipmi_lan_keepalive(struct ipmi_intf * intf);
94 static struct ipmi_rs * ipmi_lan_recv_sol(struct ipmi_intf * intf);
95 static struct ipmi_rs * ipmi_lan_send_sol(struct ipmi_intf * intf,
96 					  struct ipmi_v2_payload * payload);
97 static struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req);
98 static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp);
99 static int ipmi_lan_open(struct ipmi_intf * intf);
100 static void ipmi_lan_close(struct ipmi_intf * intf);
101 static int ipmi_lan_ping(struct ipmi_intf * intf);
102 static void ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size);
103 static void ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size);
104 
105 struct ipmi_intf ipmi_lan_intf = {
106 	.name = "lan",
107 	.desc = "IPMI v1.5 LAN Interface",
108 	.setup = ipmi_lan_setup,
109 	.open = ipmi_lan_open,
110 	.close = ipmi_lan_close,
111 	.sendrecv = ipmi_lan_send_cmd,
112 	.sendrsp = ipmi_lan_send_rsp,
113 	.recv_sol = ipmi_lan_recv_sol,
114 	.send_sol = ipmi_lan_send_sol,
115 	.keepalive = ipmi_lan_keepalive,
116 	.set_max_request_data_size = ipmi_lan_set_max_rq_data_size,
117 	.set_max_response_data_size = ipmi_lan_set_max_rp_data_size,
118 	.target_addr = IPMI_BMC_SLAVE_ADDR,
119 };
120 
121 static struct ipmi_rq_entry *
ipmi_req_add_entry(struct ipmi_intf * intf,struct ipmi_rq * req,uint8_t req_seq)122 ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req, uint8_t req_seq)
123 {
124 	struct ipmi_rq_entry * e;
125 
126 	e = malloc(sizeof(struct ipmi_rq_entry));
127 	if (e == NULL) {
128 		lprintf(LOG_ERR, "ipmitool: malloc failure");
129 		return NULL;
130 	}
131 
132 	memset(e, 0, sizeof(struct ipmi_rq_entry));
133 	memcpy(&e->req, req, sizeof(struct ipmi_rq));
134 
135 	e->intf = intf;
136 	e->rq_seq = req_seq;
137 
138 	if (ipmi_req_entries == NULL)
139 		ipmi_req_entries = e;
140 	else
141 		ipmi_req_entries_tail->next = e;
142 
143 	ipmi_req_entries_tail = e;
144 	lprintf(LOG_DEBUG+3, "added list entry seq=0x%02x cmd=0x%02x",
145 		e->rq_seq, e->req.msg.cmd);
146 	return e;
147 }
148 
149 static struct ipmi_rq_entry *
ipmi_req_lookup_entry(uint8_t seq,uint8_t cmd)150 ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd)
151 {
152 	struct ipmi_rq_entry * e = ipmi_req_entries;
153 	while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
154 		if (e->next == NULL || e == e->next)
155 			return NULL;
156 		e = e->next;
157 	}
158 	return e;
159 }
160 
161 static void
ipmi_req_remove_entry(uint8_t seq,uint8_t cmd)162 ipmi_req_remove_entry(uint8_t seq, uint8_t cmd)
163 {
164 	struct ipmi_rq_entry * p, * e, * saved_next_entry;
165 
166 	e = p = ipmi_req_entries;
167 
168 	while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) {
169 		p = e;
170 		e = e->next;
171 	}
172 	if (e) {
173 		lprintf(LOG_DEBUG+3, "removed list entry seq=0x%02x cmd=0x%02x",
174 			seq, cmd);
175 		saved_next_entry = e->next;
176 		p->next = (p->next == e->next) ? NULL : e->next;
177 		/* If entry being removed is first in list, fix up list head */
178 		if (ipmi_req_entries == e) {
179 			if (ipmi_req_entries != p)
180 				ipmi_req_entries = p;
181 			else
182 				ipmi_req_entries = saved_next_entry;
183 		}
184 		/* If entry being removed is last in list, fix up list tail */
185 		if (ipmi_req_entries_tail == e) {
186 			if (ipmi_req_entries_tail != p)
187 				ipmi_req_entries_tail = p;
188 			else
189 				ipmi_req_entries_tail = NULL;
190 		}
191 		if (e->msg_data) {
192 			free(e->msg_data);
193 			e->msg_data = NULL;
194 		}
195 		free(e);
196 		e = NULL;
197 	}
198 }
199 
200 static void
ipmi_req_clear_entries(void)201 ipmi_req_clear_entries(void)
202 {
203 	struct ipmi_rq_entry * p, * e;
204 
205 	e = ipmi_req_entries;
206 	while (e) {
207 		lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x",
208 			e->rq_seq, e->req.msg.cmd);
209 		if (e->next != NULL) {
210 			p = e->next;
211 			free(e);
212 			e = p;
213 		} else {
214 			free(e);
215 			e = NULL;
216 			break;
217 		}
218 	}
219 	ipmi_req_entries = NULL;
220 	ipmi_req_entries_tail = NULL;
221 }
222 
223 static int
get_random(void * data,int len)224 get_random(void *data, int len)
225 {
226 	int fd = open("/dev/urandom", O_RDONLY);
227 	int rv;
228 
229 	if (fd < 0)
230 		return errno;
231 	if (len < 0) {
232 		close(fd);
233 		return errno; /* XXX: ORLY? */
234 	}
235 
236 	rv = read(fd, data, len);
237 
238 	close(fd);
239 	return rv;
240 }
241 
242 static int
ipmi_lan_send_packet(struct ipmi_intf * intf,uint8_t * data,int data_len)243 ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len)
244 {
245 	if (verbose > 2)
246 		printbuf(data, data_len, "send_packet");
247 
248 	return send(intf->fd, data, data_len, 0);
249 }
250 
251 static struct ipmi_rs *
ipmi_lan_recv_packet(struct ipmi_intf * intf)252 ipmi_lan_recv_packet(struct ipmi_intf * intf)
253 {
254 	static struct ipmi_rs rsp;
255 	fd_set read_set;
256 	fd_set err_set;
257 	struct timeval tmout;
258 	int ret;
259 
260 	FD_ZERO(&read_set);
261 	FD_SET(intf->fd, &read_set);
262 
263 	FD_ZERO(&err_set);
264 	FD_SET(intf->fd, &err_set);
265 
266 	tmout.tv_sec = intf->ssn_params.timeout;
267 	tmout.tv_usec = 0;
268 
269 	ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout);
270 	if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set))
271 		return NULL;
272 
273 	/* the first read may return ECONNREFUSED because the rmcp ping
274 	 * packet--sent to UDP port 623--will be processed by both the
275 	 * BMC and the OS.
276 	 *
277 	 * The problem with this is that the ECONNREFUSED takes
278 	 * priority over any other received datagram; that means that
279 	 * the Connection Refused shows up _before_ the response packet,
280 	 * regardless of the order they were sent out.  (unless the
281 	 * response is read before the connection refused is returned)
282 	 */
283 	ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
284 
285 	if (ret < 0) {
286 		FD_ZERO(&read_set);
287 		FD_SET(intf->fd, &read_set);
288 
289 		FD_ZERO(&err_set);
290 		FD_SET(intf->fd, &err_set);
291 
292 		tmout.tv_sec = intf->ssn_params.timeout;
293 		tmout.tv_usec = 0;
294 
295 		ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout);
296 		if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set))
297 			return NULL;
298 
299 		ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0);
300 		if (ret < 0)
301 			return NULL;
302 	}
303 
304 	if (ret == 0)
305 		return NULL;
306 
307 	rsp.data[ret] = '\0';
308 	rsp.data_len = ret;
309 
310 	if (verbose > 2)
311 		printbuf(rsp.data, rsp.data_len, "recv_packet");
312 
313 	return &rsp;
314 }
315 
316 /*
317  * parse response RMCP "pong" packet
318  *
319  * return -1 if ping response not received
320  * returns 0 if IPMI is NOT supported
321  * returns 1 if IPMI is supported
322  *
323  * udp.source	= 0x026f	// RMCP_UDP_PORT
324  * udp.dest	= ?		// udp.source from rmcp-ping
325  * udp.len	= ?
326  * udp.check	= ?
327  * rmcp.ver	= 0x06		// RMCP Version 1.0
328  * rmcp.__res	= 0x00		// RESERVED
329  * rmcp.seq	= 0xff		// no RMCP ACK
330  * rmcp.class	= 0x06		// RMCP_CLASS_ASF
331  * asf.iana	= 0x000011be	// ASF_RMCP_IANA
332  * asf.type	= 0x40		// ASF_TYPE_PONG
333  * asf.tag	= ?		// asf.tag from rmcp-ping
334  * asf.__res	= 0x00		// RESERVED
335  * asf.len	= 0x10		// 16 bytes
336  * asf.data[3:0]= 0x000011be	// IANA# = RMCP_ASF_IANA if no OEM
337  * asf.data[7:4]= 0x00000000	// OEM-defined (not for IPMI)
338  * asf.data[8]	= 0x81		// supported entities
339  * 				// [7]=IPMI [6:4]=RES [3:0]=ASF_1.0
340  * asf.data[9]	= 0x00		// supported interactions (reserved)
341  * asf.data[f:a]= 0x000000000000
342  */
343 static int
ipmi_handle_pong(struct ipmi_intf * intf,struct ipmi_rs * rsp)344 ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp)
345 {
346 	struct rmcp_pong * pong;
347 
348 	if (rsp == NULL)
349 		return -1;
350 
351 	pong = (struct rmcp_pong *)rsp->data;
352 
353 	lprintf(LOG_DEBUG,
354 		"Received IPMI/RMCP response packet: \n"
355 		"  IPMI%s Supported\n"
356 		"  ASF Version %s\n"
357 		"  RMCP Version %s\n"
358 		"  RMCP Sequence %d\n"
359 		"  IANA Enterprise %ld\n",
360 		(pong->sup_entities & 0x80) ? "" : " NOT",
361 		(pong->sup_entities & 0x01) ? "1.0" : "unknown",
362 		(pong->rmcp.ver == 6) ? "1.0" : "unknown",
363 		pong->rmcp.seq,
364 		ntohl(pong->iana));
365 
366 	return (pong->sup_entities & 0x80) ? 1 : 0;
367 }
368 
369 /* build and send RMCP presence ping packet
370  *
371  * RMCP ping
372  *
373  * udp.source	= ?
374  * udp.dest	= 0x026f	// RMCP_UDP_PORT
375  * udp.len	= ?
376  * udp.check	= ?
377  * rmcp.ver	= 0x06		// RMCP Version 1.0
378  * rmcp.__res	= 0x00		// RESERVED
379  * rmcp.seq	= 0xff		// no RMCP ACK
380  * rmcp.class	= 0x06		// RMCP_CLASS_ASF
381  * asf.iana	= 0x000011be	// ASF_RMCP_IANA
382  * asf.type	= 0x80		// ASF_TYPE_PING
383  * asf.tag	= ?		// ASF sequence number
384  * asf.__res	= 0x00		// RESERVED
385  * asf.len	= 0x00
386  *
387  */
388 static int
ipmi_lan_ping(struct ipmi_intf * intf)389 ipmi_lan_ping(struct ipmi_intf * intf)
390 {
391 	struct asf_hdr asf_ping = {
392 		.iana	= htonl(ASF_RMCP_IANA),
393 		.type	= ASF_TYPE_PING,
394 	};
395 	struct rmcp_hdr rmcp_ping = {
396 		.ver	= RMCP_VERSION_1,
397 		.class	= RMCP_CLASS_ASF,
398 		.seq	= 0xff,
399 	};
400 	uint8_t * data;
401 	int len = sizeof(rmcp_ping) + sizeof(asf_ping);
402 	int rv;
403 
404 	data = malloc(len);
405 	if (data == NULL) {
406 		lprintf(LOG_ERR, "ipmitool: malloc failure");
407 		return -1;
408 	}
409 	memset(data, 0, len);
410 	memcpy(data, &rmcp_ping, sizeof(rmcp_ping));
411 	memcpy(data+sizeof(rmcp_ping), &asf_ping, sizeof(asf_ping));
412 
413 	lprintf(LOG_DEBUG, "Sending IPMI/RMCP presence ping packet");
414 
415 	rv = ipmi_lan_send_packet(intf, data, len);
416 
417 	free(data);
418 	data = NULL;
419 
420 	if (rv < 0) {
421 		lprintf(LOG_ERR, "Unable to send IPMI presence ping packet");
422 		return -1;
423 	}
424 
425 	if (ipmi_lan_poll_recv(intf) == 0)
426 		return 0;
427 
428 	return 1;
429 }
430 
431 /*
432  * The "thump" functions are used to send an extra packet following each
433  * request message.  This may kick-start some BMCs that get confused with
434  * bad passwords or operate poorly under heavy network load.
435  */
436 static void
ipmi_lan_thump_first(struct ipmi_intf * intf)437 ipmi_lan_thump_first(struct ipmi_intf * intf)
438 {
439 	/* is this random data? */
440 	uint8_t data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 				   0x07, 0x20, 0x18, 0xc8, 0xc2, 0x01, 0x01, 0x3c };
442 	ipmi_lan_send_packet(intf, data, 16);
443 }
444 
445 static void
ipmi_lan_thump(struct ipmi_intf * intf)446 ipmi_lan_thump(struct ipmi_intf * intf)
447 {
448 	uint8_t data[10] = "thump";
449 	ipmi_lan_send_packet(intf, data, 10);
450 }
451 
452 static struct ipmi_rs *
ipmi_lan_poll_recv(struct ipmi_intf * intf)453 ipmi_lan_poll_recv(struct ipmi_intf * intf)
454 {
455 	struct rmcp_hdr rmcp_rsp;
456 	struct ipmi_rs * rsp;
457 	struct ipmi_rq_entry * entry;
458 	int x=0, rv;
459 	uint8_t our_address = intf->my_addr;
460 
461 	if (our_address == 0)
462 		our_address = IPMI_BMC_SLAVE_ADDR;
463 
464 	rsp = ipmi_lan_recv_packet(intf);
465 
466 	while (rsp != NULL) {
467 
468 		/* parse response headers */
469 		memcpy(&rmcp_rsp, rsp->data, 4);
470 
471 		switch (rmcp_rsp.class) {
472 		case RMCP_CLASS_ASF:
473 			/* ping response packet */
474 			rv = ipmi_handle_pong(intf, rsp);
475 			return (rv <= 0) ? NULL : rsp;
476 		case RMCP_CLASS_IPMI:
477 			/* handled by rest of function */
478 			break;
479 		default:
480 			lprintf(LOG_DEBUG, "Invalid RMCP class: %x",
481 				rmcp_rsp.class);
482 			rsp = ipmi_lan_recv_packet(intf);
483 			continue;
484 		}
485 
486 		x = 4;
487 		rsp->session.authtype = rsp->data[x++];
488 		memcpy(&rsp->session.seq, rsp->data+x, 4);
489 		x += 4;
490 		memcpy(&rsp->session.id, rsp->data+x, 4);
491 		x += 4;
492 
493 		if (rsp->session.id == (intf->session->session_id + 0x10000000)) {
494 			/* With SOL, authtype is always NONE, so we have no authcode */
495 			rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_SOL;
496 
497 			rsp->session.msglen = rsp->data[x++];
498 
499 			rsp->payload.sol_packet.packet_sequence_number =
500 				rsp->data[x++] & 0x0F;
501 
502 			rsp->payload.sol_packet.acked_packet_number =
503 				rsp->data[x++] & 0x0F;
504 
505 			rsp->payload.sol_packet.accepted_character_count =
506 				rsp->data[x++];
507 
508 			rsp->payload.sol_packet.is_nack =
509 				rsp->data[x] & 0x40;
510 
511 			rsp->payload.sol_packet.transfer_unavailable =
512 				rsp->data[x] & 0x20;
513 
514 			rsp->payload.sol_packet.sol_inactive =
515 				rsp->data[x] & 0x10;
516 
517 			rsp->payload.sol_packet.transmit_overrun =
518 				rsp->data[x] & 0x08;
519 
520 			rsp->payload.sol_packet.break_detected =
521 				rsp->data[x++] & 0x04;
522 
523 			x++; /* On ISOL there's and additional fifth byte before the data starts */
524 
525 			lprintf(LOG_DEBUG, "SOL sequence number     : 0x%02x",
526 				rsp->payload.sol_packet.packet_sequence_number);
527 
528 			lprintf(LOG_DEBUG, "SOL acked packet        : 0x%02x",
529 				rsp->payload.sol_packet.acked_packet_number);
530 
531 			lprintf(LOG_DEBUG, "SOL accepted char count : 0x%02x",
532 				rsp->payload.sol_packet.accepted_character_count);
533 
534 			lprintf(LOG_DEBUG, "SOL is nack             : %s",
535 				rsp->payload.sol_packet.is_nack? "true" : "false");
536 
537 			lprintf(LOG_DEBUG, "SOL xfer unavailable    : %s",
538 				rsp->payload.sol_packet.transfer_unavailable? "true" : "false");
539 
540 			lprintf(LOG_DEBUG, "SOL inactive            : %s",
541 				rsp->payload.sol_packet.sol_inactive? "true" : "false");
542 
543 			lprintf(LOG_DEBUG, "SOL transmit overrun    : %s",
544 				rsp->payload.sol_packet.transmit_overrun? "true" : "false");
545 
546 			lprintf(LOG_DEBUG, "SOL break detected      : %s",
547 				rsp->payload.sol_packet.break_detected? "true" : "false");
548 		}
549 		else
550 		{
551 			/* Standard IPMI 1.5 packet */
552 			rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI;
553 			if (intf->session->active && (rsp->session.authtype || intf->session->authtype))
554 				x += 16;
555 
556 			rsp->session.msglen = rsp->data[x++];
557 			rsp->payload.ipmi_response.rq_addr = rsp->data[x++];
558 			rsp->payload.ipmi_response.netfn   = rsp->data[x] >> 2;
559 			rsp->payload.ipmi_response.rq_lun  = rsp->data[x++] & 0x3;
560 			x++;		/* checksum */
561 			rsp->payload.ipmi_response.rs_addr = rsp->data[x++];
562 			rsp->payload.ipmi_response.rq_seq  = rsp->data[x] >> 2;
563 			rsp->payload.ipmi_response.rs_lun  = rsp->data[x++] & 0x3;
564 			rsp->payload.ipmi_response.cmd     = rsp->data[x++];
565 			rsp->ccode          = rsp->data[x++];
566 
567 			if (verbose > 2)
568 				printbuf(rsp->data, rsp->data_len, "ipmi message header");
569 
570 			lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header");
571 			lprintf(LOG_DEBUG+1, "<<   Authtype   : %s",
572 				val2str(rsp->session.authtype, ipmi_authtype_session_vals));
573 			lprintf(LOG_DEBUG+1, "<<   Sequence   : 0x%08lx",
574 				(long)rsp->session.seq);
575 			lprintf(LOG_DEBUG+1, "<<   Session ID : 0x%08lx",
576 				(long)rsp->session.id);
577 			lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header");
578 			lprintf(LOG_DEBUG+1, "<<   Rq Addr    : %02x",
579 				rsp->payload.ipmi_response.rq_addr);
580 			lprintf(LOG_DEBUG+1, "<<   NetFn      : %02x",
581 				rsp->payload.ipmi_response.netfn);
582 			lprintf(LOG_DEBUG+1, "<<   Rq LUN     : %01x",
583 				rsp->payload.ipmi_response.rq_lun);
584 			lprintf(LOG_DEBUG+1, "<<   Rs Addr    : %02x",
585 				rsp->payload.ipmi_response.rs_addr);
586 			lprintf(LOG_DEBUG+1, "<<   Rq Seq     : %02x",
587 				rsp->payload.ipmi_response.rq_seq);
588 			lprintf(LOG_DEBUG+1, "<<   Rs Lun     : %01x",
589 				rsp->payload.ipmi_response.rs_lun);
590 			lprintf(LOG_DEBUG+1, "<<   Command    : %02x",
591 				rsp->payload.ipmi_response.cmd);
592 			lprintf(LOG_DEBUG+1, "<<   Compl Code : 0x%02x",
593 				rsp->ccode);
594 
595 			/* now see if we have outstanding entry in request list */
596 			entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
597 						      rsp->payload.ipmi_response.cmd);
598 			if (entry) {
599 				lprintf(LOG_DEBUG+2, "IPMI Request Match found");
600 				if ((intf->target_addr != our_address) && bridge_possible) {
601 					if ((rsp->data_len) && (rsp->payload.ipmi_response.netfn == 7) &&
602 					    (rsp->payload.ipmi_response.cmd != 0x34)) {
603 						if (verbose > 2)
604 							printbuf(&rsp->data[x], rsp->data_len-x,
605 								 "bridge command response");
606 					}
607 					/* bridged command: lose extra header */
608 					if (entry->bridging_level &&
609 					    rsp->payload.ipmi_response.netfn == 7 &&
610 					    rsp->payload.ipmi_response.cmd == 0x34) {
611 						entry->bridging_level--;
612 						if (rsp->data_len - x - 1 == 0) {
613 							rsp = !rsp->ccode ? ipmi_lan_recv_packet(intf) : NULL;
614 							if (!entry->bridging_level)
615 								entry->req.msg.cmd = entry->req.msg.target_cmd;
616 							if (rsp == NULL) {
617 								ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.cmd);
618 							}
619 							continue;
620 						} else {
621 							/* The bridged answer data are inside the incoming packet */
622 							memmove(rsp->data + x - 7,
623 								rsp->data + x,
624 								rsp->data_len - x - 1);
625 							rsp->data[x - 8] -= 8;
626 							rsp->data_len -= 8;
627 							entry->rq_seq = rsp->data[x - 3] >> 2;
628 							if (!entry->bridging_level)
629 								entry->req.msg.cmd = entry->req.msg.target_cmd;
630 							continue;
631 						}
632 					} else {
633 						//x += sizeof(rsp->payload.ipmi_response);
634 						if (rsp->data[x-1] != 0)
635 							lprintf(LOG_DEBUG, "WARNING: Bridged "
636 								"cmd ccode = 0x%02x",
637 								rsp->data[x-1]);
638 					}
639 				}
640 				ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq,
641 						      rsp->payload.ipmi_response.cmd);
642 			} else {
643 				lprintf(LOG_INFO, "IPMI Request Match NOT FOUND");
644 				rsp = ipmi_lan_recv_packet(intf);
645 				continue;
646 			}
647 		}
648 
649 		break;
650 	}
651 
652 	/* shift response data to start of array */
653 	if (rsp && rsp->data_len > x) {
654 		rsp->data_len -= x;
655 		if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI)
656 			rsp->data_len -= 1; /* We don't want the checksum */
657 		memmove(rsp->data, rsp->data + x, rsp->data_len);
658 		memset(rsp->data + rsp->data_len, 0, IPMI_BUF_SIZE - rsp->data_len);
659 	}
660 
661 	return rsp;
662 }
663 
664 /*
665  * IPMI LAN Request Message Format
666  * +--------------------+
667  * |  rmcp.ver          | 4 bytes
668  * |  rmcp.__reserved   |
669  * |  rmcp.seq          |
670  * |  rmcp.class        |
671  * +--------------------+
672  * |  session.authtype  | 9 bytes
673  * |  session.seq       |
674  * |  session.id        |
675  * +--------------------+
676  * | [session.authcode] | 16 bytes (AUTHTYPE != none)
677  * +--------------------+
678  * |  message length    | 1 byte
679  * +--------------------+
680  * |  message.rs_addr   | 6 bytes
681  * |  message.netfn_lun |
682  * |  message.checksum  |
683  * |  message.rq_addr   |
684  * |  message.rq_seq    |
685  * |  message.cmd       |
686  * +--------------------+
687  * | [request data]     | data_len bytes
688  * +--------------------+
689  * |  checksum          | 1 byte
690  * +--------------------+
691  */
692 static struct ipmi_rq_entry *
ipmi_lan_build_cmd(struct ipmi_intf * intf,struct ipmi_rq * req,int isRetry)693 ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req, int isRetry)
694 {
695 	struct rmcp_hdr rmcp = {
696 		.ver		= RMCP_VERSION_1,
697 		.class		= RMCP_CLASS_IPMI,
698 		.seq		= 0xff,
699 	};
700 	uint8_t * msg, * temp;
701 	int cs, mp, tmp;
702 	int ap = 0;
703 	int len = 0;
704 	int cs2 = 0, cs3 = 0;
705 	struct ipmi_rq_entry * entry;
706 	struct ipmi_session * s = intf->session;
707 	static int curr_seq = 0;
708 	uint8_t our_address = intf->my_addr;
709 
710 	if (our_address == 0)
711 		our_address = IPMI_BMC_SLAVE_ADDR;
712 
713 	if (isRetry == 0)
714 		curr_seq++;
715 
716 	if (curr_seq >= 64)
717 		curr_seq = 0;
718 
719 	// Bug in the existing code where it keeps on adding same command/seq pair
720 	// in the lookup entry list.
721 	// Check if we have cmd,seq pair already in our list. As we are not changing
722 	// the seq number we have to re-use the node which has existing
723 	// command and sequence number. If we add then we will have redundant node with
724 	// same cmd,seq pair
725 	entry = ipmi_req_lookup_entry(curr_seq, req->msg.cmd);
726 	if (entry)
727 	{
728 		// This indicates that we have already same command and seq in list
729 		// No need to add once again and we will re-use the existing node.
730 		// Only thing we have to do is clear the msg_data as we create
731 		// a new one below in the code for it.
732 		if (entry->msg_data) {
733 			free(entry->msg_data);
734 			entry->msg_data = NULL;
735 		}
736 	}
737 	else
738 	{
739 		// We dont have this request in the list so we can add it
740 		// to the list
741 		entry = ipmi_req_add_entry(intf, req, curr_seq);
742 		if (entry == NULL)
743 			return NULL;
744 	}
745 
746 	len = req->msg.data_len + 29;
747 	if (s->active && s->authtype)
748 		len += 16;
749 	if (intf->transit_addr != intf->my_addr && intf->transit_addr != 0)
750 		len += 8;
751 	msg = malloc(len);
752 	if (msg == NULL) {
753 		lprintf(LOG_ERR, "ipmitool: malloc failure");
754 		return NULL;
755 	}
756 	memset(msg, 0, len);
757 
758 	/* rmcp header */
759 	memcpy(msg, &rmcp, sizeof(rmcp));
760 	len = sizeof(rmcp);
761 
762 	/* ipmi session header */
763 	msg[len++] = s->active ? s->authtype : 0;
764 
765 	msg[len++] = s->in_seq & 0xff;
766 	msg[len++] = (s->in_seq >> 8) & 0xff;
767 	msg[len++] = (s->in_seq >> 16) & 0xff;
768 	msg[len++] = (s->in_seq >> 24) & 0xff;
769 	memcpy(msg+len, &s->session_id, 4);
770 	len += 4;
771 
772 	/* ipmi session authcode */
773 	if (s->active && s->authtype) {
774 		ap = len;
775 		memcpy(msg+len, s->authcode, 16);
776 		len += 16;
777 	}
778 
779 	/* message length */
780 	if ((intf->target_addr == our_address) || !bridge_possible) {
781 		entry->bridging_level = 0;
782 		msg[len++] = req->msg.data_len + 7;
783 		cs = mp = len;
784 	} else {
785 		/* bridged request: encapsulate w/in Send Message */
786 		entry->bridging_level = 1;
787 		msg[len++] = req->msg.data_len + 15 +
788 		  (intf->transit_addr != intf->my_addr && intf->transit_addr != 0 ? 8 : 0);
789 		cs = mp = len;
790 		msg[len++] = IPMI_BMC_SLAVE_ADDR;
791 		msg[len++] = IPMI_NETFN_APP << 2;
792 		tmp = len - cs;
793 		msg[len++] = ipmi_csum(msg+cs, tmp);
794 		cs2 = len;
795 		msg[len++] = IPMI_REMOTE_SWID;
796 		msg[len++] = curr_seq << 2;
797 		msg[len++] = 0x34;			/* Send Message rqst */
798 		entry->req.msg.target_cmd = entry->req.msg.cmd;	/* Save target command */
799 		entry->req.msg.cmd = 0x34;		/* (fixup request entry) */
800 
801 		if (intf->transit_addr == intf->my_addr || intf->transit_addr == 0) {
802 		        msg[len++] = (0x40|intf->target_channel); /* Track request*/
803 		} else {
804 		        entry->bridging_level++;
805                		msg[len++] = (0x40|intf->transit_channel); /* Track request*/
806 			cs = len;
807 			msg[len++] = intf->transit_addr;
808 			msg[len++] = IPMI_NETFN_APP << 2;
809 			tmp = len - cs;
810 			msg[len++] = ipmi_csum(msg+cs, tmp);
811 			cs3 = len;
812 			msg[len++] = intf->my_addr;
813 			msg[len++] = curr_seq << 2;
814 			msg[len++] = 0x34;			/* Send Message rqst */
815 			msg[len++] = (0x40|intf->target_channel); /* Track request */
816 		}
817 		cs = len;
818 	}
819 
820 	/* ipmi message header */
821 	msg[len++] = entry->bridging_level ? intf->target_addr : IPMI_BMC_SLAVE_ADDR;
822 	msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
823 	tmp = len - cs;
824 	msg[len++] = ipmi_csum(msg+cs, tmp);
825 	cs = len;
826 
827 	if (!entry->bridging_level)
828 		msg[len++] = IPMI_REMOTE_SWID;
829    /* Bridged message */
830 	else if (entry->bridging_level)
831 		msg[len++] = intf->my_addr;
832 
833 	entry->rq_seq = curr_seq;
834 	msg[len++] = entry->rq_seq << 2;
835 	msg[len++] = req->msg.cmd;
836 
837 	lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header (level %d)", entry->bridging_level);
838 	lprintf(LOG_DEBUG+1, ">>   Authtype   : %s",
839 	       val2str(s->authtype, ipmi_authtype_session_vals));
840 	lprintf(LOG_DEBUG+1, ">>   Sequence   : 0x%08lx", (long)s->in_seq);
841 	lprintf(LOG_DEBUG+1, ">>   Session ID : 0x%08lx", (long)s->session_id);
842 	lprintf(LOG_DEBUG+1, ">> IPMI Request Message Header");
843 	lprintf(LOG_DEBUG+1, ">>   Rs Addr    : %02x", intf->target_addr);
844 	lprintf(LOG_DEBUG+1, ">>   NetFn      : %02x", req->msg.netfn);
845 	lprintf(LOG_DEBUG+1, ">>   Rs LUN     : %01x", 0);
846 	lprintf(LOG_DEBUG+1, ">>   Rq Addr    : %02x", IPMI_REMOTE_SWID);
847 	lprintf(LOG_DEBUG+1, ">>   Rq Seq     : %02x", entry->rq_seq);
848 	lprintf(LOG_DEBUG+1, ">>   Rq Lun     : %01x", 0);
849 	lprintf(LOG_DEBUG+1, ">>   Command    : %02x", req->msg.cmd);
850 
851 	/* message data */
852 	if (req->msg.data_len) {
853  		memcpy(msg+len, req->msg.data, req->msg.data_len);
854 		len += req->msg.data_len;
855 	}
856 
857 	/* second checksum */
858 	tmp = len - cs;
859 	msg[len++] = ipmi_csum(msg+cs, tmp);
860 
861 	/* bridged request: 2nd checksum */
862 	if (entry->bridging_level) {
863 		if (intf->transit_addr != intf->my_addr && intf->transit_addr != 0) {
864 			tmp = len - cs3;
865 			msg[len++] = ipmi_csum(msg+cs3, tmp);
866 		}
867 		tmp = len - cs2;
868 		msg[len++] = ipmi_csum(msg+cs2, tmp);
869 	}
870 
871 	if (s->active) {
872 		/*
873 		 * s->authcode is already copied to msg+ap but some
874 		 * authtypes require portions of the ipmi message to
875 		 * create the authcode so they must be done last.
876 		 */
877 		switch (s->authtype) {
878 		case IPMI_SESSION_AUTHTYPE_MD5:
879 			temp = ipmi_auth_md5(s, msg+mp, msg[mp-1]);
880 			memcpy(msg+ap, temp, 16);
881 			break;
882 		case IPMI_SESSION_AUTHTYPE_MD2:
883 			temp = ipmi_auth_md2(s, msg+mp, msg[mp-1]);
884 			memcpy(msg+ap, temp, 16);
885 			break;
886 		}
887 	}
888 
889 	if (s->in_seq) {
890 		s->in_seq++;
891 		if (s->in_seq == 0)
892 			s->in_seq++;
893 	}
894 
895 	entry->msg_len = len;
896 	entry->msg_data = msg;
897 
898 	return entry;
899 }
900 
901 static struct ipmi_rs *
ipmi_lan_send_cmd(struct ipmi_intf * intf,struct ipmi_rq * req)902 ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
903 {
904 	struct ipmi_rq_entry * entry;
905 	struct ipmi_rs * rsp = NULL;
906 	int try = 0;
907 	int isRetry = 0;
908 
909 	lprintf(LOG_DEBUG, "ipmi_lan_send_cmd:opened=[%d], open=[%d]",
910 		intf->opened, intf->open);
911 
912 	if (intf->opened == 0 && intf->open != NULL) {
913 		if (intf->open(intf) < 0) {
914 			lprintf(LOG_DEBUG, "Failed to open LAN interface");
915 			return NULL;
916 		}
917 		lprintf(LOG_DEBUG, "\topened=[%d], open=[%d]",
918 			intf->opened, intf->open);
919 	}
920 
921 	for (;;) {
922 		isRetry = ( try > 0 ) ? 1 : 0;
923 
924 		entry = ipmi_lan_build_cmd(intf, req, isRetry);
925 		if (entry == NULL) {
926 			lprintf(LOG_ERR, "Aborting send command, unable to build");
927 			return NULL;
928 		}
929 
930 		if (ipmi_lan_send_packet(intf, entry->msg_data, entry->msg_len) < 0) {
931 			try++;
932 			usleep(5000);
933 			ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.target_cmd);
934 			continue;
935 		}
936 
937 		/* if we are set to noanswer we do not expect response */
938 		if (intf->noanswer)
939 			break;
940 
941 		if (ipmi_oem_active(intf, "intelwv2"))
942 			ipmi_lan_thump(intf);
943 
944 		usleep(100);
945 
946 		rsp = ipmi_lan_poll_recv(intf);
947 
948 		/* Duplicate Request ccode most likely indicates a response to
949 		   a previous retry. Ignore and keep polling. */
950 		if((rsp != NULL) && (rsp->ccode == 0xcf)) {
951 			rsp = NULL;
952 			rsp = ipmi_lan_poll_recv(intf);
953 		}
954 
955 		if (rsp)
956 			break;
957 
958 		usleep(5000);
959 		if (++try >= intf->ssn_params.retry) {
960 			lprintf(LOG_DEBUG, "  No response from remote controller");
961 			break;
962 		}
963 	}
964 
965 	// We need to cleanup the existing entries from the list. Because if we
966 	// keep it and then when we send the new command and if the response is for
967 	// old command it still matches it and then returns success.
968 	// This is the corner case where the remote controller responds very slowly.
969 	//
970 	// Example: We have to send command 23 and 2d.
971 	// If we send command,seq as 23,10 and if we dont get any response it will
972 	// retry 4 times with 23,10 and then come out here and indicate that there is no
973 	// reponse from the remote controller and will send the next command for
974 	// ie 2d,11. And if the BMC is slow to respond and returns 23,10 then it
975 	// will match it in the list and will take response of command 23 as response
976 	// for command 2d and return success. So ideally when retries are done and
977 	// are out of this function we should be clearing the list to be safe so that
978 	// we dont match the old response with new request.
979 	//          [23, 10] --> BMC
980 	//          [23, 10] --> BMC
981 	//          [23, 10] --> BMC
982 	//          [23, 10] --> BMC
983 	//          [2D, 11] --> BMC
984 	//                   <-- [23, 10]
985 	//  here if we maintain 23,10 in the list then it will get matched and consider
986 	//  23 response as response for 2D.
987 	ipmi_req_clear_entries();
988 
989 	return rsp;
990 }
991 
992 static uint8_t *
ipmi_lan_build_rsp(struct ipmi_intf * intf,struct ipmi_rs * rsp,int * llen)993 ipmi_lan_build_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp, int * llen)
994 {
995 	struct rmcp_hdr rmcp = {
996 		.ver	= RMCP_VERSION_1,
997 		.class	= RMCP_CLASS_IPMI,
998 		.seq	= 0xff,
999 	};
1000 	struct ipmi_session * s = intf->session;
1001 	int cs, mp, ap = 0, tmp;
1002 	int len;
1003 	uint8_t * msg;
1004 
1005 	len = rsp->data_len + 22;
1006 	if (s->active)
1007 		len += 16;
1008 
1009 	msg = malloc(len);
1010 	if (msg == NULL) {
1011 		lprintf(LOG_ERR, "ipmitool: malloc failure");
1012 		return NULL;
1013 	}
1014 	memset(msg, 0, len);
1015 
1016 	/* rmcp header */
1017 	memcpy(msg, &rmcp, 4);
1018 	len = sizeof(rmcp);
1019 
1020 	/* ipmi session header */
1021 	msg[len++] = s->active ? s->authtype : 0;
1022 
1023 	if (s->in_seq) {
1024 		s->in_seq++;
1025 		if (s->in_seq == 0)
1026 			s->in_seq++;
1027 	}
1028 	memcpy(msg+len, &s->in_seq, 4);
1029 	len += 4;
1030 	memcpy(msg+len, &s->session_id, 4);
1031 	len += 4;
1032 
1033 	/* session authcode, if session active and authtype is not none */
1034 	if (s->active && s->authtype) {
1035 		ap = len;
1036 		memcpy(msg+len, s->authcode, 16);
1037 		len += 16;
1038 	}
1039 
1040 	/* message length */
1041 	msg[len++] = rsp->data_len + 8;
1042 
1043 	/* message header */
1044 	cs = mp = len;
1045 	msg[len++] = IPMI_REMOTE_SWID;
1046 	msg[len++] = rsp->msg.netfn << 2;
1047 	tmp = len - cs;
1048 	msg[len++] = ipmi_csum(msg+cs, tmp);
1049 	cs = len;
1050 	msg[len++] = IPMI_BMC_SLAVE_ADDR;
1051 	msg[len++] = (rsp->msg.seq << 2) | (rsp->msg.lun & 3);
1052 	msg[len++] = rsp->msg.cmd;
1053 
1054 	/* completion code */
1055 	msg[len++] = rsp->ccode;
1056 
1057 	/* message data */
1058 	if (rsp->data_len) {
1059 		memcpy(msg+len, rsp->data, rsp->data_len);
1060 		len += rsp->data_len;
1061 	}
1062 
1063 	/* second checksum */
1064 	tmp = len - cs;
1065 	msg[len++] = ipmi_csum(msg+cs, tmp);
1066 
1067 	if (s->active) {
1068 		uint8_t * d;
1069 		switch (s->authtype) {
1070 		case IPMI_SESSION_AUTHTYPE_MD5:
1071 			d = ipmi_auth_md5(s, msg+mp, msg[mp-1]);
1072 			memcpy(msg+ap, d, 16);
1073 			break;
1074 		case IPMI_SESSION_AUTHTYPE_MD2:
1075 			d = ipmi_auth_md2(s, msg+mp, msg[mp-1]);
1076 			memcpy(msg+ap, d, 16);
1077 			break;
1078 		}
1079 	}
1080 
1081 	*llen = len;
1082 	return msg;
1083 }
1084 
1085 static int
ipmi_lan_send_rsp(struct ipmi_intf * intf,struct ipmi_rs * rsp)1086 ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp)
1087 {
1088 	uint8_t * msg;
1089 	int len = 0;
1090 	int rv;
1091 
1092 	msg = ipmi_lan_build_rsp(intf, rsp, &len);
1093 	if (len <= 0 || msg == NULL) {
1094 		lprintf(LOG_ERR, "Invalid response packet");
1095 		if (msg != NULL) {
1096 			free(msg);
1097 			msg = NULL;
1098 		}
1099 		return -1;
1100 	}
1101 
1102 	rv = sendto(intf->fd, msg, len, 0,
1103 		    (struct sockaddr *)&intf->session->addr,
1104 		    intf->session->addrlen);
1105 	if (rv < 0) {
1106 		lprintf(LOG_ERR, "Packet send failed");
1107 		if (msg != NULL) {
1108 			free(msg);
1109 			msg = NULL;
1110 		}
1111 		return -1;
1112 	}
1113 
1114 	if (msg != NULL) {
1115 		free(msg);
1116 		msg = NULL;
1117 	}
1118 	return 0;
1119 }
1120 
1121 /*
1122  * IPMI SOL Payload Format
1123  * +--------------------+
1124  * |  rmcp.ver          | 4 bytes
1125  * |  rmcp.__reserved   |
1126  * |  rmcp.seq          |
1127  * |  rmcp.class        |
1128  * +--------------------+
1129  * |  session.authtype  | 9 bytes
1130  * |  session.seq       |
1131  * |  session.id        |
1132  * +--------------------+
1133  * |  message length    | 1 byte
1134  * +--------------------+
1135  * |  sol.seq           | 5 bytes
1136  * |  sol.ack_seq       |
1137  * |  sol.acc_count     |
1138  * |  sol.control       |
1139  * |  sol.__reserved    |
1140  * +--------------------+
1141  * | [request data]     | data_len bytes
1142  * +--------------------+
1143  */
ipmi_lan_build_sol_msg(struct ipmi_intf * intf,struct ipmi_v2_payload * payload,int * llen)1144 uint8_t * ipmi_lan_build_sol_msg(struct ipmi_intf * intf,
1145 				 struct ipmi_v2_payload * payload,
1146 				 int * llen)
1147 {
1148 	struct rmcp_hdr rmcp = {
1149 		.ver		= RMCP_VERSION_1,
1150 		.class		= RMCP_CLASS_IPMI,
1151 		.seq		= 0xff,
1152 	};
1153 	struct ipmi_session * session = intf->session;
1154 
1155 	/* msg will hold the entire message to be sent */
1156 	uint8_t * msg;
1157 
1158 	int len = 0;
1159 
1160 	len =	sizeof(rmcp)                                 +  // RMCP Header (4)
1161 		10                                           +  // IPMI Session Header
1162 		5                                            +  // SOL header
1163 		payload->payload.sol_packet.character_count;    // The actual payload
1164 
1165 	msg = malloc(len);
1166 	if (msg == NULL) {
1167 		lprintf(LOG_ERR, "ipmitool: malloc failure");
1168 		return NULL;
1169 	}
1170 	memset(msg, 0, len);
1171 
1172 	/* rmcp header */
1173 	memcpy(msg, &rmcp, sizeof(rmcp));
1174 	len = sizeof(rmcp);
1175 
1176 	/* ipmi session header */
1177 	msg[len++] = 0; /* SOL is always authtype = NONE */
1178 	msg[len++] = session->in_seq & 0xff;
1179 	msg[len++] = (session->in_seq >> 8) & 0xff;
1180 	msg[len++] = (session->in_seq >> 16) & 0xff;
1181 	msg[len++] = (session->in_seq >> 24) & 0xff;
1182 
1183 	msg[len++] = session->session_id & 0xff;
1184 	msg[len++] = (session->session_id >> 8) & 0xff;
1185 	msg[len++] = (session->session_id >> 16) & 0xff;
1186 	msg[len++] = ((session->session_id >> 24) + 0x10) & 0xff; /* Add 0x10 to MSB for SOL */
1187 
1188 	msg[len++] = payload->payload.sol_packet.character_count + 5;
1189 
1190 	/* sol header */
1191 	msg[len++] = payload->payload.sol_packet.packet_sequence_number;
1192 	msg[len++] = payload->payload.sol_packet.acked_packet_number;
1193 	msg[len++] = payload->payload.sol_packet.accepted_character_count;
1194 	msg[len]    = payload->payload.sol_packet.is_nack           ? 0x40 : 0;
1195 	msg[len]   |= payload->payload.sol_packet.assert_ring_wor   ? 0x20 : 0;
1196 	msg[len]   |= payload->payload.sol_packet.generate_break    ? 0x10 : 0;
1197 	msg[len]   |= payload->payload.sol_packet.deassert_cts      ? 0x08 : 0;
1198 	msg[len]   |= payload->payload.sol_packet.deassert_dcd_dsr  ? 0x04 : 0;
1199 	msg[len]   |= payload->payload.sol_packet.flush_inbound     ? 0x02 : 0;
1200 	msg[len++] |= payload->payload.sol_packet.flush_outbound    ? 0x01 : 0;
1201 
1202 	len++; /* On SOL there's and additional fifth byte before the data starts */
1203 
1204 	if (payload->payload.sol_packet.character_count) {
1205 		/* We may have data to add */
1206 		memcpy(msg + len,
1207 		       payload->payload.sol_packet.data,
1208 		       payload->payload.sol_packet.character_count);
1209 		len += payload->payload.sol_packet.character_count;
1210 	}
1211 
1212 	session->in_seq++;
1213 	if (session->in_seq == 0)
1214 		session->in_seq++;
1215 
1216 	*llen = len;
1217 	return msg;
1218 }
1219 
1220 /*
1221  * is_sol_packet
1222  */
1223 static int
is_sol_packet(struct ipmi_rs * rsp)1224 is_sol_packet(struct ipmi_rs * rsp)
1225 {
1226 	return (rsp                                                           &&
1227 		(rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL));
1228 }
1229 
1230 
1231 
1232 /*
1233  * sol_response_acks_packet
1234  */
1235 static int
sol_response_acks_packet(struct ipmi_rs * rsp,struct ipmi_v2_payload * payload)1236 sol_response_acks_packet(struct ipmi_rs         * rsp,
1237 			 struct ipmi_v2_payload * payload)
1238 {
1239 	return (is_sol_packet(rsp)                                            &&
1240 		payload                                                       &&
1241 		(payload->payload_type    == IPMI_PAYLOAD_TYPE_SOL)           &&
1242 		(rsp->payload.sol_packet.acked_packet_number ==
1243 		 payload->payload.sol_packet.packet_sequence_number));
1244 }
1245 
1246 /*
1247  * ipmi_lan_send_sol_payload
1248  *
1249  */
1250 static struct ipmi_rs *
ipmi_lan_send_sol_payload(struct ipmi_intf * intf,struct ipmi_v2_payload * payload)1251 ipmi_lan_send_sol_payload(struct ipmi_intf * intf,
1252 			  struct ipmi_v2_payload * payload)
1253 {
1254 	struct ipmi_rs      * rsp = NULL;
1255 	uint8_t             * msg;
1256 	int                   len;
1257 	int                   try = 0;
1258 
1259 	if (intf->opened == 0 && intf->open != NULL) {
1260 		if (intf->open(intf) < 0)
1261 			return NULL;
1262 	}
1263 
1264 	msg = ipmi_lan_build_sol_msg(intf, payload, &len);
1265 	if (len <= 0 || msg == NULL) {
1266 		lprintf(LOG_ERR, "Invalid SOL payload packet");
1267 		if (msg != NULL) {
1268 			free(msg);
1269 			msg = NULL;
1270 		}
1271 		return NULL;
1272 	}
1273 
1274 	lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n");
1275 
1276 	for (;;) {
1277 		if (ipmi_lan_send_packet(intf, msg, len) < 0) {
1278 			try++;
1279 			usleep(5000);
1280 			continue;
1281 		}
1282 
1283 		/* if we are set to noanswer we do not expect response */
1284 		if (intf->noanswer)
1285 			break;
1286 
1287 		if (payload->payload.sol_packet.packet_sequence_number == 0) {
1288 			/* We're just sending an ACK.  No need to retry. */
1289 			break;
1290 		}
1291 
1292 		usleep(100);
1293 
1294 		rsp = ipmi_lan_recv_sol(intf); /* Grab the next packet */
1295 
1296 		if (sol_response_acks_packet(rsp, payload))
1297 			break;
1298 
1299 		else if (is_sol_packet(rsp) && rsp->data_len)
1300 		{
1301 			/*
1302 			 * We're still waiting for our ACK, but we more data from
1303 			 * the BMC
1304 			 */
1305 			intf->session->sol_data.sol_input_handler(rsp);
1306 		}
1307 
1308 		usleep(5000);
1309 		if (++try >= intf->ssn_params.retry) {
1310 			lprintf(LOG_DEBUG, "  No response from remote controller");
1311 			break;
1312 		}
1313 	}
1314 
1315 	if (msg != NULL) {
1316 		free(msg);
1317 		msg = NULL;
1318 	}
1319 	return rsp;
1320 }
1321 
1322 /*
1323  * is_sol_partial_ack
1324  *
1325  * Determine if the response is a partial ACK/NACK that indicates
1326  * we need to resend part of our packet.
1327  *
1328  * returns the number of characters we need to resend, or
1329  *         0 if this isn't an ACK or we don't need to resend anything
1330  */
is_sol_partial_ack(struct ipmi_v2_payload * v2_payload,struct ipmi_rs * rsp)1331 static int is_sol_partial_ack(struct ipmi_v2_payload * v2_payload,
1332 			      struct ipmi_rs         * rsp)
1333 {
1334 	int chars_to_resend = 0;
1335 
1336 	if (v2_payload                                &&
1337 	    rsp                                       &&
1338 	    is_sol_packet(rsp)                        &&
1339 	    sol_response_acks_packet(rsp, v2_payload) &&
1340 	    (rsp->payload.sol_packet.accepted_character_count <
1341 	     v2_payload->payload.sol_packet.character_count))
1342 	{
1343 		if (rsp->payload.sol_packet.accepted_character_count == 0) {
1344 			/* We should not resend data */
1345 			chars_to_resend = 0;
1346 		}
1347 		else
1348 		{
1349 			chars_to_resend =
1350 				v2_payload->payload.sol_packet.character_count -
1351 				rsp->payload.sol_packet.accepted_character_count;
1352 		}
1353 	}
1354 
1355 	return chars_to_resend;
1356 }
1357 
1358 /*
1359  * set_sol_packet_sequence_number
1360  */
set_sol_packet_sequence_number(struct ipmi_intf * intf,struct ipmi_v2_payload * v2_payload)1361 static void set_sol_packet_sequence_number(struct ipmi_intf * intf,
1362 					   struct ipmi_v2_payload * v2_payload)
1363 {
1364 	/* Keep our sequence number sane */
1365 	if (intf->session->sol_data.sequence_number > 0x0F)
1366 		intf->session->sol_data.sequence_number = 1;
1367 
1368 	v2_payload->payload.sol_packet.packet_sequence_number =
1369 		intf->session->sol_data.sequence_number++;
1370 }
1371 
1372 /*
1373  * ipmi_lan_send_sol
1374  *
1375  * Sends a SOL packet..  We handle partial ACK/NACKs from the BMC here.
1376  *
1377  * Returns a pointer to the SOL ACK we received, or
1378  *         0 on failure
1379  *
1380  */
1381 struct ipmi_rs *
ipmi_lan_send_sol(struct ipmi_intf * intf,struct ipmi_v2_payload * v2_payload)1382 ipmi_lan_send_sol(struct ipmi_intf * intf,
1383 		  struct ipmi_v2_payload * v2_payload)
1384 {
1385 	struct ipmi_rs * rsp;
1386 	int chars_to_resend = 0;
1387 
1388 	v2_payload->payload_type   = IPMI_PAYLOAD_TYPE_SOL;
1389 
1390 	/*
1391 	 * Payload length is just the length of the character
1392 	 * data here.
1393 	 */
1394 	v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */
1395 
1396 	set_sol_packet_sequence_number(intf, v2_payload);
1397 
1398 	v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */
1399 
1400 	rsp = ipmi_lan_send_sol_payload(intf, v2_payload);
1401 
1402 	/* Determine if we need to resend some of our data */
1403 	chars_to_resend = is_sol_partial_ack(v2_payload, rsp);
1404 
1405 	while (chars_to_resend)
1406 	{
1407 		/*
1408 		 * We first need to handle any new data we might have
1409 		 * received in our NACK
1410 		 */
1411 		if (rsp->data_len)
1412 			intf->session->sol_data.sol_input_handler(rsp);
1413 
1414 		set_sol_packet_sequence_number(intf, v2_payload);
1415 
1416 		/* Just send the required data */
1417 		memmove(v2_payload->payload.sol_packet.data,
1418 			v2_payload->payload.sol_packet.data +
1419 			rsp->payload.sol_packet.accepted_character_count,
1420 			chars_to_resend);
1421 
1422 		v2_payload->payload.sol_packet.character_count = chars_to_resend;
1423 
1424 		rsp = ipmi_lan_send_sol_payload(intf, v2_payload);
1425 
1426 		chars_to_resend = is_sol_partial_ack(v2_payload, rsp);
1427 	}
1428 
1429 	return rsp;
1430 }
1431 
1432 /*
1433  * check_sol_packet_for_new_data
1434  *
1435  * Determine whether the SOL packet has already been seen
1436  * and whether the packet has new data for us.
1437  *
1438  * This function has the side effect of removing an previously
1439  * seen data, and moving new data to the front.
1440  *
1441  * It also "Remembers" the data so we don't get repeats.
1442  *
1443  */
1444 static int
check_sol_packet_for_new_data(struct ipmi_intf * intf,struct ipmi_rs * rsp)1445 check_sol_packet_for_new_data(struct ipmi_intf * intf,
1446 			      struct ipmi_rs *rsp)
1447 {
1448 	static uint8_t last_received_sequence_number = 0;
1449 	static uint8_t last_received_byte_count      = 0;
1450 	int new_data_size                            = 0;
1451 
1452 	if (rsp &&
1453 	    (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL))
1454 
1455 	{
1456 		uint8_t unaltered_data_len = rsp->data_len;
1457 		if (rsp->payload.sol_packet.packet_sequence_number ==
1458 		    last_received_sequence_number)
1459 		{
1460 			/*
1461 			 * This is the same as the last packet, but may include
1462 			 * extra data
1463 			 */
1464 			new_data_size = rsp->data_len - last_received_byte_count;
1465 
1466 			if (new_data_size > 0)
1467 			{
1468 				/* We have more data to process */
1469 				memmove(rsp->data,
1470 					rsp->data +
1471 					rsp->data_len - new_data_size,
1472 					new_data_size);
1473 			}
1474 
1475 			rsp->data_len = new_data_size;
1476 		}
1477 
1478 		/*
1479 		 *Rember the data for next round
1480 		 */
1481 		if (rsp && rsp->payload.sol_packet.packet_sequence_number)
1482 		{
1483 			last_received_sequence_number =
1484 				rsp->payload.sol_packet.packet_sequence_number;
1485 			last_received_byte_count = unaltered_data_len;
1486 		}
1487 	}
1488 
1489 	return new_data_size;
1490 }
1491 
1492 /*
1493  * ack_sol_packet
1494  *
1495  * Provided the specified packet looks reasonable, ACK it.
1496  */
1497 static void
ack_sol_packet(struct ipmi_intf * intf,struct ipmi_rs * rsp)1498 ack_sol_packet(struct ipmi_intf * intf,
1499 	       struct ipmi_rs * rsp)
1500 {
1501 	if (rsp &&
1502 	    (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) &&
1503 	    (rsp->payload.sol_packet.packet_sequence_number))
1504 	{
1505 		struct ipmi_v2_payload ack;
1506 
1507 		memset(&ack, 0, sizeof(struct ipmi_v2_payload));
1508 
1509 		ack.payload_type = IPMI_PAYLOAD_TYPE_SOL;
1510 
1511 		/*
1512 		 * Payload length is just the length of the character
1513 		 * data here.
1514 		 */
1515 		ack.payload_length = 0;
1516 
1517 		/* ACK packets have sequence numbers of 0 */
1518 		ack.payload.sol_packet.packet_sequence_number = 0;
1519 
1520 		ack.payload.sol_packet.acked_packet_number =
1521 			rsp->payload.sol_packet.packet_sequence_number;
1522 
1523 		ack.payload.sol_packet.accepted_character_count = rsp->data_len;
1524 
1525 		ipmi_lan_send_sol_payload(intf, &ack);
1526 	}
1527 }
1528 
1529 /*
1530  * ipmi_recv_sol
1531  *
1532  * Receive a SOL packet and send an ACK in response.
1533  *
1534  */
1535 static struct ipmi_rs *
ipmi_lan_recv_sol(struct ipmi_intf * intf)1536 ipmi_lan_recv_sol(struct ipmi_intf * intf)
1537 {
1538 	struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf);
1539 
1540 	ack_sol_packet(intf, rsp);
1541 
1542 	/*
1543 	 * Remembers the data sent, and alters the data to just
1544 	 * include the new stuff.
1545 	 */
1546 	check_sol_packet_for_new_data(intf, rsp);
1547 
1548 	return rsp;
1549 }
1550 
1551 /* send a get device id command to keep session active */
1552 static int
ipmi_lan_keepalive(struct ipmi_intf * intf)1553 ipmi_lan_keepalive(struct ipmi_intf * intf)
1554 {
1555 	struct ipmi_rs * rsp;
1556 	struct ipmi_rq req = {
1557 		.msg = {
1558 			.netfn = IPMI_NETFN_APP,
1559 			.cmd = 1,
1560 		}
1561 	};
1562 
1563 	if (!intf->opened)
1564 		return 0;
1565 
1566 	rsp = intf->sendrecv(intf, &req);
1567 	if (rsp == NULL)
1568 		return -1;
1569 	if (rsp->ccode > 0)
1570 		return -1;
1571 
1572 	return 0;
1573 }
1574 
1575 /*
1576  * IPMI Get Channel Authentication Capabilities Command
1577  */
1578 static int
ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)1579 ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)
1580 {
1581 	struct ipmi_rs * rsp;
1582 	struct ipmi_rq req;
1583 	struct ipmi_session * s = intf->session;
1584 	struct ipmi_session_params *p = &intf->ssn_params;
1585 	uint8_t msg_data[2];
1586 
1587 	msg_data[0] = IPMI_LAN_CHANNEL_E;
1588 	msg_data[1] = p->privlvl;
1589 
1590 	memset(&req, 0, sizeof(req));
1591 	req.msg.netfn    = IPMI_NETFN_APP;
1592 	req.msg.cmd      = 0x38;
1593 	req.msg.data     = msg_data;
1594 	req.msg.data_len = 2;
1595 
1596 	rsp = intf->sendrecv(intf, &req);
1597 	if (rsp == NULL) {
1598 		lprintf(LOG_INFO, "Get Auth Capabilities command failed");
1599 		return -1;
1600 	}
1601 	if (verbose > 2)
1602 		printbuf(rsp->data, rsp->data_len, "get_auth_capabilities");
1603 
1604 	if (rsp->ccode > 0) {
1605 		lprintf(LOG_INFO, "Get Auth Capabilities command failed: %s",
1606 			val2str(rsp->ccode, completion_code_vals));
1607 		return -1;
1608 	}
1609 
1610 	lprintf(LOG_DEBUG, "Channel %02x Authentication Capabilities:",
1611 		rsp->data[0]);
1612 	lprintf(LOG_DEBUG, "  Privilege Level : %s",
1613 		val2str(req.msg.data[1], ipmi_privlvl_vals));
1614 	lprintf(LOG_DEBUG, "  Auth Types      : %s%s%s%s%s",
1615 		(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) ? "NONE " : "",
1616 		(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2) ? "MD2 " : "",
1617 		(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5) ? "MD5 " : "",
1618 		(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) ? "PASSWORD " : "",
1619 		(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM) ? "OEM " : "");
1620 	lprintf(LOG_DEBUG, "  Per-msg auth    : %sabled",
1621 		(rsp->data[2] & IPMI_AUTHSTATUS_PER_MSG_DISABLED) ?
1622 		"dis" : "en");
1623 	lprintf(LOG_DEBUG, "  User level auth : %sabled",
1624 		(rsp->data[2] & IPMI_AUTHSTATUS_PER_USER_DISABLED) ?
1625 		"dis" : "en");
1626 	lprintf(LOG_DEBUG, "  Non-null users  : %sabled",
1627 		(rsp->data[2] & IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED) ?
1628 		"en" : "dis");
1629 	lprintf(LOG_DEBUG, "  Null users      : %sabled",
1630 		(rsp->data[2] & IPMI_AUTHSTATUS_NULL_USERS_ENABLED) ?
1631 		"en" : "dis");
1632 	lprintf(LOG_DEBUG, "  Anonymous login : %sabled",
1633 		(rsp->data[2] & IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED) ?
1634 		"en" : "dis");
1635 	lprintf(LOG_DEBUG, "");
1636 
1637 	s->authstatus = rsp->data[2];
1638 
1639 	if (p->password &&
1640 	    (p->authtype_set == 0 ||
1641 	     p->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) &&
1642 	    (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5))
1643 	{
1644 		s->authtype = IPMI_SESSION_AUTHTYPE_MD5;
1645 	}
1646 	else if (p->password &&
1647 		 (p->authtype_set == 0 ||
1648 		  p->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) &&
1649 		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2))
1650 	{
1651 		s->authtype = IPMI_SESSION_AUTHTYPE_MD2;
1652 	}
1653 	else if (p->password &&
1654 		 (p->authtype_set == 0 ||
1655 		  p->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) &&
1656 		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD))
1657 	{
1658 		s->authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
1659 	}
1660 	else if (p->password &&
1661 		 (p->authtype_set == 0 ||
1662 		  p->authtype_set == IPMI_SESSION_AUTHTYPE_OEM) &&
1663 		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM))
1664 	{
1665 		s->authtype = IPMI_SESSION_AUTHTYPE_OEM;
1666 	}
1667 	else if ((p->authtype_set == 0 ||
1668 		  p->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) &&
1669 		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE))
1670 	{
1671 		s->authtype = IPMI_SESSION_AUTHTYPE_NONE;
1672 	}
1673 	else {
1674 		if (!(rsp->data[1] & 1<<p->authtype_set))
1675 			lprintf(LOG_ERR, "Authentication type %s not supported",
1676 			       val2str(p->authtype_set, ipmi_authtype_session_vals));
1677 		else
1678 			lprintf(LOG_ERR, "No supported authtypes found");
1679 
1680 		return -1;
1681 	}
1682 
1683 	lprintf(LOG_DEBUG, "Proceeding with AuthType %s",
1684 		val2str(s->authtype, ipmi_authtype_session_vals));
1685 
1686 	return 0;
1687 }
1688 
1689 /*
1690  * IPMI Get Session Challenge Command
1691  * returns a temporary session ID and 16 byte challenge string
1692  */
1693 static int
ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)1694 ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)
1695 {
1696 	struct ipmi_rs * rsp;
1697 	struct ipmi_rq req;
1698 	struct ipmi_session * s = intf->session;
1699 	uint8_t msg_data[17];
1700 
1701 	memset(msg_data, 0, 17);
1702 	msg_data[0] = s->authtype;
1703 	memcpy(msg_data+1, intf->ssn_params.username, 16);
1704 
1705 	memset(&req, 0, sizeof(req));
1706 	req.msg.netfn		= IPMI_NETFN_APP;
1707 	req.msg.cmd		= 0x39;
1708 	req.msg.data		= msg_data;
1709 	req.msg.data_len	= 17; /* 1 byte for authtype, 16 for user */
1710 
1711 	rsp = intf->sendrecv(intf, &req);
1712 	if (rsp == NULL) {
1713 		lprintf(LOG_ERR, "Get Session Challenge command failed");
1714 		return -1;
1715 	}
1716 	if (verbose > 2)
1717 		printbuf(rsp->data, rsp->data_len, "get_session_challenge");
1718 
1719 	if (rsp->ccode > 0) {
1720 		switch (rsp->ccode) {
1721 		case 0x81:
1722 			lprintf(LOG_ERR, "Invalid user name");
1723 			break;
1724 		case 0x82:
1725 			lprintf(LOG_ERR, "NULL user name not enabled");
1726 			break;
1727 		default:
1728 			lprintf(LOG_ERR, "Get Session Challenge command failed: %s",
1729 				val2str(rsp->ccode, completion_code_vals));
1730 		}
1731 		return -1;
1732 	}
1733 
1734 	memcpy(&s->session_id, rsp->data, 4);
1735 	memcpy(s->challenge, rsp->data + 4, 16);
1736 
1737 	lprintf(LOG_DEBUG, "Opening Session");
1738 	lprintf(LOG_DEBUG, "  Session ID      : %08lx", (long)s->session_id);
1739 	lprintf(LOG_DEBUG, "  Challenge       : %s", buf2str(s->challenge, 16));
1740 
1741 	return 0;
1742 }
1743 
1744 /*
1745  * IPMI Activate Session Command
1746  */
1747 static int
ipmi_activate_session_cmd(struct ipmi_intf * intf)1748 ipmi_activate_session_cmd(struct ipmi_intf * intf)
1749 {
1750 	struct ipmi_rs * rsp;
1751 	struct ipmi_rq req;
1752 	struct ipmi_session * s = intf->session;
1753 	uint8_t msg_data[22];
1754 
1755 	memset(&req, 0, sizeof(req));
1756 	req.msg.netfn = IPMI_NETFN_APP;
1757 	req.msg.cmd = 0x3a;
1758 
1759 	msg_data[0] = s->authtype;
1760 	msg_data[1] = intf->ssn_params.privlvl;
1761 
1762 	/* supermicro oem authentication hack */
1763 	if (ipmi_oem_active(intf, "supermicro")) {
1764 		uint8_t * special = ipmi_auth_special(s);
1765 		memcpy(intf->session->authcode, special, 16);
1766 		memset(msg_data + 2, 0, 16);
1767 		lprintf(LOG_DEBUG, "  OEM Auth        : %s",
1768 			buf2str(special, 16));
1769 	} else {
1770 		memcpy(msg_data + 2, s->challenge, 16);
1771 	}
1772 
1773 	/* setup initial outbound sequence number */
1774 	get_random(msg_data+18, 4);
1775 
1776 	req.msg.data = msg_data;
1777 	req.msg.data_len = 22;
1778 
1779 	s->active = 1;
1780 
1781 	lprintf(LOG_DEBUG, "  Privilege Level : %s",
1782 		val2str(msg_data[1], ipmi_privlvl_vals));
1783 	lprintf(LOG_DEBUG, "  Auth Type       : %s",
1784 		val2str(s->authtype, ipmi_authtype_session_vals));
1785 
1786 	rsp = intf->sendrecv(intf, &req);
1787 	if (rsp == NULL) {
1788 		lprintf(LOG_ERR, "Activate Session command failed");
1789 		s->active = 0;
1790 		return -1;
1791 	}
1792 	if (verbose > 2)
1793 		printbuf(rsp->data, rsp->data_len, "activate_session");
1794 
1795 	if (rsp->ccode) {
1796 		fprintf(stderr, "Activate Session error:");
1797 		switch (rsp->ccode) {
1798 		case 0x81:
1799 			lprintf(LOG_ERR, "\tNo session slot available");
1800 			break;
1801 		case 0x82:
1802 			lprintf(LOG_ERR, "\tNo slot available for given user - "
1803 				"limit reached");
1804 			break;
1805 		case 0x83:
1806 			lprintf(LOG_ERR, "\tNo slot available to support user "
1807 				"due to maximum privilege capacity");
1808 			break;
1809 		case 0x84:
1810 			lprintf(LOG_ERR, "\tSession sequence out of range");
1811 			break;
1812 		case 0x85:
1813 			lprintf(LOG_ERR, "\tInvalid session ID in request");
1814 			break;
1815 		case 0x86:
1816 			lprintf(LOG_ERR, "\tRequested privilege level "
1817 				"exceeds limit");
1818 			break;
1819 		case 0xd4:
1820 			lprintf(LOG_ERR, "\tInsufficient privilege level");
1821 			break;
1822 		default:
1823 			lprintf(LOG_ERR, "\t%s",
1824 				val2str(rsp->ccode, completion_code_vals));
1825 		}
1826 		return -1;
1827 	}
1828 
1829 	memcpy(&s->session_id, rsp->data + 1, 4);
1830 	s->in_seq = rsp->data[8] << 24 | rsp->data[7] << 16 | rsp->data[6] << 8 | rsp->data[5];
1831 	if (s->in_seq == 0)
1832 		++s->in_seq;
1833 
1834 	if (s->authstatus & IPMI_AUTHSTATUS_PER_MSG_DISABLED)
1835 		s->authtype = IPMI_SESSION_AUTHTYPE_NONE;
1836 	else if (s->authtype != (rsp->data[0] & 0xf)) {
1837 		lprintf(LOG_ERR, "Invalid Session AuthType %s in response",
1838 			val2str(s->authtype, ipmi_authtype_session_vals));
1839 		return -1;
1840 	}
1841 
1842 	lprintf(LOG_DEBUG, "\nSession Activated");
1843 	lprintf(LOG_DEBUG, "  Auth Type       : %s",
1844 		val2str(rsp->data[0], ipmi_authtype_session_vals));
1845 	lprintf(LOG_DEBUG, "  Max Priv Level  : %s",
1846 		val2str(rsp->data[9], ipmi_privlvl_vals));
1847 	lprintf(LOG_DEBUG, "  Session ID      : %08lx", (long)s->session_id);
1848 	lprintf(LOG_DEBUG, "  Inbound Seq     : %08lx\n", (long)s->in_seq);
1849 
1850 	return 0;
1851 }
1852 
1853 
1854 /*
1855  * IPMI Set Session Privilege Level Command
1856  */
1857 static int
ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)1858 ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
1859 {
1860 	struct ipmi_rs * rsp;
1861 	struct ipmi_rq req;
1862 	uint8_t privlvl = intf->ssn_params.privlvl;
1863 	uint8_t backup_bridge_possible = bridge_possible;
1864 
1865 	if (privlvl <= IPMI_SESSION_PRIV_USER)
1866 		return 0;	/* no need to set higher */
1867 
1868 	memset(&req, 0, sizeof(req));
1869 	req.msg.netfn		= IPMI_NETFN_APP;
1870 	req.msg.cmd		= 0x3b;
1871 	req.msg.data		= &privlvl;
1872 	req.msg.data_len	= 1;
1873 
1874 	bridge_possible = 0;
1875 	rsp = intf->sendrecv(intf, &req);
1876 	bridge_possible = backup_bridge_possible;
1877 
1878 	if (rsp == NULL) {
1879 		lprintf(LOG_ERR, "Set Session Privilege Level to %s failed",
1880 			val2str(privlvl, ipmi_privlvl_vals));
1881 		return -1;
1882 	}
1883 	if (verbose > 2)
1884 		printbuf(rsp->data, rsp->data_len, "set_session_privlvl");
1885 
1886 	if (rsp->ccode > 0) {
1887 		lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s",
1888 			val2str(privlvl, ipmi_privlvl_vals),
1889 			val2str(rsp->ccode, completion_code_vals));
1890 		return -1;
1891 	}
1892 
1893 	lprintf(LOG_DEBUG, "Set Session Privilege Level to %s\n",
1894 		val2str(rsp->data[0], ipmi_privlvl_vals));
1895 
1896 	return 0;
1897 }
1898 
1899 static int
ipmi_close_session_cmd(struct ipmi_intf * intf)1900 ipmi_close_session_cmd(struct ipmi_intf * intf)
1901 {
1902 	struct ipmi_rs * rsp;
1903 	struct ipmi_rq req;
1904 	uint8_t msg_data[4];
1905 	uint32_t session_id = intf->session->session_id;
1906 
1907 	if (intf->session->active == 0)
1908 		return -1;
1909 
1910 	intf->target_addr = IPMI_BMC_SLAVE_ADDR;
1911 	bridge_possible = 0;  /* Not a bridge message */
1912 
1913 	memcpy(&msg_data, &session_id, 4);
1914 
1915 	memset(&req, 0, sizeof(req));
1916 	req.msg.netfn		= IPMI_NETFN_APP;
1917 	req.msg.cmd		= 0x3c;
1918 	req.msg.data		= msg_data;
1919 	req.msg.data_len	= 4;
1920 
1921 	rsp = intf->sendrecv(intf, &req);
1922 	if (rsp == NULL) {
1923 		lprintf(LOG_ERR, "Close Session command failed");
1924 		return -1;
1925 	}
1926 	if (verbose > 2)
1927 		printbuf(rsp->data, rsp->data_len, "close_session");
1928 
1929 	if (rsp->ccode == 0x87) {
1930 		lprintf(LOG_ERR, "Failed to Close Session: invalid "
1931 			"session ID %08lx", (long)session_id);
1932 		return -1;
1933 	}
1934 	if (rsp->ccode > 0) {
1935 		lprintf(LOG_ERR, "Close Session command failed: %s",
1936 			val2str(rsp->ccode, completion_code_vals));
1937 		return -1;
1938 	}
1939 
1940 	lprintf(LOG_DEBUG, "Closed Session %08lx\n", (long)session_id);
1941 
1942 	return 0;
1943 }
1944 
1945 /*
1946  * IPMI LAN Session Activation (IPMI spec v1.5 section 12.9)
1947  *
1948  * 1. send "RMCP Presence Ping" message, response message will
1949  *    indicate whether the platform supports IPMI
1950  * 2. send "Get Channel Authentication Capabilities" command
1951  *    with AUTHTYPE = none, response packet will contain information
1952  *    about supported challenge/response authentication types
1953  * 3. send "Get Session Challenge" command with AUTHTYPE = none
1954  *    and indicate the authentication type in the message, response
1955  *    packet will contain challenge string and temporary session ID.
1956  * 4. send "Activate Session" command, authenticated with AUTHTYPE
1957  *    sent in previous message.  Also sends the initial value for
1958  *    the outbound sequence number for BMC.
1959  * 5. BMC returns response confirming session activation and
1960  *    session ID for this session and initial inbound sequence.
1961  */
1962 static int
ipmi_lan_activate_session(struct ipmi_intf * intf)1963 ipmi_lan_activate_session(struct ipmi_intf * intf)
1964 {
1965 	int rc;
1966 
1967 	/* don't fail on ping because its not always supported.
1968 	 * Supermicro's IPMI LAN 1.5 cards don't tolerate pings.
1969 	 */
1970 	if (!ipmi_oem_active(intf, "supermicro"))
1971 		ipmi_lan_ping(intf);
1972 
1973 	/* Some particular Intel boards need special help
1974 	 */
1975 	if (ipmi_oem_active(intf, "intelwv2"))
1976 		ipmi_lan_thump_first(intf);
1977 
1978 	rc = ipmi_get_auth_capabilities_cmd(intf);
1979 	if (rc < 0) {
1980 		goto fail;
1981 	}
1982 
1983 	rc = ipmi_get_session_challenge_cmd(intf);
1984 	if (rc < 0)
1985 		goto fail;
1986 
1987 	rc = ipmi_activate_session_cmd(intf);
1988 	if (rc < 0)
1989 		goto fail;
1990 
1991 	intf->abort = 0;
1992 
1993 	rc = ipmi_set_session_privlvl_cmd(intf);
1994 	if (rc < 0)
1995 		goto close_fail;
1996 
1997 	return 0;
1998 
1999  close_fail:
2000 	ipmi_close_session_cmd(intf);
2001  fail:
2002 	lprintf(LOG_ERR, "Error: Unable to establish LAN session");
2003 	return -1;
2004 }
2005 
2006 void
ipmi_lan_close(struct ipmi_intf * intf)2007 ipmi_lan_close(struct ipmi_intf * intf)
2008 {
2009 	if (!intf->abort && intf->session)
2010 		ipmi_close_session_cmd(intf);
2011 
2012 	if (intf->fd >= 0) {
2013 		close(intf->fd);
2014 		intf->fd = -1;
2015 	}
2016 
2017 	ipmi_req_clear_entries();
2018 	ipmi_intf_session_cleanup(intf);
2019 	intf->opened = 0;
2020 	intf->manufacturer_id = IPMI_OEM_UNKNOWN;
2021 	intf = NULL;
2022 }
2023 
2024 static int
ipmi_lan_open(struct ipmi_intf * intf)2025 ipmi_lan_open(struct ipmi_intf * intf)
2026 {
2027 	int rc;
2028 	struct ipmi_session *s;
2029 	struct ipmi_session_params *p;
2030 
2031 	if (intf == NULL || intf->opened)
2032 		return -1;
2033 
2034 	s = intf->session;
2035 	p = &intf->ssn_params;
2036 
2037 	if (p->port == 0)
2038 		p->port = IPMI_LAN_PORT;
2039 	if (p->privlvl == 0)
2040 		p->privlvl = IPMI_SESSION_PRIV_ADMIN;
2041 	if (p->timeout == 0)
2042 		p->timeout = IPMI_LAN_TIMEOUT;
2043 	if (p->retry == 0)
2044 		p->retry = IPMI_LAN_RETRY;
2045 
2046 	if (p->hostname == NULL || strlen((const char *)p->hostname) == 0) {
2047 		lprintf(LOG_ERR, "No hostname specified!");
2048 		return -1;
2049 	}
2050 
2051 	if (ipmi_intf_socket_connect(intf) == -1) {
2052 		lprintf(LOG_ERR, "Could not open socket!");
2053 		return -1;
2054 	}
2055 
2056 	s = (struct ipmi_session *)malloc(sizeof(struct ipmi_session));
2057 	if (!s) {
2058 		lprintf(LOG_ERR, "ipmitool: malloc failure");
2059 		goto fail;
2060 	}
2061 
2062 	intf->opened = 1;
2063 	intf->abort = 1;
2064 
2065 	intf->session = s;
2066 
2067 	memset(s, 0, sizeof(struct ipmi_session));
2068 	s->sol_data.sequence_number = 1;
2069 	s->timeout = p->timeout;
2070 	memcpy(&s->authcode, &p->authcode_set, sizeof(s->authcode));
2071 	s->addrlen = sizeof(s->addr);
2072 	if (getsockname(intf->fd, (struct sockaddr *)&s->addr, &s->addrlen)) {
2073 		goto fail;
2074 	}
2075 
2076 	/* try to open session */
2077 	rc = ipmi_lan_activate_session(intf);
2078 	if (rc < 0) {
2079 	    goto fail;
2080 	}
2081 
2082 	/* automatically detect interface request and response sizes */
2083 	hpm2_detect_max_payload_size(intf);
2084 
2085 	/* set manufactirer OEM id */
2086 	intf->manufacturer_id = ipmi_get_oem(intf);
2087 
2088 	/* now allow bridging */
2089 	bridge_possible = 1;
2090 	return intf->fd;
2091 
2092  fail:
2093 	lprintf(LOG_ERR, "Error: Unable to establish IPMI v1.5 / RMCP session");
2094 	intf->close(intf);
2095 	return -1;
2096 }
2097 
2098 static int
ipmi_lan_setup(struct ipmi_intf * intf)2099 ipmi_lan_setup(struct ipmi_intf * intf)
2100 {
2101 	/* setup default LAN maximum request and response sizes */
2102 	intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;
2103 	intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE;
2104 
2105 	return 0;
2106 }
2107 
2108 static void
ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf,uint16_t size)2109 ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)
2110 {
2111 	if (size + 7 > 0xFF) {
2112 		size = 0xFF - 7;
2113 	}
2114 
2115 	intf->max_request_data_size = size;
2116 }
2117 
2118 static void
ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf,uint16_t size)2119 ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)
2120 {
2121 	if (size + 8 > 0xFF) {
2122 		size = 0xFF - 8;
2123 	}
2124 
2125 	intf->max_response_data_size = size;
2126 }
2127