81 lines
3.2 KiB
Text
81 lines
3.2 KiB
Text
link printf, hexcvt
|
|
|
|
procedure main()
|
|
L := ["192.168.0.1", # private
|
|
"127.0.0.1", # loop back
|
|
"127.0.0.1:80", # loop back +port
|
|
"2001:db8:85a3:0:0:8a2e:370:7334", # doc, IPv6 for 555-1234
|
|
"2001:db8:85a3::8a2e:370:7334", # doc
|
|
"::1", # loop back
|
|
"[::1]:80", # loop back +port
|
|
"::", # unspecified
|
|
"::ffff:192.168.0.1", # transition
|
|
"2605:2700:0:3::4713:93e3", # RC
|
|
"[2605:2700:0:3::4713:93e3]:80", # RC
|
|
"::ffff:71.19.147.227", # RC transition
|
|
"[::ffff:71.19.147.227]:80", # RC transition +port
|
|
"[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443", # doc +port
|
|
"256.0.0.0", # invalid
|
|
"g::1"] # invalid
|
|
|
|
every x := !L do {
|
|
if x ? (ip := ipmatch(), port := portmatch(), pos(0)) then {
|
|
if i := IPv4decode(ip) then
|
|
printf("%s is the IPv4 address = x'%s'",x,i)
|
|
else if i := IPv6decode(ip) then
|
|
printf("%s is the IPv6 address = x'%s'",x,i)
|
|
else {
|
|
printf("%s is not a valid IP address\n",x)
|
|
next
|
|
}
|
|
if \port then printf(" port=%s\n",port) else printf("\n")
|
|
}
|
|
else printf("%s is not an IP address\n",x)
|
|
}
|
|
end
|
|
|
|
|
|
procedure ipmatch() #: match an ip v4/v6 address
|
|
static c4,c6
|
|
initial {
|
|
c4 := &digits ++ '.'
|
|
c6 := &digits ++ 'abcdef:'
|
|
}
|
|
suspend (="[" || ( (="::ffff:" || tab(many(c4))) | tab(many(c6)) ) || ="]") |
|
|
( ="::ffff:" || tab(many(c4))) | tab(many(c6|c4))
|
|
end
|
|
|
|
procedure portmatch() #: match a port number
|
|
return (=":",0 < (65536 > tab(many(&digits)))) | &null
|
|
end
|
|
|
|
procedure IPv4decode(s) #: match IPv4 to hex string
|
|
s ? ( ip := (0 <= (256 > tab(many(&digits)))), ip *:= 256, =".",
|
|
ip +:= (0 <= (256 > tab(many(&digits)))), ip *:= 256, =".",
|
|
ip +:= (0 <= (256 > tab(many(&digits)))), ip *:= 256, =".",
|
|
ip +:= (0 <= (256 > tab(many(&digits)))),
|
|
return right(hexstring(ip,,&lcase),8) )
|
|
end
|
|
|
|
procedure IPv6decode(s) #: IPv6 to hex string
|
|
s ?:= 2(="[", tab(-1), ="]") # remove any []
|
|
if find(".",s) then # transitional
|
|
s ? ( tab(many(':0')), ="ffff:",
|
|
return right("ffff" || IPv4decode(tab(0)),32,"0") )
|
|
else {
|
|
h := t := ""
|
|
s ? {
|
|
while x := tab(find(":")) do { # head
|
|
if *x <= 4 then h ||:= right(x,4,"0")
|
|
if ="::" then break
|
|
else move(1)
|
|
}
|
|
while x := tab(find(":")|0) do { # tail
|
|
if *x <= 4 then t ||:= right(x,4,"0")
|
|
move(1) | break
|
|
}
|
|
if x := h || repl("0",32-(*h+*t)) || t then # and insides
|
|
return x
|
|
}
|
|
}
|
|
end
|