Skip to content

Architecture

Daniele Lacamera edited this page Dec 2, 2015 · 21 revisions

Architecture

In this section the architecture of the stack is described, from the core data structures to the functional flow.

Main data types

Protocols

A TCP/IP stack is made of layers, each one represented by a protocol. The main structure representing a protocol in picoTCP is the structure pico_protocol defined in pico_protocols.h.

struct pico_protocol {
    char name[MAX_PROTOCOL_NAME];
    uint32_t hash;
    enum pico_layer layer;
    uint16_t proto_number;
    struct pico_queue *q_in;
    struct pico_queue *q_out;
    struct pico_frame *(*alloc)(struct pico_protocol *self, uint16_t size); /* Frame allocation. */
    int (*push)(struct pico_protocol *self, struct pico_frame *p);    /* Push function, for active outgoing pkts from above */
    int (*process_out)(struct pico_protocol *self, struct pico_frame *p);  /* Send loop. */
    int (*process_in)(struct pico_protocol *self, struct pico_frame *p);  /* Recv loop. */
    uint16_t (*get_mtu)(struct pico_protocol *self);
}

Here is a brief description of the fields:

  • name contains a unique name used to identify the protocol implementation. Values for this fields look like “ipv4” or “tcp”

  • hash is a signature obtained by hashing the name with the pico_hash function. It is used for fast matches in ordered structures and it is generated automatically when the protocol gets registered to the stack. layer is an identifier of the OSI layer where the protocol belongs to. For convention, all the protocols that connect directly to the networking core protocols (IPv4/IPv6), such as ICMP, must be grouped in the PICO_PROTO_TRANSPORT layer.

  • q_in and q_out refer to the queues of frames traversing the protocol in either direction. For a better understanding of the queuing mechanism, refer to the Queues section in this chapter.

  • alloc is a pointer to the function, provided by the protocol, that offers the capability of allocating outgoing frames at this level, which would take into account all the protocols overhead in the stack. This function is only mandatory if the top layers utilize a generic function for the frame allocation in the bottom layers. For example, in order to allocate an outgoing IP frame, the IPv4 protocol implementation associates this pointer to a function called pico_ipv4_alloc, which takes into account the overhead of the IPv4 header and the possible underlying datalink headers.

    static struct pico_frame *pico_ipv4_alloc(struct pico_protocol *self, uint16_t size) { struct pico_frame *f = pico_frame_alloc(size + PICO_SIZE_IP4HDR + PICO_SIZE_ETHHDR); IGNORE_PARAMETER(self); if (!f) return NULL; f->datalink_hdr = f->buffer; f->net_hdr = f->buffer + PICO_SIZE_ETHHDR; f->net_len = PICO_SIZE_IP4HDR; f->transport_hdr = f->net_hdr + PICO_SIZE_IP4HDR; f->transport_len = size; f->len = size + PICO_SIZE_IP4HDR; return f; }

Clone this wiki locally