[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

(LibAnet)(Patch) This Patch made possible the use in High Integrity Systems.



  Hi!

    Because I Known the  source code of both,
 I believe Libanet is faster and safer than gnat-sockets
But gnat-sockets et.all claim categorically to be secure in the domains of High Integrity, High Security and Real Time Systems
. Whats "The Magic" for this ? the Magic for this
is have categorization pragmas ( or attributes) and some initial re-work;

With this categorization added tools from this fields can be used flawlesse. :-D

The patch in anex made this use of tools and et.all possible. :-)

Enjoy!

p.s.: any sugestion and tests is wellcome! this patch is my donation to Libanet Project. :-)


--
"There are many plans in the Human heart, But
 is the Lord's Purpose that prevails"

"Existem Muitos planos e desejos no coração Humano, MAS
são os Propósitos do Senhor que prevalecem"

  []'s Dani:-)
diff --git a/Anet_lib_Sym.gpr b/Anet_lib_Sym.gpr
new file mode 120000
index 0000000..204f89e
--- /dev/null
+++ b/Anet_lib_Sym.gpr
@@ -0,0 +1 @@
+anet_lib.gpr
\ No newline at end of file
diff --git a/anet_common.gpr b/anet_common.gpr
index 3c3f621..a4f4a4f 100644
--- a/anet_common.gpr
+++ b/anet_common.gpr
@@ -37,7 +37,7 @@ project Anet_Common is
 
    Compiler_Switches := ("-gnatygAdISuxo",
                          "-gnatVa",
-                         "-gnat05",
+                         "-gnat2005",
                          "-gnatf",
                          "-fstack-check",
                          "-gnato",
@@ -46,4 +46,3 @@ project Anet_Common is
    Binder_Switches   := ("-E");
 
 end Anet_Common;
-
diff --git a/anet_lib.gpr b/anet_lib.gpr
index 0378ab1..8ac57e6 100644
--- a/anet_lib.gpr
+++ b/anet_lib.gpr
@@ -45,4 +45,3 @@ project Anet_Lib is
    end Compiler;
 
 end Anet_Lib;
-
diff --git a/src/anet-arp.adb b/src/anet-arp.adb
index 9866c8b..cabcc16 100644
--- a/src/anet-arp.adb
+++ b/src/anet-arp.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Byte_Swapping;
 
 package body Anet.ARP is
diff --git a/src/anet-arp.ads b/src/anet-arp.ads
index d57421a..b86354b 100644
--- a/src/anet-arp.ads
+++ b/src/anet-arp.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.ARP is
 
+   pragma Pure (Anet.ARP);
+
    ARP_Header_Length : constant := 28;
    --  ARP for IPv4 header size in bytes.
 
diff --git a/src/anet-auxiliary.adb b/src/anet-auxiliary.adb
new file mode 100644
index 0000000..11b0ab5
--- /dev/null
+++ b/src/anet-auxiliary.adb
@@ -0,0 +1,190 @@
+
+pragma Detect_Blocking;
+
+package body Anet.Auxiliary is
+
+   function Simple_Count   (Source :  String; --  Ok!
+                           Pattern :  String;
+                           contiguous  :  Boolean := False) return Natural
+   is
+      I        : Integer            := 0;
+      PL       : constant Integer   := Pattern'Length - 1;
+
+      SFirst   :          Integer   := Source'First - 1;
+      SLast    : constant Integer   := Source'Last;
+   begin
+      if Source'Length = 0 or else PL < 0   --  or else SLast < PL
+         or else SLast < SFirst + PL
+      then
+         return 0;
+      end if;
+
+      loop1 :
+      loop
+         SFirst := SFirst + 1;
+
+         exit loop1 when SFirst + PL > SLast;
+
+         if Source (SFirst .. SFirst + PL) = Pattern then
+            I := I + 1;
+
+            SFirst := SFirst + PL;
+
+            exit loop1 when SFirst + PL + 1 > SLast;
+
+            if contiguous and then
+               Source (SFirst + 1 .. SFirst + 1 + PL) /= Pattern
+            then
+               exit loop1;
+            end if;
+         end if;
+      end loop loop1;
+
+      return I;
+   end Simple_Count;
+
+   procedure Simple_Count  (Source  :  String; --  Ok!
+                           Pattern  :  String;
+                           From     :  Positive;
+                           contiguous  :  Boolean := False;
+                           First_Index :  out   Integer;
+                           Last_Index  :  out   Integer;
+                           Counted     :  out   Integer)
+   is
+      FI       : Boolean            := True;
+      I        : Integer            := 0;
+      PL       : constant Integer   := Pattern'Length - 1; -- qAp :-)
+
+      SFirst   :          Integer   := Source'First + From - 2;
+      SLast    : constant Integer   := Source'Last;
+
+   begin
+      First_Index := 0;
+      Counted     := 0;
+      Last_Index  := 0;
+
+      if Source'Length = 0 or else PL < 0 or else SLast < PL + From
+         or else SLast < SFirst + PL
+      then
+         return;
+      end if;
+
+      loop1 :
+      loop
+
+         SFirst := SFirst + 1;
+
+         exit loop1 when SFirst + PL > SLast;
+
+         if Source (SFirst .. SFirst + PL) = Pattern then
+
+            I := I + 1;
+
+            if FI then
+               First_Index := SFirst;
+               FI := False;
+            end if;
+
+            SFirst := SFirst + PL;
+
+            Last_Index := SFirst;
+
+            exit loop1 when SFirst + PL + 1 > SLast;
+
+            if contiguous and then
+               Source (SFirst + 1 .. SFirst + 1 + PL) /= Pattern
+            then
+                  exit loop1;
+            end if;
+
+         end if;
+      end loop loop1;
+
+      Counted     := I;
+   end Simple_Count;
+
+   function Simple_Index   (Source  :  String;
+                           Pattern  :  String;
+                           From     :  Positive;
+                           Forward  :  Boolean  := True) return Natural
+   is
+      PL       : constant Integer   := Pattern'Length - 1;
+
+      SFirst   :          Integer   := Source'First + From - 2;
+      SLast    :          Integer   := Source'Last + 1;
+
+   begin
+      if Source'Length = 0 or else PL < 0 or else SLast < PL
+         or else SFirst > SLast
+      then
+         return 0;
+      end if;
+
+      if Forward then
+         loop1 :
+         loop
+            SFirst := SFirst + 1;
+
+            exit loop1 when SFirst + PL >= SLast;
+
+            if Source (SFirst .. SFirst + PL) = Pattern then
+               return SFirst;
+            end if;
+
+         end loop loop1;
+      else
+         loop2 :
+         loop
+            SLast := SLast - 1;
+
+            exit loop2 when SLast - PL <= SFirst;
+
+            if Source (SLast - PL .. SLast) = Pattern then
+               return SLast - PL;
+            end if;
+         end loop loop2;
+      end if;
+
+      return 0;
+   end Simple_Index;
+
+   function Simple_Trim    (Source  :  String;
+                           Side     :  Trim_end) return String
+   is
+      FS :  Integer  := Source'First;
+      LS :  Integer  := Source'Last;
+   begin
+      if Source'Length < 1 then
+         return "";
+      end if;
+
+      if Side = Left or else Side = Both then
+         FS := FS - 1;
+         loop1 :
+         loop
+            FS := FS + 1;
+            exit loop1 when FS > LS or else Source (FS) /= ' ';
+         end loop loop1;
+      end if;
+
+      if FS > LS then
+         return "";
+      end if;
+
+      if Side = Right or else Side = Both then
+         LS := LS + 1;
+         loop2 :
+         loop
+            LS := LS - 1;
+            exit loop2 when FS > LS or else Source (LS) /= ' ';
+         end loop loop2;
+      end if;
+
+      if FS > LS then
+         return "";
+      end if;
+
+      return Source (FS .. LS);
+   end Simple_Trim;
+
+end Anet.Auxiliary;
diff --git a/src/anet-auxiliary.ads b/src/anet-auxiliary.ads
new file mode 100644
index 0000000..8abeaab
--- /dev/null
+++ b/src/anet-auxiliary.ads
@@ -0,0 +1,41 @@
+
+pragma License (Modified_GPL);
+pragma Detect_Blocking;
+
+package Anet.Auxiliary is
+
+   pragma Pure (Auxiliary);
+
+   type Trim_end is (Left, Right, Both);
+
+   Index_Error : exception;
+   Pattern_Error : exception;
+
+   function Simple_Count   (Source :  String;
+                           Pattern :  String;
+                           contiguous  :  Boolean := False) return Natural;
+   pragma Inline (Simple_Count);
+   pragma Pure_Function (Simple_Count);
+
+   procedure Simple_Count  (Source  :  String;
+                           Pattern  :  String;
+                           From     :  Positive; -- in range of Source
+                           contiguous  :  Boolean := False;
+                           First_Index :  out   Integer;
+                           Last_Index  :  out   Integer;
+                           Counted     :  out   Integer);
+   pragma Inline (Simple_Count);
+
+   function Simple_Index   (Source  :  String;
+                           Pattern  :  String;
+                           From     :  Positive;
+                           Forward  :  Boolean  := True) return Natural;
+   pragma Inline (Simple_Index);
+   pragma Pure_Function (Simple_Index);
+
+   function Simple_Trim    (Source  :  String;
+                           Side     :  Trim_end) return String;
+   pragma Inline (Simple_Trim);
+   pragma Pure_Function (Simple_Trim);
+
+end Anet.Auxiliary;
diff --git a/src/anet-byte_swapping.adb b/src/anet-byte_swapping.adb
index a978a98..7704283 100644
--- a/src/anet-byte_swapping.adb
+++ b/src/anet-byte_swapping.adb
@@ -21,10 +21,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with System;
+pragma Detect_Blocking;
 
+with System;
 with GNAT.Byte_Swapping;
 
+pragma Elaborate_All (System);
+pragma Elaborate_All (GNAT.Byte_Swapping);
+
 package body Anet.Byte_Swapping is
 
    use type System.Bit_Order;
diff --git a/src/anet-byte_swapping.ads b/src/anet-byte_swapping.ads
index 0876b66..44aa7a7 100644
--- a/src/anet-byte_swapping.ads
+++ b/src/anet-byte_swapping.ads
@@ -21,22 +21,34 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Byte_Swapping is
 
+   pragma Pure (Anet.Byte_Swapping);
+
    function Host_To_Network (Input : Double_Byte) return Double_Byte;
    --  Convert given input double byte from host byte order to network byte
    --  order.
+   pragma Inline (Host_To_Network);
+   pragma Pure_Function (Host_To_Network);
 
    function Host_To_Network (Input : Word32) return Word32;
    --  Convert given input 32bit word from host byte order to network byte
    --  order.
+   pragma Inline (Host_To_Network);
+   pragma Pure_Function (Host_To_Network);
 
    function Network_To_Host (Input : Double_Byte) return Double_Byte;
    --  Convert given input double byte from network byte order to host byte
    --  order.
+   pragma Inline (Network_To_Host);
+   pragma Pure_Function (Network_To_Host);
 
    function Network_To_Host (Input : Word32) return Word32;
    --  Convert given input 32bit word from network byte order to host byte
    --  order.
+   pragma Inline (Network_To_Host);
+   pragma Pure_Function (Network_To_Host);
 
 end Anet.Byte_Swapping;
diff --git a/src/anet-constants.ads b/src/anet-constants.ads
index 9db4177..a6148c5 100644
--- a/src/anet-constants.ads
+++ b/src/anet-constants.ads
@@ -21,12 +21,18 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 pragma Warnings (Off);
 with System.OS_Constants;
 pragma Warnings (On);
 
+pragma Elaborate_All (System.OS_Constants);
+
 package Anet.Constants is
 
+   pragma Pure (Anet.Constants);
+
    package Sys renames System.OS_Constants;
 
    --------------
diff --git a/src/anet-errno.adb b/src/anet-errno.adb
index d6de360..28046b4 100644
--- a/src/anet-errno.adb
+++ b/src/anet-errno.adb
@@ -27,7 +27,9 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Ada.Strings.Fixed;
+pragma Detect_Blocking;
+
+with Anet.Auxiliary;
 
 package body Anet.Errno
 is
@@ -39,12 +41,13 @@ is
       Message : String)
    is
       use type Interfaces.C.int;
+      use      Auxiliary;
    begin
       if Result = C_Failure then
          raise Socket_Error with Message & " - " & Get_Errno_String
-           & " (" & Ada.Strings.Fixed.Trim
+           & " (" & Auxiliary.Simple_Trim
            (Source => GNAT.OS_Lib.Errno'Img,
-            Side   => Ada.Strings.Left) & ")";
+            Side   => Left) & ")";
       end if;
    end Check_Or_Raise;
 
diff --git a/src/anet-errno.ads b/src/anet-errno.ads
index a173d2d..b212159 100644
--- a/src/anet-errno.ads
+++ b/src/anet-errno.ads
@@ -27,12 +27,17 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Interfaces.C;
+pragma Detect_Blocking;
 
+with Interfaces.C;
 with GNAT.OS_Lib;
 
+pragma Elaborate_All (Interfaces.C);
+pragma Elaborate_All (GNAT.OS_Lib);
+
 package Anet.Errno
 is
+   pragma Preelaborate (Anet.Errno);
 
    function Get_Errno_String
      (Err     : Integer := GNAT.OS_Lib.Errno;
diff --git a/src/anet-ipv4.adb b/src/anet-ipv4.adb
index 8c8fdcf..3ac1a1c 100644
--- a/src/anet-ipv4.adb
+++ b/src/anet-ipv4.adb
@@ -21,13 +21,17 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with System;
 
 with Anet.Byte_Swapping;
 with Anet.Constants;
-with Anet.Util;
+with Anet.Util_Pure;
 with Anet.UDP;
 
+pragma Elaborate_All (System);
+
 package body Anet.IPv4 is
 
    type Four_Bit_Type is range 0 .. 15;
@@ -114,7 +118,7 @@ package body Anet.IPv4 is
       IP_Header.Daddr    := Dst_IP;
 
       IP_Header.Checksum := Byte_Swapping.Host_To_Network
-        (Input => Util.Calculate_One_Complement (Data => Hdr_Buffer));
+        (Input => Util_Pure.Calculate_One_Complement (Data => Hdr_Buffer));
 
       return Hdr_Buffer;
    end Create_Header;
@@ -213,7 +217,7 @@ package body Anet.IPv4 is
 
          IP_Header.Checksum := 0;
 
-         Chk_Calc := Util.Calculate_One_Complement (Data => Hdr_Buffer);
+         Chk_Calc := Util_Pure.Calculate_One_Complement (Data => Hdr_Buffer);
          if Chk_Pkt /= Chk_Calc then
             raise Invalid_IP_Packet with "IP header checksum" & Chk_Pkt'Img
               & " invalid, should be" & Chk_Calc'Img;
diff --git a/src/anet-ipv4.ads b/src/anet-ipv4.ads
index 0bbf2c2..555a7a9 100644
--- a/src/anet-ipv4.ads
+++ b/src/anet-ipv4.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.IPv4 is
 
+   pragma Pure (Anet.IPv4);
+
    IP_Header_Length : constant := 20;
    --  IP Header size in bytes.
 
diff --git a/src/anet-os.adb b/src/anet-os.adb
index 3e4a146..fda4961 100644
--- a/src/anet-os.adb
+++ b/src/anet-os.adb
@@ -21,7 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Ada.Directories;
+pragma Detect_Blocking;
+
 with Ada.Streams.Stream_IO;
 with Ada.IO_Exceptions;
 
@@ -33,6 +34,12 @@ with GNAT.OS_Lib;
 with Anet.Errno;
 with Anet.Constants;
 
+pragma Elaborate_All (Ada.IO_Exceptions);
+pragma Elaborate_All (Ada.Streams.Stream_IO);
+pragma Elaborate_All (Interfaces.C);
+pragma Elaborate_All (Interfaces.C_Streams);
+pragma Elaborate_All (GNAT.OS_Lib);
+
 package body Anet.OS is
 
    -------------------------------------------------------------------------
@@ -104,7 +111,7 @@ package body Anet.OS is
          Len  : Stream_Element_Offset;
          Data : Stream_Element_Array
            (1 .. Stream_Element_Offset
-              (Ada.Directories.Size (Name => Filename)));
+              (Stream_IO.Size (Data_File)));
       begin
          Stream_IO.Read (File => Data_File,
                          Item => Data,
diff --git a/src/anet-os.ads b/src/anet-os.ads
index db685ac..27058ac 100644
--- a/src/anet-os.ads
+++ b/src/anet-os.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.OS is
 
+   pragma Preelaborate (Anet.OS);
+
    procedure Execute (Command : String);
    --  Execute given command with /bin/sh.
 
diff --git a/src/anet-receivers-datagram.adb b/src/anet-receivers-datagram.adb
index 90e4f75..a14a1be 100644
--- a/src/anet-receivers-datagram.adb
+++ b/src/anet-receivers-datagram.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Receivers.Datagram is
 
    procedure Empty_Cb
diff --git a/src/anet-receivers-datagram.ads b/src/anet-receivers-datagram.ads
index 844e514..f715026 100644
--- a/src/anet-receivers-datagram.ads
+++ b/src/anet-receivers-datagram.ads
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Sockets;
 
 generic
@@ -43,6 +45,8 @@ generic
 
 package Anet.Receivers.Datagram is
 
+   pragma Preelaborate (Anet.Receivers.Datagram);
+
    Buffsize : constant Ada.Streams.Stream_Element_Offset;
    --  Buffer size used.
 
diff --git a/src/anet-receivers-stream.adb b/src/anet-receivers-stream.adb
index 2ca58c0..b9d6833 100644
--- a/src/anet-receivers-stream.adb
+++ b/src/anet-receivers-stream.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Receivers.Stream is
 
    procedure Empty_Cb
diff --git a/src/anet-receivers-stream.ads b/src/anet-receivers-stream.ads
index 73a3fd7..d4e3be0 100644
--- a/src/anet-receivers-stream.ads
+++ b/src/anet-receivers-stream.ads
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Sockets;
 
 generic
@@ -42,6 +44,8 @@ generic
 
 package Anet.Receivers.Stream is
 
+   pragma Preelaborate (Anet.Receivers.Stream);
+
    Buffsize : constant Ada.Streams.Stream_Element_Offset;
    --  Buffer size used.
 
diff --git a/src/anet-receivers.adb b/src/anet-receivers.adb
index 864b3f1..3476beb 100644
--- a/src/anet-receivers.adb
+++ b/src/anet-receivers.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Receivers is
 
    -------------------------------------------------------------------------
diff --git a/src/anet-receivers.ads b/src/anet-receivers.ads
index 2a81e00..94da935 100644
--- a/src/anet-receivers.ads
+++ b/src/anet-receivers.ads
@@ -21,12 +21,19 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Ada.Exceptions;
 
 with System;
 
+pragma Elaborate_All (Ada.Exceptions);
+pragma Elaborate_All (System);
+
 package Anet.Receivers is
 
+   pragma Preelaborate (Anet.Receivers);
+
    type Count_Type is mod System.Max_Binary_Modulus;
 
    type Error_Handler_Callback is not null access procedure
diff --git a/src/anet-sockets-filters.adb b/src/anet-sockets-filters.adb
index 3d2d5be..e62baa7 100644
--- a/src/anet-sockets-filters.adb
+++ b/src/anet-sockets-filters.adb
@@ -21,12 +21,16 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with System;
 
 with Anet.Errno;
 with Anet.Constants;
 with Anet.Sockets.Thin;
 
+pragma Elaborate_All (System);
+
 package body Anet.Sockets.Filters is
 
    type Sock_Fprog_Type is record
diff --git a/src/anet-sockets-filters.ads b/src/anet-sockets-filters.ads
index 41e27a1..933758b 100644
--- a/src/anet-sockets-filters.ads
+++ b/src/anet-sockets-filters.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Filters is
 
+   pragma Preelaborate (Anet.Sockets.Filters);
+
    type Sock_Filter_Type is record
       Code : Interfaces.Unsigned_16;
       --  Actual filter code.
diff --git a/src/anet-sockets-inet-iface.ads b/src/anet-sockets-inet-iface.ads
index 83229d4..f972a41 100644
--- a/src/anet-sockets-inet-iface.ads
+++ b/src/anet-sockets-inet-iface.ads
@@ -20,10 +20,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Types;
 
 package Anet.Sockets.Inet.Iface is
 
+   pragma Preelaborate (Anet.Sockets.Inet.Iface);
+
    procedure Bind
      (Socket : in out Inet_Socket_Type;
       Iface  :        Types.Iface_Name_Type);
diff --git a/src/anet-sockets-inet.adb b/src/anet-sockets-inet.adb
index ead97fd..7dc4430 100644
--- a/src/anet-sockets-inet.adb
+++ b/src/anet-sockets-inet.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Errno;
 with Anet.Constants;
 with Anet.OS_Constants;
diff --git a/src/anet-sockets-inet.ads b/src/anet-sockets-inet.ads
index 2da81fd..d8364fe 100644
--- a/src/anet-sockets-inet.ads
+++ b/src/anet-sockets-inet.ads
@@ -21,10 +21,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Types;
 
 package Anet.Sockets.Inet is
 
+   pragma Preelaborate (Anet.Sockets.Inet);
+
    type Inet_Socket_Type is abstract new Socket_Type with private;
    --  Internet socket.
 
diff --git a/src/anet-sockets-net_ifaces.adb b/src/anet-sockets-net_ifaces.adb
index c62fc09..c6882c3 100644
--- a/src/anet-sockets-net_ifaces.adb
+++ b/src/anet-sockets-net_ifaces.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Interfaces.C;
 
 with Anet.Errno;
@@ -28,6 +30,8 @@ with Anet.Constants;
 with Anet.Sockets.Inet;
 with Anet.Sockets.Thin.Netdev.Requests;
 
+pragma Elaborate_All (Interfaces.C);
+
 package body Anet.Sockets.Net_Ifaces is
 
    use Anet.Sockets.Thin.Netdev;
diff --git a/src/anet-sockets-net_ifaces.ads b/src/anet-sockets-net_ifaces.ads
index 3ad8b1b..bd99257 100644
--- a/src/anet-sockets-net_ifaces.ads
+++ b/src/anet-sockets-net_ifaces.ads
@@ -21,10 +21,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Types;
 
 package Anet.Sockets.Net_Ifaces is
 
+   pragma Preelaborate (Anet.Sockets.Net_Ifaces);
+
    function Get_Iface_Index (Name : Types.Iface_Name_Type) return Positive;
    --  Get interface index of interface given by name.
 
diff --git a/src/anet-sockets-thin-netdev.ads b/src/anet-sockets-thin-netdev.ads
index ea0b585..31e7ce3 100644
--- a/src/anet-sockets-thin-netdev.ads
+++ b/src/anet-sockets-thin-netdev.ads
@@ -20,10 +20,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Sockets.Thin.Sockaddr;
 
 package Anet.Sockets.Thin.Netdev is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Netdev);
