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 33 #include <stdlib.h> 34 #include <stdio.h> 35 #include <inttypes.h> 36 #include <string.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <netinet/in.h> 40 #include <arpa/inet.h> 41 #include <errno.h> 42 #include <unistd.h> 43 #include <netdb.h> 44 #include <time.h> 45 #include <fcntl.h> 46 #include <assert.h> 47 48 #ifdef HAVE_CONFIG_H 49 # include <config.h> 50 #endif 51 #include <ipmitool/helper.h> 52 #include <ipmitool/log.h> 53 #include <ipmitool/ipmi.h> 54 #include <ipmitool/ipmi_lanp.h> 55 #include <ipmitool/ipmi_channel.h> 56 #include <ipmitool/ipmi_intf.h> 57 #include <ipmitool/ipmi_strings.h> 58 #include <ipmitool/hpm2.h> 59 #include <ipmitool/bswap.h> 60 #include <openssl/rand.h> 61 62 #include "lanplus.h" 63 #include "lanplus_crypt.h" 64 #include "lanplus_crypt_impl.h" 65 #include "lanplus_dump.h" 66 #include "rmcp.h" 67 #include "asf.h" 68 69 /* 70 * LAN interface is required to support 45 byte request transactions and 71 * 42 byte response transactions. 72 */ 73 #define IPMI_LAN_MAX_REQUEST_SIZE 38 /* 45 - 7 */ 74 #define IPMI_LAN_MAX_RESPONSE_SIZE 34 /* 42 - 8 */ 75 76 extern const struct valstr ipmi_rakp_return_codes[]; 77 extern const struct valstr ipmi_priv_levels[]; 78 extern const struct valstr ipmi_auth_algorithms[]; 79 extern const struct valstr ipmi_integrity_algorithms[]; 80 extern const struct valstr ipmi_encryption_algorithms[]; 81 82 static struct ipmi_rq_entry * ipmi_req_entries; 83 static struct ipmi_rq_entry * ipmi_req_entries_tail; 84 85 86 static int ipmi_lanplus_setup(struct ipmi_intf * intf); 87 static int ipmi_lanplus_keepalive(struct ipmi_intf * intf); 88 static int ipmi_lan_send_packet(struct ipmi_intf * intf, uint8_t * data, int data_len); 89 static struct ipmi_rs * ipmi_lan_recv_packet(struct ipmi_intf * intf); 90 static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf); 91 static struct ipmi_rs * ipmi_lanplus_send_ipmi_cmd(struct ipmi_intf * intf, struct ipmi_rq * req); 92 static struct ipmi_rs * ipmi_lanplus_send_payload(struct ipmi_intf * intf, 93 struct ipmi_v2_payload * payload); 94 static void getIpmiPayloadWireRep( 95 struct ipmi_intf * intf, 96 struct ipmi_v2_payload * payload, /* in */ 97 uint8_t * out, 98 struct ipmi_rq * req, 99 uint8_t rq_seq, 100 uint8_t curr_seq); 101 static void getSolPayloadWireRep( 102 struct ipmi_intf * intf, 103 uint8_t * msg, 104 struct ipmi_v2_payload * payload); 105 static void read_open_session_response(struct ipmi_rs * rsp, int offset); 106 static void read_rakp2_message(struct ipmi_rs * rsp, int offset, uint8_t alg); 107 static void read_rakp4_message(struct ipmi_rs * rsp, int offset, uint8_t alg); 108 static void read_session_data(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s); 109 static void read_session_data_v15(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s); 110 static void read_session_data_v2x(struct ipmi_rs * rsp, int * offset, struct ipmi_session *s); 111 static void read_ipmi_response(struct ipmi_rs * rsp, int * offset); 112 static void read_sol_packet(struct ipmi_rs * rsp, int * offset); 113 static struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf); 114 static struct ipmi_rs * ipmi_lanplus_send_sol( 115 struct ipmi_intf * intf, 116 struct ipmi_v2_payload * payload); 117 static int check_sol_packet_for_new_data( 118 struct ipmi_intf * intf, 119 struct ipmi_rs *rsp); 120 static void ack_sol_packet( 121 struct ipmi_intf * intf, 122 struct ipmi_rs * rsp); 123 static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size); 124 static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size); 125 126 static uint8_t bridgePossible = 0; 127 128 struct ipmi_intf ipmi_lanplus_intf = { 129 name: "lanplus", 130 desc: "IPMI v2.0 RMCP+ LAN Interface", 131 setup: ipmi_lanplus_setup, 132 open: ipmi_lanplus_open, 133 close: ipmi_lanplus_close, 134 sendrecv: ipmi_lanplus_send_ipmi_cmd, 135 recv_sol: ipmi_lanplus_recv_sol, 136 send_sol: ipmi_lanplus_send_sol, 137 keepalive: ipmi_lanplus_keepalive, 138 set_max_request_data_size: ipmi_lanp_set_max_rq_data_size, 139 set_max_response_data_size: ipmi_lanp_set_max_rp_data_size, 140 target_addr: IPMI_BMC_SLAVE_ADDR, 141 }; 142 143 144 extern int verbose; 145 146 147 148 /* 149 * lanplus_get_requested_ciphers 150 * 151 * Set the authentication, integrity and encryption algorithms based 152 * on the cipher suite ID. See table 22-19 in the IPMIv2 spec for the 153 * source of this information. 154 * 155 * param cipher_suite_id [in] 156 * param auth_alg [out] 157 * param integrity_alg [out] 158 * param crypt_alg [out] 159 * 160 * returns 0 on success 161 * 1 on failure 162 */ 163 int lanplus_get_requested_ciphers(int cipher_suite_id, 164 uint8_t * auth_alg, 165 uint8_t * integrity_alg, 166 uint8_t * crypt_alg) 167 { 168 if ((cipher_suite_id < 0) || (cipher_suite_id > 14)) 169 return 1; 170 171 /* See table 22-19 for the source of the statement */ 172 switch (cipher_suite_id) 173 { 174 case 0: 175 *auth_alg = IPMI_AUTH_RAKP_NONE; 176 *integrity_alg = IPMI_INTEGRITY_NONE; 177 *crypt_alg = IPMI_CRYPT_NONE; 178 break; 179 case 1: 180 *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1; 181 *integrity_alg = IPMI_INTEGRITY_NONE; 182 *crypt_alg = IPMI_CRYPT_NONE; 183 break; 184 case 2: 185 *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1; 186 *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96; 187 *crypt_alg = IPMI_CRYPT_NONE; 188 break; 189 case 3: 190 *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1; 191 *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96; 192 *crypt_alg = IPMI_CRYPT_AES_CBC_128; 193 break; 194 case 4: 195 *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1; 196 *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96; 197 *crypt_alg = IPMI_CRYPT_XRC4_128; 198 break; 199 case 5: 200 *auth_alg = IPMI_AUTH_RAKP_HMAC_SHA1; 201 *integrity_alg = IPMI_INTEGRITY_HMAC_SHA1_96; 202 *crypt_alg = IPMI_CRYPT_XRC4_40; 203 break; 204 case 6: 205 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 206 *integrity_alg = IPMI_INTEGRITY_NONE; 207 *crypt_alg = IPMI_CRYPT_NONE; 208 break; 209 case 7: 210 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 211 *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128; 212 *crypt_alg = IPMI_CRYPT_NONE; 213 break; 214 case 8: 215 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 216 *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128; 217 *crypt_alg = IPMI_CRYPT_AES_CBC_128; 218 break; 219 case 9: 220 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 221 *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128; 222 *crypt_alg = IPMI_CRYPT_XRC4_128; 223 break; 224 case 10: 225 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 226 *integrity_alg = IPMI_INTEGRITY_HMAC_MD5_128; 227 *crypt_alg = IPMI_CRYPT_XRC4_40; 228 break; 229 case 11: 230 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 231 *integrity_alg = IPMI_INTEGRITY_MD5_128; 232 *crypt_alg = IPMI_CRYPT_NONE; 233 break; 234 case 12: 235 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 236 *integrity_alg = IPMI_INTEGRITY_MD5_128; 237 *crypt_alg = IPMI_CRYPT_AES_CBC_128; 238 break; 239 case 13: 240 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 241 *integrity_alg = IPMI_INTEGRITY_MD5_128; 242 *crypt_alg = IPMI_CRYPT_XRC4_128; 243 break; 244 case 14: 245 *auth_alg = IPMI_AUTH_RAKP_HMAC_MD5; 246 *integrity_alg = IPMI_INTEGRITY_MD5_128; 247 *crypt_alg = IPMI_CRYPT_XRC4_40; 248 break; 249 } 250 251 return 0; 252 } 253 254 255 256 /* 257 * Reverse the order of arbitrarily long strings of bytes 258 */ 259 void lanplus_swap( 260 uint8_t * buffer, 261 int length) 262 { 263 int i; 264 uint8_t temp; 265 266 for (i =0; i < length/2; ++i) 267 { 268 temp = buffer[i]; 269 buffer[i] = buffer[length - 1 - i]; 270 buffer[length - 1 - i] = temp; 271 } 272 } 273 274 275 276 static const struct valstr plus_payload_types_vals[] = { 277 { IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message 278 { IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN) 279 { IPMI_PAYLOAD_TYPE_OEM, "OEM (2)" }, // OEM Explicid 280 281 { IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST, "OpenSession Req (0x10)" }, 282 { IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE,"OpenSession Resp (0x11)" }, 283 { IPMI_PAYLOAD_TYPE_RAKP_1, "RAKP1 (0x12)" }, 284 { IPMI_PAYLOAD_TYPE_RAKP_2, "RAKP2 (0x13)" }, 285 { IPMI_PAYLOAD_TYPE_RAKP_3, "RAKP3 (0x14)" }, 286 { IPMI_PAYLOAD_TYPE_RAKP_4, "RAKP4 (0x15)" }, 287 { 0x00, NULL }, 288 }; 289 290 291 static struct ipmi_rq_entry * 292 ipmi_req_add_entry(struct ipmi_intf * intf, struct ipmi_rq * req, uint8_t req_seq) 293 { 294 struct ipmi_rq_entry * e; 295 296 e = malloc(sizeof(struct ipmi_rq_entry)); 297 if (e == NULL) { 298 lprintf(LOG_ERR, "ipmitool: malloc failure"); 299 return NULL; 300 } 301 302 memset(e, 0, sizeof(struct ipmi_rq_entry)); 303 memcpy(&e->req, req, sizeof(struct ipmi_rq)); 304 305 e->intf = intf; 306 e->rq_seq = req_seq; 307 308 if (ipmi_req_entries == NULL) 309 ipmi_req_entries = e; 310 else 311 ipmi_req_entries_tail->next = e; 312 313 ipmi_req_entries_tail = e; 314 lprintf(LOG_DEBUG+3, "added list entry seq=0x%02x cmd=0x%02x", 315 e->rq_seq, e->req.msg.cmd); 316 return e; 317 } 318 319 320 static struct ipmi_rq_entry * 321 ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd) 322 { 323 struct ipmi_rq_entry * e = ipmi_req_entries; 324 325 while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) { 326 if (e == e->next) 327 return NULL; 328 e = e->next; 329 } 330 return e; 331 } 332 333 static void 334 ipmi_req_remove_entry(uint8_t seq, uint8_t cmd) 335 { 336 struct ipmi_rq_entry * p, * e, * saved_next_entry; 337 338 e = p = ipmi_req_entries; 339 340 while (e && (e->rq_seq != seq || e->req.msg.cmd != cmd)) { 341 p = e; 342 e = e->next; 343 } 344 if (e) { 345 lprintf(LOG_DEBUG+3, "removed list entry seq=0x%02x cmd=0x%02x", 346 seq, cmd); 347 saved_next_entry = e->next; 348 p->next = (p->next == e->next) ? NULL : e->next; 349 /* If entry being removed is first in list, fix up list head */ 350 if (ipmi_req_entries == e) { 351 if (ipmi_req_entries != p) 352 ipmi_req_entries = p; 353 else 354 ipmi_req_entries = saved_next_entry; 355 } 356 /* If entry being removed is last in list, fix up list tail */ 357 if (ipmi_req_entries_tail == e) { 358 if (ipmi_req_entries_tail != p) 359 ipmi_req_entries_tail = p; 360 else 361 ipmi_req_entries_tail = NULL; 362 } 363 364 if (e->msg_data) { 365 free(e->msg_data); 366 e->msg_data = NULL; 367 } 368 free(e); 369 e = NULL; 370 } 371 } 372 373 static void 374 ipmi_req_clear_entries(void) 375 { 376 struct ipmi_rq_entry * p, * e; 377 378 e = ipmi_req_entries; 379 while (e) { 380 lprintf(LOG_DEBUG+3, "cleared list entry seq=0x%02x cmd=0x%02x", 381 e->rq_seq, e->req.msg.cmd); 382 p = e->next; 383 free(e); 384 e = p; 385 } 386 } 387 388 389 int 390 ipmi_lan_send_packet( 391 struct ipmi_intf * intf, 392 uint8_t * data, int 393 data_len) 394 { 395 if (verbose >= 5) 396 printbuf(data, data_len, ">> sending packet"); 397 398 return send(intf->fd, data, data_len, 0); 399 } 400 401 402 403 struct ipmi_rs * 404 ipmi_lan_recv_packet(struct ipmi_intf * intf) 405 { 406 static struct ipmi_rs rsp; 407 fd_set read_set, err_set; 408 struct timeval tmout; 409 int ret; 410 411 FD_ZERO(&read_set); 412 FD_SET(intf->fd, &read_set); 413 414 FD_ZERO(&err_set); 415 FD_SET(intf->fd, &err_set); 416 417 tmout.tv_sec = intf->session->timeout; 418 tmout.tv_usec = 0; 419 420 ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); 421 if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set)) 422 return NULL; 423 424 /* the first read may return ECONNREFUSED because the rmcp ping 425 * packet--sent to UDP port 623--will be processed by both the 426 * BMC and the OS. 427 * 428 * The problem with this is that the ECONNREFUSED takes 429 * priority over any other received datagram; that means that 430 * the Connection Refused shows up _before_ the response packet, 431 * regardless of the order they were sent out. (unless the 432 * response is read before the connection refused is returned) 433 */ 434 ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0); 435 436 if (ret < 0) { 437 FD_ZERO(&read_set); 438 FD_SET(intf->fd, &read_set); 439 440 FD_ZERO(&err_set); 441 FD_SET(intf->fd, &err_set); 442 443 tmout.tv_sec = intf->session->timeout; 444 tmout.tv_usec = 0; 445 446 ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); 447 if (ret < 0 || FD_ISSET(intf->fd, &err_set) || !FD_ISSET(intf->fd, &read_set)) 448 return NULL; 449 450 ret = recv(intf->fd, &rsp.data, IPMI_BUF_SIZE, 0); 451 if (ret < 0) 452 return NULL; 453 } 454 455 if (ret == 0) 456 return NULL; 457 458 rsp.data[ret] = '\0'; 459 rsp.data_len = ret; 460 461 if (verbose >= 5) 462 printbuf(rsp.data, rsp.data_len, "<< received packet"); 463 464 return &rsp; 465 } 466 467 468 469 /* 470 * parse response RMCP "pong" packet 471 * 472 * return -1 if ping response not received 473 * returns 0 if IPMI is NOT supported 474 * returns 1 if IPMI is supported 475 * 476 * udp.source = 0x026f // RMCP_UDP_PORT 477 * udp.dest = ? // udp.source from rmcp-ping 478 * udp.len = ? 479 * udp.check = ? 480 * rmcp.ver = 0x06 // RMCP Version 1.0 481 * rmcp.__res = 0x00 // RESERVED 482 * rmcp.seq = 0xff // no RMCP ACK 483 * rmcp.class = 0x06 // RMCP_CLASS_ASF 484 * asf.iana = 0x000011be // ASF_RMCP_IANA 485 * asf.type = 0x40 // ASF_TYPE_PONG 486 * asf.tag = ? // asf.tag from rmcp-ping 487 * asf.__res = 0x00 // RESERVED 488 * asf.len = 0x10 // 16 bytes 489 * asf.data[3:0]= 0x000011be // IANA# = RMCP_ASF_IANA if no OEM 490 * asf.data[7:4]= 0x00000000 // OEM-defined (not for IPMI) 491 * asf.data[8] = 0x81 // supported entities 492 * // [7]=IPMI [6:4]=RES [3:0]=ASF_1.0 493 * asf.data[9] = 0x00 // supported interactions (reserved) 494 * asf.data[f:a]= 0x000000000000 495 */ 496 static int 497 ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp) 498 { 499 struct rmcp_pong { 500 struct rmcp_hdr rmcp; 501 struct asf_hdr asf; 502 uint32_t iana; 503 uint32_t oem; 504 uint8_t sup_entities; 505 uint8_t sup_interact; 506 uint8_t reserved[6]; 507 } * pong; 508 509 if (!rsp) 510 return -1; 511 512 pong = (struct rmcp_pong *)rsp->data; 513 514 if (verbose) 515 printf("Received IPMI/RMCP response packet: " 516 "IPMI%s Supported\n", 517 (pong->sup_entities & 0x80) ? "" : " NOT"); 518 519 if (verbose > 1) 520 printf(" ASF Version %s\n" 521 " RMCP Version %s\n" 522 " RMCP Sequence %d\n" 523 " IANA Enterprise %lu\n\n", 524 (pong->sup_entities & 0x01) ? "1.0" : "unknown", 525 (pong->rmcp.ver == 6) ? "1.0" : "unknown", 526 pong->rmcp.seq, 527 (unsigned long)ntohl(pong->iana)); 528 529 return (pong->sup_entities & 0x80) ? 1 : 0; 530 } 531 532 533 /* build and send RMCP presence ping packet 534 * 535 * RMCP ping 536 * 537 * udp.source = ? 538 * udp.dest = 0x026f // RMCP_UDP_PORT 539 * udp.len = ? 540 * udp.check = ? 541 * rmcp.ver = 0x06 // RMCP Version 1.0 542 * rmcp.__res = 0x00 // RESERVED 543 * rmcp.seq = 0xff // no RMCP ACK 544 * rmcp.class = 0x06 // RMCP_CLASS_ASF 545 * asf.iana = 0x000011be // ASF_RMCP_IANA 546 * asf.type = 0x80 // ASF_TYPE_PING 547 * asf.tag = ? // ASF sequence number 548 * asf.__res = 0x00 // RESERVED 549 * asf.len = 0x00 550 * 551 */ 552 int 553 ipmiv2_lan_ping(struct ipmi_intf * intf) 554 { 555 struct asf_hdr asf_ping = { 556 .iana = htonl(ASF_RMCP_IANA), 557 .type = ASF_TYPE_PING, 558 }; 559 struct rmcp_hdr rmcp_ping = { 560 .ver = RMCP_VERSION_1, 561 .class = RMCP_CLASS_ASF, 562 .seq = 0xff, 563 }; 564 uint8_t * data; 565 int len = sizeof(rmcp_ping) + sizeof(asf_ping); 566 int rv; 567 568 data = malloc(len); 569 if (data == NULL) { 570 lprintf(LOG_ERR, "ipmitool: malloc failure"); 571 return -1; 572 } 573 memset(data, 0, len); 574 memcpy(data, &rmcp_ping, sizeof(rmcp_ping)); 575 memcpy(data+sizeof(rmcp_ping), &asf_ping, sizeof(asf_ping)); 576 577 lprintf(LOG_DEBUG, "Sending IPMI/RMCP presence ping packet"); 578 579 rv = ipmi_lan_send_packet(intf, data, len); 580 581 free(data); 582 data = NULL; 583 584 if (rv < 0) { 585 lprintf(LOG_ERR, "Unable to send IPMI presence ping packet"); 586 return -1; 587 } 588 589 if (ipmi_lan_poll_recv(intf) == 0) 590 return 0; 591 592 return 1; 593 } 594 595 596 /** 597 * 598 * ipmi_lan_poll_recv 599 * 600 * Receive whatever comes back. Ignore received packets that don't correspond 601 * to a request we've sent. 602 * 603 * Returns: the ipmi_rs packet describing the/a reponse we expect. 604 */ 605 static struct ipmi_rs * 606 ipmi_lan_poll_recv(struct ipmi_intf * intf) 607 { 608 struct rmcp_hdr rmcp_rsp; 609 struct ipmi_rs * rsp; 610 struct ipmi_session * session = intf->session; 611 int offset, rv; 612 uint16_t payload_size; 613 uint8_t ourAddress = intf->my_addr; 614 615 if (ourAddress == 0) { 616 ourAddress = IPMI_BMC_SLAVE_ADDR; 617 } 618 619 rsp = ipmi_lan_recv_packet(intf); 620 621 /* 622 * Not positive why we're looping. Do we sometimes get stuff we don't 623 * expect? 624 */ 625 while (rsp != NULL) { 626 627 /* parse response headers */ 628 memcpy(&rmcp_rsp, rsp->data, 4); 629 630 if (rmcp_rsp.class == RMCP_CLASS_ASF) { 631 /* might be ping response packet */ 632 rv = ipmi_handle_pong(intf, rsp); 633 return (rv <= 0) ? NULL : rsp; 634 } 635 636 if (rmcp_rsp.class != RMCP_CLASS_IPMI) { 637 lprintf(LOG_DEBUG, "Invalid RMCP class: %x", 638 rmcp_rsp.class); 639 rsp = ipmi_lan_recv_packet(intf); 640 continue; 641 } 642 643 644 /* 645 * The authtype / payload type determines what we are receiving 646 */ 647 offset = 4; 648 649 650 /*-------------------------------------------------------------------- 651 * 652 * The current packet could be one of several things: 653 * 654 * 1) An IPMI 1.5 packet (the response to our GET CHANNEL 655 * AUTHENTICATION CAPABILITIES request) 656 * 2) An RMCP+ message with an IPMI reponse payload 657 * 3) AN RMCP+ open session response 658 * 4) An RAKP-2 message (response to an RAKP 1 message) 659 * 5) An RAKP-4 message (response to an RAKP 3 message) 660 * 6) A Serial Over LAN packet 661 * 7) An Invalid packet (one that doesn't match a request) 662 * ------------------------------------------------------------------- 663 */ 664 665 read_session_data(rsp, &offset, intf->session); 666 667 if (lanplus_has_valid_auth_code(rsp, intf->session) == 0) 668 { 669 lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!"); 670 rsp = ipmi_lan_recv_packet(intf); 671 assert(0); 672 //continue; 673 } 674 675 if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) && 676 (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && 677 (rsp->session.bEncrypted)) 678 679 { 680 lanplus_decrypt_payload(session->v2_data.crypt_alg, 681 session->v2_data.k2, 682 rsp->data + offset, 683 rsp->session.msglen, 684 rsp->data + offset, 685 &payload_size); 686 } 687 else 688 payload_size = rsp->session.msglen; 689 690 691 /* 692 * Handle IPMI responses (case #1 and #2) -- all IPMI reponses 693 */ 694 if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) 695 { 696 struct ipmi_rq_entry * entry; 697 int payload_start = offset; 698 int extra_data_length; 699 read_ipmi_response(rsp, &offset); 700 701 lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); 702 lprintf(LOG_DEBUG+1, "<< Authtype : %s", 703 val2str(rsp->session.authtype, ipmi_authtype_session_vals)); 704 lprintf(LOG_DEBUG+1, "<< Payload type : %s", 705 val2str(rsp->session.payloadtype, plus_payload_types_vals)); 706 lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", 707 (long)rsp->session.id); 708 lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", 709 (long)rsp->session.seq); 710 lprintf(LOG_DEBUG+1, "<< IPMI Msg/Payload Length : %d", 711 rsp->session.msglen); 712 lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); 713 lprintf(LOG_DEBUG+1, "<< Rq Addr : %02x", 714 rsp->payload.ipmi_response.rq_addr); 715 lprintf(LOG_DEBUG+1, "<< NetFn : %02x", 716 rsp->payload.ipmi_response.netfn); 717 lprintf(LOG_DEBUG+1, "<< Rq LUN : %01x", 718 rsp->payload.ipmi_response.rq_lun); 719 lprintf(LOG_DEBUG+1, "<< Rs Addr : %02x", 720 rsp->payload.ipmi_response.rs_addr); 721 lprintf(LOG_DEBUG+1, "<< Rq Seq : %02x", 722 rsp->payload.ipmi_response.rq_seq); 723 lprintf(LOG_DEBUG+1, "<< Rs Lun : %01x", 724 rsp->payload.ipmi_response.rs_lun); 725 lprintf(LOG_DEBUG+1, "<< Command : %02x", 726 rsp->payload.ipmi_response.cmd); 727 lprintf(LOG_DEBUG+1, "<< Compl Code : 0x%02x", 728 rsp->ccode); 729 730 /* Are we expecting this packet? */ 731 entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, 732 rsp->payload.ipmi_response.cmd); 733 734 if (entry != NULL) { 735 lprintf(LOG_DEBUG+2, "IPMI Request Match found"); 736 if ( intf->target_addr != intf->my_addr && 737 bridgePossible && 738 rsp->data_len && 739 rsp->payload.ipmi_response.cmd == 0x34 && 740 (rsp->payload.ipmi_response.netfn == 0x06 || 741 rsp->payload.ipmi_response.netfn == 0x07) && 742 rsp->payload.ipmi_response.rs_lun == 0 ) 743 { 744 /* Check completion code */ 745 if (rsp->data[offset-1] == 0) 746 { 747 lprintf(LOG_DEBUG, "Bridged command answer," 748 " waiting for next answer... "); 749 ipmi_req_remove_entry( 750 rsp->payload.ipmi_response.rq_seq, 751 rsp->payload.ipmi_response.cmd); 752 return ipmi_lan_poll_recv(intf); 753 } 754 else 755 { 756 lprintf(LOG_DEBUG, "WARNING: Bridged " 757 "cmd ccode = 0x%02x", 758 rsp->data[offset-1]); 759 } 760 761 if (rsp->data_len && 762 rsp->payload.ipmi_response.cmd == 0x34) { 763 memcpy(rsp->data, &rsp->data[offset], 764 (rsp->data_len-offset)); 765 if (verbose > 2) 766 printbuf( &rsp->data[offset], 767 (rsp->data_len-offset), 768 "bridge command response"); 769 } 770 } 771 772 ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, 773 rsp->payload.ipmi_response.cmd); 774 } else { 775 lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); 776 rsp = ipmi_lan_recv_packet(intf); 777 continue; 778 } 779 780 /* 781 * Good packet. Shift response data to start of array. 782 * rsp->data becomes the variable length IPMI response data 783 * rsp->data_len becomes the length of that data 784 */ 785 extra_data_length = payload_size - (offset - payload_start) - 1; 786 if (rsp != NULL && extra_data_length) 787 { 788 rsp->data_len = extra_data_length; 789 memmove(rsp->data, rsp->data + offset, extra_data_length); 790 } 791 else 792 rsp->data_len = 0; 793 794 break; 795 } 796 797 798 /* 799 * Open Response 800 */ 801 else if (rsp->session.payloadtype == 802 IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE) 803 { 804 if (session->v2_data.session_state != 805 LANPLUS_STATE_OPEN_SESSION_SENT) 806 { 807 lprintf(LOG_ERR, "Error: Received an Unexpected Open Session " 808 "Response"); 809 rsp = ipmi_lan_recv_packet(intf); 810 continue; 811 } 812 813 read_open_session_response(rsp, offset); 814 break; 815 } 816 817 818 /* 819 * RAKP 2 820 */ 821 else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2) 822 { 823 if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT) 824 { 825 lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message"); 826 rsp = ipmi_lan_recv_packet(intf); 827 continue; 828 } 829 830 read_rakp2_message(rsp, offset, session->v2_data.auth_alg); 831 break; 832 } 833 834 835 /* 836 * RAKP 4 837 */ 838 else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4) 839 { 840 if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT) 841 { 842 lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message"); 843 rsp = ipmi_lan_recv_packet(intf); 844 continue; 845 } 846 847 read_rakp4_message(rsp, offset, session->v2_data.auth_alg); 848 break; 849 } 850 851 852 /* 853 * SOL 854 */ 855 else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) 856 { 857 int payload_start = offset; 858 int extra_data_length; 859 860 if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) 861 { 862 lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet"); 863 rsp = ipmi_lan_recv_packet(intf); 864 continue; 865 } 866 867 read_sol_packet(rsp, &offset); 868 extra_data_length = payload_size - (offset - payload_start); 869 if (rsp && extra_data_length) 870 { 871 rsp->data_len = extra_data_length; 872 memmove(rsp->data, rsp->data + offset, extra_data_length); 873 } 874 else 875 rsp->data_len = 0; 876 877 break; 878 } 879 880 else 881 { 882 lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x", 883 rsp->session.payloadtype); 884 assert(0); 885 } 886 } 887 888 return rsp; 889 } 890 891 892 893 /* 894 * read_open_session_reponse 895 * 896 * Initialize the ipmi_rs from the IPMI 2.x open session response data. 897 * 898 * The offset should point to the first byte of the the Open Session Response 899 * payload when this function is called. 900 * 901 * param rsp [in/out] reading from the data and writing to the open_session_response 902 * section 903 * param offset [in] tells us where the Open Session Response payload starts 904 * 905 * returns 0 on success, 1 on error 906 */ 907 void 908 read_open_session_response(struct ipmi_rs * rsp, int offset) 909 { 910 memset(&rsp->payload.open_session_response, 0, 911 sizeof(rsp->payload.open_session_response)); 912 913 /* Message tag */ 914 rsp->payload.open_session_response.message_tag = rsp->data[offset]; 915 916 /* RAKP reponse code */ 917 rsp->payload.open_session_response.rakp_return_code = rsp->data[offset + 1]; 918 919 /* Maximum privilege level */ 920 rsp->payload.open_session_response.max_priv_level = rsp->data[offset + 2]; 921 922 /*** offset + 3 is reserved ***/ 923 924 /* Remote console session ID */ 925 memcpy(&(rsp->payload.open_session_response.console_id), 926 rsp->data + offset + 4, 927 4); 928 #if WORDS_BIGENDIAN 929 rsp->payload.open_session_response.console_id = 930 BSWAP_32(rsp->payload.open_session_response.console_id); 931 #endif 932 933 /* only tag, status, privlvl, and console id are returned if error */ 934 if (rsp->payload.open_session_response.rakp_return_code != 935 IPMI_RAKP_STATUS_NO_ERRORS) 936 return; 937 938 /* BMC session ID */ 939 memcpy(&(rsp->payload.open_session_response.bmc_id), 940 rsp->data + offset + 8, 941 4); 942 #if WORDS_BIGENDIAN 943 rsp->payload.open_session_response.bmc_id = 944 BSWAP_32(rsp->payload.open_session_response.bmc_id); 945 #endif 946 947 /* And of course, our negotiated algorithms */ 948 rsp->payload.open_session_response.auth_alg = rsp->data[offset + 16]; 949 rsp->payload.open_session_response.integrity_alg = rsp->data[offset + 24]; 950 rsp->payload.open_session_response.crypt_alg = rsp->data[offset + 32]; 951 } 952 953 954 955 /* 956 * read_rakp2_message 957 * 958 * Initialize the ipmi_rs from the IPMI 2.x RAKP 2 message 959 * 960 * The offset should point the first byte of the the RAKP 2 payload when this 961 * function is called. 962 * 963 * param rsp [in/out] reading from the data variable and writing to the rakp 2 964 * section 965 * param offset [in] tells us where hte rakp2 payload starts 966 * param auth_alg [in] describes the authentication algorithm was agreed upon in 967 * the open session request/response phase. We need to know that here so 968 * that we know how many bytes (if any) to read fromt the packet. 969 * 970 * returns 0 on success, 1 on error 971 */ 972 void 973 read_rakp2_message( 974 struct ipmi_rs * rsp, 975 int offset, 976 uint8_t auth_alg) 977 { 978 int i; 979 980 /* Message tag */ 981 rsp->payload.rakp2_message.message_tag = rsp->data[offset]; 982 983 /* RAKP reponse code */ 984 rsp->payload.rakp2_message.rakp_return_code = rsp->data[offset + 1]; 985 986 /* Console session ID */ 987 memcpy(&(rsp->payload.rakp2_message.console_id), 988 rsp->data + offset + 4, 989 4); 990 #if WORDS_BIGENDIAN 991 rsp->payload.rakp2_message.console_id = 992 BSWAP_32(rsp->payload.rakp2_message.console_id); 993 #endif 994 995 /* BMC random number */ 996 memcpy(&(rsp->payload.rakp2_message.bmc_rand), 997 rsp->data + offset + 8, 998 16); 999 #if WORDS_BIGENDIAN 1000 lanplus_swap(rsp->payload.rakp2_message.bmc_rand, 16); 1001 #endif 1002 1003 /* BMC GUID */ 1004 memcpy(&(rsp->payload.rakp2_message.bmc_guid), 1005 rsp->data + offset + 24, 1006 16); 1007 #if WORDS_BIGENDIAN 1008 lanplus_swap(rsp->payload.rakp2_message.bmc_guid, 16); 1009 #endif 1010 1011 /* Key exchange authentication code */ 1012 switch (auth_alg) 1013 { 1014 case IPMI_AUTH_RAKP_NONE: 1015 /* Nothing to do here */ 1016 break; 1017 1018 case IPMI_AUTH_RAKP_HMAC_SHA1: 1019 /* We need to copy 20 bytes */ 1020 for (i = 0; i < 20; ++i) 1021 rsp->payload.rakp2_message.key_exchange_auth_code[i] = 1022 rsp->data[offset + 40 + i]; 1023 break; 1024 1025 case IPMI_AUTH_RAKP_HMAC_MD5: 1026 lprintf(LOG_ERR, "read_rakp2_message: no support for " 1027 "IPMI_AUTH_RAKP_HMAC_MD5"); 1028 assert(0); 1029 break; 1030 } 1031 } 1032 1033 1034 1035 /* 1036 * read_rakp4_message 1037 * 1038 * Initialize the ipmi_rs from the IPMI 2.x RAKP 4 message 1039 * 1040 * The offset should point the first byte of the the RAKP 4 payload when this 1041 * function is called. 1042 * 1043 * param rsp [in/out] reading from the data variable and writing to the rakp 1044 * 4 section 1045 * param offset [in] tells us where hte rakp4 payload starts 1046 * param integrity_alg [in] describes the authentication algorithm was 1047 * agreed upon in the open session request/response phase. We need 1048 * to know that here so that we know how many bytes (if any) to read 1049 * from the packet. 1050 * 1051 * returns 0 on success, 1 on error 1052 */ 1053 void 1054 read_rakp4_message( 1055 struct ipmi_rs * rsp, 1056 int offset, 1057 uint8_t auth_alg) 1058 { 1059 int i; 1060 1061 /* Message tag */ 1062 rsp->payload.rakp4_message.message_tag = rsp->data[offset]; 1063 1064 /* RAKP reponse code */ 1065 rsp->payload.rakp4_message.rakp_return_code = rsp->data[offset + 1]; 1066 1067 /* Console session ID */ 1068 memcpy(&(rsp->payload.rakp4_message.console_id), 1069 rsp->data + offset + 4, 1070 4); 1071 #if WORDS_BIGENDIAN 1072 rsp->payload.rakp4_message.console_id = 1073 BSWAP_32(rsp->payload.rakp4_message.console_id); 1074 #endif 1075 1076 1077 /* Integrity check value */ 1078 switch (auth_alg) 1079 { 1080 case IPMI_AUTH_RAKP_NONE: 1081 /* Nothing to do here */ 1082 break; 1083 1084 case IPMI_AUTH_RAKP_HMAC_SHA1: 1085 /* We need to copy 12 bytes */ 1086 for (i = 0; i < 12; ++i) 1087 rsp->payload.rakp4_message.integrity_check_value[i] = 1088 rsp->data[offset + 8 + i]; 1089 break; 1090 1091 case IPMI_AUTH_RAKP_HMAC_MD5: 1092 lprintf(LOG_ERR, "read_rakp4_message: no support " 1093 "for authentication algorithm 0x%x", auth_alg); 1094 assert(0); 1095 break; 1096 } 1097 } 1098 1099 1100 1101 1102 /* 1103 * read_session_data 1104 * 1105 * Initialize the ipmi_rsp from the session data in the packet 1106 * 1107 * The offset should point the first byte of the the IPMI session when this 1108 * function is called. 1109 * 1110 * param rsp [in/out] we read from the data buffer and populate the session 1111 * specific fields. 1112 * param offset [in/out] should point to the beginning of the session when 1113 * this function is called. The offset will be adjusted to 1114 * point to the end of the session when this function exits. 1115 * param session holds our session state 1116 */ 1117 void 1118 read_session_data( 1119 struct ipmi_rs * rsp, 1120 int * offset, 1121 struct ipmi_session * s) 1122 { 1123 /* We expect to read different stuff depending on the authtype */ 1124 rsp->session.authtype = rsp->data[*offset]; 1125 1126 if (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) 1127 read_session_data_v2x(rsp, offset, s); 1128 else 1129 read_session_data_v15(rsp, offset, s); 1130 } 1131 1132 1133 1134 /* 1135 * read_session_data_v2x 1136 * 1137 * Initialize the ipmi_rsp from the v2.x session header of the packet. 1138 * 1139 * The offset should point to the first byte of the the IPMI session when this 1140 * function is called. When this function exits, offset will point to the 1141 * start of payload. 1142 * 1143 * Should decrypt and perform integrity checking here? 1144 * 1145 * param rsp [in/out] we read from the data buffer and populate the session 1146 * specific fields. 1147 * param offset [in/out] should point to the beginning of the session when this 1148 * function is called. The offset will be adjusted to point to 1149 * the end of the session when this function exits. 1150 * param s holds our session state 1151 */ 1152 void 1153 read_session_data_v2x( 1154 struct ipmi_rs * rsp, 1155 int * offset, 1156 struct ipmi_session * s) 1157 { 1158 rsp->session.authtype = rsp->data[(*offset)++]; 1159 1160 rsp->session.bEncrypted = (rsp->data[*offset] & 0x80 ? 1 : 0); 1161 rsp->session.bAuthenticated = (rsp->data[*offset] & 0x40 ? 1 : 0); 1162 1163 1164 /* Payload type */ 1165 rsp->session.payloadtype = rsp->data[(*offset)++] & 0x3F; 1166 1167 /* Session ID */ 1168 memcpy(&rsp->session.id, rsp->data + *offset, 4); 1169 *offset += 4; 1170 #if WORDS_BIGENDIAN 1171 rsp->session.id = BSWAP_32(rsp->session.id); 1172 #endif 1173 1174 1175 /* 1176 * Verify that the session ID is what we think it should be 1177 */ 1178 if ((s->v2_data.session_state == LANPLUS_STATE_ACTIVE) && 1179 (rsp->session.id != s->v2_data.console_id)) 1180 { 1181 lprintf(LOG_ERR, "packet session id 0x%x does not " 1182 "match active session 0x%0x", 1183 rsp->session.id, s->v2_data.console_id); 1184 assert(0); 1185 } 1186 1187 1188 /* Ignored, so far */ 1189 memcpy(&rsp->session.seq, rsp->data + *offset, 4); 1190 *offset += 4; 1191 #if WORDS_BIGENDIAN 1192 rsp->session.seq = BSWAP_32(rsp->session.seq); 1193 #endif 1194 1195 memcpy(&rsp->session.msglen, rsp->data + *offset, 2); 1196 *offset += 2; 1197 #if WORDS_BIGENDIAN 1198 rsp->session.msglen = BSWAP_16(rsp->session.msglen); 1199 #endif 1200 } 1201 1202 1203 1204 /* 1205 * read_session_data_v15 1206 * 1207 * Initialize the ipmi_rsp from the session header of the packet. 1208 * 1209 * The offset should point the first byte of the the IPMI session when this 1210 * function is called. When this function exits, the offset will point to 1211 * the start of the IPMI message. 1212 * 1213 * param rsp [in/out] we read from the data buffer and populate the session 1214 * specific fields. 1215 * param offset [in/out] should point to the beginning of the session when this 1216 * function is called. The offset will be adjusted to point to the 1217 * end of the session when this function exits. 1218 * param s holds our session state 1219 */ 1220 void read_session_data_v15( 1221 struct ipmi_rs * rsp, 1222 int * offset, 1223 struct ipmi_session * s) 1224 { 1225 /* All v15 messages are IPMI messages */ 1226 rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI; 1227 1228 rsp->session.authtype = rsp->data[(*offset)++]; 1229 1230 /* All v15 messages that we will receive are unencrypted/unauthenticated */ 1231 rsp->session.bEncrypted = 0; 1232 rsp->session.bAuthenticated = 0; 1233 1234 /* skip the session id and sequence number fields */ 1235 *offset += 8; 1236 1237 /* This is the size of the whole payload */ 1238 rsp->session.msglen = rsp->data[(*offset)++]; 1239 } 1240 1241 1242 1243 /* 1244 * read_ipmi_response 1245 * 1246 * Initialize the ipmi_rs from with the IPMI response specific data 1247 * 1248 * The offset should point the first byte of the the IPMI payload when this 1249 * function is called. 1250 * 1251 * param rsp [in/out] we read from the data buffer and populate the IPMI 1252 * specific fields. 1253 * param offset [in/out] should point to the beginning of the IPMI payload when 1254 * this function is called. 1255 */ 1256 void read_ipmi_response(struct ipmi_rs * rsp, int * offset) 1257 { 1258 /* 1259 * The data here should be decrypted by now. 1260 */ 1261 rsp->payload.ipmi_response.rq_addr = rsp->data[(*offset)++]; 1262 rsp->payload.ipmi_response.netfn = rsp->data[*offset] >> 2; 1263 rsp->payload.ipmi_response.rq_lun = rsp->data[(*offset)++] & 0x3; 1264 (*offset)++; /* checksum */ 1265 rsp->payload.ipmi_response.rs_addr = rsp->data[(*offset)++]; 1266 rsp->payload.ipmi_response.rq_seq = rsp->data[*offset] >> 2; 1267 rsp->payload.ipmi_response.rs_lun = rsp->data[(*offset)++] & 0x3; 1268 rsp->payload.ipmi_response.cmd = rsp->data[(*offset)++]; 1269 rsp->ccode = rsp->data[(*offset)++]; 1270 1271 } 1272 1273 1274 1275 /* 1276 * read_sol_packet 1277 * 1278 * Initialize the ipmi_rs with the SOL response data 1279 * 1280 * The offset should point the first byte of the the SOL payload when this 1281 * function is called. 1282 * 1283 * param rsp [in/out] we read from the data buffer and populate the 1284 * SOL specific fields. 1285 * param offset [in/out] should point to the beginning of the SOL payload 1286 * when this function is called. 1287 */ 1288 void read_sol_packet(struct ipmi_rs * rsp, int * offset) 1289 { 1290 1291 /* 1292 * The data here should be decrypted by now. 1293 */ 1294 rsp->payload.sol_packet.packet_sequence_number = 1295 rsp->data[(*offset)++] & 0x0F; 1296 1297 rsp->payload.sol_packet.acked_packet_number = 1298 rsp->data[(*offset)++] & 0x0F; 1299 1300 rsp->payload.sol_packet.accepted_character_count = 1301 rsp->data[(*offset)++]; 1302 1303 rsp->payload.sol_packet.is_nack = 1304 rsp->data[*offset] & 0x40; 1305 1306 rsp->payload.sol_packet.transfer_unavailable = 1307 rsp->data[*offset] & 0x20; 1308 1309 rsp->payload.sol_packet.sol_inactive = 1310 rsp->data[*offset] & 0x10; 1311 1312 rsp->payload.sol_packet.transmit_overrun = 1313 rsp->data[*offset] & 0x08; 1314 1315 rsp->payload.sol_packet.break_detected = 1316 rsp->data[(*offset)++] & 0x04; 1317 1318 lprintf(LOG_DEBUG, "<<<<<<<<<< RECV FROM BMC <<<<<<<<<<<"); 1319 lprintf(LOG_DEBUG, "< SOL sequence number : 0x%02x", 1320 rsp->payload.sol_packet.packet_sequence_number); 1321 lprintf(LOG_DEBUG, "< SOL acked packet : 0x%02x", 1322 rsp->payload.sol_packet.acked_packet_number); 1323 lprintf(LOG_DEBUG, "< SOL accepted char count : 0x%02x", 1324 rsp->payload.sol_packet.accepted_character_count); 1325 lprintf(LOG_DEBUG, "< SOL is nack : %s", 1326 rsp->payload.sol_packet.is_nack? "true" : "false"); 1327 lprintf(LOG_DEBUG, "< SOL xfer unavailable : %s", 1328 rsp->payload.sol_packet.transfer_unavailable? "true" : "false"); 1329 lprintf(LOG_DEBUG, "< SOL inactive : %s", 1330 rsp->payload.sol_packet.sol_inactive? "true" : "false"); 1331 lprintf(LOG_DEBUG, "< SOL transmit overrun : %s", 1332 rsp->payload.sol_packet.transmit_overrun? "true" : "false"); 1333 lprintf(LOG_DEBUG, "< SOL break detected : %s", 1334 rsp->payload.sol_packet.break_detected? "true" : "false"); 1335 lprintf(LOG_DEBUG, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); 1336 1337 if (verbose >= 5) 1338 printbuf(rsp->data + *offset - 4, 4, "SOL MSG FROM BMC"); 1339 } 1340 1341 1342 1343 /* 1344 * getIpmiPayloadWireRep 1345 * 1346 * param out [out] will contain our wire representation 1347 * param req [in] is the IPMI request to be written 1348 * param crypt_alg [in] specifies the encryption to use 1349 * param rq_seq [in] is the IPMI command sequence number. 1350 */ 1351 void getIpmiPayloadWireRep( 1352 struct ipmi_intf * intf, /* in out */ 1353 struct ipmi_v2_payload * payload, /* in */ 1354 uint8_t * msg, 1355 struct ipmi_rq * req, 1356 uint8_t rq_seq, 1357 uint8_t curr_seq) 1358 { 1359 int cs, tmp, len; 1360 int cs2 = 0; 1361 int cs3 = 0; 1362 uint8_t ourAddress = intf->my_addr; 1363 uint8_t bridgedRequest = 0; 1364 1365 if (ourAddress == 0) 1366 ourAddress = IPMI_BMC_SLAVE_ADDR; 1367 1368 len = 0; 1369 1370 /* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */ 1371 if ((intf->target_addr == ourAddress) || (!bridgePossible)) { 1372 cs = len; 1373 } else { 1374 bridgedRequest = 1; 1375 1376 if(intf->transit_addr != ourAddress && intf->transit_addr != 0) 1377 { 1378 bridgedRequest++; 1379 } 1380 /* bridged request: encapsulate w/in Send Message */ 1381 cs = len; 1382 msg[len++] = IPMI_BMC_SLAVE_ADDR; 1383 msg[len++] = IPMI_NETFN_APP << 2; 1384 tmp = len - cs; 1385 msg[len++] = ipmi_csum(msg+cs, tmp); 1386 cs2 = len; 1387 msg[len++] = IPMI_REMOTE_SWID; 1388 msg[len++] = curr_seq << 2; 1389 1390 1391 msg[len++] = 0x34; /* Send Message rqst */ 1392 if(bridgedRequest == 2) 1393 msg[len++] = (0x40|intf->transit_channel); /* Track request*/ 1394 else 1395 msg[len++] = (0x40|intf->target_channel); /* Track request*/ 1396 1397 payload->payload_length += 7; 1398 cs = len; 1399 1400 if(bridgedRequest == 2) 1401 { 1402 /* bridged request: encapsulate w/in Send Message */ 1403 cs = len; 1404 msg[len++] = intf->transit_addr; 1405 msg[len++] = IPMI_NETFN_APP << 2; 1406 tmp = len - cs; 1407 msg[len++] = ipmi_csum(msg+cs, tmp); 1408 cs3 = len; 1409 msg[len++] = intf->my_addr; 1410 msg[len++] = curr_seq << 2; 1411 msg[len++] = 0x34; /* Send Message rqst */ 1412 #if 0 /* From lan.c example */ 1413 entry->req.msg.target_cmd = entry->req.msg.cmd; /* Save target command */ 1414 entry->req.msg.cmd = 0x34; /* (fixup request entry) */ 1415 #endif 1416 msg[len++] = (0x40|intf->target_channel); /* Track request*/ 1417 1418 payload->payload_length += 7; 1419 1420 cs = len; 1421 } 1422 } 1423 1424 lprintf(LOG_DEBUG,"%s RqAddr %#x transit %#x:%#x target %#x:%#x " 1425 "bridgePossible %d", 1426 bridgedRequest ? "Bridging" : "Local", 1427 intf->my_addr, intf->transit_addr, intf->transit_channel, 1428 intf->target_addr, intf->target_channel, 1429 bridgePossible); 1430 1431 /* rsAddr */ 1432 msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */ 1433 1434 /* net Fn */ 1435 msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3); 1436 tmp = len - cs; 1437 1438 /* checkSum */ 1439 msg[len++] = ipmi_csum(msg+cs, tmp); 1440 cs = len; 1441 1442 /* rqAddr */ 1443 if (!bridgedRequest) 1444 msg[len++] = IPMI_REMOTE_SWID; 1445 else /* Bridged message */ 1446 msg[len++] = intf->my_addr; 1447 1448 /* rqSeq / rqLUN */ 1449 msg[len++] = rq_seq << 2; 1450 1451 /* cmd */ 1452 msg[len++] = req->msg.cmd; 1453 1454 /* message data */ 1455 if (req->msg.data_len) { 1456 memcpy(msg + len, req->msg.data, req->msg.data_len); 1457 len += req->msg.data_len; 1458 } 1459 1460 /* second checksum */ 1461 tmp = len - cs; 1462 msg[len++] = ipmi_csum(msg+cs, tmp); 1463 1464 /* Dual bridged request: 2nd checksum */ 1465 if (bridgedRequest == 2) { 1466 tmp = len - cs3; 1467 msg[len++] = ipmi_csum(msg+cs3, tmp); 1468 payload->payload_length += 1; 1469 } 1470 1471 /* bridged request: 2nd checksum */ 1472 if (bridgedRequest) { 1473 tmp = len - cs2; 1474 msg[len++] = ipmi_csum(msg+cs2, tmp); 1475 payload->payload_length += 1; 1476 } 1477 } 1478 1479 1480 1481 /* 1482 * getSolPayloadWireRep 1483 * 1484 * param msg [out] will contain our wire representation 1485 * param payload [in] holds the v2 payload with our SOL data 1486 */ 1487 void getSolPayloadWireRep( 1488 struct ipmi_intf * intf, /* in out */ 1489 uint8_t * msg, /* output */ 1490 struct ipmi_v2_payload * payload) /* input */ 1491 { 1492 int i = 0; 1493 1494 lprintf(LOG_DEBUG, ">>>>>>>>>> SENDING TO BMC >>>>>>>>>>"); 1495 lprintf(LOG_DEBUG, "> SOL sequence number : 0x%02x", 1496 payload->payload.sol_packet.packet_sequence_number); 1497 lprintf(LOG_DEBUG, "> SOL acked packet : 0x%02x", 1498 payload->payload.sol_packet.acked_packet_number); 1499 lprintf(LOG_DEBUG, "> SOL accepted char count : 0x%02x", 1500 payload->payload.sol_packet.accepted_character_count); 1501 lprintf(LOG_DEBUG, "> SOL is nack : %s", 1502 payload->payload.sol_packet.is_nack ? "true" : "false"); 1503 lprintf(LOG_DEBUG, "> SOL assert ring wor : %s", 1504 payload->payload.sol_packet.assert_ring_wor ? "true" : "false"); 1505 lprintf(LOG_DEBUG, "> SOL generate break : %s", 1506 payload->payload.sol_packet.generate_break ? "true" : "false"); 1507 lprintf(LOG_DEBUG, "> SOL deassert cts : %s", 1508 payload->payload.sol_packet.deassert_cts ? "true" : "false"); 1509 lprintf(LOG_DEBUG, "> SOL deassert dcd dsr : %s", 1510 payload->payload.sol_packet.deassert_dcd_dsr ? "true" : "false"); 1511 lprintf(LOG_DEBUG, "> SOL flush inbound : %s", 1512 payload->payload.sol_packet.flush_inbound ? "true" : "false"); 1513 lprintf(LOG_DEBUG, "> SOL flush outbound : %s", 1514 payload->payload.sol_packet.flush_outbound ? "true" : "false"); 1515 1516 msg[i++] = payload->payload.sol_packet.packet_sequence_number; 1517 msg[i++] = payload->payload.sol_packet.acked_packet_number; 1518 msg[i++] = payload->payload.sol_packet.accepted_character_count; 1519 1520 msg[i] = payload->payload.sol_packet.is_nack ? 0x40 : 0; 1521 msg[i] |= payload->payload.sol_packet.assert_ring_wor ? 0x20 : 0; 1522 msg[i] |= payload->payload.sol_packet.generate_break ? 0x10 : 0; 1523 msg[i] |= payload->payload.sol_packet.deassert_cts ? 0x08 : 0; 1524 msg[i] |= payload->payload.sol_packet.deassert_dcd_dsr ? 0x04 : 0; 1525 msg[i] |= payload->payload.sol_packet.flush_inbound ? 0x02 : 0; 1526 msg[i++] |= payload->payload.sol_packet.flush_outbound ? 0x01 : 0; 1527 1528 /* We may have data to add */ 1529 memcpy(msg + i, 1530 payload->payload.sol_packet.data, 1531 payload->payload.sol_packet.character_count); 1532 1533 lprintf(LOG_DEBUG, "> SOL character count : %d", 1534 payload->payload.sol_packet.character_count); 1535 lprintf(LOG_DEBUG, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); 1536 1537 if (verbose >= 5 && payload->payload.sol_packet.character_count) 1538 printbuf(payload->payload.sol_packet.data, payload->payload.sol_packet.character_count, "SOL SEND DATA"); 1539 1540 /* 1541 * At this point, the payload length becomes the whole payload 1542 * length, including the 4 bytes at the beginning of the SOL 1543 * packet 1544 */ 1545 payload->payload_length = payload->payload.sol_packet.character_count + 4; 1546 } 1547 1548 1549 1550 /* 1551 * ipmi_lanplus_build_v2x_msg 1552 * 1553 * Encapsulates the payload data to create the IPMI v2.0 / RMCP+ packet. 1554 * 1555 * 1556 * IPMI v2.0 LAN Request Message Format 1557 * +----------------------+ 1558 * | rmcp.ver | 4 bytes 1559 * | rmcp.__reserved | 1560 * | rmcp.seq | 1561 * | rmcp.class | 1562 * +----------------------+ 1563 * | session.authtype | 10 bytes 1564 * | session.payloadtype | 1565 * | session.id | 1566 * | session.seq | 1567 * +----------------------+ 1568 * | message length | 2 bytes 1569 * +----------------------+ 1570 * | Confidentiality Hdr | var (possibly absent) 1571 * +----------------------+ 1572 * | Paylod | var Payload 1573 * +----------------------+ 1574 * | Confidentiality Trlr | var (possibly absent) 1575 * +----------------------+ 1576 * | Integrity pad | var (possibly absent) 1577 * +----------------------+ 1578 * | Pad length | 1 byte (WTF?) 1579 * +----------------------+ 1580 * | Next Header | 1 byte (WTF?) 1581 * +----------------------+ 1582 * | Authcode | var (possibly absent) 1583 * +----------------------+ 1584 */ 1585 void 1586 ipmi_lanplus_build_v2x_msg( 1587 struct ipmi_intf * intf, /* in */ 1588 struct ipmi_v2_payload * payload, /* in */ 1589 int * msg_len, /* out */ 1590 uint8_t ** msg_data, /* out */ 1591 uint8_t curr_seq) 1592 { 1593 uint32_t session_trailer_length = 0; 1594 struct ipmi_session * session = intf->session; 1595 struct rmcp_hdr rmcp = { 1596 .ver = RMCP_VERSION_1, 1597 .class = RMCP_CLASS_IPMI, 1598 .seq = 0xff, 1599 }; 1600 1601 /* msg will hold the entire message to be sent */ 1602 uint8_t * msg; 1603 int len = 0; 1604 1605 1606 len = 1607 sizeof(rmcp) + // RMCP Header (4) 1608 10 + // IPMI Session Header 1609 2 + // Message length 1610 payload->payload_length + // The actual payload 1611 IPMI_MAX_INTEGRITY_PAD_SIZE + // Integrity Pad 1612 1 + // Pad Length 1613 1 + // Next Header 1614 IPMI_MAX_AUTH_CODE_SIZE; // Authcode 1615 1616 1617 msg = malloc(len); 1618 if (msg == NULL) { 1619 lprintf(LOG_ERR, "ipmitool: malloc failure"); 1620 return; 1621 } 1622 memset(msg, 0, len); 1623 1624 /* 1625 *------------------------------------------ 1626 * RMCP HEADER 1627 *------------------------------------------ 1628 */ 1629 memcpy(msg, &rmcp, sizeof(rmcp)); 1630 len = sizeof(rmcp); 1631 1632 1633 /* 1634 *------------------------------------------ 1635 * IPMI SESSION HEADER 1636 *------------------------------------------ 1637 */ 1638 /* ipmi session Auth Type / Format is always 0x06 for IPMI v2 */ 1639 msg[IPMI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; 1640 1641 /* Payload Type -- also specifies whether were authenticated/encyrpted */ 1642 msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; 1643 1644 if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) 1645 { 1646 msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= 1647 ((session->v2_data.crypt_alg != IPMI_CRYPT_NONE )? 0x80 : 0x00); 1648 msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= 1649 ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00); 1650 } 1651 1652 if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) 1653 { 1654 /* Session ID -- making it LSB */ 1655 msg[IPMI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; 1656 msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; 1657 msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; 1658 msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; 1659 1660 /* Sequence Number -- making it LSB */ 1661 msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM ] = session->out_seq & 0xff; 1662 msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8) & 0xff; 1663 msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; 1664 msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; 1665 } 1666 1667 /* 1668 * Payload Length is set below (we don't know how big the payload is until after 1669 * encryption). 1670 */ 1671 1672 /* 1673 * Payload 1674 * 1675 * At this point we are ready to slam the payload in. 1676 * This includes: 1677 * 1) The confidentiality header 1678 * 2) The payload proper (possibly encrypted) 1679 * 3) The confidentiality trailer 1680 * 1681 */ 1682 switch (payload->payload_type) 1683 { 1684 case IPMI_PAYLOAD_TYPE_IPMI: 1685 getIpmiPayloadWireRep(intf, 1686 payload, /* in */ 1687 msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 1688 payload->payload.ipmi_request.request, 1689 payload->payload.ipmi_request.rq_seq, 1690 curr_seq); 1691 break; 1692 1693 case IPMI_PAYLOAD_TYPE_SOL: 1694 getSolPayloadWireRep(intf, 1695 msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 1696 payload); 1697 1698 if (verbose >= 5) 1699 printbuf(msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 4, "SOL MSG TO BMC"); 1700 1701 len += payload->payload_length; 1702 1703 break; 1704 1705 case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST: 1706 /* never encrypted, so our job is easy */ 1707 memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 1708 payload->payload.open_session_request.request, 1709 payload->payload_length); 1710 len += payload->payload_length; 1711 break; 1712 1713 case IPMI_PAYLOAD_TYPE_RAKP_1: 1714 /* never encrypted, so our job is easy */ 1715 memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 1716 payload->payload.rakp_1_message.message, 1717 payload->payload_length); 1718 len += payload->payload_length; 1719 break; 1720 1721 case IPMI_PAYLOAD_TYPE_RAKP_3: 1722 /* never encrypted, so our job is easy */ 1723 memcpy(msg + IPMI_LANPLUS_OFFSET_PAYLOAD, 1724 payload->payload.rakp_3_message.message, 1725 payload->payload_length); 1726 len += payload->payload_length; 1727 break; 1728 1729 default: 1730 lprintf(LOG_ERR, "unsupported payload type 0x%x", 1731 payload->payload_type); 1732 free(msg); 1733 msg = NULL; 1734 assert(0); 1735 break; 1736 } 1737 1738 1739 /* 1740 *------------------------------------------ 1741 * ENCRYPT THE PAYLOAD IF NECESSARY 1742 *------------------------------------------ 1743 */ 1744 if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) 1745 { 1746 /* Payload len is adjusted as necessary by lanplus_encrypt_payload */ 1747 lanplus_encrypt_payload(session->v2_data.crypt_alg, /* input */ 1748 session->v2_data.k2, /* input */ 1749 msg + IPMI_LANPLUS_OFFSET_PAYLOAD, /* input */ 1750 payload->payload_length, /* input */ 1751 msg + IPMI_LANPLUS_OFFSET_PAYLOAD, /* output */ 1752 &(payload->payload_length)); /* output */ 1753 1754 } 1755 1756 /* Now we know the payload length */ 1757 msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE ] = 1758 payload->payload_length & 0xff; 1759 msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = 1760 (payload->payload_length >> 8) & 0xff; 1761 1762 1763 /* 1764 *------------------------------------------ 1765 * SESSION TRAILER 1766 *------------------------------------------ 1767 */ 1768 if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) && 1769 (session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)) 1770 { 1771 uint32_t i, hmac_length, integrity_pad_size = 0, hmac_input_size; 1772 uint8_t * hmac_output; 1773 uint32_t start_of_session_trailer = 1774 IPMI_LANPLUS_OFFSET_PAYLOAD + 1775 payload->payload_length; 1776 1777 1778 /* 1779 * Determine the required integrity pad length. We have to make the 1780 * data range covered by the authcode a multiple of 4. 1781 */ 1782 uint32_t length_before_authcode; 1783 1784 if (ipmi_oem_active(intf, "icts")) { 1785 length_before_authcode = 1786 12 + /* the stuff before the payload */ 1787 payload->payload_length; 1788 } else { 1789 length_before_authcode = 1790 12 + /* the stuff before the payload */ 1791 payload->payload_length + 1792 1 + /* pad length field */ 1793 1; /* next header field */ 1794 } 1795 1796 if (length_before_authcode % 4) 1797 integrity_pad_size = 4 - (length_before_authcode % 4); 1798 1799 for (i = 0; i < integrity_pad_size; ++i) 1800 msg[start_of_session_trailer + i] = 0xFF; 1801 1802 /* Pad length */ 1803 msg[start_of_session_trailer + integrity_pad_size] = integrity_pad_size; 1804 1805 /* Next Header */ 1806 msg[start_of_session_trailer + integrity_pad_size + 1] = 1807 0x07; /* Hardcoded per the spec, table 13-8 */ 1808 1809 hmac_input_size = 1810 12 + 1811 payload->payload_length + 1812 integrity_pad_size + 1813 2; 1814 1815 hmac_output = 1816 msg + 1817 IPMI_LANPLUS_OFFSET_PAYLOAD + 1818 payload->payload_length + 1819 integrity_pad_size + 1820 2; 1821 1822 if (verbose > 2) 1823 printbuf(msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); 1824 1825 1826 /* Auth Code */ 1827 lanplus_HMAC(session->v2_data.integrity_alg, 1828 session->v2_data.k1, /* key */ 1829 20, /* key length */ 1830 msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ 1831 hmac_input_size, 1832 hmac_output, 1833 &hmac_length); 1834 1835 assert(hmac_length == 20); 1836 1837 if (verbose > 2) 1838 printbuf(hmac_output, 12, "authcode output"); 1839 1840 /* Set session_trailer_length appropriately */ 1841 session_trailer_length = 1842 integrity_pad_size + 1843 2 + /* pad length + next header */ 1844 12; /* Size of the authcode (we only use the first 12 bytes) */ 1845 } 1846 1847 1848 ++(session->out_seq); 1849 if (!session->out_seq) 1850 ++(session->out_seq); 1851 1852 *msg_len = 1853 IPMI_LANPLUS_OFFSET_PAYLOAD + 1854 payload->payload_length + 1855 session_trailer_length; 1856 *msg_data = msg; 1857 } 1858 1859 1860 1861 /* 1862 * ipmi_lanplus_build_v2x_ipmi_cmd 1863 * 1864 * Wraps ipmi_lanplus_build_v2x_msg and returns a new entry object for the 1865 * command 1866 * 1867 */ 1868 static struct ipmi_rq_entry * 1869 ipmi_lanplus_build_v2x_ipmi_cmd( 1870 struct ipmi_intf * intf, 1871 struct ipmi_rq * req, 1872 int isRetry) 1873 { 1874 struct ipmi_v2_payload v2_payload; 1875 struct ipmi_rq_entry * entry; 1876 1877 /* 1878 * We have a problem. we need to know the sequence number here, 1879 * because we use it in our stored entry. But we also need to 1880 * know the sequence number when we generate our IPMI 1881 * representation far below. 1882 */ 1883 static uint8_t curr_seq = 0; 1884 1885 if( isRetry == 0 ) 1886 curr_seq += 1; 1887 1888 if (curr_seq >= 64) 1889 curr_seq = 0; 1890 1891 1892 /* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */ 1893 if ((intf->target_addr == intf->my_addr) || (!bridgePossible)) 1894 { 1895 entry = ipmi_req_add_entry(intf, req, curr_seq); 1896 } 1897 else /* it's a bridge command */ 1898 { 1899 unsigned char backup_cmd; 1900 1901 /* Add entry for cmd */ 1902 entry = ipmi_req_add_entry(intf, req, curr_seq); 1903 1904 if(entry) 1905 { 1906 /* Add entry for bridge cmd */ 1907 backup_cmd = req->msg.cmd; 1908 req->msg.cmd = 0x34; 1909 entry = ipmi_req_add_entry(intf, req, curr_seq); 1910 req->msg.cmd = backup_cmd; 1911 } 1912 } 1913 1914 if (entry == NULL) 1915 return NULL; 1916 1917 // Build our payload 1918 v2_payload.payload_type = IPMI_PAYLOAD_TYPE_IPMI; 1919 v2_payload.payload_length = req->msg.data_len + 7; 1920 v2_payload.payload.ipmi_request.request = req; 1921 v2_payload.payload.ipmi_request.rq_seq = curr_seq; 1922 1923 ipmi_lanplus_build_v2x_msg(intf, // in 1924 &v2_payload, // in 1925 &(entry->msg_len), // out 1926 &(entry->msg_data), // out 1927 curr_seq); // in 1928 1929 return entry; 1930 } 1931 1932 1933 1934 1935 1936 /* 1937 * IPMI LAN Request Message Format 1938 * +--------------------+ 1939 * | rmcp.ver | 4 bytes 1940 * | rmcp.__reserved | 1941 * | rmcp.seq | 1942 * | rmcp.class | 1943 * +--------------------+ 1944 * | session.authtype | 9 bytes 1945 * | session.seq | 1946 * | session.id | 1947 * +--------------------+ 1948 * | [session.authcode] | 16 bytes (AUTHTYPE != none) 1949 * +--------------------+ 1950 * | message length | 1 byte 1951 * +--------------------+ 1952 * | message.rs_addr | 6 bytes 1953 * | message.netfn_lun | 1954 * | message.checksum | 1955 * | message.rq_addr | 1956 * | message.rq_seq | 1957 * | message.cmd | 1958 * +--------------------+ 1959 * | [request data] | data_len bytes 1960 * +--------------------+ 1961 * | checksum | 1 byte 1962 * +--------------------+ 1963 */ 1964 static struct ipmi_rq_entry * 1965 ipmi_lanplus_build_v15_ipmi_cmd( 1966 struct ipmi_intf * intf, 1967 struct ipmi_rq * req) 1968 { 1969 struct rmcp_hdr rmcp = { 1970 .ver = RMCP_VERSION_1, 1971 .class = RMCP_CLASS_IPMI, 1972 .seq = 0xff, 1973 }; 1974 uint8_t * msg; 1975 int cs, mp, len = 0, tmp; 1976 struct ipmi_session * session = intf->session; 1977 struct ipmi_rq_entry * entry; 1978 1979 entry = ipmi_req_add_entry(intf, req, 0); 1980 if (entry == NULL) 1981 return NULL; 1982 1983 len = req->msg.data_len + 21; 1984 1985 msg = malloc(len); 1986 if (msg == NULL) { 1987 lprintf(LOG_ERR, "ipmitool: malloc failure"); 1988 return NULL; 1989 } 1990 memset(msg, 0, len); 1991 1992 /* rmcp header */ 1993 memcpy(msg, &rmcp, sizeof(rmcp)); 1994 len = sizeof(rmcp); 1995 1996 /* 1997 * ipmi session header 1998 */ 1999 /* Authtype should always be none for 1.5 packets sent from this 2000 * interface 2001 */ 2002 msg[len++] = IPMI_SESSION_AUTHTYPE_NONE; 2003 2004 msg[len++] = session->out_seq & 0xff; 2005 msg[len++] = (session->out_seq >> 8) & 0xff; 2006 msg[len++] = (session->out_seq >> 16) & 0xff; 2007 msg[len++] = (session->out_seq >> 24) & 0xff; 2008 2009 /* 2010 * The session ID should be all zeroes for pre-session commands. We 2011 * should only be using the 1.5 interface for the pre-session Get 2012 * Channel Authentication Capabilities command 2013 */ 2014 msg[len++] = 0; 2015 msg[len++] = 0; 2016 msg[len++] = 0; 2017 msg[len++] = 0; 2018 2019 /* message length */ 2020 msg[len++] = req->msg.data_len + 7; 2021 2022 /* ipmi message header */ 2023 cs = mp = len; 2024 msg[len++] = IPMI_BMC_SLAVE_ADDR; 2025 msg[len++] = req->msg.netfn << 2; 2026 tmp = len - cs; 2027 msg[len++] = ipmi_csum(msg+cs, tmp); 2028 cs = len; 2029 msg[len++] = IPMI_REMOTE_SWID; 2030 2031 entry->rq_seq = 0; 2032 2033 msg[len++] = entry->rq_seq << 2; 2034 msg[len++] = req->msg.cmd; 2035 2036 lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header"); 2037 lprintf(LOG_DEBUG+1, ">> Authtype : %s", 2038 val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_session_vals)); 2039 lprintf(LOG_DEBUG+1, ">> Sequence : 0x%08lx", 2040 (long)session->out_seq); 2041 lprintf(LOG_DEBUG+1, ">> Session ID : 0x%08lx", 2042 (long)0); 2043 2044 lprintf(LOG_DEBUG+1, ">> IPMI Request Message Header"); 2045 lprintf(LOG_DEBUG+1, ">> Rs Addr : %02x", IPMI_BMC_SLAVE_ADDR); 2046 lprintf(LOG_DEBUG+1, ">> NetFn : %02x", req->msg.netfn); 2047 lprintf(LOG_DEBUG+1, ">> Rs LUN : %01x", 0); 2048 lprintf(LOG_DEBUG+1, ">> Rq Addr : %02x", IPMI_REMOTE_SWID); 2049 lprintf(LOG_DEBUG+1, ">> Rq Seq : %02x", entry->rq_seq); 2050 lprintf(LOG_DEBUG+1, ">> Rq Lun : %01x", 0); 2051 lprintf(LOG_DEBUG+1, ">> Command : %02x", req->msg.cmd); 2052 2053 /* message data */ 2054 if (req->msg.data_len) { 2055 memcpy(msg+len, req->msg.data, req->msg.data_len); 2056 len += req->msg.data_len; 2057 } 2058 2059 /* second checksum */ 2060 tmp = len - cs; 2061 msg[len++] = ipmi_csum(msg+cs, tmp); 2062 2063 entry->msg_len = len; 2064 entry->msg_data = msg; 2065 2066 return entry; 2067 } 2068 2069 2070 2071 /* 2072 * is_sol_packet 2073 */ 2074 static int 2075 is_sol_packet(struct ipmi_rs * rsp) 2076 { 2077 return (rsp && 2078 (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && 2079 (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)); 2080 } 2081 2082 2083 2084 /* 2085 * sol_response_acks_packet 2086 */ 2087 static int 2088 sol_response_acks_packet( 2089 struct ipmi_rs * rsp, 2090 struct ipmi_v2_payload * payload) 2091 { 2092 return (is_sol_packet(rsp) && 2093 payload && 2094 (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) && 2095 (rsp->payload.sol_packet.acked_packet_number == 2096 payload->payload.sol_packet.packet_sequence_number)); 2097 } 2098 2099 2100 2101 /* 2102 * ipmi_lanplus_send_payload 2103 * 2104 */ 2105 struct ipmi_rs * 2106 ipmi_lanplus_send_payload( 2107 struct ipmi_intf * intf, 2108 struct ipmi_v2_payload * payload) 2109 { 2110 struct ipmi_rs * rsp = NULL; 2111 uint8_t * msg_data; 2112 int msg_length; 2113 struct ipmi_session * session = intf->session; 2114 struct ipmi_rq_entry * entry = NULL; 2115 int try = 0; 2116 int xmit = 1; 2117 time_t ltime; 2118 uint32_t saved_timeout; 2119 2120 if (!intf->opened && intf->open && intf->open(intf) < 0) 2121 return NULL; 2122 2123 /* 2124 * The session timeout is initialized in the above interface open, 2125 * so it will only be valid after the open completes. 2126 */ 2127 saved_timeout = session->timeout; 2128 while (try < session->retry) { 2129 //ltime = time(NULL); 2130 2131 if (xmit) { 2132 ltime = time(NULL); 2133 2134 if (payload->payload_type == IPMI_PAYLOAD_TYPE_IPMI) 2135 { 2136 /* 2137 * Build an IPMI v1.5 or v2 command 2138 */ 2139 struct ipmi_rq * ipmi_request = payload->payload.ipmi_request.request; 2140 2141 lprintf(LOG_DEBUG, ""); 2142 lprintf(LOG_DEBUG, ">> Sending IPMI command payload"); 2143 lprintf(LOG_DEBUG, ">> netfn : 0x%02x", ipmi_request->msg.netfn); 2144 lprintf(LOG_DEBUG, ">> command : 0x%02x", ipmi_request->msg.cmd); 2145 2146 if (verbose > 1) 2147 { 2148 uint16_t i; 2149 fprintf(stderr, ">> data : "); 2150 for (i = 0; i < ipmi_request->msg.data_len; ++i) 2151 fprintf(stderr, "0x%02x ", ipmi_request->msg.data[i]); 2152 fprintf(stderr, "\n\n"); 2153 } 2154 2155 2156 /* 2157 * If we are presession, and the command is GET CHANNEL AUTHENTICATION 2158 * CAPABILITIES, we will build the command in v1.5 format. This is so 2159 * that we can ask any server whether it supports IPMI v2 / RMCP+ 2160 * before we attempt to open a v2.x session. 2161 */ 2162 if ((ipmi_request->msg.netfn == IPMI_NETFN_APP) && 2163 (ipmi_request->msg.cmd == IPMI_GET_CHANNEL_AUTH_CAP) && 2164 (session->v2_data.bmc_id == 0)) // jme - check 2165 { 2166 lprintf(LOG_DEBUG+1, "BUILDING A v1.5 COMMAND"); 2167 entry = ipmi_lanplus_build_v15_ipmi_cmd(intf, ipmi_request); 2168 } 2169 else 2170 { 2171 int isRetry = ( try > 0 ? 1 : 0 ); 2172 2173 lprintf(LOG_DEBUG+1, "BUILDING A v2 COMMAND"); 2174 entry = ipmi_lanplus_build_v2x_ipmi_cmd(intf, ipmi_request, isRetry); 2175 } 2176 2177 if (entry == NULL) { 2178 lprintf(LOG_ERR, "Aborting send command, unable to build"); 2179 return NULL; 2180 } 2181 2182 msg_data = entry->msg_data; 2183 msg_length = entry->msg_len; 2184 } 2185 2186 else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST) 2187 { 2188 lprintf(LOG_DEBUG, ">> SENDING AN OPEN SESSION REQUEST\n"); 2189 assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION 2190 || session->v2_data.session_state == LANPLUS_STATE_OPEN_SESSION_SENT); 2191 2192 ipmi_lanplus_build_v2x_msg(intf, /* in */ 2193 payload, /* in */ 2194 &msg_length, /* out */ 2195 &msg_data, /* out */ 2196 0); /* irrelevant for this msg*/ 2197 2198 } 2199 2200 else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RAKP_1) 2201 { 2202 lprintf(LOG_DEBUG, ">> SENDING A RAKP 1 MESSAGE\n"); 2203 assert(session->v2_data.session_state == 2204 LANPLUS_STATE_OPEN_SESSION_RECEIEVED); 2205 2206 ipmi_lanplus_build_v2x_msg(intf, /* in */ 2207 payload, /* in */ 2208 &msg_length, /* out */ 2209 &msg_data, /* out */ 2210 0); /* irrelevant for this msg*/ 2211 2212 } 2213 2214 else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RAKP_3) 2215 { 2216 lprintf(LOG_DEBUG, ">> SENDING A RAKP 3 MESSAGE\n"); 2217 assert(session->v2_data.session_state == 2218 LANPLUS_STATE_RAKP_2_RECEIVED); 2219 2220 ipmi_lanplus_build_v2x_msg(intf, /* in */ 2221 payload, /* in */ 2222 &msg_length, /* out */ 2223 &msg_data, /* out */ 2224 0); /* irrelevant for this msg*/ 2225 2226 } 2227 2228 else if (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) 2229 { 2230 lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n"); 2231 assert(session->v2_data.session_state == LANPLUS_STATE_ACTIVE); 2232 2233 ipmi_lanplus_build_v2x_msg(intf, /* in */ 2234 payload, /* in */ 2235 &msg_length, /* out */ 2236 &msg_data, /* out */ 2237 0); /* irrelevant for this msg*/ 2238 } 2239 2240 else 2241 { 2242 lprintf(LOG_ERR, "Payload type 0x%0x is unsupported!", 2243 payload->payload_type); 2244 assert(0); 2245 } 2246 2247 2248 if (ipmi_lan_send_packet(intf, msg_data, msg_length) < 0) { 2249 lprintf(LOG_ERR, "IPMI LAN send command failed"); 2250 return NULL; 2251 } 2252 } 2253 2254 /* if we are set to noanswer we do not expect response */ 2255 if (intf->noanswer) 2256 break; 2257 2258 usleep(100); /* Not sure what this is for */ 2259 2260 /* Remember our connection state */ 2261 switch (payload->payload_type) 2262 { 2263 case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST: 2264 session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT; 2265 /* not retryable for timeouts, force no retry */ 2266 try = session->retry; 2267 break; 2268 case IPMI_PAYLOAD_TYPE_RAKP_1: 2269 session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT; 2270 /* not retryable for timeouts, force no retry */ 2271 try = session->retry; 2272 break; 2273 case IPMI_PAYLOAD_TYPE_RAKP_3: 2274 /* not retryable for timeouts, force no retry */ 2275 try = session->retry; 2276 session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT; 2277 break; 2278 } 2279 2280 2281 /* 2282 * Special case for SOL outbound packets. 2283 */ 2284 if (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) 2285 { 2286 if (! payload->payload.sol_packet.packet_sequence_number) 2287 { 2288 /* We're just sending an ACK. No need to retry. */ 2289 break; 2290 } 2291 2292 2293 rsp = ipmi_lanplus_recv_sol(intf); /* Grab the next packet */ 2294 2295 if (sol_response_acks_packet(rsp, payload)) 2296 break; 2297 2298 else if (is_sol_packet(rsp) && rsp->data_len) 2299 { 2300 /* 2301 * We're still waiting for our ACK, but we more data from 2302 * the BMC 2303 */ 2304 intf->session->sol_data.sol_input_handler(rsp); 2305 /* In order to avoid duplicate output, just set data_len to 0 */ 2306 rsp->data_len = 0; 2307 } 2308 } 2309 2310 2311 /* Non-SOL processing */ 2312 else 2313 { 2314 rsp = ipmi_lan_poll_recv(intf); 2315 2316 /* Duplicate Request ccode most likely indicates a response to 2317 a previous retry. Ignore and keep polling. */ 2318 while ((rsp != NULL) && (rsp->ccode == 0xcf)) 2319 { 2320 rsp = NULL; 2321 rsp = ipmi_lan_poll_recv(intf); 2322 } 2323 2324 if (rsp) 2325 break; 2326 /* This payload type is retryable for timeouts. */ 2327 if ((payload->payload_type == IPMI_PAYLOAD_TYPE_IPMI) && entry) { 2328 ipmi_req_remove_entry( entry->rq_seq, entry->req.msg.cmd); 2329 } 2330 } 2331 2332 /* only timeout if time exceeds the timeout value */ 2333 xmit = ((time(NULL) - ltime) >= session->timeout); 2334 2335 usleep(5000); 2336 2337 if (xmit) { 2338 /* increment session timeout by 1 second each retry */ 2339 session->timeout++; 2340 } 2341 2342 try++; 2343 } 2344 session->timeout = saved_timeout; 2345 2346 /* IPMI messages are deleted under ipmi_lan_poll_recv() */ 2347 switch (payload->payload_type) { 2348 case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST: 2349 case IPMI_PAYLOAD_TYPE_RAKP_1: 2350 case IPMI_PAYLOAD_TYPE_RAKP_3: 2351 free(msg_data); 2352 msg_data = NULL; 2353 break; 2354 } 2355 2356 return rsp; 2357 } 2358 2359 2360 2361 /* 2362 * is_sol_partial_ack 2363 * 2364 * Determine if the response is a partial ACK/NACK that indicates 2365 * we need to resend part of our packet. 2366 * 2367 * returns the number of characters we need to resend, or 2368 * 0 if this isn't an ACK or we don't need to resend anything 2369 */ 2370 int is_sol_partial_ack( 2371 struct ipmi_intf * intf, 2372 struct ipmi_v2_payload * v2_payload, 2373 struct ipmi_rs * rs) 2374 { 2375 int chars_to_resend = 0; 2376 2377 if (v2_payload && 2378 rs && 2379 is_sol_packet(rs) && 2380 sol_response_acks_packet(rs, v2_payload) && 2381 (rs->payload.sol_packet.accepted_character_count < 2382 v2_payload->payload.sol_packet.character_count)) 2383 { 2384 if (ipmi_oem_active(intf, "intelplus") && 2385 rs->payload.sol_packet.accepted_character_count == 0) 2386 return 0; 2387 2388 chars_to_resend = 2389 v2_payload->payload.sol_packet.character_count - 2390 rs->payload.sol_packet.accepted_character_count; 2391 } 2392 2393 return chars_to_resend; 2394 } 2395 2396 2397 2398 /* 2399 * set_sol_packet_sequence_number 2400 */ 2401 static void set_sol_packet_sequence_number( 2402 struct ipmi_intf * intf, 2403 struct ipmi_v2_payload * v2_payload) 2404 { 2405 /* Keep our sequence number sane */ 2406 if (intf->session->sol_data.sequence_number > 0x0F) 2407 intf->session->sol_data.sequence_number = 1; 2408 2409 v2_payload->payload.sol_packet.packet_sequence_number = 2410 intf->session->sol_data.sequence_number++; 2411 } 2412 2413 2414 2415 /* 2416 * ipmi_lanplus_send_sol 2417 * 2418 * Sends a SOL packet.. We handle partial ACK/NACKs from the BMC here. 2419 * 2420 * Returns a pointer to the SOL ACK we received, or 2421 * 0 on failure 2422 * 2423 */ 2424 struct ipmi_rs * 2425 ipmi_lanplus_send_sol( 2426 struct ipmi_intf * intf, 2427 struct ipmi_v2_payload * v2_payload) 2428 { 2429 struct ipmi_rs * rs; 2430 2431 /* 2432 * chars_to_resend indicates either that we got a NACK telling us 2433 * that we need to resend some part of our data. 2434 */ 2435 int chars_to_resend = 0; 2436 2437 v2_payload->payload_type = IPMI_PAYLOAD_TYPE_SOL; 2438 2439 /* 2440 * Payload length is just the length of the character 2441 * data here. 2442 */ 2443 v2_payload->payload_length = v2_payload->payload.sol_packet.character_count; 2444 2445 v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */ 2446 2447 set_sol_packet_sequence_number(intf, v2_payload); 2448 2449 v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */ 2450 2451 rs = ipmi_lanplus_send_payload(intf, v2_payload); 2452 2453 /* Determine if we need to resend some of our data */ 2454 chars_to_resend = is_sol_partial_ack(intf, v2_payload, rs); 2455 2456 while (rs && !rs->payload.sol_packet.transfer_unavailable && 2457 !rs->payload.sol_packet.is_nack && 2458 chars_to_resend) 2459 { 2460 /* 2461 * We first need to handle any new data we might have 2462 * received in our NACK 2463 */ 2464 if (rs->data_len) 2465 intf->session->sol_data.sol_input_handler(rs); 2466 2467 set_sol_packet_sequence_number(intf, v2_payload); 2468 2469 /* Just send the required data */ 2470 memmove(v2_payload->payload.sol_packet.data, 2471 v2_payload->payload.sol_packet.data + 2472 rs->payload.sol_packet.accepted_character_count, 2473 chars_to_resend); 2474 2475 v2_payload->payload.sol_packet.character_count = chars_to_resend; 2476 2477 v2_payload->payload_length = v2_payload->payload.sol_packet.character_count; 2478 2479 rs = ipmi_lanplus_send_payload(intf, v2_payload); 2480 2481 chars_to_resend = is_sol_partial_ack(intf, v2_payload, rs); 2482 } 2483 2484 return rs; 2485 } 2486 2487 2488 2489 /* 2490 * check_sol_packet_for_new_data 2491 * 2492 * Determine whether the SOL packet has already been seen 2493 * and whether the packet has new data for us. 2494 * 2495 * This function has the side effect of removing an previously 2496 * seen data, and moving new data to the front. 2497 * 2498 * It also "Remembers" the data so we don't get repeats. 2499 * 2500 * returns the number of new bytes in the SOL packet 2501 */ 2502 static int 2503 check_sol_packet_for_new_data( 2504 struct ipmi_intf * intf, 2505 struct ipmi_rs *rsp) 2506 { 2507 static uint8_t last_received_sequence_number = 0; 2508 static uint8_t last_received_byte_count = 0; 2509 int new_data_size = 0; 2510 2511 2512 if (rsp && 2513 (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && 2514 (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)) 2515 { 2516 /* Store the data length before we mod it */ 2517 uint8_t unaltered_data_len = rsp->data_len; 2518 2519 if (rsp->payload.sol_packet.packet_sequence_number == 2520 last_received_sequence_number) 2521 { 2522 2523 /* 2524 * This is the same as the last packet, but may include 2525 * extra data 2526 */ 2527 new_data_size = rsp->data_len - last_received_byte_count; 2528 2529 if (new_data_size > 0) 2530 { 2531 /* We have more data to process */ 2532 memmove(rsp->data, 2533 rsp->data + 2534 rsp->data_len - new_data_size, 2535 new_data_size); 2536 } 2537 2538 rsp->data_len = new_data_size; 2539 } 2540 2541 2542 /* 2543 *Rember the data for next round 2544 */ 2545 if (rsp->payload.sol_packet.packet_sequence_number) 2546 { 2547 last_received_sequence_number = 2548 rsp->payload.sol_packet.packet_sequence_number; 2549 2550 last_received_byte_count = unaltered_data_len; 2551 } 2552 } 2553 2554 2555 return new_data_size; 2556 } 2557 2558 2559 2560 /* 2561 * ack_sol_packet 2562 * 2563 * Provided the specified packet looks reasonable, ACK it. 2564 */ 2565 static void 2566 ack_sol_packet( 2567 struct ipmi_intf * intf, 2568 struct ipmi_rs * rsp) 2569 { 2570 if (rsp && 2571 (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && 2572 (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && 2573 (rsp->payload.sol_packet.packet_sequence_number)) 2574 { 2575 struct ipmi_v2_payload ack; 2576 2577 bzero(&ack, sizeof(struct ipmi_v2_payload)); 2578 2579 ack.payload_type = IPMI_PAYLOAD_TYPE_SOL; 2580 2581 /* 2582 * Payload length is just the length of the character 2583 * data here. 2584 */ 2585 ack.payload_length = 0; 2586 2587 /* ACK packets have sequence numbers of 0 */ 2588 ack.payload.sol_packet.packet_sequence_number = 0; 2589 2590 ack.payload.sol_packet.acked_packet_number = 2591 rsp->payload.sol_packet.packet_sequence_number; 2592 2593 ack.payload.sol_packet.accepted_character_count = rsp->data_len; 2594 2595 ipmi_lanplus_send_payload(intf, &ack); 2596 } 2597 } 2598 2599 2600 2601 /* 2602 * ipmi_lanplus_recv_sol 2603 * 2604 * Receive a SOL packet and send an ACK in response. 2605 * 2606 */ 2607 struct ipmi_rs * 2608 ipmi_lanplus_recv_sol(struct ipmi_intf * intf) 2609 { 2610 struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf); 2611 2612 if (rsp && rsp->session.authtype != 0) 2613 { 2614 ack_sol_packet(intf, rsp); 2615 2616 /* 2617 * Remembers the data sent, and alters the data to just 2618 * include the new stuff. 2619 */ 2620 check_sol_packet_for_new_data(intf, rsp); 2621 } 2622 return rsp; 2623 } 2624 2625 2626 2627 /** 2628 * ipmi_lanplus_send_ipmi_cmd 2629 * 2630 * Build a payload request and dispatch it. 2631 */ 2632 struct ipmi_rs * 2633 ipmi_lanplus_send_ipmi_cmd( 2634 struct ipmi_intf * intf, 2635 struct ipmi_rq * req) 2636 { 2637 struct ipmi_v2_payload v2_payload; 2638 2639 v2_payload.payload_type = IPMI_PAYLOAD_TYPE_IPMI; 2640 v2_payload.payload.ipmi_request.request = req; 2641 2642 return ipmi_lanplus_send_payload(intf, &v2_payload); 2643 } 2644 2645 2646 /* 2647 * ipmi_get_auth_capabilities_cmd 2648 * 2649 * This command may have to be sent twice. We first ask for the 2650 * authentication capabilities with the "request IPMI v2 data bit" 2651 * set. If this fails, we send the same command without that bit 2652 * set. 2653 * 2654 * param intf is the initialized (but possibly) pre-session interface 2655 * on which we will send the command 2656 * param auth_cap [out] will be initialized to hold the Get Channel 2657 * Authentication Capabilities return data on success. Its 2658 * contents will be undefined on error. 2659 * 2660 * returns 0 on success 2661 * non-zero if we were unable to contact the BMC, or we cannot 2662 * get a successful response 2663 * 2664 */ 2665 static int 2666 ipmi_get_auth_capabilities_cmd( 2667 struct ipmi_intf * intf, 2668 struct get_channel_auth_cap_rsp * auth_cap) 2669 { 2670 struct ipmi_rs * rsp; 2671 struct ipmi_rq req; 2672 uint8_t msg_data[2]; 2673 uint8_t backupBridgePossible; 2674 2675 backupBridgePossible = bridgePossible; 2676 2677 bridgePossible = 0; 2678 2679 msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well 2680 msg_data[1] = intf->session->privlvl; 2681 2682 memset(&req, 0, sizeof(req)); 2683 req.msg.netfn = IPMI_NETFN_APP; // 0x06 2684 req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; // 0x38 2685 req.msg.data = msg_data; 2686 req.msg.data_len = 2; 2687 2688 rsp = intf->sendrecv(intf, &req); 2689 2690 if (rsp == NULL || rsp->ccode > 0) { 2691 /* 2692 * It's very possible that this failed because we asked for IPMI 2693 * v2 data. Ask again, without requesting IPMI v2 data. 2694 */ 2695 msg_data[0] &= 0x7F; 2696 2697 rsp = intf->sendrecv(intf, &req); 2698 2699 if (rsp == NULL) { 2700 lprintf(LOG_INFO, "Get Auth Capabilities error"); 2701 return 1; 2702 } 2703 if (rsp->ccode > 0) { 2704 lprintf(LOG_INFO, "Get Auth Capabilities error: %s", 2705 val2str(rsp->ccode, completion_code_vals)); 2706 return 1; 2707 } 2708 } 2709 2710 2711 memcpy(auth_cap, 2712 rsp->data, 2713 sizeof(struct get_channel_auth_cap_rsp)); 2714 2715 bridgePossible = backupBridgePossible; 2716 2717 return 0; 2718 } 2719 2720 2721 2722 static int 2723 ipmi_close_session_cmd(struct ipmi_intf * intf) 2724 { 2725 struct ipmi_rs * rsp; 2726 struct ipmi_rq req; 2727 uint8_t msg_data[4]; 2728 uint32_t bmc_session_lsbf; 2729 uint8_t backupBridgePossible; 2730 2731 if (intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE) 2732 return -1; 2733 2734 backupBridgePossible = bridgePossible; 2735 2736 intf->target_addr = IPMI_BMC_SLAVE_ADDR; 2737 bridgePossible = 0; 2738 2739 bmc_session_lsbf = intf->session->v2_data.bmc_id; 2740 #if WORDS_BIGENDIAN 2741 bmc_session_lsbf = BSWAP_32(bmc_session_lsbf); 2742 #endif 2743 2744 memcpy(&msg_data, &bmc_session_lsbf, 4); 2745 2746 memset(&req, 0, sizeof(req)); 2747 req.msg.netfn = IPMI_NETFN_APP; 2748 req.msg.cmd = 0x3c; 2749 req.msg.data = msg_data; 2750 req.msg.data_len = 4; 2751 2752 rsp = intf->sendrecv(intf, &req); 2753 if (rsp == NULL) { 2754 /* Looks like the session was closed */ 2755 lprintf(LOG_ERR, "Close Session command failed"); 2756 return -1; 2757 } 2758 if (verbose > 2) 2759 printbuf(rsp->data, rsp->data_len, "close_session"); 2760 2761 if (rsp->ccode == 0x87) { 2762 lprintf(LOG_ERR, "Failed to Close Session: invalid " 2763 "session ID %08lx", 2764 (long)intf->session->v2_data.bmc_id); 2765 return -1; 2766 } 2767 if (rsp->ccode > 0) { 2768 lprintf(LOG_ERR, "Close Session command failed: %s", 2769 val2str(rsp->ccode, completion_code_vals)); 2770 return -1; 2771 } 2772 2773 lprintf(LOG_DEBUG, "Closed Session %08lx\n", 2774 (long)intf->session->v2_data.bmc_id); 2775 2776 bridgePossible = backupBridgePossible; 2777 2778 return 0; 2779 } 2780 2781 2782 2783 /* 2784 * ipmi_lanplus_open_session 2785 * 2786 * Build and send the open session command. See section 13.17 of the IPMI 2787 * v2 specification for details. 2788 */ 2789 static int 2790 ipmi_lanplus_open_session(struct ipmi_intf * intf) 2791 { 2792 struct ipmi_v2_payload v2_payload; 2793 struct ipmi_session * session = intf->session; 2794 uint8_t * msg; 2795 struct ipmi_rs * rsp; 2796 /* 0 = success, 1 = error, 2 = timeout */ 2797 int rc = 0; 2798 2799 2800 /* 2801 * Build an Open Session Request Payload 2802 */ 2803 msg = (uint8_t*)malloc(IPMI_OPEN_SESSION_REQUEST_SIZE); 2804 if (msg == NULL) { 2805 lprintf(LOG_ERR, "ipmitool: malloc failure"); 2806 return 1; 2807 } 2808 2809 memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE); 2810 2811 msg[0] = 0; /* Message tag */ 2812 if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN) 2813 msg[1] = session->privlvl; 2814 else 2815 msg[1] = 0; /* Give us highest privlg level based on supported algorithms */ 2816 msg[2] = 0; /* reserved */ 2817 msg[3] = 0; /* reserved */ 2818 2819 /* Choose our session ID for easy recognition in the packet dump */ 2820 session->v2_data.console_id = 0xA0A2A3A4; 2821 msg[4] = session->v2_data.console_id & 0xff; 2822 msg[5] = (session->v2_data.console_id >> 8) & 0xff; 2823 msg[6] = (session->v2_data.console_id >> 16) & 0xff; 2824 msg[7] = (session->v2_data.console_id >> 24) & 0xff; 2825 2826 2827 if (lanplus_get_requested_ciphers(session->cipher_suite_id, 2828 &(session->v2_data.requested_auth_alg), 2829 &(session->v2_data.requested_integrity_alg), 2830 &(session->v2_data.requested_crypt_alg))) 2831 { 2832 lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n", 2833 session->cipher_suite_id); 2834 free(msg); 2835 msg = NULL; 2836 return 1; 2837 } 2838 2839 2840 /* 2841 * Authentication payload 2842 */ 2843 msg[8] = 0; /* specifies authentication payload */ 2844 msg[9] = 0; /* reserved */ 2845 msg[10] = 0; /* reserved */ 2846 msg[11] = 8; /* payload length */ 2847 msg[12] = session->v2_data.requested_auth_alg; 2848 msg[13] = 0; /* reserved */ 2849 msg[14] = 0; /* reserved */ 2850 msg[15] = 0; /* reserved */ 2851 2852 /* 2853 * Integrity payload 2854 */ 2855 msg[16] = 1; /* specifies integrity payload */ 2856 msg[17] = 0; /* reserved */ 2857 msg[18] = 0; /* reserved */ 2858 msg[19] = 8; /* payload length */ 2859 msg[20] = session->v2_data.requested_integrity_alg; 2860 msg[21] = 0; /* reserved */ 2861 msg[22] = 0; /* reserved */ 2862 msg[23] = 0; /* reserved */ 2863 2864 /* 2865 * Confidentiality/Encryption payload 2866 */ 2867 msg[24] = 2; /* specifies confidentiality payload */ 2868 msg[25] = 0; /* reserved */ 2869 msg[26] = 0; /* reserved */ 2870 msg[27] = 8; /* payload length */ 2871 msg[28] = session->v2_data.requested_crypt_alg; 2872 msg[29] = 0; /* reserved */ 2873 msg[30] = 0; /* reserved */ 2874 msg[31] = 0; /* reserved */ 2875 2876 2877 v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST; 2878 v2_payload.payload_length = IPMI_OPEN_SESSION_REQUEST_SIZE; 2879 v2_payload.payload.open_session_request.request = msg; 2880 2881 rsp = ipmi_lanplus_send_payload(intf, &v2_payload); 2882 2883 free(msg); 2884 msg = NULL; 2885 if (rsp == NULL ) { 2886 lprintf(LOG_DEBUG, "Timeout in open session response message."); 2887 return 2; 2888 } 2889 if (verbose) 2890 lanplus_dump_open_session_response(rsp); 2891 2892 if (rsp->payload.open_session_response.rakp_return_code != 2893 IPMI_RAKP_STATUS_NO_ERRORS) 2894 { 2895 lprintf(LOG_WARNING, "Error in open session response message : %s\n", 2896 val2str(rsp->payload.open_session_response.rakp_return_code, 2897 ipmi_rakp_return_codes)); 2898 return 1; 2899 } 2900 else 2901 { 2902 if (rsp->payload.open_session_response.console_id != 2903 session->v2_data.console_id) { 2904 lprintf(LOG_WARNING, "Warning: Console session ID is not " 2905 "what we requested"); 2906 } 2907 2908 session->v2_data.max_priv_level = 2909 rsp->payload.open_session_response.max_priv_level; 2910 session->v2_data.bmc_id = 2911 rsp->payload.open_session_response.bmc_id; 2912 session->v2_data.auth_alg = 2913 rsp->payload.open_session_response.auth_alg; 2914 session->v2_data.integrity_alg = 2915 rsp->payload.open_session_response.integrity_alg; 2916 session->v2_data.crypt_alg = 2917 rsp->payload.open_session_response.crypt_alg; 2918 session->v2_data.session_state = 2919 LANPLUS_STATE_OPEN_SESSION_RECEIEVED; 2920 2921 2922 /* 2923 * Verify that we have agreed on a cipher suite 2924 */ 2925 if (rsp->payload.open_session_response.auth_alg != 2926 session->v2_data.requested_auth_alg) 2927 { 2928 lprintf(LOG_WARNING, "Authentication algorithm 0x%02x is " 2929 "not what we requested 0x%02x\n", 2930 rsp->payload.open_session_response.auth_alg, 2931 session->v2_data.requested_auth_alg); 2932 rc = 1; 2933 } 2934 else if (rsp->payload.open_session_response.integrity_alg != 2935 session->v2_data.requested_integrity_alg) 2936 { 2937 lprintf(LOG_WARNING, "Integrity algorithm 0x%02x is " 2938 "not what we requested 0x%02x\n", 2939 rsp->payload.open_session_response.integrity_alg, 2940 session->v2_data.requested_integrity_alg); 2941 rc = 1; 2942 } 2943 else if (rsp->payload.open_session_response.crypt_alg != 2944 session->v2_data.requested_crypt_alg) 2945 { 2946 lprintf(LOG_WARNING, "Encryption algorithm 0x%02x is " 2947 "not what we requested 0x%02x\n", 2948 rsp->payload.open_session_response.crypt_alg, 2949 session->v2_data.requested_crypt_alg); 2950 rc = 1; 2951 } 2952 2953 } 2954 2955 return rc; 2956 } 2957 2958 2959 2960 /* 2961 * ipmi_lanplus_rakp1 2962 * 2963 * Build and send the RAKP 1 message as part of the IPMI v2 / RMCP+ session 2964 * negotiation protocol. We also read and validate the RAKP 2 message received 2965 * from the BMC, here. See section 13.20 of the IPMI v2 specification for 2966 * details. 2967 * 2968 * returns 0 on success 2969 * 1 on failure 2970 * 2971 * Note that failure is only indicated if we have an internal error of 2972 * some kind. If we actually get a RAKP 2 message in response to our 2973 * RAKP 1 message, any errors will be stored in 2974 * session->v2_data.rakp2_return_code and sent to the BMC in the RAKP 2975 * 3 message. 2976 */ 2977 static int 2978 ipmi_lanplus_rakp1(struct ipmi_intf * intf) 2979 { 2980 struct ipmi_v2_payload v2_payload; 2981 struct ipmi_session * session = intf->session; 2982 uint8_t * msg; 2983 struct ipmi_rs * rsp; 2984 int rc = 0; /* 0 = success, 1 = error, 2 = timeout */ 2985 2986 /* 2987 * Build a RAKP 1 message 2988 */ 2989 msg = (uint8_t*)malloc(IPMI_RAKP1_MESSAGE_SIZE); 2990 if (msg == NULL) { 2991 lprintf(LOG_ERR, "ipmitool: malloc failure"); 2992 return 1; 2993 } 2994 memset(msg, 0, IPMI_RAKP1_MESSAGE_SIZE); 2995 2996 2997 msg[0] = 0; /* Message tag */ 2998 2999 msg[1] = 0; /* reserved */ 3000 msg[2] = 0; /* reserved */ 3001 msg[3] = 0; /* reserved */ 3002 3003 /* BMC session ID */ 3004 msg[4] = session->v2_data.bmc_id & 0xff; 3005 msg[5] = (session->v2_data.bmc_id >> 8) & 0xff; 3006 msg[6] = (session->v2_data.bmc_id >> 16) & 0xff; 3007 msg[7] = (session->v2_data.bmc_id >> 24) & 0xff; 3008 3009 3010 /* We need a 16 byte random number */ 3011 if (lanplus_rand(session->v2_data.console_rand, 16)) 3012 { 3013 // ERROR; 3014 lprintf(LOG_ERR, "ERROR generating random number " 3015 "in ipmi_lanplus_rakp1"); 3016 free(msg); 3017 msg = NULL; 3018 return 1; 3019 } 3020 memcpy(msg + 8, session->v2_data.console_rand, 16); 3021 #if WORDS_BIGENDIAN 3022 lanplus_swap(msg + 8, 16); 3023 #endif 3024 3025 if (verbose > 1) 3026 printbuf(session->v2_data.console_rand, 16, 3027 ">> Console generated random number"); 3028 3029 3030 /* 3031 * Requested maximum privilege level. 3032 */ 3033 msg[24] = session->privlvl | session->v2_data.lookupbit; 3034 session->v2_data.requested_role = msg[24]; 3035 msg[25] = 0; /* reserved */ 3036 msg[26] = 0; /* reserved */ 3037 3038 3039 /* Username specification */ 3040 msg[27] = strlen((const char *)session->username); 3041 if (msg[27] > IPMI_MAX_USER_NAME_LENGTH) 3042 { 3043 lprintf(LOG_ERR, "ERROR: user name too long. " 3044 "(Exceeds %d characters)", 3045 IPMI_MAX_USER_NAME_LENGTH); 3046 free(msg); 3047 msg = NULL; 3048 return 1; 3049 } 3050 memcpy(msg + 28, session->username, msg[27]); 3051 3052 v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; 3053 v2_payload.payload_length = 3054 IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]); 3055 v2_payload.payload.rakp_1_message.message = msg; 3056 3057 rsp = ipmi_lanplus_send_payload(intf, &v2_payload); 3058 3059 free(msg); 3060 msg = NULL; 3061 3062 if (rsp == NULL) 3063 { 3064 lprintf(LOG_WARNING, "> Error: no response from RAKP 1 message"); 3065 return 2; 3066 } 3067 3068 session->v2_data.session_state = LANPLUS_STATE_RAKP_2_RECEIVED; 3069 3070 if (verbose) 3071 lanplus_dump_rakp2_message(rsp, session->v2_data.auth_alg); 3072 3073 3074 3075 if (rsp->payload.rakp2_message.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS) 3076 { 3077 lprintf(LOG_INFO, "RAKP 2 message indicates an error : %s", 3078 val2str(rsp->payload.rakp2_message.rakp_return_code, 3079 ipmi_rakp_return_codes)); 3080 rc = 1; 3081 } 3082 3083 else 3084 { 3085 memcpy(session->v2_data.bmc_rand, rsp->payload.rakp2_message.bmc_rand, 16); 3086 memcpy(session->v2_data.bmc_guid, rsp->payload.rakp2_message.bmc_guid, 16); 3087 3088 if (verbose > 2) 3089 printbuf(session->v2_data.bmc_rand, 16, "bmc_rand"); 3090 3091 /* 3092 * It is at this point that we have to decode the random number and determine 3093 * whether the BMC has authenticated. 3094 */ 3095 if (! lanplus_rakp2_hmac_matches(session, 3096 rsp->payload.rakp2_message.key_exchange_auth_code, 3097 intf)) 3098 { 3099 /* Error */ 3100 lprintf(LOG_INFO, "> RAKP 2 HMAC is invalid"); 3101 session->v2_data.rakp2_return_code = IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE; 3102 rc = 1; 3103 } 3104 else 3105 { 3106 /* Success */ 3107 session->v2_data.rakp2_return_code = IPMI_RAKP_STATUS_NO_ERRORS; 3108 } 3109 } 3110 3111 return rc; 3112 } 3113 3114 3115 3116 /* 3117 * ipmi_lanplus_rakp3 3118 * 3119 * Build and send the RAKP 3 message as part of the IPMI v2 / RMCP+ session 3120 * negotiation protocol. We also read and validate the RAKP 4 message received 3121 * from the BMC, here. See section 13.20 of the IPMI v2 specification for 3122 * details. 3123 * 3124 * If the RAKP 2 return code is not IPMI_RAKP_STATUS_NO_ERRORS, we will 3125 * exit with an error code immediately after sendint the RAKP 3 message. 3126 * 3127 * param intf is the intf that holds all the state we are concerned with 3128 * 3129 * returns 0 on success 3130 * 1 on failure 3131 */ 3132 static int 3133 ipmi_lanplus_rakp3(struct ipmi_intf * intf) 3134 { 3135 struct ipmi_v2_payload v2_payload; 3136 struct ipmi_session * session = intf->session; 3137 uint8_t * msg; 3138 struct ipmi_rs * rsp; 3139 3140 assert(session->v2_data.session_state == LANPLUS_STATE_RAKP_2_RECEIVED); 3141 3142 /* 3143 * Build a RAKP 3 message 3144 */ 3145 msg = (uint8_t*)malloc(IPMI_RAKP3_MESSAGE_MAX_SIZE); 3146 if (msg == NULL) { 3147 lprintf(LOG_ERR, "ipmitool: malloc failure"); 3148 return 1; 3149 } 3150 memset(msg, 0, IPMI_RAKP3_MESSAGE_MAX_SIZE); 3151 3152 3153 msg[0] = 0; /* Message tag */ 3154 msg[1] = session->v2_data.rakp2_return_code; 3155 3156 msg[2] = 0; /* reserved */ 3157 msg[3] = 0; /* reserved */ 3158 3159 /* BMC session ID */ 3160 msg[4] = session->v2_data.bmc_id & 0xff; 3161 msg[5] = (session->v2_data.bmc_id >> 8) & 0xff; 3162 msg[6] = (session->v2_data.bmc_id >> 16) & 0xff; 3163 msg[7] = (session->v2_data.bmc_id >> 24) & 0xff; 3164 3165 v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_3; 3166 v2_payload.payload_length = 8; 3167 v2_payload.payload.rakp_3_message.message = msg; 3168 3169 /* 3170 * If the rakp2 return code indicates and error, we don't have to 3171 * generate an authcode or session integrity key. In that case, we 3172 * are simply sending a RAKP 3 message to indicate to the BMC that the 3173 * RAKP 2 message caused an error. 3174 */ 3175 if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS) 3176 { 3177 uint32_t auth_length; 3178 3179 if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf)) 3180 { 3181 /* Error */ 3182 lprintf(LOG_INFO, "> Error generating RAKP 3 authcode"); 3183 free(msg); 3184 msg = NULL; 3185 return 1; 3186 } 3187 else 3188 { 3189 /* Success */ 3190 v2_payload.payload_length += auth_length; 3191 } 3192 3193 /* Generate our Session Integrity Key, K1, and K2 */ 3194 if (lanplus_generate_sik(session, intf)) 3195 { 3196 /* Error */ 3197 lprintf(LOG_INFO, "> Error generating session integrity key"); 3198 free(msg); 3199 msg = NULL; 3200 return 1; 3201 } 3202 else if (lanplus_generate_k1(session)) 3203 { 3204 /* Error */ 3205 lprintf(LOG_INFO, "> Error generating K1 key"); 3206 free(msg); 3207 msg = NULL; 3208 return 1; 3209 } 3210 else if (lanplus_generate_k2(session)) 3211 { 3212 /* Error */ 3213 lprintf(LOG_INFO, "> Error generating K1 key"); 3214 free(msg); 3215 msg = NULL; 3216 return 1; 3217 } 3218 } 3219 3220 3221 rsp = ipmi_lanplus_send_payload(intf, &v2_payload); 3222 3223 free(msg); 3224 msg = NULL; 3225 3226 if (session->v2_data.rakp2_return_code != IPMI_RAKP_STATUS_NO_ERRORS) 3227 { 3228 /* 3229 * If the previous RAKP 2 message received was deemed erroneous, 3230 * we have nothing else to do here. We only sent the RAKP 3 message 3231 * to indicate to the BMC that the RAKP 2 message failed. 3232 */ 3233 return 1; 3234 } 3235 else if (rsp == NULL) 3236 { 3237 lprintf(LOG_WARNING, "> Error: no response from RAKP 3 message"); 3238 return 2; 3239 } 3240 3241 3242 /* 3243 * We have a RAKP 4 message to chew on. 3244 */ 3245 if (verbose) 3246 lanplus_dump_rakp4_message(rsp, session->v2_data.auth_alg); 3247 3248 3249 if (rsp->payload.open_session_response.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS) 3250 { 3251 lprintf(LOG_INFO, "RAKP 4 message indicates an error : %s", 3252 val2str(rsp->payload.rakp4_message.rakp_return_code, 3253 ipmi_rakp_return_codes)); 3254 return 1; 3255 } 3256 3257 else 3258 { 3259 /* Validate the authcode */ 3260 if (lanplus_rakp4_hmac_matches(session, 3261 rsp->payload.rakp4_message.integrity_check_value, 3262 intf)) 3263 { 3264 /* Success */ 3265 session->v2_data.session_state = LANPLUS_STATE_ACTIVE; 3266 } 3267 else 3268 { 3269 /* Error */ 3270 lprintf(LOG_INFO, "> RAKP 4 message has invalid integrity check value"); 3271 return 1; 3272 } 3273 } 3274 3275 intf->abort = 0; 3276 return 0; 3277 } 3278 3279 3280 3281 /** 3282 * ipmi_lan_close 3283 */ 3284 void 3285 ipmi_lanplus_close(struct ipmi_intf * intf) 3286 { 3287 if (!intf->abort) 3288 ipmi_close_session_cmd(intf); 3289 3290 if (intf->fd >= 0) 3291 close(intf->fd); 3292 3293 ipmi_req_clear_entries(); 3294 3295 if (intf->session) { 3296 free(intf->session); 3297 intf->session = NULL; 3298 } 3299 3300 intf->session = NULL; 3301 intf->opened = 0; 3302 intf->manufacturer_id = IPMI_OEM_UNKNOWN; 3303 intf = NULL; 3304 } 3305 3306 3307 3308 static int 3309 ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf) 3310 { 3311 struct ipmi_rs * rsp; 3312 struct ipmi_rq req; 3313 uint8_t backupBridgePossible; 3314 uint8_t privlvl = intf->session->privlvl; 3315 3316 if (privlvl <= IPMI_SESSION_PRIV_USER) 3317 return 0; /* no need to set higher */ 3318 3319 backupBridgePossible = bridgePossible; 3320 3321 bridgePossible = 0; 3322 3323 memset(&req, 0, sizeof(req)); 3324 req.msg.netfn = IPMI_NETFN_APP; 3325 req.msg.cmd = 0x3b; 3326 req.msg.data = &privlvl; 3327 req.msg.data_len = 1; 3328 3329 rsp = intf->sendrecv(intf, &req); 3330 if (rsp == NULL) { 3331 lprintf(LOG_ERR, "Set Session Privilege Level to %s failed", 3332 val2str(privlvl, ipmi_privlvl_vals)); 3333 bridgePossible = backupBridgePossible; 3334 return -1; 3335 } 3336 if (verbose > 2) 3337 printbuf(rsp->data, rsp->data_len, "set_session_privlvl"); 3338 3339 if (rsp->ccode > 0) { 3340 lprintf(LOG_ERR, "Set Session Privilege Level to %s failed: %s", 3341 val2str(privlvl, ipmi_privlvl_vals), 3342 val2str(rsp->ccode, completion_code_vals)); 3343 bridgePossible = backupBridgePossible; 3344 return -1; 3345 } 3346 3347 lprintf(LOG_DEBUG, "Set Session Privilege Level to %s\n", 3348 val2str(rsp->data[0], ipmi_privlvl_vals)); 3349 3350 bridgePossible = backupBridgePossible; 3351 3352 return 0; 3353 } 3354 3355 /** 3356 * ipmi_lanplus_open 3357 */ 3358 int 3359 ipmi_lanplus_open(struct ipmi_intf * intf) 3360 { 3361 int rc; 3362 int retry; 3363 struct get_channel_auth_cap_rsp auth_cap; 3364 struct ipmi_session *session; 3365 3366 if (!intf || !intf->session) 3367 return -1; 3368 session = intf->session; 3369 3370 3371 if (!session->port) 3372 session->port = IPMI_LANPLUS_PORT; 3373 if (!session->privlvl) 3374 session->privlvl = IPMI_SESSION_PRIV_ADMIN; 3375 if (!session->timeout) 3376 session->timeout = IPMI_LAN_TIMEOUT; 3377 if (!session->retry) 3378 session->retry = IPMI_LAN_RETRY; 3379 3380 if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) { 3381 lprintf(LOG_ERR, "No hostname specified!"); 3382 return -1; 3383 } 3384 3385 intf->abort = 1; 3386 3387 3388 /* Setup our lanplus session state */ 3389 session->v2_data.auth_alg = IPMI_AUTH_RAKP_NONE; 3390 session->v2_data.crypt_alg = IPMI_CRYPT_NONE; 3391 session->v2_data.console_id = 0x00; 3392 session->v2_data.bmc_id = 0x00; 3393 session->sol_data.sequence_number = 1; 3394 //session->sol_data.last_received_sequence_number = 0; 3395 //session->sol_data.last_received_byte_count = 0; 3396 memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); 3397 3398 /* Kg is set in ipmi_intf */ 3399 //memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE); 3400 3401 if (ipmi_intf_socket_connect (intf) == -1) { 3402 lprintf(LOG_ERR, "Could not open socket!"); 3403 return -1; 3404 } 3405 3406 if (intf->fd < 0) { 3407 lperror(LOG_ERR, "Connect to %s failed", 3408 session->hostname); 3409 intf->close(intf); 3410 return -1; 3411 } 3412 3413 intf->opened = 1; 3414 3415 /* 3416 * 3417 * Make sure the BMC supports IPMI v2 / RMCP+ 3418 */ 3419 if (!ipmi_oem_active(intf, "i82571spt") && 3420 ipmi_get_auth_capabilities_cmd(intf, &auth_cap)) { 3421 lprintf(LOG_INFO, "Error issuing Get Channel " 3422 "Authentication Capabilies request"); 3423 goto fail; 3424 } 3425 3426 if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) 3427 { 3428 lprintf(LOG_INFO, "This BMC does not support IPMI v2 / RMCP+"); 3429 goto fail; 3430 } 3431 3432 /* 3433 * If the open/rakp1/rakp3 sequence encounters a timeout, the whole sequence 3434 * needs to restart. The individual messages are not individually retryable, 3435 * as the session state is advancing. 3436 */ 3437 for (retry = 0; retry < IPMI_LAN_RETRY; retry++) { 3438 session->v2_data.session_state = LANPLUS_STATE_PRESESSION; 3439 /* 3440 * Open session 3441 */ 3442 if ((rc = ipmi_lanplus_open_session(intf)) == 1) { 3443 intf->close(intf); 3444 goto fail; 3445 } 3446 if (rc == 2) { 3447 lprintf(LOG_DEBUG, "Retry lanplus open session, %d", retry); 3448 continue; 3449 } 3450 /* 3451 * RAKP 1 3452 */ 3453 if ((rc = ipmi_lanplus_rakp1(intf)) == 1) { 3454 intf->close(intf); 3455 goto fail; 3456 } 3457 if (rc == 2) { 3458 lprintf(LOG_DEBUG, "Retry lanplus rakp1, %d", retry); 3459 continue; 3460 } 3461 /* 3462 * RAKP 3 3463 */ 3464 if ((rc = ipmi_lanplus_rakp3(intf)) == 1) { 3465 intf->close(intf); 3466 goto fail; 3467 } 3468 if (rc == 0) break; 3469 lprintf(LOG_DEBUG,"Retry lanplus rakp3, %d", retry); 3470 } 3471 3472 lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n"); 3473 3474 if (!ipmi_oem_active(intf, "i82571spt")) { 3475 rc = ipmi_set_session_privlvl_cmd(intf); 3476 if (rc < 0) { 3477 intf->close(intf); 3478 goto fail; 3479 } 3480 } 3481 intf->manufacturer_id = ipmi_get_oem(intf); 3482 bridgePossible = 1; 3483 3484 /* automatically detect interface request and response sizes */ 3485 hpm2_detect_max_payload_size(intf); 3486 3487 return intf->fd; 3488 3489 fail: 3490 lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session"); 3491 intf->opened = 0; 3492 return -1; 3493 } 3494 3495 3496 3497 void test_crypt1(void) 3498 { 3499 uint8_t key[] = 3500 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 3501 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14}; 3502 3503 uint16_t bytes_encrypted; 3504 uint16_t bytes_decrypted; 3505 uint8_t decrypt_buffer[1000]; 3506 uint8_t encrypt_buffer[1000]; 3507 3508 uint8_t data[] = 3509 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 3510 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 3511 0x11, 0x12}; 3512 3513 printbuf(data, sizeof(data), "original data"); 3514 3515 if (lanplus_encrypt_payload(IPMI_CRYPT_AES_CBC_128, 3516 key, 3517 data, 3518 sizeof(data), 3519 encrypt_buffer, 3520 &bytes_encrypted)) 3521 { 3522 lprintf(LOG_ERR, "Encrypt test failed"); 3523 assert(0); 3524 } 3525 printbuf(encrypt_buffer, bytes_encrypted, "encrypted payload"); 3526 3527 3528 if (lanplus_decrypt_payload(IPMI_CRYPT_AES_CBC_128, 3529 key, 3530 encrypt_buffer, 3531 bytes_encrypted, 3532 decrypt_buffer, 3533 &bytes_decrypted)) 3534 { 3535 lprintf(LOG_ERR, "Decrypt test failed\n"); 3536 assert(0); 3537 } 3538 printbuf(decrypt_buffer, bytes_decrypted, "decrypted payload"); 3539 3540 lprintf(LOG_DEBUG, "\nDone testing the encrypt/decyrpt methods!\n"); 3541 exit(0); 3542 } 3543 3544 3545 3546 void test_crypt2(void) 3547 { 3548 uint8_t key[] = 3549 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 3550 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14}; 3551 uint8_t iv[] = 3552 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 3553 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14}; 3554 uint8_t data[8] = "12345678"; 3555 3556 uint8_t encrypt_buffer[1000]; 3557 uint8_t decrypt_buffer[1000]; 3558 uint32_t bytes_encrypted; 3559 uint32_t bytes_decrypted; 3560 3561 printbuf((const uint8_t *)data, strlen((const char *)data), "input data"); 3562 3563 lanplus_encrypt_aes_cbc_128(iv, 3564 key, 3565 data, 3566 strlen((const char *)data), 3567 encrypt_buffer, 3568 &bytes_encrypted); 3569 printbuf((const uint8_t *)encrypt_buffer, bytes_encrypted, "encrypt_buffer"); 3570 3571 lanplus_decrypt_aes_cbc_128(iv, 3572 key, 3573 encrypt_buffer, 3574 bytes_encrypted, 3575 decrypt_buffer, 3576 &bytes_decrypted); 3577 printbuf((const uint8_t *)decrypt_buffer, bytes_decrypted, "decrypt_buffer"); 3578 3579 lprintf(LOG_INFO, "\nDone testing the encrypt/decyrpt methods!\n"); 3580 exit(0); 3581 } 3582 3583 3584 /** 3585 * send a get device id command to keep session active 3586 */ 3587 static int 3588 ipmi_lanplus_keepalive(struct ipmi_intf * intf) 3589 { 3590 struct ipmi_rs * rsp; 3591 struct ipmi_rq req = { msg: { 3592 netfn: IPMI_NETFN_APP, 3593 cmd: 1, 3594 }}; 3595 3596 if (!intf->opened) 3597 return 0; 3598 3599 rsp = intf->sendrecv(intf, &req); 3600 while (rsp != NULL && is_sol_packet(rsp)) { 3601 /* rsp was SOL data instead of our answer */ 3602 /* since it didn't go through the sol recv, do sol recv stuff here */ 3603 ack_sol_packet(intf, rsp); 3604 check_sol_packet_for_new_data(intf, rsp); 3605 if (rsp->data_len) 3606 intf->session->sol_data.sol_input_handler(rsp); 3607 rsp = ipmi_lan_poll_recv(intf); 3608 if (rsp == NULL) /* the get device id answer never got back, but retry mechanism was bypassed by SOL data */ 3609 return 0; /* so get device id command never returned, the connection is still alive */ 3610 } 3611 3612 if (rsp == NULL) 3613 return -1; 3614 if (rsp->ccode > 0) 3615 return -1; 3616 3617 return 0; 3618 } 3619 3620 3621 /** 3622 * ipmi_lanplus_setup 3623 */ 3624 static int ipmi_lanplus_setup(struct ipmi_intf * intf) 3625 { 3626 //test_crypt1(); 3627 assert("ipmi_lanplus_setup"); 3628 3629 if (lanplus_seed_prng(16)) 3630 return -1; 3631 3632 intf->session = malloc(sizeof(struct ipmi_session)); 3633 if (intf->session == NULL) { 3634 lprintf(LOG_ERR, "ipmitool: malloc failure"); 3635 return -1; 3636 } 3637 memset(intf->session, 0, sizeof(struct ipmi_session)); 3638 3639 /* setup default LAN maximum request and response sizes */ 3640 intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE; 3641 intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE; 3642 3643 return 0; 3644 } 3645 3646 static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size) 3647 { 3648 if (intf->session->cipher_suite_id == 3) { 3649 /* 3650 * encrypted payload can only be multiple of 16 bytes 3651 */ 3652 size &= ~15; 3653 3654 /* 3655 * decrement payload size on confidentiality header size 3656 * plus minimal confidentiality trailer size 3657 */ 3658 size -= (16 + 1); 3659 } 3660 3661 intf->max_request_data_size = size; 3662 } 3663 3664 static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size) 3665 { 3666 if (intf->session->cipher_suite_id == 3) { 3667 /* 3668 * encrypted payload can only be multiple of 16 bytes 3669 */ 3670 size &= ~15; 3671 3672 /* 3673 * decrement payload size on confidentiality header size 3674 * plus minimal confidentiality trailer size 3675 */ 3676 size -= (16 + 1); 3677 } 3678 3679 intf->max_response_data_size = size; 3680 } 3681