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