Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow more input after embedded IPv4 in V6 range #65

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions Data/IP/Addr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -554,37 +554,43 @@
return $ bs1 ++ spring ++ bs2

ip6 :: Parser IPv6
ip6 = skipSpaces >> toIPv6 <$> ip6'

ip6' :: Parser [Int]
ip6' = ip4Embedded
<|> do colon2
bs <- option [] hexcolon
format [] bs
<|> try (do rs <- hexcolon
check rs
return rs)
<|> do bs1 <- hexcolon2
bs2 <- option [] hexcolon
format bs1 bs2
ip6 = ip6' True

ip6' :: Bool -> Parser IPv6
ip6' checkTermination = skipSpaces >> toIPv6 <$> ip6arr
where
hexcolon = hex `sepBy1` char ':'
hexcolon2 = manyTill (hex <* char ':') (char ':')
check bs = when (length bs /= 8) (fail "IPv6 address4")
ip6arr = ip4Embedded' checkTermination
<|> do colon2
bs <- option [] hexcolon
format [] bs
<|> try (do rs <- hexcolon
check rs
return rs)
<|> do bs1 <- hexcolon2
bs2 <- option [] hexcolon
format bs1 bs2
where
hexcolon = hex `sepBy1` char ':'
hexcolon2 = manyTill (hex <* char ':') (char ':')
check bs = when (length bs /= 8) (fail "IPv6 address4")

ip4Embedded :: Parser [Int]
ip4Embedded = try (do colon2
ip4Embedded = ip4Embedded' True

ip4Embedded' :: Bool -> Parser [Int]
ip4Embedded' checkTermination =
try (do colon2
bs <- beforeEmbedded
embedded <- ip4' True
embedded <- ip4' checkTermination
format [] (bs ++ ip4ToIp6 embedded))
-- matches 2001:db8::192.0.2.1
<|> try (do bs1 <- manyTill (try $ hex <* char ':') (char ':')
bs2 <- option [] beforeEmbedded
embedded <- ip4' True
embedded <- ip4' checkTermination
format bs1 (bs2 ++ ip4ToIp6 embedded))
-- matches 2001:db8:11e:c00:aa:bb:192.0.2.1
<|> try (do bs <- beforeEmbedded
embedded <- ip4' True
embedded <- ip4' checkTermination
let rs = bs ++ ip4ToIp6 embedded
check rs
return rs)
Expand Down Expand Up @@ -632,7 +638,7 @@
ipv4ToIPv6 :: IPv4 -> IPv6
ipv4ToIPv6 ip = toIPv6b [0,0,0,0,0,0,0,0,0,0,0xff,0xff,i1,i2,i3,i4]
where
[i1,i2,i3,i4] = fromIPv4 ip

Check warning on line 641 in Data/IP/Addr.hs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 9.2)

Pattern match(es) are non-exhaustive

Check warning on line 641 in Data/IP/Addr.hs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 9.2)

Pattern match(es) are non-exhaustive

Check warning on line 641 in Data/IP/Addr.hs

View workflow job for this annotation

GitHub Actions / build (macOS-latest, 9.2)

Pattern match(es) are non-exhaustive

Check warning on line 641 in Data/IP/Addr.hs

View workflow job for this annotation

GitHub Actions / build (windows-latest, 9.2)

Pattern match(es) are non-exhaustive

-- | Convert 'SockAddr' to 'IP'.
--
Expand Down
2 changes: 1 addition & 1 deletion Data/IP/Range.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ IP4 a `maskedIPv4` IP4 m = IP4 (a .&. m)

ip6range :: Parser (AddrRange IPv6)
ip6range = do
ip <- ip6
ip <- ip6' False
len <- maskLen 128
let msk = maskIPv6 len
adr = ip `maskedIPv6` msk
Expand Down
3 changes: 3 additions & 0 deletions test/IPSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module IPSpec where
import Control.Applicative
#endif
import Data.IP
import Data.Maybe (isJust)
import Safe (readMay)
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
Expand Down Expand Up @@ -71,6 +72,8 @@ spec = do
(readMay " ::1" :: Maybe IPv4) `shouldBe` readMay "::1"
it "does not read overflow mask lengths" $ do
(readMay "192.168.0.1/18446744073709551648" :: Maybe (AddrRange IPv4)) `shouldBe` Nothing
it "can read embedded v4 in v6 range" $ do
(readMay "::ffff:192.0.2.0/120" :: Maybe (AddrRange IPv6)) `shouldSatisfy` isJust

to_str_ipv4 :: AddrRange IPv4 -> Bool
to_str_ipv4 a = readMay (show a) == Just a
Expand Down
Loading