Juraj
Juraj

Reputation: 870

Parsing IPv6 address

I need to convert IPv6 from string like "fe80::dd99:5d56:cf09:b1ef" to Binary or to (Word64,Word64). Closest I came to is Network.IP.Addr package, but I'm a newbie and this signature is impenetrable for me:

net6Parser :: (CharParsing μ, Monad μ, IsNetAddr n, NetHost n ~ IP6) => μ n

Can someone please provide an example how to use it, or recommend any other package?

Upvotes: 5

Views: 506

Answers (2)

Juraj
Juraj

Reputation: 870

While Thomas' answer is correct and helpful, I totally forgot there's getAddrInfo standard function and I ended up using its output like:

fromSockAddr :: SockAddr -> (Word64, Word64)
fromSockAddr a = case a of
               -- SockAddrInet pn ha (IPV4 not needed)
               SockAddrInet6 pn fi ha sid -> decode $ encode ha :: (Word64,Word64)

Upvotes: 0

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64750

The network-ip package appears to use the textual type class and its related package. Looking at that class's documentation, I see mention of an obvious helper fromString that sounds good. A quick test suggests this is what you're looking for:

> import Data.Textual
> import Network.IP.Addr
> fromString  "fe80::dd99:5d56:cf09:b1ef" :: Maybe IP6
Just (ip6FromWords 0xfe80 0x0 0x0 0x0 0xdd99 0x5d56 0xcf09 0xb1ef)

So that works fine. Now how do we get those 8 Word16 values into a couple Word64s? The most efficient way is to use fromIntegral, bit shifts, and logical OR. I'm feeling lazy so lets just serialize it into a bytestring then deserialize it as two Word64s. No promise that I have the endian right but...

> import Data.Binary
> let x = it -- the prior result, the IPv6
> fmap (decode . encode) it :: Maybe (Word64,Word64)
Just (18338657682652659712,15967896581240893935)

Upvotes: 4

Related Questions