OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-ethmac/] [tcp.c] - Diff between revs 61 and 80

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 61 Rev 80
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.