(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: