Skip to content
Stephane Carrez edited this page Nov 11, 2016 · 3 revisions

Network stack

Embedded Network Stack

The Embedded Network Stack is a small IPv4 network stack intended to be used by small embedded Ada applications.

Network Buffers

The Net.Buffers package provides support for network buffer management. A network buffer can hold a single packet frame so that it is limited to 1500 bytes of payload with 14 or 16 bytes for the Ethernet header. The network buffers are allocated by the Ethernet driver during the initialization to setup the Ethernet receive queue. The allocation of network buffers for the transmission is under the responsibility of the application.

Before receiving a packet, the application also has to allocate a network buffer. Upon successful reception of a packet by the Receive procedure, the allocated network buffer will be given to the Ethernet receive queue and the application will get back the received buffer. There is no memory copy.

The package defines two important types: Buffer_Type and Buffer_List. These two types are limited types to forbid copies and force a strict design to applications. The Buffer_Type describes the packet frame and it provides various operations to access the buffer. The Buffer_List defines a list of buffers.

The network buffers are kept within a single linked list managed by a protected object. Because interrupt handlers can release a buffer, that protected object has the priority System.Max_Interrupt_Priority. The protected operations are very basic and are in O(1) complexity so that their execution is bounded in time whatever the arguments.

Before anything, the network buffers have to be allocated. The application can do this by reserving some memory region (using STM32.SDRAM.Reserve) and adding the region with the Add_Region procedure. The region must be a multiple of NET_ALLOC_SIZE constant. To allocate 32 buffers, you can do the following:

NET_BUFFER_SIZE  : constant Interfaces.Unsigned_32 := Net.Buffers.NET_ALLOC_SIZE * 32;
...
Net.Buffers.Add_Region (STM32.SDRAM.Reserve (Amount => NET_BUFFER_SIZE), NET_BUFFER_SIZE);

An application will allocate a buffer by using the Allocate operation and this is as easy as:

Packet : Net.Buffers.Buffer_Type;
...
Net.Buffers.Allocate (Packet);

What happens if there is no available buffer? No exception is raised because the networks stack is intended to be used in embedded systems where exceptions are not available. You have to check if the allocation succeeded by using the Is_Null function:

if Packet.Is_Null then
  null; --  Oops
end if;

Serialization

Several serialization operations are provided to build or extract information from a packet. Before proceeding to the serialization, it is necessary to set the packet type. The packet type is necessary to reserve room for the protocol headers. To build a UDP packet, the UDP_PACKET type will be used:

Packet.Set_Type (Net.Buffers.UDP_PACKET);

Then, several Put operations are provided to serialize the data. By default integers are serialized in network byte order. The Put_Uint8 serializes one byte, the Put_Uint16 two bytes, the Put_Uint32 four bytes. The Put_String operation will serialize a string. A NUL byte is optional and can be added when the With_Null optional parameter is set. The example below creates a DNS query packet:

Packet.Put_Uint16 (1234);  -- XID
Packet.Put_Uint16 (16#0100#); -- Flags
Packet.Put_Uint16 (1); --  # queries
Packet.Put_Uint16 (0);
Packet.Put_Uint32 (0);
Packet.Put_Uint8 (16#3#);  -- Query
Packet.Put_String ("www.google.fr", With_Null => True);
Packet.Put_Uint16 (16#1#); --  A record
Packet.Put_Uint16 (16#1#); --  IN class

After a packet is serialized, the length get be obtained by using the

Len : Net.Uint16 := Packet.Get_Data_Length;

Network Interface

The Ifnet_Type represents the network interface driver that allows to receive or send packets.

ARP Protocol

The Net.Protos.Arp package implements the support for the ARP protocol used for the resolution of IPv4 addresses. The package maintains a ARP database within an Ada protected object.

The Resolve procedure is the main entry point for the resolution of the IPv4 address. Given a target IP address, it first looks in the ARP database for the associated Ethernet address. When the Ethernet address is known, it updates the Ethernet header so that the packet can be sent to the network interface.

When the Ethernet address is now known, the Resolve procedure puts the packet in a queue and it makes an ARP request.

The Receive procedure should be called when a ARP packet is received. It is responsible for replying to ARP requests from other hosts on the network and handling ARP response for our requests. It updates the ARP database only when we receive a ARP response from one of our ARP query.


Generated by Dynamo from net.ads

Clone this wiki locally