Common Modules for TCP/IP stack

For the implementation of my version of a TCP/IP stack I need some modules that not always directly related to networking.  These modules will be described here.

1. Pool for packet buffers

One of the most important building blocks in the TCP/IP stack is the packet buffer.  All communication (incoming and outgoing) is going through the packet buffer.  The most perfomant way to use a packet buffer is to use static memory, especially when working with micro controllers.  Another way is allocate them dynamically from the memory heap, if your heap is big enough.  Since heap sizes are mostly quite limited when working with micro controllers, they’re not really an option here.  Static buffers are more perfomant as you don’t need to allocate the memory area for your buffer; the memory is allocated at compile time.  Heap based buffers are more memory efficient, but do require some extra manipulation (malloc, memset, free, …).

My application doesn’t need many buffers as I’m not processing network packets in parallel; I just need to queue one or two packets when sending data requires some additional look up.  The first version uses fixed length buffers, were the length is determined by the longest packet.  The controllers I have are limited by the MTU to 1518 bytes, so my packet buffers will be each 1518 bytes long.  My estimation is that for pure UDP operations I need 3 buffers at most, so a pool of 5 will be more than enough to start with.  Later when developing the TCP part I’ll decide the final size of the pool as TCP demands more than UDP, due to the fragmented packets.

The basic structure consists of 3 elements:

  • state of the buffer (free/occupied)
  • the payload (fixed size of 1518 bytes maximum)
  • length of the payload (char array can contain lots of zeroes, thus impossible to measure with strlen)

The header shows 4 functions that can be used anywhere in the TCP/IP stack:

  • pbuf_alloc, allocates a free buffer from the pool
  • pbuf_free, returns a buffer to the pool
  • pbuf_merge, merges two buffers into one (not used, due to the fixed size)
  • pbuf_occ_count, counts the occupied buffers (for statistics)

Source files:  and 

pbuf.c (2.0 KiB)

2. Delay routines

As explained in another post, you can’t live without.  You’ll find more explanations here.

3. Debugging

Some of the debugging can be achieved by the hardware debugger and semihosting, but in this case a LCD seems to be far more useful.  I’ll explain the working of the LCD in another post.

Tagged , , , . Bookmark the permalink.

4 Responses to Common Modules for TCP/IP stack

  1. Patrice says:

    merci pour vos info sur stack ip, mais comment récuperer le contenu d’un pbuf en clair pour pouvoir l’utiliser ?
    Je trouve aucune expilcation sur le sujet.
    Avec stm32 et lwip, j’arrive a bien faire fonctionner dans tous les sens en tcp et en udp, mais j’arrive pas a convertir le buffer de reception en quelque chose d’utilisable.
    j’arrive a le faire sous linux en C, mais pas avec lwip, avez vous une idée comment convertir en clair, genre string ?

    • PatrickPatrick says:

      Hello Patrice,
      My French is quite good, but I’m going to reply in English as my site uses mainly English.

      The pbuf or packet buffer just holds a string that represents the data packets as you would capture them with a network sniffer. My pbuf is quite different to the one from lwip but basically it holds the same data. To get useful information out of it, you will have to create types that represent the UDP and TCP data structures. Check my documentation section in downloads, start with the diagram for EthernetII and build up from there the data you need according to the received packet or packet you’re going to send. A small non-functional example (code has been assembled from different files):

      typedef struct __attribute__((__packed__)) eth_frame {
      uint8_t to_addr[6];
      uint8_t from_addr[6];
      uint16_t type;
      uint8_t data[];
      } eth_frame_t;

      typedef struct __attribute__((__packed__)) ip_packet {
      uint8_t ver_head_len;
      uint8_t tos;
      uint16_t total_len;
      uint16_t fragment_id;
      uint16_t flags_fragment_offset;
      uint8_t ttl;
      uint8_t protocol;
      uint16_t cksum;
      uint32_t from_addr;
      uint32_t to_addr;
      uint8_t data[];
      } ip_packet_t;

      typedef struct icmp_echo_packet {
      uint8_t type;
      uint8_t code;
      uint16_t cksum;
      uint16_t id;
      uint16_t seq;
      uint8_t data[];
      } icmp_echo_packet_t;

      err_t icmp_input(pbuf_t *p, netif_t *inp) {
      eth_frame_t *frame = (void *) p->payload;
      ip_packet_t *ip = (void *) frame->data;
      icmp_echo_packet_t *icmp = (void *) ip->data;

      The trick is to cast the data block of the upper stack element into a lower one.


  2. oussama zaidi says:

    Hi Patrick
    I have a question which is a little out of the subject, i hope you don’t mind to response.
    My project is an input/output module which generate and receive analog and digital signals and communicate to network with a tcp/ip connection, i didn’t choose yet the platform to work with i am confused between BeagleBone and STM32F4, i know that they are different and i know that BeagleBone is so much easier to work with specially for the tcp/ip part, but i need to know more caracteristiques of both of them to choose right i am a beginner and i don’t have a good idea of the advantages and disadvantages of each one, like which is more stable, which gives me a better tcp/ip connection, which consume less… somethings like that, i need your advice thank you a lot

Leave a Reply

Your email address will not be published. Required fields are marked *

WordPress Anti Spam by WP-SpamShield