File 3351-Add-IP-checking-functions.patch of Package erlang

From a6d6a63af979ebafb95a716375e7300af94dd9f9 Mon Sep 17 00:00:00 2001
From: Maria Scott <maria-12648430@hnc-agency.org>
Date: Fri, 11 Feb 2022 14:42:43 +0100
Subject: [PATCH] Add IP checking functions

---
 lib/kernel/doc/src/inet.xml    | 30 +++++++++++++++++
 lib/kernel/src/inet.erl        | 22 ++++++++++++-
 lib/kernel/test/inet_SUITE.erl | 60 +++++++++++++++++++++++++++++++++-
 3 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index e1edf3e657..81b9ca8301 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -782,6 +782,36 @@ get_tcpi_sacked(Sock) ->
       </desc>
     </func>
 
+    <func>
+      <name name="is_ip_address" arity="1" since="OTP 25.0"/>
+      <fsummary>Tests if <c>IPAddress</c> is an IPv4 or IPv6 address tuple.</fsummary>
+      <desc>
+        <p>Tests if <c>IPAddress</c> is an
+          <seetype marker="#ip_address"><c>ip_address()</c></seetype>
+          and returns <c>true</c> if so, otherwise <c>false</c>.</p>
+      </desc>
+    </func>
+
+    <func>
+      <name name="is_ipv4_address" arity="1" since="OTP 25.0"/>
+      <fsummary>Tests if <c>IPAddress</c> is an IPv4 address tuple.</fsummary>
+      <desc>
+        <p>Tests if <c>IPAddress</c> is an
+          <seetype marker="#ip4_address"><c>ip4_address()</c></seetype>
+          and returns <c>true</c> if so, otherwise <c>false</c>.</p>
+      </desc>
+    </func>
+
+    <func>
+      <name name="is_ipv6_address" arity="1" since="OTP 25.0"/>
+      <fsummary>Tests if <c>IPAddress</c> is an IPv6 address tuple.</fsummary>
+      <desc>
+        <p>Tests if <c>IPAddress</c> is an
+          <seetype marker="#ip6_address"><c>ip6_address()</c></seetype>
+          and returns <c>true</c> if so, otherwise <c>false</c>.</p>
+      </desc>
+    </func>
+
     <func>
       <name name="ntoa" arity="1"  since="OTP R16B02"/>
       <fsummary>Convert IPv6/IPV4 address to ASCII.</fsummary>
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 731329bf05..f0d06e3861 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -32,7 +32,8 @@
 	 ifget/3, ifget/2, ifset/3, ifset/2,
 	 getstat/1, getstat/2,
          info/1, socket_to_list/1,
-	 ip/1, stats/0, options/0, 
+	 ip/1, is_ipv4_address/1, is_ipv6_address/1, is_ip_address/1,
+	 stats/0, options/0, 
 	 pushf/3, popf/1, close/1, gethostname/0, gethostname/1, 
 	 parse_ipv4_address/1, parse_ipv6_address/1, parse_ipv4strict_address/1,
 	 parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1,
@@ -754,6 +755,25 @@ ip(Name) ->
 	Error -> Error
     end.
 
+-spec is_ipv4_address(IPv4Address) -> boolean() when
+      IPv4Address :: ip4_address() | term().
+is_ipv4_address({A,B,C,D}) when ?ip(A,B,C,D) ->
+    true;
+is_ipv4_address(_) ->
+    false.
+
+-spec is_ipv6_address(IPv6Address) -> boolean() when
+      IPv6Address :: ip6_address() | term().
+is_ipv6_address({A,B,C,D,E,F,G,H}) when ?ip6(A,B,C,D,E,F,G,H) ->
+    true;
+is_ipv6_address(_) ->
+    false.
+
+-spec is_ip_address(IPAddress) -> boolean() when
+      IPAddress :: ip_address() | term().
+is_ip_address(Address) ->
+    is_ipv4_address(Address) orelse is_ipv6_address(Address).
+
 %% This function returns the erlang port used (with inet_drv)
 
 -spec getll(Socket :: socket()) -> {'ok', socket()}.
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index 5b92087ebc..ef66f3b257 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -47,6 +47,7 @@
 	 lookup_bad_search_option/1,
 	 getif/1,
 	 getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1,
