Line 52... |
Line 52... |
#include "telnet.h"
|
#include "telnet.h"
|
|
|
|
|
/* Global variables */
|
/* Global variables */
|
int tcp_checksum_errors_g = 0;
|
int tcp_checksum_errors_g = 0;
|
|
socket_t* first_socket_g;
|
|
socket_t* socket1_g;
|
|
|
|
/* input argument is a pointer to the previous socket,
|
|
if this is the first socket object, then it is NULL */
|
|
socket_t* new_socket(socket_t* prev)
|
|
{
|
|
socket_t* socket;
|
|
int i;
|
|
|
|
socket = (socket_t*) malloc(sizeof(socket_t));
|
|
socket->rx_packet = (packet_t*) malloc(sizeof(packet_t));
|
|
|
|
/* Create space for an array of pointers */
|
|
socket->tcp_buf = malloc (TCP_TX_BUFFERS * sizeof (void *));
|
|
|
|
/* Create space for a set of buffers, each pointed to by an element of the array */
|
|
for (i=0;i<TCP_TX_BUFFERS;i=i+1) {
|
|
socket->tcp_buf[i] = (packet_buffer_t*) malloc (sizeof (packet_buffer_t));
|
|
socket->tcp_buf[i]->payload_valid = 0;
|
|
socket->tcp_buf[i]->starting_seq = 0;
|
|
socket->tcp_buf[i]->ending_seq = 0;
|
|
socket->tcp_buf[i]->len_bytes = 0;
|
|
socket->tcp_buf[i]->ack_received = 0;
|
|
}
|
|
|
|
socket->telnet_txbuf = init_line_buffer(0x80000);
|
|
socket->telnet_rxbuf = init_line_buffer(0x1000);
|
|
|
|
socket->packets_sent = 0;
|
|
socket->packets_received = 0;
|
|
socket->packets_resent = 0;
|
|
|
|
socket->telnet_sent_opening_message = 0;
|
|
socket->telnet_echo_mode = 0;
|
|
socket->telnet_connection_state = TELNET_CLOSED;
|
|
socket->telnet_options_sent = 0;
|
|
|
|
socket->tcp_current_buf = 0;
|
|
socket->tcp_reset = 0;
|
|
socket->tcp_connection_state = TCP_CLOSED;
|
|
socket->tcp_disconnect = 0;
|
|
socket->tcp_seq = 0x100; /* should be random initial seq number for tcp */
|
|
socket->tcp_last_seq = socket->tcp_seq;
|
|
socket->tcp_last_ack = 0;
|
|
|
|
|
|
/* Chain the socket objects together */
|
|
if (prev == NULL){
|
|
socket->first = socket;
|
|
socket->id = 0;
|
|
}
|
|
else {
|
|
socket->first = prev->first;
|
|
socket->id = prev->id + 1;
|
|
prev->next = socket;
|
|
}
|
|
socket->next = NULL;
|
|
|
|
return socket;
|
|
}
|
|
|
|
|
|
/* All received tcp packets with dset ip == me arrive here */
|
void parse_tcp_packet(char * buf, packet_t* rx_packet)
|
void parse_tcp_packet(char * buf, packet_t* rx_packet)
|
{
|
{
|
int i;
|
int i;
|
int ptr;
|
int ptr;
|
socket_t* socket;
|
socket_t* socket;
|
|
int found=0;
|
|
|
/* TCP Length */
|
/* TCP Length */
|
rx_packet->tcp_len = rx_packet->ip_len - rx_packet->ip_header_len*4;
|
rx_packet->tcp_len = rx_packet->ip_len - rx_packet->ip_header_len*4;
|
rx_packet->tcp_hdr_len = (buf[12]>>4)*4;
|
rx_packet->tcp_hdr_len = (buf[12]>>4)*4;
|
|
|
Line 73... |
Line 136... |
rx_packet->tcp_payload_len = 0;
|
rx_packet->tcp_payload_len = 0;
|
|
|
/* Verify the TCP checksum is correct */
|
/* Verify the TCP checksum is correct */
|
if (tcp_checksum(buf, rx_packet, 0)) {
|
if (tcp_checksum(buf, rx_packet, 0)) {
|
tcp_checksum_errors_g++;
|
tcp_checksum_errors_g++;
|
goto error_out;
|
return;
|
}
|
}
|
|
|
|
|
rx_packet->tcp_src_port = buf[0]<<8|buf[1];
|
rx_packet->tcp_src_port = buf[0]<<8|buf[1];
|
rx_packet->tcp_dst_port = buf[2]<<8|buf[3];
|
rx_packet->tcp_dst_port = buf[2]<<8|buf[3];
|
Line 85... |
Line 148... |
rx_packet->tcp_ack = buf[8]<<24|buf[9]<<16|buf[10]<<8|buf[11];
|
rx_packet->tcp_ack = buf[8]<<24|buf[9]<<16|buf[10]<<8|buf[11];
|
rx_packet->tcp_flags = buf[13];
|
rx_packet->tcp_flags = buf[13];
|
rx_packet->tcp_window_size = buf[14]<<8|buf[15];
|
rx_packet->tcp_window_size = buf[14]<<8|buf[15];
|
|
|
|
|
|
/* only interested in telnet packet to dest port xx */
|
|
if (rx_packet->tcp_dst_port != 23) {
|
|
return;
|
|
}
|
|
|
if (rx_packet->tcp_hdr_len > 20) {
|
if (rx_packet->tcp_hdr_len > 20) {
|
/* Get the source time stamp */
|
/* Get the source time stamp */
|
parse_tcp_options(buf, rx_packet);
|
parse_tcp_options(buf, rx_packet);
|
}
|
}
|
|
|
|
|
/* --------------------------------------------------
|
/* --------------------------------------------------
|
Assign the received packet to a socket
|
Assign the received packet to a socket
|
-------------------------------------------------- */
|
-------------------------------------------------- */
|
|
/* seach for an open socket that matches the tcp connection */
|
|
socket = first_socket_g;
|
|
for(;;){
|
|
if (socket->tcp_connection_state != TCP_CLOSED &&
|
|
socket->rx_packet->tcp_src_port == rx_packet->tcp_src_port) {
|
|
found=1;
|
|
break;
|
|
}
|
|
if (socket->next!=NULL)
|
|
socket=socket->next;
|
|
else
|
|
break;
|
|
}
|
|
|
/* socket 0 open and matches ? */
|
|
if (socket0_g->tcp_connection_state != TCP_CLOSED &&
|
/* Search for an available closed soeckt to reuse */
|
socket0_g->rx_packet->tcp_src_port == rx_packet->tcp_src_port)
|
if (!found){
|
socket = socket0_g;
|
socket = first_socket_g;
|
|
for(;;){
|
/* socket 1 open and matches ? */
|
if (socket->tcp_connection_state == TCP_CLOSED) {
|
else if (socket1_g->tcp_connection_state != TCP_CLOSED &&
|
found=1;
|
socket1_g->rx_packet->tcp_src_port == rx_packet->tcp_src_port)
|
break;
|
socket = socket1_g;
|
}
|
|
if (socket->next!=NULL)
|
/* no matches. Pick an unused socket */
|
socket=socket->next;
|
else if (socket0_g->tcp_connection_state == TCP_CLOSED)
|
|
socket = socket0_g;
|
|
else if (socket1_g->tcp_connection_state == TCP_CLOSED)
|
|
socket = socket1_g;
|
|
else
|
else
|
goto error_out;
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* All available sockets being used. Add a new one to the end of the chain */
|
|
if (!found) {
|
|
socket = new_socket(socket);
|
|
}
|
|
|
|
|
/* Copy the rx_packet structure into the socket */
|
/* Copy the rx_packet structure into the socket */
|
memcpy(socket->rx_packet, rx_packet, sizeof(packet_t));
|
memcpy(socket->rx_packet, rx_packet, sizeof(packet_t));
|
|
|
tcp_response(buf, socket);
|
tcp_response(buf, socket);
|
|
|
error_out:
|
|
return;
|
|
}
|
}
|
|
|
|
|
/* Get the tcp source time stamp by walking through the options */
|
/* Get the tcp source time stamp by walking through the options */
|
void parse_tcp_options(char * buf, packet_t* rx_packet)
|
void parse_tcp_options(char * buf, packet_t* rx_packet)
|
Line 579... |
Line 661... |
|
|
return header_checksum16(buf, len_tcp, sum);
|
return header_checksum16(buf, len_tcp, sum);
|
}
|
}
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|
|
/* handle tcp connections and process buffers
|
|
Poll all sockets in turn for activity */
|
|
void process_tcp(socket_t* socket)
|
|
{
|
|
/* Check if any tcp packets need to be re-transmitted */
|
|
tcp_retransmit(socket);
|
|
|
|
/* Handle exit command */
|
|
if (socket->tcp_disconnect && socket->tcp_connection_state == TCP_OPEN) {
|
|
tcp_disconnect(socket);
|
|
}
|
|
|
|
/* Reset connection */
|
|
else if (socket->tcp_reset) {
|
|
socket->tcp_connection_state = TCP_CLOSED;
|
|
socket->telnet_connection_state = TELNET_CLOSED;
|
|
socket->telnet_options_sent = 0;
|
|
tcp_reply(socket, NULL, 0);
|
|
socket->tcp_reset = 0;
|
|
}
|
|
|
|
/* handle telnet messages */
|
|
else if (socket->tcp_connection_state == TCP_OPEN){
|
|
process_telnet(socket);
|
|
}
|
|
}
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|