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