+
    type Netdev_Request_Name is
      (If_Addr,
       If_Flags,
diff --git a/src/anet-sockets-thin.ads b/src/anet-sockets-thin.ads
index 4a84d8c..a344236 100644
--- a/src/anet-sockets-thin.ads
+++ b/src/anet-sockets-thin.ads
@@ -21,10 +21,16 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with System;
 
+pragma Elaborate_All (System);
+
 package Anet.Sockets.Thin is
 
+   pragma Preelaborate (Anet.Sockets.Thin);
+
    type IPv4_Mreq_Type is record
       Imr_Multiaddr : IPv4_Addr_Type;
       Imr_Interface : IPv4_Addr_Type;
diff --git a/src/anet-sockets-unix.adb b/src/anet-sockets-unix.adb
index 11b4678..c18d2c8 100644
--- a/src/anet-sockets-unix.adb
+++ b/src/anet-sockets-unix.adb
@@ -21,8 +21,9 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Ada.Strings.Fixed;
+pragma Detect_Blocking;
 
+with Anet.Auxiliary;
 with Anet.OS;
 with Anet.Errno;
 
@@ -189,9 +190,9 @@ package body Anet.Sockets.Unix is
    function To_String (Path : Full_Path_Type) return String
    is
    begin
-      return Ada.Strings.Fixed.Trim
+      return Anet.Auxiliary.Simple_Trim
         (Source => String (Path),
-         Side   => Ada.Strings.Right);
+         Side   => Anet.Auxiliary.Right);
    end To_String;
 
 end Anet.Sockets.Unix;
diff --git a/src/anet-sockets-unix.ads b/src/anet-sockets-unix.ads
index ad4a535..e91fdfe 100644
--- a/src/anet-sockets-unix.ads
+++ b/src/anet-sockets-unix.ads
@@ -21,17 +21,23 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-private with Ada.Strings.Unbounded;
+pragma Detect_Blocking;
 
+private with Ada.Strings.Unbounded;
 with Anet.Sockets.Thin.Unix;
 
+pragma Elaborate_All (Ada.Strings.Unbounded);
+
 package Anet.Sockets.Unix is
 
+   pragma Preelaborate (Anet.Sockets.Unix);
+
    subtype Path_Range is Positive range 1 .. Thin.Unix.UNIX_PATH_MAX - 1;
    --  Range of unix paths.
 
    type Path_Type is array (Path_Range range <>) of Character;
    --  Unix path type.
+   pragma Preelaborable_Initialization (Path_Type);
 
    subtype Full_Path_Type is Path_Type (Path_Range);
    --  Unix path with max. possible size.
@@ -41,6 +47,7 @@ package Anet.Sockets.Unix is
 
    function To_String (Path : Full_Path_Type) return String;
    --  Returned trimmed string representation of given full path.
+   pragma Pure_Function (To_String);
 
    type Unix_Socket_Type is abstract new Socket_Type with private;
    --  UNIX domain socket.
diff --git a/src/anet-sockets.adb b/src/anet-sockets.adb
index 6656e10..a51e1e6 100644
--- a/src/anet-sockets.adb
+++ b/src/anet-sockets.adb
@@ -21,12 +21,15 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with GNAT.OS_Lib;
+pragma Detect_Blocking;
 
+with GNAT.OS_Lib;
 with Anet.Errno;
 with Anet.OS_Constants;
 with Anet.Sockets.Thin;
 
+pragma Elaborate_All (GNAT.OS_Lib);
+
 package body Anet.Sockets is
 
    package C renames Interfaces.C;
diff --git a/src/anet-sockets.ads b/src/anet-sockets.ads
index 83f2464..b1086f8 100644
--- a/src/anet-sockets.ads
+++ b/src/anet-sockets.ads
@@ -21,15 +21,20 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-private with Ada.Finalization;
+pragma Detect_Blocking;
 
+private with Ada.Finalization;
 with Interfaces.C;
-
 with Anet.Constants;
 with Anet.Socket_Families;
 
+pragma Elaborate_All (Ada.Finalization);
+pragma Elaborate_All (Interfaces.C);
+
 package Anet.Sockets is
 
