diff options
-rw-r--r-- | ip.pl | 67 |
1 files changed, 47 insertions, 20 deletions
@@ -3,14 +3,17 @@ :- use_module(library(clpfd)). :- use_module(library(dcg/basics)). -ip4(A, B, C, D, Addr) :- +make_ip4(A, B, C, D, ip4(A, B, C, D, Addr)) :- + Addr #= (A * 2^24 + B * 2^16 + C * 2^8 + D). + +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). -ip4_range(ip4(_, _, _, _), Range) :- +ip4_range(ip4(_, _, _, _), Range) :- Range in 0..32. ip_format(ip4(A, B, C, D, _), Str) :- @@ -19,37 +22,51 @@ ip_format(ip4(A, B, C, D, _), Str) :- ip_format(ip4_range(ip4(A, B, C, D, _), Range), Str) :- format(string(Str), "~w.~w.~w.~w/~w", [A, B, C, D, Range]). -ip4_g(A, B, C, D) --> ip4_num(A), ".", ip4_num(B), ".", ip4_num(C), ".", ip4_num(D). ip4_num(D) --> integer(D), { D >= 0, D =< 255 }. +ip4_syntax(A, B, C, D) --> ip4_num(A), ".", ip4_num(B), ".", ip4_num(C), ".", ip4_num(D). +ip4_range_syntax(A, B, C, D, R) --> + ip4_syntax(A, B, C, D), "/", number(R), + { R >= 0, R =< 32 }. ip4_parse(Str, Obj) :- string_codes(Str, Codes), - phrase(ip4_g(A, B, C, D), Codes), + phrase(ip4_syntax(A, B, C, D), Codes), Obj = ip4(A, B, C, D). -ip6_g(A, B, C, D, E, F, G, H) --> - ip6_num(A), ":", - ip6_num(B), ":", - ip6_num(C), ":", - ip6_num(D), ":", - ip6_num(E), ":", - ip6_num(F), ":", - ip6_num(G), ":", +ip4_range_parse(Str, Obj) :- + string_codes(Str, Codes), + phrase(ip4_range_syntax(A, B, C, D, Range), Codes), + make_ip4(A, B, C, D, Ip), + Obj = ip4_range(Ip, Range). + +ip6_syntax(A, B, C, D, E, F, G, H) --> + ip6_num(A), ":", + ip6_num(B), ":", + ip6_num(C), ":", + ip6_num(D), ":", + ip6_num(E), ":", + ip6_num(F), ":", + ip6_num(G), ":", ip6_num(H). ip6_num(D) --> xinteger(D), { D >= 0, D =< 65535 }. ip6_parse(Str, Obj) :- string_codes(Str, Codes), - phrase(ip6_g(A, B, C, D, E, F, G, H), Codes), + phrase(ip6_syntax(A, B, C, D, E, F, G, H), Codes), Obj = ip6(A, B, C, D, E, F, G, H). ip_parse(Str, Obj) :- string_codes(Str, Codes), ( - phrase(ip4_g(A, B, C, D), Codes) + phrase(ip4_syntax(A, B, C, D), Codes) -> Obj = ip4(A, B, C, D) - ; phrase(ip6_g(A, B, C, D, E, F, G, H), Codes), - Obj = ip6(A, B, C, D, E, F, G, H) + ; ( + phrase(ip4_range_syntax(A, B, C, D, R), Codes) + -> make_ip4(A, B, C, D, Ip), + Obj = ip4_range(Ip, R) + ; phrase(ip6_syntax(A, B, C, D, E, F, G, H), Codes), + Obj = ip6(A, B, C, D, E, F, G, H) + ) ). :- begin_tests(lists). @@ -72,6 +89,11 @@ test(ip4_parse) :- ip4_parse("1.2.3.4", Ip), assertion(Ip == ip4(1, 2, 3, 4)). +test(ip4_range_parse) :- + ip4_range_parse("1.2.3.4/24", Ip), + A #= 2^24 + 2 * 2^16 + 3 * 2^8 + 4, + assertion(Ip == ip4_range(ip4(1, 2, 3, 4, A), 24)). + test(ip6_parse) :- ip6_parse("1:2:3:4:5:6:a:b", Ip), assertion(Ip == ip6(1, 2, 3, 4, 5, 6, 10, 11)). @@ -81,11 +103,16 @@ test(ip6_parse) :- assertion(Ip == ip6(0, 2, 3, 4, 5, 6, 10, 11)). test(ip_parse) :- - ip_parse("0:2:3:4:5:6:a:b", Ip), - assertion(Ip == ip6(0, 2, 3, 4, 5, 6, 10, 11)). - -test(ip_parse) :- ip_parse("127.0.0.1", Ip), assertion(Ip == ip4(127, 0, 0, 1)). +test(ip_parse) :- + ip_parse("192.168.10.4/24", R), + make_ip4(192, 168, 10, 4, Ip), + assertion(R == ip4_range(Ip, 24)). + +test(ip_parse) :- + ip_parse("0:2:3:4:5:6:a:b", Ip), + assertion(Ip == ip6(0, 2, 3, 4, 5, 6, 10, 11)). + :- end_tests(lists). |