+	 is_ip_address/1,
 	 parse_strict_address/1, ipv4_mapped_ipv6_address/1, ntoa/1,
          simple_netns/1, simple_netns_open/1,
          add_del_host/1, add_del_host_v6/1,
@@ -71,7 +72,7 @@ all() ->
     [
      t_gethostbyaddr, t_gethostbyname, t_getaddr,
      t_gethostbyaddr_v6, t_gethostbyname_v6, t_getaddr_v6,
-     ipv4_to_ipv6, host_and_addr, {group, parse},
+     ipv4_to_ipv6, host_and_addr, is_ip_address, {group, parse},
      t_gethostnative, gethostnative_parallell, cname_loop,
      missing_hosts_reload, hosts_file_quirks,
      gethostnative_debug_level, gethostnative_soft_restart,
@@ -816,6 +817,63 @@ parse_strict_address(Config) when is_list(Config) ->
     {ok, {3089,3106,23603,50240,0,0,119,136}} =
 	inet:parse_strict_address("c11:0c22:5c33:c440::077:0088").
 
+is_ip_address(Config) when is_list(Config) ->
+    IPv4Addresses = [
+        {0, 0, 0, 0},
+        {255, 255, 255, 255}
+    ],
+    IPv6Addresses = [
+        {0, 0, 0, 0, 0, 0, 0, 0},
+        {16#ffff, 16#ffff, 16#ffff, 16#ffff, 16#ffff, 16#ffff, 16#ffff, 16#ffff}
+    ],
+    NonIPAddresses = [
+        foo,
+        "0.0.0.0",
+        {},
+        {0},
+        {0, 0},
+        {0, 0, 0},
+        {0, 0, 0, 0, 0},
+        {0, 0, 0, 0, 0, 0},
+        {0, 0, 0, 0, 0, 0, 0},
+        {0, 0, 0, 0, 0, 0, 0, 0, 0},
+        {0, 0, 0, foo},
+        {0, 0, 0, 0, 0, 0, 0, foo},
+        {0, 0, 0, 256},
+        {0, 0, 256, 0},
+        {0, 256, 0, 0},
+        {256, 0, 0, 0},
+        {0, 0, 0, 0, 0, 0, 0, 16#10000},
+        {0, 0, 0, 0, 0, 0, 16#10000, 0},
+        {0, 0, 0, 0, 0, 16#10000, 0, 0},
+        {0, 0, 0, 0, 16#10000, 0, 0, 0},
+        {0, 0, 0, 16#10000, 0, 0, 0, 0},
+        {0, 0, 16#10000, 0, 0, 0, 0, 0},
+        {0, 16#10000, 0, 0, 0, 0, 0, 0},
+        {16#10000, 0, 0, 0, 0, 0, 0, 0},
+        {0, 0, 0, -1},
+        {0, 0, -1, 0},
+        {0, -1, 0, 0},
+        {-1, 0, 0, 0},
+        {0, 0, 0, 0, 0, 0, 0, -1},
+        {0, 0, 0, 0, 0, 0, -1, 0},
+        {0, 0, 0, 0, 0, -1, 0, 0},
+        {0, 0, 0, 0, -1, 0, 0, 0},
+        {0, 0, 0, -1, 0, 0, 0, 0},
+        {0, 0, -1, 0, 0, 0, 0, 0},
+        {0, -1, 0, 0, 0, 0, 0, 0},
+        {-1, 0, 0, 0, 0, 0, 0, 0}
+    ],
+
+    true = lists:all(fun inet:is_ipv4_address/1, IPv4Addresses),
+    false = lists:any(fun inet:is_ipv4_address/1, IPv6Addresses ++ NonIPAddresses),
+
+    true = lists:all(fun inet:is_ipv6_address/1, IPv6Addresses),
+    false = lists:any(fun inet:is_ipv6_address/1, IPv4Addresses ++ NonIPAddresses),
+
+    true = lists:all(fun inet:is_ip_address/1, IPv6Addresses ++ IPv4Addresses),
+    false = lists:any(fun inet:is_ip_address/1, NonIPAddresses).
+
 ipv4_mapped_ipv6_address(Config) when is_list(Config) ->
     {D1,D2,D3,D4} = IPv4Address =
         {rand:uniform(256) - 1,
-- 
2.34.1

openSUSE Build Service is sponsored by