Anet is a networking library for the Ada programming language.

Features

The Anet networking library has the following features:

  • BSD socket implementation

  • High abstraction level

  • Extendable socket type hierarchy

  • Socket receiver tasks (Stream and Datagram)

  • Ada type serialisation/deserialisation over sockets

  • Supported socket families

    • IPv4 (AF_INET)

    • IPv6 (AF_INET6)

    • Packet (AF_PACKET)

    • UNIX domain (AF_UNIX)

    • Netlink (AF_NETLINK)

  • Supported socket modes

    • Stream (TCP)

    • Datagram (UDP)

    • RAW

  • Support for IPv4/IPv6 multicast

  • UDP/IPv4 packet creation and validation

  • Binding to the Linux Packet Filter (LPF) system

Licence

Copyright (C) 2011-2013 secunet Security Networks AG
Copyright (C) 2011-2013 Reto Buerki <reet@codelabs.ch>
Copyright (C) 2011-2013 Adrian-Ken Rueegsegger <ken@codelabs.ch>

Free use of this software is granted under the terms of the GNAT Modified
General Public License (GMGPL).

Download

Release version

The current release version of Anet is available at http://www.codelabs.ch/download/.

Verify a Release

To verify the integrity and authenticity of the distribution tarball, import the key http://www.codelabs.ch/keys/0xBB793815pub.asc and type the following command:

$ gpg --verify libanet-{version}.tar.bz2.sig

The key fingerprint of the public key (0xBB793815) is:

Key fingerprint = A2FB FF56 83FB 67D8 017B  C50C F8C5 F8B5 BB79 3815

Development version

The current development version of Anet is available through its git repository:

$ git clone http://git.codelabs.ch/git/anet.git

A browsable version of the repository is also available here: http://git.codelabs.ch/?p=anet.git

Build

To compile Anet on your system, you need to have the following software installed:

If you want to run the unit tests before installation of Anet (which is recommended) you furthermore need to have the following installed:

Testing

Anet contains a unit test suite which can be run by entering the following command:

$ make tests

All tests should be marked with PASS behind the test name.

Installation

To install Anet on your system, type the following:

$ make PREFIX=/usr/local install

If no PREFIX is specified, $(HOME)/libraries is used as install destination.

Example

Server (UNIX/TCP)

--
--  Copyright (C) 2012 secunet Security Networks AG
--  Copyright (C) 2012 Reto Buerki <reet@codelabs.ch>
--  Copyright (C) 2012 Adrian-Ken Rueegsegger <ken@codelabs.ch>
--
--  This program is free software; you can redistribute it and/or modify it
--  under the terms of the GNU General Public License as published by the
--  Free Software Foundation; either version 2 of the License, or (at your
--  option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
--
--  This program is distributed in the hope that it will be useful, but
--  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
--  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--  for more details.
--
--  As a special exception, if other files instantiate generics from this
--  unit,  or  you  link  this  unit  with  other  files  to  produce  an
--  executable   this  unit  does  not  by  itself  cause  the  resulting
--  executable to  be  covered by the  GNU General  Public License.  This
--  exception does  not  however  invalidate  any  other reasons why  the
--  executable file might be covered by the GNU Public License.
--

with Ada.Streams;

with Anet.Streams;
with Anet.Sockets.Unix;
with Anet.Receivers.Stream;

procedure Server is

   package Unix_TCP_Receiver is new Anet.Receivers.Stream
     (Socket_Type => Anet.Sockets.Unix.TCP_Socket_Type);

   procedure Handle_Request
     (Recv_Data :     Ada.Streams.Stream_Element_Array;
      Send_Data : out Ada.Streams.Stream_Element_Array;
      Send_Last : out Ada.Streams.Stream_Element_Offset);
   --  Handle requests from clients.

   procedure Handle_Request
     (Recv_Data :     Ada.Streams.Stream_Element_Array;
      Send_Data : out Ada.Streams.Stream_Element_Array;
      Send_Last : out Ada.Streams.Stream_Element_Offset)
   is
      Stream : aliased Anet.Streams.Memory_Stream_Type (Max_Elements => 4);
      Number : Integer;
   begin
      Stream.Set_Buffer (Buffer => Recv_Data);
      Integer'Read (Stream'Access, Number);

      Number := Number + 1;

      Integer'Write (Stream'Access, Number);
      Send_Last := Stream.Get_Buffer'Length;
      Send_Data (Send_Data'First .. Send_Last) := Stream.Get_Buffer;
   end Handle_Request;

   Socket   : aliased Anet.Sockets.Unix.TCP_Socket_Type;
   Receiver : Unix_TCP_Receiver.Receiver_Type (S => Socket'Access);
begin
   Socket.Init;
   Socket.Bind (Path => "/tmp/anet.example");
   Receiver.Listen (Callback => Handle_Request'Access);
end Server;

Client (UNIX/TCP)

--
--  Copyright (C) 2012 secunet Security Networks AG
--  Copyright (C) 2012 Reto Buerki <reet@codelabs.ch>
--  Copyright (C) 2012 Adrian-Ken Rueegsegger <ken@codelabs.ch>
--
--  This program is free software; you can redistribute it and/or modify it
--  under the terms of the GNU General Public License as published by the
--  Free Software Foundation; either version 2 of the License, or (at your
--  option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
--
--  This program is distributed in the hope that it will be useful, but
--  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
--  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--  for more details.
--
--  As a special exception, if other files instantiate generics from this
--  unit,  or  you  link  this  unit  with  other  files  to  produce  an
--  executable   this  unit  does  not  by  itself  cause  the  resulting
--  executable to  be  covered by the  GNU General  Public License.  This
--  exception does  not  however  invalidate  any  other reasons why  the
--  executable file might be covered by the GNU Public License.
--

with Ada.Text_IO;
with Ada.Streams;

with Anet.Streams;
with Anet.Sockets.Unix;

procedure Client is
   Number : Integer := 0;
   Socket : Anet.Sockets.Unix.TCP_Socket_Type;
   Stream : aliased Anet.Streams.Memory_Stream_Type (Max_Elements => 4);
begin
   Socket.Init;
   Socket.Connect (Path => "/tmp/anet.example");

   loop
      Ada.Text_IO.Put_Line ("PING" & Number'Img);
      Integer'Write (Stream'Access, Number);
      Socket.Send (Item => Stream.Get_Buffer);

      declare
         Buffer : Ada.Streams.Stream_Element_Array (1 .. 4);
         Last   : Ada.Streams.Stream_Element_Offset;
      begin
         Socket.Receive (Item => Buffer,
                         Last => Last);
         Stream.Set_Buffer (Buffer => Buffer (Buffer'First .. Last));
         Integer'Read (Stream'Access, Number);
         Ada.Text_IO.Put_Line ("PONG" & Number'Img);
      end;

      delay 1.0;
   end loop;
end Client;