void handle_tcp(const unsigned char *bytes, uint16_t segment_len) { struct tcphdr *tcp_hdr = (struct tcphdr *) bytes; tcp_hdr->th_sport = ntohs(tcp_hdr->th_sport); tcp_hdr->th_dport = ntohs(tcp_hdr->th_dport); printf2("TCP %u -> %u, [", tcp_hdr->th_sport, tcp_hdr->th_dport); print_flags(tcp_hdr->th_flags); print2("], "); printf2("seq %u, ack %u, win %u\n", ntohl(tcp_hdr->seq), ntohl(tcp_hdr->ack_seq), ntohs(tcp_hdr->window)); int data_offset = 4 * tcp_hdr->th_off; const unsigned char *end = bytes + data_offset; bytes += sizeof(struct tcphdr); while(bytes < end) { uint8_t kind = *bytes++; uint8_t len = 0; if(kind != 0 && kind != 1) len = *bytes++; printf3(" option %u: ", kind); switch(kind) { case 0: print3("end of options"); break; case 1: print3("no operation (NOP)"); break; case 2: printf3("MSS %u", (*(uint32_t*) bytes)); break; case 3: print3("window scale"); break; case 4: print3("SACK permited"); break; case 5: print3("SACK"); break; case 8: print3("timestamps"); break; default: print3("unknown"); break; } print3("\n"); // advance by the size of the option read if(kind != 0 && kind != 1) bytes += len - 2; } if(tcp_hdr->th_sport == 80 || tcp_hdr->th_dport == 80) { handle_http((const char *) bytes); } else if(tcp_hdr->th_sport == 23 || tcp_hdr->th_dport == 23) { handle_telnet(bytes, segment_len - data_offset); } else { printf1("??? Unknown TCP application with ports %u -> %u\n", tcp_hdr->th_sport, tcp_hdr->th_dport); } }
static int handle_user_char(console_info_t *info, unsigned char c) { int rv; if (info->tn_pos) c = handle_telnet(info, c); if (!c) return 0; switch(c) { case TN_IAC: if (info->telnet) { info->tn_buf[0] = c; info->tn_pos = 1; } else goto handle_char; break; case 8: case 0x7f: if (info->pos > 0) { info->pos--; if (info->echo) rv = write(info->outfd, "\b \b", 3); } break; case 4: if (info->pos == 0) { if (info->echo) rv = write(info->outfd, "\n", 1); return 1; } break; case 10: case 13: if (info->echo) { rv = write(info->outfd, "\n", 1); if (info->telnet) rv = write(info->outfd, "\r", 1); } info->buffer[info->pos] = '\0'; if (strcmp(info->buffer, "noecho") == 0) { info->echo = 0; } else { ipmi_emu_cmd(&info->out, info->data->emu, info->buffer); } rv = write(info->outfd, "> ", 2); info->pos = 0; break; handle_char: default: if (info->pos >= sizeof(info->buffer)-1) { char *msg = "\nCommand is too long, max of %d characters\n"; rv = write(info->outfd, msg, strlen(msg)); } else { info->buffer[info->pos] = c; info->pos++; if (info->echo) rv = write(info->outfd, &c, 1); } } return 0; }