+   pragma Preelaborate (Anet.Sockets);
+
    type Mode_Type is
      (Datagram_Socket,
       Raw_Socket,
diff --git a/src/anet-streams.adb b/src/anet-streams.adb
index b53f7cc..261bd6b 100644
--- a/src/anet-streams.adb
+++ b/src/anet-streams.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Streams is
 
    -------------------------------------------------------------------------
diff --git a/src/anet-streams.ads b/src/anet-streams.ads
index 14ee3e8..67046be 100644
--- a/src/anet-streams.ads
+++ b/src/anet-streams.ads
@@ -21,13 +21,19 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-package Anet.Streams is
+pragma Detect_Blocking;
+
+package Anet.Streams
+
+is
+   pragma Pure (Anet.Streams);
 
    type Memory_Stream_Type (Max_Elements : Ada.Streams.Stream_Element_Offset)
      is new Ada.Streams.Root_Stream_Type with private;
    --  In-memory stream type. Can be used to serialize/deserialize record types
    --  over a socket. The Max_Elements discriminant defines the maximal number
    --  of elements the stream is able to store.
+   pragma Preelaborable_Initialization (Memory_Stream_Type);
 
    overriding
    procedure Read
diff --git a/src/anet-thin.ads b/src/anet-thin.ads
index 2f609f5..2cbab31 100644
--- a/src/anet-thin.ads
+++ b/src/anet-thin.ads
@@ -20,28 +20,17 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with System;
+pragma Detect_Blocking;
 
-with Interfaces.C.Strings;
+with Interfaces.C;
+
+pragma Elaborate_All (Interfaces.C);
 
 package Anet.Thin is
 
+   pragma Preelaborate (Anet.Thin);
+
    function C_Getpid return Interfaces.C.int;
    pragma Import (C, C_Getpid, "getpid");
 
-   function C_Inet_Pton
-     (Af  : Interfaces.C.int;
-      Src : Interfaces.C.Strings.chars_ptr;
-      Dst : System.Address)
-      return Interfaces.C.int;
-   pragma Import (C, C_Inet_Pton, "inet_pton");
-
-   function C_Inet_Ntop
-     (Af   : Interfaces.C.int;
-      Src  : System.Address;
-      Dst  : Interfaces.C.Strings.chars_ptr;
-      Size : Interfaces.C.unsigned)
-      return Interfaces.C.Strings.chars_ptr;
-   pragma Import (C, C_Inet_Ntop, "inet_ntop");
-
 end Anet.Thin;
diff --git a/src/anet-types.adb b/src/anet-types.adb
index 7ba8715..be44ec3 100644
--- a/src/anet-types.adb
+++ b/src/anet-types.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Types is
 
    -------------------------------------------------------------------------
diff --git a/src/anet-types.ads b/src/anet-types.ads
index c3fff99..bf8783f 100644
--- a/src/anet-types.ads
+++ b/src/anet-types.ads
@@ -21,15 +21,20 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Constants;
 
 package Anet.Types is
 
+   pragma Pure (Anet.Types);
+
    subtype Iface_Name_Range is Positive range 1 .. Constants.IFNAMSIZ - 1;
    --  Range of interface name.
 
    type Iface_Name_Type is array (Iface_Name_Range range <>) of Character;
    --  Interface name type.
+   pragma Preelaborable_Initialization (Iface_Name_Type);
 
    function Is_Valid_Iface (Name : String) return Boolean;
    --  Returns true if the given name is a valid interface name.
diff --git a/src/anet-udp.adb b/src/anet-udp.adb
index 91e4eb4..18f0ded 100644
--- a/src/anet-udp.adb
+++ b/src/anet-udp.adb
@@ -21,9 +21,16 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Byte_Swapping;
-with Anet.Constants;
-with Anet.Util;
+with Anet.Util_Pure;
+
+pragma Warnings (Off);
+with System.OS_Constants;
+pragma Warnings (On);
+
+pragma Elaborate_All (System.OS_Constants);
 
 package body Anet.UDP is
 
@@ -105,7 +112,7 @@ package body Anet.UDP is
       Pseudo_Hdr.Source_Address := Src_IP;
       Pseudo_Hdr.Dest_Address   := Dst_IP;
       Pseudo_Hdr.Reserved       := 0;
-      Pseudo_Hdr.Protocol       := Constants.Sys.IPPROTO_UDP;
+      Pseudo_Hdr.Protocol       := System.OS_Constants.IPPROTO_UDP;
       Pseudo_Hdr.Length         := Byte_Swapping.Host_To_Network
         (Input => Payload'Length + Hdr_Buffer'Length);
 
@@ -113,7 +120,8 @@ package body Anet.UDP is
       Chksum_Buffer (UDP_Hdr_Idx'Range)    := Hdr_Buffer;
       Chksum_Buffer (UDP_Hdr_Idx'Last + 1 .. Chksum_Buffer'Last) := Payload;
 
-      return Util.Calculate_One_Complement (Data => Chksum_Buffer);
+      return Util_Pure.Calculate_One_Complement (
+            Data => Chksum_Buffer);
    end Compute_Checksum;
 
    -------------------------------------------------------------------------
diff --git a/src/anet-udp.ads b/src/anet-udp.ads
index 2f9bed8..736c3b3 100644
--- a/src/anet-udp.ads
+++ b/src/anet-udp.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.UDP is
 
+   pragma Pure (Anet.UDP);
+
    UDP_Header_Length : constant := 8;
    --  UDP header size in bytes.
 
@@ -35,6 +39,7 @@ package Anet.UDP is
       return Ada.Streams.Stream_Element_Array;
    --  Returns an UDP header for given source and destination port and payload.
    --  The source, destination IPv4 addresses are used for UDP checksuming.
+   pragma Pure_Function (Create_Header);
 
    procedure Validate_Checksum
      (Packet : Ada.Streams.Stream_Element_Array;
diff --git a/src/anet-util.adb b/src/anet-util.adb
index 3465007..970d8ed 100644
--- a/src/anet-util.adb
+++ b/src/anet-util.adb
@@ -21,13 +21,16 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Ada.Directories;
-with Ada.Numerics.Discrete_Random;
+pragma Detect_Blocking;
 
-with Interfaces;
+with Ada.Numerics.Discrete_Random;
+with Ada.Directories;
 
 with Anet.Thin;
 
+pragma Elaborate_All (Ada.Numerics.Discrete_Random);
+pragma Elaborate_All (Ada.Directories);
+
 package body Anet.Util is
 
    use Ada.Streams;
@@ -42,66 +45,6 @@ package body Anet.Util is
 
    -------------------------------------------------------------------------
 
-   function Calculate_One_Complement
-     (Data : Ada.Streams.Stream_Element_Array)
-      return Double_Byte
-   is
-      function Make_Even
-        (Data : Stream_Element_Array)
-         return Stream_Element_Array;
-      --  Pad data array with a nil element if it has an uneven number of
-      --  elements.
-
-      function Make_Even
-        (Data : Stream_Element_Array)
-         return Stream_Element_Array
-      is
-      begin
-         if Data'Length mod 2 = 0 then
-            return Data;
-         end if;
-
-         return D : Stream_Element_Array (Data'First .. Data'Last + 1) do
-            D (Data'Range) := Data;
-            D (D'Last)     := 0;
-         end return;
-      end Make_Even;
-
-      use Interfaces;
-
-      Sum  : Unsigned_32                   := 0;
-      Even : constant Stream_Element_Array := Make_Even (Data => Data);
-      Idx  : Stream_Element_Offset         := Even'First;
-   begin
-      loop
-         Sum := Sum + Unsigned_32 (Shift_Left
-           (Value  => Unsigned_16 (Even (Idx)),
-            Amount => 8));
-         Sum := Sum + Unsigned_32 (Even (Idx + 1));
-
-         Idx := Idx + 2;
-         exit when Idx > Even'Last;
-      end loop;
-
-      loop
-         declare
-            Carries : constant Unsigned_32
-              := Shift_Right (Value  => Sum,
-                              Amount => 16);
-         begin
-            exit when Carries < 1;
-
-            Sum := (Sum and 16#ffff#) + Carries;
-         end;
-      end loop;
-
-      Sum := (not Sum) mod 2 ** 16;
-
-      return Double_Byte (Sum);
-   end Calculate_One_Complement;
-
-   -------------------------------------------------------------------------
-
    function Random_String (Len : Positive) return String
    is
       Result : String (1 .. Len);
diff --git a/src/anet-util.ads b/src/anet-util.ads
index 88ad5e2..32b5ca2 100644
--- a/src/anet-util.ads
+++ b/src/anet-util.ads
@@ -21,12 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Util is
 
-   function Calculate_One_Complement
-     (Data : Ada.Streams.Stream_Element_Array)
-      return Double_Byte;
-   --  Calculate one's complement sum of the 16 bit aligned data bytes.
+   --  non Preelaborate because body with'ed Ada.Numerics.Discrete_Random and
+   --  Ada.Directories;
 
    function Random_String (Len : Positive) return String;
    --  Return a random string of given length.
diff --git a/src/anet-util_pure.adb b/src/anet-util_pure.adb
new file mode 100644
index 0000000..dc6a9a4
--- /dev/null
+++ b/src/anet-util_pure.adb
@@ -0,0 +1,92 @@
+--
+--  Copyright (C) 2011, 2012 secunet Security Networks AG
+--  Copyright (C) 2011-2014  Reto Buerki <reet@codelabs.ch>
+--  Copyright (C) 2011-2014  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.
+--
+
+pragma Detect_Blocking;
+
+with Interfaces;
+
+pragma Elaborate_All (Interfaces);
+
+package body Anet.Util_Pure is
+
+   use Ada.Streams;
+
+   function Calculate_One_Complement
+     (Data : Ada.Streams.Stream_Element_Array)
+      return Double_Byte
+   is
+      function Make_Even
+        (Data : Stream_Element_Array)
+         return Stream_Element_Array;
+      --  Pad data array with a nil element if it has an uneven number of
+      --  elements.
+
+      function Make_Even
+        (Data : Stream_Element_Array)
+         return Stream_Element_Array
+      is
+      begin
+         if Data'Length mod 2 = 0 then
+            return Data;
+         end if;
+
+         return D : Stream_Element_Array (Data'First .. Data'Last + 1) do
+            D (Data'Range) := Data;
+            D (D'Last)     := 0;
+         end return;
+      end Make_Even;
+
+      use Interfaces;
+
+      Sum  : Unsigned_32                   := 0;
+      Even : constant Stream_Element_Array := Make_Even (Data => Data);
+      Idx  : Stream_Element_Offset         := Even'First;
+   begin
+      loop
+         Sum := Sum + Unsigned_32 (Shift_Left
+           (Value  => Unsigned_16 (Even (Idx)),
+            Amount => 8));
+         Sum := Sum + Unsigned_32 (Even (Idx + 1));
+
+         Idx := Idx + 2;
+         exit when Idx > Even'Last;
+      end loop;
+
+      loop
+         declare
+            Carries : constant Unsigned_32
+              := Shift_Right (Value  => Sum,
+                              Amount => 16);
+         begin
+            exit when Carries < 1;
+
+            Sum := (Sum and 16#ffff#) + Carries;
+         end;
+      end loop;
+
+      Sum := (not Sum) mod 2 ** 16;
+
+      return Double_Byte (Sum);
+   end Calculate_One_Complement;
+
+end Anet.Util_Pure;
diff --git a/src/anet-util_pure.ads b/src/anet-util_pure.ads
new file mode 100644
index 0000000..89b0083
--- /dev/null
+++ b/src/anet-util_pure.ads
@@ -0,0 +1,36 @@
+--
+--  Copyright (C) 2011, 2012 secunet Security Networks AG
+--  Copyright (C) 2011, 2012 Reto Buerki <reet@codelabs.ch>
+--  Copyright (C) 2011, 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.
+--
+
+pragma Detect_Blocking;
+
+package Anet.Util_Pure is
+
+   pragma Pure (Anet.Util_Pure);
+
+   function Calculate_One_Complement
+     (Data : Ada.Streams.Stream_Element_Array)
+      return Double_Byte;
+   --  Calculate one's complement sum of the 16 bit aligned data bytes.
+   pragma Pure_Function (Calculate_One_Complement);
+
+end Anet.Util_Pure;
diff --git a/src/anet.adb b/src/anet.adb
index 60ac074..6b66464 100644
--- a/src/anet.adb
+++ b/src/anet.adb
@@ -21,14 +21,9 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Ada.Strings.Fixed;
-with Ada.Strings.Unbounded;
+pragma Detect_Blocking;
 
-with Interfaces.C.Strings;
-
-with Anet.Thin;
-with Anet.Errno;
-with Anet.Socket_Families;
+with Anet.Auxiliary;
 
 package body Anet is
 
@@ -55,10 +50,13 @@ package body Anet is
 
    -------------------------------------------------------------------------
 
-   function To_Hex (B : Byte) return String
+   function To_Hex (B : Byte; LowerCase : Boolean := True) return String
    is
-      Hex_To_Char : constant String (1 .. 16) := "0123456789ABCDEF";
+      Hex_To_Char :          String (1 .. 16) := "0123456789abcdef";
    begin
+      if not LowerCase then
+         Hex_To_Char (11 .. 16) := "ABCDEF";
+      end if;
       return Result : String (1 .. 2) do
          Result (1) := Hex_To_Char (Natural (B / 16) + 1);
          Result (2) := Hex_To_Char (Natural (B mod 16) + 1);
@@ -69,15 +67,19 @@ package body Anet is
 
    function To_Hex (Data : Ada.Streams.Stream_Element_Array) return String
    is
-      use Ada.Strings.Unbounded;
-
-      S : Unbounded_String;
+      S  :  String (1 .. (Data'Length * 2) + 2) := (others => ' ');
+      I  :  Natural  := 1;
    begin
+      if Data'Length = 0 then
+         return S (1 .. 0);
+      end if;
+
       for B in Data'Range loop
-         S := S & To_Hex (B => Byte (Data (B)));
+         S (I .. I + 1) := To_Hex (B => Byte (Data (B)));
+         I :=  I + 2;
       end loop;
 
-      return To_String (S);
+      return S (1 .. I - 1);
    end To_Hex;
 
    -------------------------------------------------------------------------
@@ -97,7 +99,7 @@ package body Anet is
          raise Constraint_Error with "Unable to convert empty string to IP";
       end if;
 
-      if Ada.Strings.Fixed.Count (Source  => Str,
+      if Auxiliary.Simple_Count (Source  => Str,
                                   Pattern => ".") /= 3
       then
          raise Constraint_Error with
@@ -110,7 +112,7 @@ package body Anet is
          Dot_Idx  : Natural := Str'First;
       begin
          for I in IPv4_Addr_Type'Range loop
-            Dot_Idx := Ada.Strings.Fixed.Index
+            Dot_Idx := Auxiliary.Simple_Index
               (From    => Left_Idx,
                Source  => Str,
                Pattern => ".");
@@ -140,25 +142,179 @@ package body Anet is
 
    function To_IPv6_Addr (Str : String) return IPv6_Addr_Type
    is
-      Result  : IPv6_Addr_Type   := (others => 0);
-      Err     : Interfaces.C.int := 0;
-      Src_Ptr : Interfaces.C.Strings.chars_ptr
-        := Interfaces.C.Strings.New_String (Str);
+      use Auxiliary;
+
+      Str_TMP     : String (1 .. Str'Length + 1)   := ":" & Str;
+
+      C2C : constant Natural := Simple_Count (Source  => Str, Pattern => "::");
+      C1C : constant Natural := Simple_Count (Source  => Str, Pattern => ":");
+      C1D : constant Natural := Simple_Count (Source  => Str, Pattern => ".");
+
+      Buffer_Str  :  String (1 .. 48)  := (1 => ':', others => '0');
+      Buffer_1st  :  Integer           := Buffer_Str'First;
+      FI          : Boolean            := True;
+      NColon      : Integer            := C1C;
+      NextC       : Integer            := 0;
+      NextD       : Integer            := 0;
+      MI0         : Integer            := Str_TMP'First;
+      MI2         : constant  Integer  := Str_TMP'Last;
    begin
-      Err := Thin.C_Inet_Pton
-        (Af  => Socket_Families.Families (Socket_Families.Family_Inet6),
-         Src => Src_Ptr,
-         Dst => Result'Address);
-      Interfaces.C.Strings.Free (Src_Ptr);
-
-      case Err is
-         when 1 => return Result;
-         when 0 => raise Constraint_Error with "Invalid IPv6 address '"
-              & Str & "'";
+      if Str = "" then
+         raise Constraint_Error with "Unable to convert empty string to IP";
+      end if;
+
+      if Str = "::" then
+         return Any_Addr_V6;
+      end if;
+
+      if Str = "::1" then
+         return Loopback_Addr_V6;
+      end if;
+
+      if C1C < 2 or else C1C > 7 then
+         raise Constraint_Error with
+           "Valid IPv6 address string must contain between 2 to 7 colons";
+      end if;
+
+      if C2C > 1 then
+         raise Constraint_Error with
+           "Valid IPv6 address string must contain only 1 group of :: colons";
+      end if;
+
+      if C1D /= 0 then
+         if C1D /= 3 then
+            raise Constraint_Error with
+              "Valid IPv6 address string with embedded IPv4 must "
+              & "contain 0 or 3 dots";
+         end if;
+         if not (
+            (Str_TMP'Last > 7 and then
+               Str_TMP (2 .. 8) = "::ffff:") or else
+            (Str_TMP'Last > 30 and then
+               Str_TMP (2 .. 31) = "0000:0000:0000:0000:0000:ffff:") or else
+            (Str_TMP'Last > 15 and then
+               Str_TMP (2 .. 16) = "0:0:0:0:0:ffff:")
+               )
+         then
+            raise Constraint_Error with
+              "Valid IPv6 address string with embedded IPv4 must "
+              & "start with ::ffff: or equivalent ";
+         end if;
+         NColon := NColon + 1;
+      end if;
+
+      loop1 :
+      loop
+         exit loop1 when MI0 > MI2;
+
+         NextC := Simple_Index   (Source   => Str_TMP,   Pattern  => ":",
+                                  From     => MI0 + 1,   Forward  => True);
+         if NextC <= 0 then
+            if C1D /= 0 then
+               exit loop1;
+            end if;
+            NextC := Str_TMP'Last + 1;
+         end if;
+
+         if Str_TMP (MI0) /= ':' then
+            goto cont_loop1;
+         end if;
+
+         if FI and then Str_TMP (MI0 + 1) = ':' then
+            loop2 :
+            loop
+               Buffer_1st := Buffer_1st + 5;
+               Buffer_Str (Buffer_1st) := ':';
+               NColon := NColon + 1;
+               exit loop2 when NColon > 7;
+            end loop loop2;
+            FI := False;
+            goto cont_loop1;
+         end if;
+
+         if Buffer_1st < 1 then
+            Buffer_1st := 2;
+         end if;
+
+         Buffer_Str (Buffer_1st + (5 - (NextC - MI0 - 1))  .. Buffer_1st + 5)
+            := Str_TMP (MI0 + 1  .. NextC - 1) & ":";
+         Buffer_1st := Buffer_1st + 5;
+         MI0 := NextC - 1;
+
+         <<cont_loop1>>
+
+         MI0 := MI0 + 1;
+      end loop loop1;
+
+      if C1D /= 0 then
+         Str_TMP (MI0)  := '.';
+         Buffer_1st     := Buffer_1st + 1;
+
+         loop3 :
+         loop
+            exit loop3 when MI0 > MI2;
+
+            NextD := Simple_Index   (Source   => Str_TMP,   Pattern  => ".",
+                                     From     => MI0 + 1,   Forward  => True);
+            if NextD <= 0 then
+               NextD := Str_TMP'Last + 1;
+            end if;
+
+            if Str_TMP (MI0) /= '.' then
+               goto cont_loop3;
+            end if;
+
+            Buffer_Str (Buffer_1st .. Buffer_1st + 1)
+               := To_Hex (Byte'Value (Str_TMP (MI0 + 1  .. NextD - 1)));
+            Buffer_1st  := Buffer_1st + 2;
+            MI0         := NextD - 1;
+
+            if (Buffer_1st - 1) mod 5 = 0  then
+               Buffer_Str (Buffer_1st)   := ':';
+               Buffer_1st                := Buffer_1st + 1;
+            end if;
+
+            <<cont_loop3>>
+
+            MI0 := MI0 + 1;
+         end loop loop3;
+
+         Buffer_1st  := Buffer_1st - 1;
+      end if;
+
+      beg2 :
+      declare
+         StrS     : constant String  := Buffer_Str (2 .. Buffer_1st - 1);
+         Left_Idx : Natural := StrS'First;
+         Dot_Idx  : Natural := StrS'First;
+         Result   : IPv6_Addr_Type;
+      begin
+         for I in IPv6_Addr_Type'First .. IPv6_Addr_Type'Length / 2 loop
+            Dot_Idx := Simple_Index
+              (From    => Left_Idx,
+               Source  => StrS,
+               Pattern => ":");
+
+            --  Check if we reached the end of the string.
+
+            if Dot_Idx = 0 then
+               Dot_Idx := StrS'Last + 1;
+            end if;
+
+            Result (I * 2 - 1) := To_Byte (StrS (Left_Idx .. Left_Idx + 1));
+            Result (I * 2)     := To_Byte
+              (StrS (Left_Idx + 2 .. Left_Idx + 3));
+
+            Left_Idx := Dot_Idx + 1;
+            Dot_Idx  := Left_Idx;
+         end loop;
+
+         return Result;
+      exception
          when others =>
-            raise Constraint_Error with "Error converting string to IPv6 "
-              & "address: " & Errno.Get_Errno_String;
-      end case;
+            raise Constraint_Error with "Invalid octet: "
+              & StrS (Left_Idx .. Dot_Idx);
+      end beg2;
    end To_IPv6_Addr;
 
    -------------------------------------------------------------------------
@@ -213,31 +369,156 @@ package body Anet is
 
    -------------------------------------------------------------------------
 
-   function To_String (Address : IPv6_Addr_Type) return String
+   function To_String (Address : IPv6_Addr_Type) return String -- ok
    is
+      Buffer : String (1 .. 60)  := (1 => ':', others => '0');
+      Buffer_1st  : Integer      := Buffer'First + 1;
+      Qt1         : Integer      := 0;
+      MI0         : Integer      := Address'First;
+      MI2      : constant Integer  := Address'Last;
+      IPv4A    : constant IPv6_Addr_Type := (11 .. 12 => 255, others => 0);
+      Ipv4B    : constant Boolean := (Address (1 .. 12) = IPv4A (1 .. 12));
+
+      use Auxiliary;
+   begin
+      --  Tested without from here
+      if Address = Any_Addr_V6 then
+         return "::";
+      end if;
+      if Address = Loopback_Addr_V6 then
+         return "::1";
+      end if;
+      if Address = IPv6_Addr_Type'(others => 255) then
+         return "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
+      end if;
+      --  to here, too. - Ok
+      loop1 :
+      loop
+         exit loop1 when MI0 > MI2;
+
+         if Ipv4B and then MI0 > 12 then
+            beg2 :
+            declare
+               dcs1  : constant String
+                  := Simple_Trim (Address (MI0)'Img, Left);
+               dcs2  : constant String
+                  := Simple_Trim (Address (MI0 + 1)'Img, Left);
+               len1  : constant Integer := dcs1'Length;
+               len2  : constant Integer := dcs2'Length;
+            begin
+               Buffer (Buffer_1st .. Buffer_1st + len1) := dcs1 & ".";
+               Buffer (Buffer_1st + len1 + 1 .. Buffer_1st + len1 + 1 + len2)
+                  := dcs2 & ".";
+               Buffer_1st  := Buffer_1st + len1 + 2 + len2;
+               goto cont_loop1;
+            end beg2;
+         end if;
 
-      INET6_ADDRSTRLEN : constant := 46;
+         if Address (MI0) = 0 and then Address (MI0 + 1) = 0 then
+            Buffer (Buffer_1st + 1) := ':';
+            Buffer_1st  := Buffer_1st + 2;
+            goto cont_loop1;
+         end if;
 
-      use type Interfaces.C.Strings.chars_ptr;
+         if Address (MI0) = 0 and then Address (MI0 + 1) < 16 then
+            Buffer (Buffer_1st) := To_Hex (Address (MI0 + 1))(2);
+            Buffer (Buffer_1st + 1) := ':';
+            Buffer_1st  := Buffer_1st + 2;
+            goto cont_loop1;
+         end if;
 
-      Buffer : Interfaces.C.Strings.chars_ptr
-        := Interfaces.C.Strings.New_String ((1 .. INET6_ADDRSTRLEN => 'x'));
-   begin
-      if Thin.C_Inet_Ntop
-        (Af   => Socket_Families.Families (Socket_Families.Family_Inet6),
-         Src  => Address'Address,
-         Dst  => Buffer,
-         Size => INET6_ADDRSTRLEN) = Interfaces.C.Strings.Null_Ptr
-      then
-         Interfaces.C.Strings.Free (Buffer);
-         raise Constraint_Error with "Error converting IPv6 address to string:"
-           & " " & Errno.Get_Errno_String;
+         if Address (MI0) = 0 then
+            Buffer (Buffer_1st .. Buffer_1st + 1)
+               := To_Hex (Address (MI0 + 1));
+            Buffer (Buffer_1st + 2) := ':';
+            Buffer_1st  := Buffer_1st + 3;
+            goto cont_loop1;
+         end if;
+         ----
+         if Address (MI0) < 16 and then Address (MI0 + 1) = 0 then
+            Buffer (Buffer_1st) := To_Hex (Address (MI0))(2);
+            Buffer (Buffer_1st + 3) := ':';
+            Buffer_1st  := Buffer_1st + 4;
+            goto cont_loop1;
+         end if;
+
+         if Address (MI0) < 16 and then Address (MI0 + 1) < 16 then
+            Buffer (Buffer_1st) := To_Hex (Address (MI0))(2);
+            Buffer (Buffer_1st + 2) := To_Hex (Address (MI0 + 1))(2);
+            Buffer (Buffer_1st + 3) := ':';
+            Buffer_1st  := Buffer_1st + 4;
+            goto cont_loop1;
+         end if;
+
+         if Address (MI0) < 16 then
+            Buffer (Buffer_1st) := To_Hex (Address (MI0))(2);
+            Buffer (Buffer_1st + 1 .. Buffer_1st + 2)
+               := To_Hex (Address (MI0 + 1));
+            Buffer (Buffer_1st + 3) := ':';
+            Buffer_1st  := Buffer_1st + 4;
+            goto cont_loop1;
+         end if;
+         ----
+
+         Buffer (Buffer_1st .. Buffer_1st + 1) := To_Hex (Address (MI0));
+         Buffer (Buffer_1st + 2 .. Buffer_1st + 3)
+            := To_Hex (Address (MI0 + 1));
+         Buffer (Buffer_1st + 4) := ':';
+         Buffer_1st  := Buffer_1st + 5;
+
+         <<cont_loop1>>
+
+         MI0 := MI0 + 2;
+      end loop loop1;
+
+      Qt1 := Simple_Count (Source => Buffer (1 .. Buffer_1st - 2),
+                           Pattern => ":0", contiguous => False);
+
+      if Qt1 <= 0 then
+         return Buffer (2 .. Buffer_1st - 2);
       end if;
 
-      return Result : constant String := Interfaces.C.Strings.Value (Buffer)
-      do
-         Interfaces.C.Strings.Free (Buffer);
-      end return;
+      beg3 :
+      declare
+         Counted  : Integer := 0;
+         Start    : Integer := 0;
+         End_At   : Integer := 0;
+
+         Counted_Tmp  : Integer := 0;
+         Start_Tmp    : Integer := 0;
+         End_At_Tmp   : Integer := 0;
+
+         Next         : Integer := Buffer'First;
+      begin
+         loop2 :
+         loop
+            Simple_Count  (Source   => Buffer (1 .. Buffer_1st - 2),
+                           Pattern  => ":0",
+                           From     => Next,
+                           contiguous  => True,
+                           First_Index => Start_Tmp,
+                           Last_Index   => End_At_Tmp,
+                           Counted     => Counted_Tmp
+                           );
+            if Counted_Tmp > Counted then
+               Counted  := Counted_Tmp;
+               Start    := Start_Tmp;
+               End_At   := End_At_Tmp;
+            end if;
+
+            exit loop2 when Start_Tmp <= 0;
+
+            Next := End_At_Tmp + 1;
+         end loop loop2;
+
+         if Start = 1 then
+            return "::" & Buffer (End_At + 2 .. Buffer_1st - 2);
+         end if;
+
+         return Buffer (2 .. Start)
+            & Buffer (End_At + 1 .. Buffer_1st - 2);
+
+      end beg3;
    end To_String;
 
    -------------------------------------------------------------------------
diff --git a/src/anet.ads b/src/anet.ads
index e71751e..1948d24 100644
--- a/src/anet.ads
+++ b/src/anet.ads
@@ -33,32 +33,42 @@ pragma Detect_Blocking;
 
 with Ada.Streams;
 
+pragma Elaborate_All (Ada.Streams);
+
 package Anet is
 
+   pragma Pure (Anet);
+
    type Byte is range 0 .. 255;
 
    subtype Hex_Byte_Str is String (1 .. 2);
 
-   function To_Hex (B : Byte) return String;
+   function To_Hex (B : Byte; LowerCase : Boolean := True) return String;
    --  Convert byte to hexadecimal string representation.
+   pragma Pure_Function (To_Hex);
 
    function To_Hex (Data : Ada.Streams.Stream_Element_Array) return String;
    --  Convert given stream element array to hex string.
+   pragma Pure_Function (To_Hex);
 
    function To_Byte (Str : Hex_Byte_Str) return Byte;
    --  Convert hex byte string to byte.
+   pragma Pure_Function (To_Byte);
 
    type Double_Byte is range 0 .. 2 ** 16 - 1;
 
    type Word32 is range 0 .. 2 ** 32 - 1;
 
    type Byte_Array is array (Positive range <>) of Byte;
+   pragma Preelaborable_Initialization (Byte_Array);
 
    function To_String (Bytes : Byte_Array) return String;
    --  Convert given byte array to string.
+   pragma Pure_Function (To_String);
 
    function To_Bytes (Str : String) return Byte_Array;
    --  Convert given string to byte array.
+   pragma Pure_Function (To_Bytes);
 
    subtype Port_Type is Double_Byte;
    --  Port number.
@@ -71,24 +81,29 @@ package Anet is
 
    type Hardware_Addr_Type is array (HW_Addr_Len_Type range <>) of Byte;
    --  Link-layer address.
+   pragma Preelaborable_Initialization (Hardware_Addr_Type);
 
    subtype Ether_Addr_Type is Hardware_Addr_Type (1 .. 6);
    --  Ethernet address.
 
    function To_String (Address : Hardware_Addr_Type) return String;
    --  Return string representation of a hardware address.
+   pragma Pure_Function (To_String);
 
    Bcast_HW_Addr : constant Ether_Addr_Type;
    --  ff:ff:ff:ff:ff:ff
 
    type IPv4_Addr_Type is array (1 .. 4) of Byte;
    --  IPv4 address.
+   pragma Preelaborable_Initialization (IPv4_Addr_Type);
 
    function To_IPv4_Addr (Str : String) return IPv4_Addr_Type;
    --  Return IPv4 address for given string.
+   pragma Pure_Function (To_IPv4_Addr);
 
    function To_String (Address : IPv4_Addr_Type) return String;
    --  Return string representation of an IPv4 address.
+   pragma Pure_Function (To_String);
 
    Any_Addr : constant IPv4_Addr_Type;
    --  0.0.0.0
@@ -101,12 +116,15 @@ package Anet is
 
    type IPv6_Addr_Type is array (1 .. 16) of Byte;
    --  IPv6 address.
+   pragma Preelaborable_Initialization (IPv6_Addr_Type);
 
    function To_IPv6_Addr (Str : String) return IPv6_Addr_Type;
    --  Return IPv6 address for given string.
+   pragma Pure_Function (To_IPv6_Addr);
 
    function To_String (Address : IPv6_Addr_Type) return String;
    --  Return string representation of an IPv6 address.
+   pragma Pure_Function (To_String);
 
    Any_Addr_V6 : constant IPv6_Addr_Type;
    --  IPv6 in6addr_any (::).
diff --git a/src/bsd/anet-os_constants.ads b/src/bsd/anet-os_constants.ads
index ffe7e05..53114e3 100644
--- a/src/bsd/anet-os_constants.ads
+++ b/src/bsd/anet-os_constants.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.OS_Constants is
 
+   pragma Pure (Anet.OS_Constants);
+
    IPV6_MULTICAST_IF   : constant := 9;  --  Sending interface
    IPV6_ADD_MEMBERSHIP : constant := 12; --  Join multicast group (IPv6)
 
diff --git a/src/bsd/anet-socket_families.ads b/src/bsd/anet-socket_families.ads
index 566750b..bed2b65 100644
--- a/src/bsd/anet-socket_families.ads
+++ b/src/bsd/anet-socket_families.ads
@@ -20,12 +20,17 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Interfaces.C;
+pragma Detect_Blocking;
 
+with Interfaces.C;
 with Anet.Constants;
 
+pragma Elaborate_All (Interfaces.C);
+
 package Anet.Socket_Families is
 
+   pragma Pure (Anet.Socket_Families);
+
    type Family_Type is
      (Family_Inet,
       Family_Inet6,
diff --git a/src/bsd/anet-sockets-inet-iface.adb b/src/bsd/anet-sockets-inet-iface.adb
index 89784d7..e2f8e4f 100644
--- a/src/bsd/anet-sockets-inet-iface.adb
+++ b/src/bsd/anet-sockets-inet-iface.adb
@@ -20,6 +20,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Sockets.Inet.Iface is
 
    Not_Supported : exception;
diff --git a/src/bsd/anet-sockets-thin-inet.adb b/src/bsd/anet-sockets-thin-inet.adb
index b6ba70c..3cd95e8 100644
--- a/src/bsd/anet-sockets-thin-inet.adb
+++ b/src/bsd/anet-sockets-thin-inet.adb
@@ -20,6 +20,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Byte_Swapping;
 
 package body Anet.Sockets.Thin.Inet is
diff --git a/src/bsd/anet-sockets-thin-inet.ads b/src/bsd/anet-sockets-thin-inet.ads
index 2086c23..7a0c64c 100644
--- a/src/bsd/anet-sockets-thin-inet.ads
+++ b/src/bsd/anet-sockets-thin-inet.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Inet is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Inet);
+
    package SF renames Anet.Socket_Families;
 
    subtype Family_Inet_Type is SF.Family_Type range
diff --git a/src/bsd/anet-sockets-thin-netdev-requests.ads b/src/bsd/anet-sockets-thin-netdev-requests.ads
index 8c4313f..b3f21b3 100644
--- a/src/bsd/anet-sockets-thin-netdev-requests.ads
+++ b/src/bsd/anet-sockets-thin-netdev-requests.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Netdev.Requests is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Netdev.Requests);
+
    SIOCGIFADDR   : constant := 16#c0206921#; --  Get address
    SIOCGIFFLAGS  : constant := 16#c0206911#; --  Get flags
    SIOCSIFFLAGS  : constant := 16#80206910#; --  Set flags
diff --git a/src/bsd/anet-sockets-thin-sockaddr.ads b/src/bsd/anet-sockets-thin-sockaddr.ads
index 8401deb..0f78e15 100644
--- a/src/bsd/anet-sockets-thin-sockaddr.ads
+++ b/src/bsd/anet-sockets-thin-sockaddr.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Sockaddr is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Sockaddr);
+
    type Sockaddr_Type is record
       Sa_Len    : Interfaces.C.unsigned_char := 16;
       --  Record size
diff --git a/src/bsd/anet-sockets-thin-unix.ads b/src/bsd/anet-sockets-thin-unix.ads
index 9b7303e..f0d0634 100644
--- a/src/bsd/anet-sockets-thin-unix.ads
+++ b/src/bsd/anet-sockets-thin-unix.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Unix is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Unix);
+
    UNIX_PATH_MAX : constant := 104;
 
    type Sockaddr_Un_Type is record
diff --git a/src/linux/anet-os_constants.ads b/src/linux/anet-os_constants.ads
index c649600..7685a83 100644
--- a/src/linux/anet-os_constants.ads
+++ b/src/linux/anet-os_constants.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.OS_Constants is
 
+   pragma Pure (Anet.OS_Constants);
+
    AF_NETLINK          : constant := 16;   --  Netlink family
    AF_PACKET           : constant := 17;   --  Packet family
 
diff --git a/src/linux/anet-socket_families.ads b/src/linux/anet-socket_families.ads
index 8fc8b5b..06925ed 100644
--- a/src/linux/anet-socket_families.ads
+++ b/src/linux/anet-socket_families.ads
@@ -20,13 +20,18 @@
 --  executable file might be covered by the GNU Public License.
 --
 
-with Interfaces.C;
+pragma Detect_Blocking;
 
+with Interfaces.C;
 with Anet.Constants;
 with Anet.OS_Constants;
 
+pragma Elaborate_All (Interfaces.C);
+
 package Anet.Socket_Families is
 
+   pragma Pure (Anet.Socket_Families);
+
    type Family_Type is
      (Family_Inet,
       Family_Inet6,
@@ -36,11 +41,11 @@ package Anet.Socket_Families is
    --  Address families.
 
    Families : constant array (Family_Type) of Interfaces.C.int
-     := (Family_Inet    => Constants.Sys.AF_INET,
-         Family_Inet6   => Constants.Sys.AF_INET6,
-         Family_Netlink => OS_Constants.AF_NETLINK,
-         Family_Packet  => OS_Constants.AF_PACKET,
-         Family_Unix    => Constants.AF_UNIX);
+     := (Family_Inet    => Anet.Constants.Sys.AF_INET,
+         Family_Inet6   => Anet.Constants.Sys.AF_INET6,
+         Family_Netlink => Anet.OS_Constants.AF_NETLINK,
+         Family_Packet  => Anet.OS_Constants.AF_PACKET,
+         Family_Unix    => Anet.Constants.AF_UNIX);
    --  Address family mapping.
 
 end Anet.Socket_Families;
diff --git a/src/linux/anet-sockets-inet-iface.adb b/src/linux/anet-sockets-inet-iface.adb
index 0da344f..0573885 100644
--- a/src/linux/anet-sockets-inet-iface.adb
+++ b/src/linux/anet-sockets-inet-iface.adb
@@ -20,6 +20,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package body Anet.Sockets.Inet.Iface is
 
    -------------------------------------------------------------------------
diff --git a/src/linux/anet-sockets-netlink.adb b/src/linux/anet-sockets-netlink.adb
index fe37440..25b8a1c 100644
--- a/src/linux/anet-sockets-netlink.adb
+++ b/src/linux/anet-sockets-netlink.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Errno;
 with Anet.OS_Constants;
 with Anet.Sockets.Thin.Netlink;
diff --git a/src/linux/anet-sockets-netlink.ads b/src/linux/anet-sockets-netlink.ads
index acce0d7..899eb47 100644
--- a/src/linux/anet-sockets-netlink.ads
+++ b/src/linux/anet-sockets-netlink.ads
@@ -21,8 +21,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Netlink is
 
+   pragma Preelaborate (Anet.Sockets.Netlink);
+
    subtype Netlink_Addr_Type is Natural;
    --  Netlink address.
 
@@ -52,6 +56,7 @@ package Anet.Sockets.Netlink is
 
    type Group_Array is array (Positive range <>) of Group_Type;
    --  Array of Netlink multicast groups.
+   pragma Preelaborable_Initialization (Group_Array);
 
    No_Groups : constant Group_Array;
 
diff --git a/src/linux/anet-sockets-packet.adb b/src/linux/anet-sockets-packet.adb
index cbd797d..163e22d 100644
--- a/src/linux/anet-sockets-packet.adb
+++ b/src/linux/anet-sockets-packet.adb
@@ -21,6 +21,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Errno;
 with Anet.Sockets.Net_Ifaces;
 with Anet.Sockets.Thin.Packet;
diff --git a/src/linux/anet-sockets-packet.ads b/src/linux/anet-sockets-packet.ads
index 56a921d..86c47e3 100644
--- a/src/linux/anet-sockets-packet.ads
+++ b/src/linux/anet-sockets-packet.ads
@@ -21,10 +21,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Types;
 
 package Anet.Sockets.Packet is
 
+   pragma Preelaborate (Anet.Sockets.Packet);
+
    type Protocol_Type is
      (Proto_Packet_Arp,
       Proto_Packet_Ip,
diff --git a/src/linux/anet-sockets-thin-inet.adb b/src/linux/anet-sockets-thin-inet.adb
index 25353f2..7ddb37a 100644
--- a/src/linux/anet-sockets-thin-inet.adb
+++ b/src/linux/anet-sockets-thin-inet.adb
@@ -20,6 +20,8 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.Byte_Swapping;
 with Anet.Socket_Families;
 
diff --git a/src/linux/anet-sockets-thin-inet.ads b/src/linux/anet-sockets-thin-inet.ads
index 1f5b640..6677f73 100644
--- a/src/linux/anet-sockets-thin-inet.ads
+++ b/src/linux/anet-sockets-thin-inet.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Inet is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Inet);
+
    package SF renames Anet.Socket_Families;
 
    subtype Family_Inet_Type is SF.Family_Type range
diff --git a/src/linux/anet-sockets-thin-netdev-requests.ads b/src/linux/anet-sockets-thin-netdev-requests.ads
index a27e9a0..967bd6d 100644
--- a/src/linux/anet-sockets-thin-netdev-requests.ads
+++ b/src/linux/anet-sockets-thin-netdev-requests.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Netdev.Requests is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Netdev.Requests);
+
    SIOCGIFADDR   : constant := 16#8915#; --  Get address
    SIOCGIFFLAGS  : constant := 16#8913#; --  Get flags
    SIOCSIFFLAGS  : constant := 16#8914#; --  Set flags
diff --git a/src/linux/anet-sockets-thin-netlink.ads b/src/linux/anet-sockets-thin-netlink.ads
index 5b9b2b5..c714990 100644
--- a/src/linux/anet-sockets-thin-netlink.ads
+++ b/src/linux/anet-sockets-thin-netlink.ads
@@ -20,10 +20,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.OS_Constants;
 
 package Anet.Sockets.Thin.Netlink is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Netlink);
+
    type Sockaddr_Nl_Type is record
       Nl_Family : Interfaces.C.unsigned_short := OS_Constants.AF_NETLINK;
       --  Address family (always AF_NETLINK)
diff --git a/src/linux/anet-sockets-thin-packet.ads b/src/linux/anet-sockets-thin-packet.ads
index f8fe423..576a7ba 100644
--- a/src/linux/anet-sockets-thin-packet.ads
+++ b/src/linux/anet-sockets-thin-packet.ads
@@ -20,10 +20,14 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 with Anet.OS_Constants;
 
 package Anet.Sockets.Thin.Packet is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Packet);
+
    type Sockaddr_Ll_Type is record
       Sa_Family   : Interfaces.C.unsigned_short := OS_Constants.AF_PACKET;
       --  Address family (always AF_PACKET)
diff --git a/src/linux/anet-sockets-thin-sockaddr.ads b/src/linux/anet-sockets-thin-sockaddr.ads
index 6585e91..4d2a3f3 100644
--- a/src/linux/anet-sockets-thin-sockaddr.ads
+++ b/src/linux/anet-sockets-thin-sockaddr.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Sockaddr is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Sockaddr);
+
    type Sockaddr_Type is record
       Sa_Family : Interfaces.C.unsigned_short;
       --  Address family
diff --git a/src/linux/anet-sockets-thin-unix.ads b/src/linux/anet-sockets-thin-unix.ads
index 9326c08..175ccb8 100644
--- a/src/linux/anet-sockets-thin-unix.ads
+++ b/src/linux/anet-sockets-thin-unix.ads
@@ -20,8 +20,12 @@
 --  executable file might be covered by the GNU Public License.
 --
 
+pragma Detect_Blocking;
+
 package Anet.Sockets.Thin.Unix is
 
+   pragma Preelaborate (Anet.Sockets.Thin.Unix);
+
    UNIX_PATH_MAX : constant := 108;
 
    type Sockaddr_Un_Type is record
diff --git a/tests/type_tests.adb b/tests/type_tests.adb
index c90779a..45ccc43 100644
--- a/tests/type_tests.adb
+++ b/tests/type_tests.adb
@@ -66,10 +66,10 @@ package body Type_Tests is
       Assert (Condition => To_String (Address => Addr1) = "00:00:00:00",
               Message   => "Addr1 mismatch");
       Assert (Condition => To_String (Address => Addr2) =
-                "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF",
+                "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff",
               Message   => "Addr2 mismatch");
       Assert (Condition => To_String (Address => Addr3) =
-                "DE:AD:BE:EF:CA:FE",
+                "de:ad:be:ef:ca:fe",
               Message   => "Addr3 mismatch");
    end HW_Addr_To_String;
 
@@ -155,7 +155,7 @@ package body Type_Tests is
         := (16#12#, 16#ca#, 16#8f#, 16#9c#, 16#05#);
       A2 : constant Stream_Element_Array (1 .. 0) := (others => <>);
    begin
-      Assert (Condition => To_Hex (Data => A1) = "12CA8F9C05",
+      Assert (Condition => To_Hex (Data => A1) = "12ca8f9c05",
               Message   => "Hex string mismatch");
       Assert (Condition => To_Hex (Data => A2) = "",
               Message   => "Empty string expected");
diff --git a/tests/util_tests.adb b/tests/util_tests.adb
index 7a43b1c..63fda2c 100644
--- a/tests/util_tests.adb
+++ b/tests/util_tests.adb
@@ -25,11 +25,14 @@ with Ada.Streams;
 
 with Anet.Util;
 
+with Anet.Util_Pure;
+
 package body Util_Tests is
 
    use Ada.Streams;
    use Ahven;
    use Anet.Util;
+   use Anet.Util_Pure;
 
    -------------------------------------------------------------------------
 

Reply to: