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

(LibAnet Patch) this patch add shorten IPv6 string representation.



  Hi!

  Attached patch to add support for shorten ipv6 string in LibAnet.
 
  Thanks!
--
"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:-)
commit a07c76488a37eec384415c3d229f7b04f7a0b885
Author: Daniel Norte de Moraes <danielcheagle@gmail.com>
Date:   Fri Sep 15 12:48:32 2017 -0300

            added shorten ipv6 string representation. :-) Enjoy!!! Thanks God and Mary and Cia!!!!! Enjoy!!!

diff --git a/src/anet.adb b/src/anet.adb
index ff7ef90..e3624cf 100644
--- a/src/anet.adb
+++ b/src/anet.adb
@@ -23,6 +23,10 @@
 
 with Ada.Strings.Fixed;
 with Ada.Strings.Unbounded;
+with Interfaces.C.Strings;
+with System;
+with Anet.Socket_Families;
+with Anet.Errno;
 
 package body Anet is
 
@@ -134,52 +138,44 @@ package body Anet is
 
    function To_IPv6_Addr (Str : String) return IPv6_Addr_Type
    is
-   begin
-      if Str = "" then
-         raise Constraint_Error with "Unable to convert empty string to IP";
-      end if;
+      use Anet.Socket_Families;
+      use Anet.Errno;
+      use Interfaces.C;
+      use System;
+      use Interfaces.C.Strings;
 
-      if Ada.Strings.Fixed.Count (Source  => Str,
-                                  Pattern => ":") /= 7
-      then
-         raise Constraint_Error with
-           "Valid IPv6 address string must contain 7 colons";
-      end if;
+      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");
 
-      declare
-         Result   : IPv6_Addr_Type;
-         Left_Idx : Natural := Str'First;
-         Dot_Idx  : Natural := Str'First;
-      begin
-         for I in IPv6_Addr_Type'First .. IPv6_Addr_Type'Length / 2 loop
-            Dot_Idx := Ada.Strings.Fixed.Index
-              (From    => Left_Idx,
-               Source  => Str,
-               Pattern => ":");
-
-            --  Check if we reached the end of the string.
-
-            if Dot_Idx = 0 then
-               Dot_Idx := Str'Last + 1;
-            end if;
+      Src_Orig : Interfaces.C.Strings.chars_ptr
+         := Interfaces.C.Strings.New_String (Str);
 
-            Result (I * 2 - 1) := To_Byte (Str (Left_Idx .. Left_Idx + 1));
-            Result (I * 2)     := To_Byte
-              (Str (Left_Idx + 2 .. Left_Idx + 3));
+      Result : IPv6_Addr_Type := (others => 0);
+      erro : Interfaces.C.int := 0;
 
-            Left_Idx := Dot_Idx + 1;
-            Dot_Idx  := Left_Idx;
-         end loop;
+   begin
+      if Str = "" then
+         Free (Src_Orig);
+         raise Constraint_Error with "Unable to convert empty string to IP";
+      end if;
+      erro := c_inet_pton (af => Families (Family_Inet6),
+                           src => Src_Orig,
+                           dst => Result'Address);
+      Free (Src_Orig);
 
+      if erro = 1 then
          return Result;
+      elsif erro = 0 then
+         raise Constraint_Error with "Invalid IP";
+      elsif erro = -1 then
+         raise Constraint_Error with " " & Get_Errno_String;
+      end if;
+      raise Constraint_Error with "Unknown Errno " & Get_Errno_String;
 
-      exception
-         when others =>
-            raise Constraint_Error with "Invalid octet: "
-              & Str (Left_Idx .. Dot_Idx);
-      end;
    end To_IPv6_Addr;
-
    -------------------------------------------------------------------------
 
    function To_String (Bytes : Byte_Array) return String
@@ -288,4 +284,41 @@ package body Anet is
       return Buffer (1 .. Length - 1);
    end To_String;
 
+   -------------------------------------------------------------------------
+
+   function To_String_Shorten (Address : IPv6_Addr_Type) return String
+   is
+      use Anet.Socket_Families;
+      use Anet.Errno;
+      use Interfaces.C;
+      use System;
+      use Interfaces.C.Strings;
+
+      function c_inet_ntop (af : Interfaces.C.int;
+                           src : System.Address;
+                           dst : Interfaces.C.Strings.chars_ptr;
+                           size : Interfaces.C.unsigned_long
+                           ) return Interfaces.C.Strings.chars_ptr;
+      pragma Import (c, c_inet_ntop, "inet_ntop");
+
+      tmp_string : constant String (1 .. 47) := (others => 'L');
+      Result_Tmp : Interfaces.C.Strings.chars_ptr
+         := New_String (tmp_string);
+   begin
+      if c_inet_ntop (af => Families (Family_Inet6),
+                           src => Address'Address,
+                           dst => Result_Tmp,
+                           size => 46) /= Interfaces.C.Strings.Null_Ptr
+      then
+         declare
+            Result : constant String := Value (Result_Tmp);
+         begin
+            Free (Result_Tmp);
+            return Result;
+         end;
+      end if;
+      Free (Result_Tmp);
+      raise Constraint_Error with " unknown Errno" & Get_Errno_String;
+   end To_String_Shorten;
+
 end Anet;
diff --git a/src/anet.ads b/src/anet.ads
index 41aca8b..d19ef27 100644
--- a/src/anet.ads
+++ b/src/anet.ads
@@ -104,6 +104,9 @@ package Anet is
    function To_String (Address : IPv6_Addr_Type) return String;
    --  Return string representation of an IPv6 address.
 
+   function To_String_Shorten (Address : IPv6_Addr_Type) return String;
+   --  Return shorten string representation of an IPv6 address.
+
    Any_Addr_V6 : constant IPv6_Addr_Type;
    --  IPv6 in6addr_any (::).
 
diff --git a/tests/type_tests.adb b/tests/type_tests.adb
index 997b435..a97b1a1 100644
--- a/tests/type_tests.adb
+++ b/tests/type_tests.adb
@@ -145,6 +145,15 @@ package body Type_Tests is
       Assert (Condition => To_String (Address => Addr3)
               = "FF02:0000:0000:0000:0000:0000:0001:0002",
               Message   => "Addr3 mismatch");
+      Assert (Condition => To_String_Shorten (Address => Addr1)
+             = "::",
+             Message   => "Addr1 shorten mismatch");
+      Assert (Condition => To_String_Shorten (Address => Addr2)
+             = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+             Message   => "Addr2 shorten mismatch");
+      Assert (Condition => To_String_Shorten (Address => Addr3)
+             = "ff02::1:2",
+             Message   => "Addr3 shorten mismatch");
    end IPv6_Addr_To_String;
 
    -------------------------------------------------------------------------

Reply to: