diff options
Diffstat (limited to 'lib/ipmi_tsol.c')
-rw-r--r-- | lib/ipmi_tsol.c | 330 |
1 files changed, 164 insertions, 166 deletions
diff --git a/lib/ipmi_tsol.c b/lib/ipmi_tsol.c index 94ea284..b4e3cc1 100644 --- a/lib/ipmi_tsol.c +++ b/lib/ipmi_tsol.c @@ -76,78 +76,77 @@ static int _altterm = 0; extern int verbose; static int -ipmi_tsol_command(struct ipmi_intf * intf, char *recvip, int port, unsigned char cmd) +ipmi_tsol_command(struct ipmi_intf *intf, char *recvip, int port, + unsigned char cmd) { - struct ipmi_rs *rsp; - struct ipmi_rq req; - unsigned char data[6]; - unsigned ip1, ip2, ip3, ip4; - - if (sscanf(recvip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) { - lprintf(LOG_ERR, "Invalid IP address: %s", recvip); - return -1; - } - + struct ipmi_rs *rsp; + struct ipmi_rq req; + unsigned char data[6]; + unsigned ip1, ip2, ip3, ip4; + + if (sscanf(recvip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) { + lprintf(LOG_ERR, "Invalid IP address: %s", recvip); + return (-1); + } memset(&req, 0, sizeof(struct ipmi_rq)); - req.msg.netfn = IPMI_NETFN_TSOL; - req.msg.cmd = cmd; - req.msg.data_len = 6; - req.msg.data = data; + req.msg.netfn = IPMI_NETFN_TSOL; + req.msg.cmd = cmd; + req.msg.data_len = 6; + req.msg.data = data; memset(data, 0, sizeof(data)); - data[0] = ip1; - data[1] = ip2; - data[2] = ip3; - data[3] = ip4; - data[4] = (port & 0xff00) >> 8; - data[5] = (port & 0xff); - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + data[0] = ip1; + data[1] = ip2; + data[2] = ip3; + data[3] = ip4; + data[4] = (port & 0xff00) >> 8; + data[5] = (port & 0xff); + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { lprintf(LOG_ERR, "Unable to perform TSOL command"); - return -1; + return (-1); } if (rsp->ccode > 0) { lprintf(LOG_ERR, "Unable to perform TSOL command: %s", - val2str(rsp->ccode, completion_code_vals)); - return -1; - } - - return 0; + val2str(rsp->ccode, completion_code_vals)); + return (-1); + } + return 0; } static int -ipmi_tsol_start(struct ipmi_intf * intf, char *recvip, int port) +ipmi_tsol_start(struct ipmi_intf *intf, char *recvip, int port) { return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_START); } static int -ipmi_tsol_stop(struct ipmi_intf * intf, char *recvip, int port) +ipmi_tsol_stop(struct ipmi_intf *intf, char *recvip, int port) { - return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_STOP); + return ipmi_tsol_command(intf, recvip, port, IPMI_TSOL_CMD_STOP); } static int -ipmi_tsol_send_keystroke(struct ipmi_intf * intf, char *buff, int length) +ipmi_tsol_send_keystroke(struct ipmi_intf *intf, char *buff, int length) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - unsigned char data[16]; + struct ipmi_rs *rsp; + struct ipmi_rq req; + unsigned char data[16]; static unsigned char keyseq = 0; memset(&req, 0, sizeof(struct ipmi_rq)); - req.msg.netfn = IPMI_NETFN_TSOL; - req.msg.cmd = IPMI_TSOL_CMD_SENDKEY; - req.msg.data_len = length + 2; - req.msg.data = data; + req.msg.netfn = IPMI_NETFN_TSOL; + req.msg.cmd = IPMI_TSOL_CMD_SENDKEY; + req.msg.data_len = length + 2; + req.msg.data = data; memset(data, 0, sizeof(data)); - data[0] = length + 1; + data[0] = length + 1; memcpy(data + 1, buff, length); data[length + 1] = keyseq++; - rsp = intf->sendrecv(intf, &req); + rsp = intf->sendrecv(intf, &req); if (verbose) { if (rsp == NULL) { lprintf(LOG_ERR, "Unable to send keystroke"); @@ -155,61 +154,56 @@ ipmi_tsol_send_keystroke(struct ipmi_intf * intf, char *buff, int length) } if (rsp->ccode > 0) { lprintf(LOG_ERR, "Unable to send keystroke: %s", - val2str(rsp->ccode, completion_code_vals)); + val2str(rsp->ccode, completion_code_vals)); return -1; } } - - return length; + return length; } static int -tsol_keepalive(struct ipmi_intf * intf) +tsol_keepalive(struct ipmi_intf *intf) { - struct timeval end; - - gettimeofday(&end, 0); - - if (end.tv_sec - _start_keepalive.tv_sec <= 30) - return 0; - - intf->keepalive(intf); - + struct timeval end; + gettimeofday(&end, 0); + if (end.tv_sec - _start_keepalive.tv_sec <= 30) { + return 0; + } + intf->keepalive(intf); gettimeofday(&_start_keepalive, 0); - - return 0; + return 0; } static void print_escape_seq(struct ipmi_intf *intf) { lprintf(LOG_NOTICE, - " %c. - terminate connection\n" - " %c^Z - suspend ipmitool\n" - " %c^X - suspend ipmitool, but don't restore tty on restart\n" - " %c? - this message\n" - " %c%c - send the escape character by typing it twice\n" - " (Note that escapes are only recognized immediately after newline.)", - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char); +" %c. - terminate connection\n" +" %c^Z - suspend ipmitool\n" +" %c^X - suspend ipmitool, but don't restore tty on restart\n" +" %c? - this message\n" +" %c%c - send the escape character by typing it twice\n" +" (Note that escapes are only recognized immediately after newline.)", + intf->session->sol_escape_char, + intf->session->sol_escape_char, + intf->session->sol_escape_char, + intf->session->sol_escape_char, + intf->session->sol_escape_char, + intf->session->sol_escape_char); } static int leave_raw_mode(void) { - if (!_in_raw_mode) + if (!_in_raw_mode) { return -1; - else if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) + } else if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) { lperror(LOG_ERR, "tcsetattr(stdin)"); - else if (tcsetattr(fileno(stdout), TCSADRAIN, &_saved_tio) == -1) + } else if (tcsetattr(fileno(stdout), TCSADRAIN, &_saved_tio) == -1) { lperror(LOG_ERR, "tcsetattr(stdout)"); - else + } else { _in_raw_mode = 0; - + } return 0; } @@ -217,16 +211,14 @@ static int enter_raw_mode(void) { struct termios tio; - if (tcgetattr(fileno(stdout), &_saved_tio) < 0) { lperror(LOG_ERR, "tcgetattr failed"); return -1; } tio = _saved_tio; - if (_altterm) { - tio.c_iflag &= (ISTRIP | IGNBRK ); + tio.c_iflag &= (ISTRIP | IGNBRK); tio.c_cflag &= ~(CSIZE | PARENB | IXON | IXOFF | IXANY); tio.c_cflag |= (CS8 |CREAD) | (IXON|IXOFF|IXANY); tio.c_lflag &= 0; @@ -241,13 +233,13 @@ enter_raw_mode(void) tio.c_cc[VTIME] = 0; } - if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) + if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) { lperror(LOG_ERR, "tcsetattr(stdin)"); - else if (tcsetattr(fileno(stdout), TCSADRAIN, &tio) < 0) + } else if (tcsetattr(fileno(stdout), TCSADRAIN, &tio) < 0) { lperror(LOG_ERR, "tcsetattr(stdout)"); - else + } else { _in_raw_mode = 1; - + } return 0; } @@ -255,11 +247,10 @@ static void suspend_self(int restore_tty) { leave_raw_mode(); - kill(getpid(), SIGTSTP); - - if (restore_tty) + if (restore_tty) { enter_raw_mode(); + } } static int @@ -272,7 +263,7 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) for(i = 0; i < len ;) { if (!in_esc) { if (last_was_cr && - (in_buff[i] == intf->session->sol_escape_char)) { + (in_buff[i] == intf->session->sol_escape_char)) { in_esc = 1; memmove(in_buff, in_buff + 1, len - i - 1); len--; @@ -289,40 +280,35 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) switch (in_buff[i]) { case '.': printf("%c. [terminated ipmitool]\n", - intf->session->sol_escape_char); + intf->session->sol_escape_char); return -1; - case 'Z' - 64: printf("%c^Z [suspend ipmitool]\n", - intf->session->sol_escape_char); - suspend_self(1); /* Restore tty back to raw */ + intf->session->sol_escape_char); + /* Restore tty back to raw */ + suspend_self(1); break; - case 'X' - 64: printf("%c^X [suspend ipmitool]\n", - intf->session->sol_escape_char); - suspend_self(0); /* Don't restore to raw mode */ + intf->session->sol_escape_char); + /* Don't restore to raw mode */ + suspend_self(0); break; - case '?': printf("%c? [ipmitool help]\n", - intf->session->sol_escape_char); + intf->session->sol_escape_char); print_escape_seq(intf); break; } - memmove(in_buff, in_buff + 1, len - i - 1); + memmove(in_buff, (in_buff + 1), (len - i - 1)); len--; in_esc = 0; - continue; } - last_was_cr = (in_buff[i] == '\r' || in_buff[i] == '\n'); - i++; } - return len; } @@ -330,27 +316,25 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) static void do_terminal_cleanup(void) { - if (_saved_winsize.ws_row > 0 && _saved_winsize.ws_col > 0) + if (_saved_winsize.ws_row > 0 && _saved_winsize.ws_col > 0) { ioctl(fileno(stdout), TIOCSWINSZ, &_saved_winsize); - + } leave_raw_mode(); - - if (errno) + if (errno) { lprintf(LOG_ERR, "Exiting due to error %d -> %s", errno, strerror(errno)); + } } static void set_terminal_size(int rows, int cols) { struct winsize winsize; - - if (rows <= 0 || cols <= 0) + if (rows <= 0 || cols <= 0) { return; - + } /* save initial winsize */ ioctl(fileno(stdout), TIOCGWINSZ, &_saved_winsize); - /* set new winsize */ winsize.ws_row = rows; winsize.ws_col = cols; @@ -361,30 +345,35 @@ static void print_tsol_usage(void) { struct winsize winsize; - - lprintf(LOG_NOTICE, "Usage: tsol [recvip] [port=NUM] [ro|rw] [rows=NUM] [cols=NUM] [altterm]"); - lprintf(LOG_NOTICE, " recvip Receiver IP Address [default=local]"); - lprintf(LOG_NOTICE, " port=NUM Receiver UDP Port [default=%d]", - IPMI_TSOL_DEF_PORT); - lprintf(LOG_NOTICE, " ro|rw Set Read-Only or Read-Write [default=rw]"); - - ioctl(fileno(stdout), TIOCGWINSZ, &winsize); - lprintf(LOG_NOTICE, " rows=NUM Set terminal rows [default=%d]", - winsize.ws_row); - lprintf(LOG_NOTICE, " cols=NUM Set terminal columns [default=%d]", - winsize.ws_col); - - lprintf(LOG_NOTICE, " altterm Alternate terminal setup [default=off]"); + lprintf(LOG_NOTICE, +"Usage: tsol [recvip] [port=NUM] [ro|rw] [rows=NUM] [cols=NUM] [altterm]"); + lprintf(LOG_NOTICE, +" recvip Receiver IP Address [default=local]"); + lprintf(LOG_NOTICE, +" port=NUM Receiver UDP Port [default=%d]", + IPMI_TSOL_DEF_PORT); + lprintf(LOG_NOTICE, +" ro|rw Set Read-Only or Read-Write [default=rw]"); + ioctl(fileno(stdout), TIOCGWINSZ, &winsize); + lprintf(LOG_NOTICE, +" rows=NUM Set terminal rows [default=%d]", + winsize.ws_row); + lprintf(LOG_NOTICE, +" cols=NUM Set terminal columns [default=%d]", + winsize.ws_col); + lprintf(LOG_NOTICE, +" altterm Alternate terminal setup [default=off]"); } int -ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) +ipmi_tsol_main(struct ipmi_intf *intf, int argc, char **argv) { struct pollfd fds_wait[3], fds_data_wait[3], *fds; struct sockaddr_in sin, myaddr, *sa_in; socklen_t mylen; char *recvip = NULL; - char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE]; + char in_buff[IPMI_BUF_SIZE]; + char out_buff[IPMI_BUF_SIZE * 8]; char buff[IPMI_BUF_SIZE + 4]; int fd_socket, result, i; int out_buff_fill, in_buff_fill; @@ -394,7 +383,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) if (strlen(intf->name) < 3 || strncmp(intf->name, "lan", 3) != 0) { lprintf(LOG_ERR, "Error: Tyan SOL is only available over lan interface"); - return -1; + return (-1); } for (i = 0; i<argc; i++) { @@ -402,24 +391,26 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) /* not free'd ...*/ /* recvip = strdup(argv[i]); */ recvip = argv[i]; - } - else if (sscanf(argv[i], "port=%d", &ip1) == 1) + } else if (sscanf(argv[i], "port=%d", &ip1) == 1) { port = ip1; - else if (sscanf(argv[i], "rows=%d", &ip1) == 1) + } else if (sscanf(argv[i], "rows=%d", &ip1) == 1) { rows = ip1; - else if (sscanf(argv[i], "cols=%d", &ip1) == 1) + } else if (sscanf(argv[i], "cols=%d", &ip1) == 1) { cols = ip1; - else if (strlen(argv[i]) == 2 && strncmp(argv[i], "ro", 2) == 0) + } else if (strlen(argv[i]) == 2 + && strncmp(argv[i], "ro", 2) == 0) { read_only = 1; - else if (strlen(argv[i]) == 2 && strncmp(argv[i], "rw", 2) == 0) + } else if (strlen(argv[i]) == 2 + && strncmp(argv[i], "rw", 2) == 0) { read_only = 0; - else if (strlen(argv[i]) == 7 && strncmp(argv[i], "altterm", 7) == 0) + } else if (strlen(argv[i]) == 7 + && strncmp(argv[i], "altterm", 7) == 0) { _altterm = 1; - else if (strlen(argv[i]) == 4 && strncmp(argv[i], "help", 4) == 0) { + } else if (strlen(argv[i]) == 4 + && strncmp(argv[i], "help", 4) == 0) { print_tsol_usage(); return 0; - } - else { + } else { print_tsol_usage(); return 0; } @@ -432,7 +423,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) sa_in = (struct sockaddr_in *)&intf->session->addr; result = inet_pton(AF_INET, (const char *)intf->session->hostname, - &sa_in->sin_addr); + &sa_in->sin_addr); if (result <= 0) { struct hostent *host = gethostbyname((const char *)intf->session->hostname); @@ -457,7 +448,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) lprintf(LOG_ERR, "Can't open port %d", port); return -1; } - if (-1 == bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin))) { + if (bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin)) == (-1)) { lprintf(LOG_ERR, "Failed to bind socket."); close(fd_socket); return -1; @@ -467,7 +458,8 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) * retrieve local IP address if not supplied on command line */ if (recvip == NULL) { - result = intf->open(intf); /* must connect first */ + /* must connect first */ + result = intf->open(intf); if (result < 0) { close(fd_socket); return -1; @@ -489,7 +481,7 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) } printf("[Starting %sSOL with receiving address %s:%d]\n", - read_only ? "Read-only " : "", recvip, port); + read_only ? "Read-only " : "", recvip, port); set_terminal_size(rows, cols); enter_raw_mode(); @@ -499,14 +491,14 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x06 0xC0 0xA8 0xA8 0x78 0x1A 0x0A */ result = ipmi_tsol_start(intf, recvip, port); - if (result < 0) { + if (result < 0) { lprintf(LOG_ERR, "Error starting SOL"); close(fd_socket); - return -1; - } + return (-1); + } printf("[SOL Session operational. Use %c? for help]\n", - intf->session->sol_escape_char); + intf->session->sol_escape_char); gettimeofday(&_start_keepalive, 0); @@ -533,52 +525,58 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) out_buff_fill = 0; in_buff_fill = 0; fds = fds_wait; - for (;;) { - result = poll(fds, 3, 15*1000); - if (result < 0) + result = poll(fds, 3, 15 * 1000); + if (result < 0) { break; + } /* send keepalive packet */ tsol_keepalive(intf); - if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){ + if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)) { socklen_t sin_len = sizeof(sin); - result = recvfrom(fd_socket, buff, sizeof(out_buff) - out_buff_fill + 4, 0, - (struct sockaddr *)&sin, &sin_len); - - /* read the data from udp socket, skip some bytes in the head */ - if((result - 4) > 0 ){ + int buff_size = sizeof(buff); + if ((sizeof(out_buff) - out_buff_fill + 4) < buff_size) { + buff_size = (sizeof(out_buff) - out_buff_fill) + 4; + if ((buff_size - 4) <= 0) { + buff_size = 0; + } + } + result = recvfrom(fd_socket, buff, + buff_size, 0, + (struct sockaddr *)&sin, &sin_len); + /* read the data from udp socket, + * skip some bytes in the head + */ + if ((result - 4) > 0) { int length = result - 4; -#if 1 - length = (unsigned char)buff[2] & 0xff; - length *= 256; - length += ((unsigned char)buff[3] & 0xff); - if ((length <= 0) || (length > (result - 4))) - length = result - 4; -#endif memcpy(out_buff + out_buff_fill, buff + 4, length); out_buff_fill += length; } } if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) { + /* Read from keyboard */ result = read(fileno(stdin), in_buff + in_buff_fill, - sizeof(in_buff) - in_buff_fill); // read from keyboard + sizeof(in_buff) - in_buff_fill); if (result > 0) { int bytes; - bytes = do_inbuf_actions(intf, in_buff + in_buff_fill, result); - if(bytes < 0) { + bytes = do_inbuf_actions(intf, + in_buff + in_buff_fill, result); + if (bytes < 0) { result = ipmi_tsol_stop(intf, recvip, port); do_terminal_cleanup(); return result; } - if (read_only) + if (read_only) { bytes = 0; + } in_buff_fill += bytes; } } if ((fds[2].revents & POLLOUT) && out_buff_fill) { - result = write(fileno(stdout), out_buff, out_buff_fill); // to screen + /* To screen */ + result = write(fileno(stdout), out_buff, out_buff_fill); if (result > 0) { out_buff_fill -= result; if (out_buff_fill) { @@ -591,7 +589,8 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) * translate key and send that to SMDC using IPMI * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x03 0x04 0x1B 0x5B 0x43 */ - result = ipmi_tsol_send_keystroke(intf, in_buff, __min(in_buff_fill,14)); + result = ipmi_tsol_send_keystroke(intf, + in_buff, __min(in_buff_fill, 14)); if (result > 0) { gettimeofday(&_start_keepalive, 0); in_buff_fill -= result; @@ -603,6 +602,5 @@ ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) fds = (in_buff_fill || out_buff_fill )? fds_data_wait : fds_wait; } - return 0; } |