From 5d27abfa7096a638892d40b381366cdad26b6382 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 21 Nov 2023 22:01:15 +0100 Subject: wip --- ip/ip.pl | 65 +++++++++++++++++++++++++++++++++++++++++------------------ ip/ip_test.pl | 33 ++++++++++++++++++------------ 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/ip/ip.pl b/ip/ip.pl index ba37602..259ecf9 100644 --- a/ip/ip.pl +++ b/ip/ip.pl @@ -5,23 +5,28 @@ :- use_module(library(charsio)). :- use_module(library(serialization/abnf)). -make_ip4(A, B, C, D, ip4(A, B, C, D, Addr)) :- - Addr #= (A * 2^24 + B * 2^16 + C * 2^8 + D). +big(A, B, C) :- C #= A^B. -ip4(A, B, C, D, Addr) :- - A in 0..255, - B in 0..255, - C in 0..255, - D in 0..255, - Addr #= (A * 2^24 + B * 2^16 + C * 2^8 + D). +make_ip4(A, B, C, D, Addr) :- + A #>= 0, A #=< 255, + B #>= 0, B #=< 255, + C #>= 0, C #=< 255, + D #>= 0, D #=< 255, + Addr #= ((A * 2^24) + (B * 2^16) + (C * 2^8) + D), + ip4(Addr). -ip4_range(ip4(_, _, _, _), Range) :- +ip4(Addr) :- Addr >= 0, Addr < 2^32. + +ip4_range(Addr, Range) :- + ip4(Addr), Range in 0..32. -ip_format(ip4(A, B, C, D, _), Str) :- +ip_format(ip4(Addr), Str) :- + make_ip4(A, B, C, D, Addr), phrase(format_("~w.~w.~w.~w", [A, B, C, D]), Str). -ip_format(ip4_range(ip4(A, B, C, D, _), Range), Str) :- +ip_format(ip4_range(Addr, Range), Str) :- + make_ip4(A, B, C, D, Addr), phrase(format_("~w.~w.~w.~w/~w", [A, B, C, D, Range]), Str). hexd(D) --> abnf_hexdig(D). @@ -48,14 +53,31 @@ ip4_range_syntax(A, B, C, D, R) --> ip4_syntax(A, B, C, D), "/", int_(R), { R >= 0, R =< 32 }. -ip4_parse(Str, Obj) :- +ip4_parse(Str, Ip) :- phrase(ip4_syntax(A, B, C, D), Str), - Obj = ip4(A, B, C, D). + make_ip4(A, B, C, D, Addr), + Ip = ip4(Addr). -ip4_range_parse(Str, Obj) :- +ip4_range_parse(Str, IpR) :- phrase(ip4_range_syntax(A, B, C, D, Range), Str), - make_ip4(A, B, C, D, Ip), - Obj = ip4_range(Ip, Range). + make_ip4(A, B, C, D, Addr), + IpR = ip4_range(Addr, Range). + +make_ip6(A, B, C, D, E, F, G, H, Addr) :- + A #>= 0, A #=< 65335, + B #>= 0, B #=< 65335, + C #>= 0, C #=< 65335, + D #>= 0, D #=< 65335, + E #>= 0, E #=< 65335, + F #>= 0, F #=< 65335, + G #>= 0, G #=< 65335, + H #>= 0, H #=< 65335, + Addr #= + (A * 2^56) + (B * 2^48) + (C * 2^40) + (D * 2^32) + + (E * 2^24) + (F * 2^16) + (G * 2^8) + H, + ip6(Addr). + +ip6(Addr) :- Addr >= 0, Addr < 2^128. ip6_syntax(A, B, C, D, E, F, G, H) --> ip6_num(A), ":", @@ -68,19 +90,22 @@ ip6_syntax(A, B, C, D, E, F, G, H) --> ip6_num(H). ip6_num(D) --> xint_(D), { D >= 0, D =< 65535 }. -ip6_parse(Str, Obj) :- +ip6_parse(Str, Ip) :- phrase(ip6_syntax(A, B, C, D, E, F, G, H), Str), - Obj = ip6(A, B, C, D, E, F, G, H). + make_ip6(A, B, C, D, E, F, G, H, Addr), + Ip = ip6(Addr). ip_parse(Str, Obj) :- ( phrase(ip4_syntax(A, B, C, D), Str) - -> Obj = ip4(A, B, C, D) + -> make_ip4(A, B, C, D, Addr), + Obj = ip4(Addr) ; ( phrase(ip4_range_syntax(A, B, C, D, R), Str) -> make_ip4(A, B, C, D, Ip), Obj = ip4_range(Ip, R) ; phrase(ip6_syntax(A, B, C, D, E, F, G, H), Str), - Obj = ip6(A, B, C, D, E, F, G, H) + make_ip6(A, B, C, D, E, F, G, H, Addr), + Obj = ip6(Addr) ) ). diff --git a/ip/ip_test.pl b/ip/ip_test.pl index 39a0abb..b2812f6 100644 --- a/ip/ip_test.pl +++ b/ip/ip_test.pl @@ -4,56 +4,63 @@ :- use_module(library(format)). test("ip4", ( - ip4(127, 0, 0, 1, A), - A =:= (127 * 2**24 + 1) + make_ip4(127, 0, 0, 1, Addr), + Addr =:= 127*2^24 + 1 )). test("ip_format", ( - ip_format(ip4(127, 0, 0, 1, _), Str), + make_ip4(127, 0, 0, 1, Addr), + ip_format(ip4(Addr), Str), Str == "127.0.0.1" )). test("ip_format #2", ( - Ip = ip4_range(ip4(192, 168, 0, 0, _), 24), + make_ip4(192, 168, 0, 0, Addr), + Ip = ip4_range(Addr, 24), ip_format(Ip, Str), Str == "192.168.0.0/24" )). test("ip4_parse #1", ( + make_ip4(1, 2, 3, 4, Addr), ip4_parse("1.2.3.4", Ip), - Ip == ip4(1, 2, 3, 4) + Ip == ip4(Addr) )). test("ip4_range_parse", ( + make_ip4(1, 2, 3, 4, Addr), ip4_range_parse("1.2.3.4/24", Ip), - A #= 2^24 + 2 * 2^16 + 3 * 2^8 + 4, - Ip == ip4_range(ip4(1, 2, 3, 4, A), 24) + Ip == ip4_range(Addr, 24) )). test("ip6_parse", ( + make_ip6(1, 2, 3, 4, 5, 6, 10, 11, Addr), ip6_parse("1:2:3:4:5:6:a:b", Ip), - Ip == ip6(1, 2, 3, 4, 5, 6, 10, 11) + Ip == ip6(Addr) )). test("ip6_parse #2", ( + make_ip6(0, 2, 3, 4, 5, 6, 10, 11, Addr), ip6_parse("0:2:3:4:5:6:a:b", Ip), - Ip == ip6(0, 2, 3, 4, 5, 6, 10, 11) + Ip == ip6(Addr) )). test("ip_parse #1", ( + make_ip4(127, 0, 0, 1, Addr), ip_parse("127.0.0.1", Ip), - Ip == ip4(127, 0, 0, 1) + Ip == ip4(Addr) )). test("ip_parse #2", ( ip_parse("192.168.10.4/24", R), - make_ip4(192, 168, 10, 4, Ip), - R == ip4_range(Ip, 24) + make_ip4(192, 168, 10, 4, Addr), + R == ip4_range(Addr, 24) )). test("ip_parse #3", ( + make_ip6(0, 2, 3, 4, 5, 6, 10, 11, Addr), ip_parse("0:2:3:4:5:6:a:b", Ip), - Ip == ip6(0, 2, 3, 4, 5, 6, 10, 11) + Ip == ip6(Addr) )). main :- -- cgit v1.2.3