
Hi, I've found myself needing to show a SockAddr type left and right in my code. Is it possible to add the appropriate definition to Network.Socket? Here is a suggestion: instance Show SockAddr where show (SockAddrUnix str) = str show (SockAddrInet port ha) = let (b1,b2,b3,b4) = ha2tpl ha in shows b1 . ('.':) . shows b2 . ('.':) . shows b3 . ('.':) . shows b4 . (':':) $ show port -- |Split up an 32-bit word in network byte order. ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4) Peter

On Fri, Oct 15, 2004 at 04:24:01PM +0200, Peter Simons wrote:
Hi,
I've found myself needing to show a SockAddr type left and right in my code. Is it possible to add the appropriate definition to Network.Socket? Here is a suggestion:
-- |Split up an 32-bit word in network byte order.
ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4)
This won't work on big-endian architectures. Couldn't GHC's HostAddress be always in host-order, with necessary conversions done behind the curtains? When I was playing with pure Haskell DNS resolver library, the current situation forced me to make foreign imports for htonl. Because of this the library is 99.9% Haskell + 0.01% C. Best regards, Tom -- .signature: Too many levels of symbolic links

At 20:43 15/10/04 +0200, Tomasz Zielonka wrote:
On Fri, Oct 15, 2004 at 04:24:01PM +0200, Peter Simons wrote:
Hi,
I've found myself needing to show a SockAddr type left and right in my code. Is it possible to add the appropriate definition to Network.Socket? Here is a suggestion:
-- |Split up an 32-bit word in network byte order.
ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4)
This won't work on big-endian architectures.
Couldn't GHC's HostAddress be always in host-order, with necessary conversions done behind the curtains?
It seems to me that using a single integer/bitstring value for internal representation of IP addresses is rather missing a trick. I'd hope that, for the most part, Haskell programs are above this kind of bit-stuffing logic, except when it comes to actually interfacing with the real world (in this case, a wire protocol). My hope for a host address representation would be an abstraction whose internal details are hidden, with functions to convert to/from textual form and wire-form (network byte order), and any other abstract operations that may be required (e.g. subnet testing). This approach should, for example, make migration to IPv6 relatively painless. But I suppose this particular horse has bolted, and we must live with the consequences. Sigh. #g --
When I was playing with pure Haskell DNS resolver library, the current situation forced me to make foreign imports for htonl. Because of this the library is 99.9% Haskell + 0.01% C.
Best regards, Tom
-- .signature: Too many levels of symbolic links _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
------------ Graham Klyne For email: http://www.ninebynine.org/#Contact

On Sat, Oct 16, 2004 at 09:37:02AM +0100, Graham Klyne wrote:
It seems to me that using a single integer/bitstring value for internal representation of IP addresses is rather missing a trick.
But that's just what IP4 address is: 32 bits
My hope for a host address representation would be an abstraction whose internal details are hidden, with functions to convert to/from textual form and wire-form (network byte order), and any other abstract operations that may be required (e.g. subnet testing). This approach should, for example, make migration to IPv6 relatively painless.
You can make such abstraction on top of the existing one. I would be very sad if I couldn't just use IP4 addresses when I want to. Best regards, Tom -- .signature: Too many levels of symbolic links

At 11:09 16/10/04 +0200, Tomasz Zielonka wrote:
On Sat, Oct 16, 2004 at 09:37:02AM +0100, Graham Klyne wrote:
It seems to me that using a single integer/bitstring value for internal representation of IP addresses is rather missing a trick.
But that's just what IP4 address is: 32 bits
Well, on the wire it's 32 bits, but from an application's viewpoint, IMO, it's an abstract value that is used to address an endpoint. From the user's PoV, it's (usually) four decimal numbers separated by '.'.
My hope for a host address representation would be an abstraction whose internal details are hidden, with functions to convert to/from textual form and wire-form (network byte order), and any other abstract operations that may be required (e.g. subnet testing). This approach should, for example, make migration to IPv6 relatively painless.
You can make such abstraction on top of the existing one. I would be very sad if I couldn't just use IP4 addresses when I want to.
I guess you have your reasons for saying that, though I can't see what they might be. In all my network programming (*) my goal has been to abstract away from this underlying 32-bit-ness as quickly as possible. My concern for making an abstraction on top of the host-order 32-bit value is that some trickery is needed to make the code portable. I'd like to see any host-specific details dealt with as deep as possible in the library structures. #g -- (*) with one exception: implementing an address translation gateway. In that case, the (on-the-wire) address format was pretty much the primary concern of the entire software system, but I regard that as an exceptional case. ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact

Tomasz Zielonka writes:
ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4)
This won't work on big-endian architectures.
Why not? Peter

Tomasz Zielonka writes:
ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4)
This won't work on big-endian architectures.
Why not?
Because it assumes that network byte order is the opposite of host byte order. Network order is big-endian, so if host-order is big-endian, too, then that is not the case, and ha2tpl returns the bytes in the wrong order. Cheers, Wolfgang

On Sun, Oct 17, 2004 at 11:57:49PM +0200, Peter Simons wrote:
Tomasz Zielonka writes:
ha2tpl :: HostAddress -> (Int, Int, Int, Int) ha2tpl n = let (b1,n1) = (n .&. 255, n `shiftR` 8) (b2,n2) = (n1 .&. 255, n1 `shiftR` 8) (b3,n3) = (n2 .&. 255, n2 `shiftR` 8) b4 = n3 .&. 255 in (fromEnum b1, fromEnum b2, fromEnum b3, fromEnum b4)
This won't work on big-endian architectures.
Why not?
Because GHC keeps HostAddress in network-order (aka big-endian) but Data.Bits works in host order. First octet of IP4 address is the most significant byte in network-order word, but here you take it from the least significant byte. I assume that HostAddress on big-endian machines is also kept in network-order - but there this is the same as the host-order, so if you take the least significant byte you will get the last IP4 octet. Best regards, Tom -- .signature: Too many levels of symbolic links
participants (5)
-
Graham Klyne
-
Graham Klyne
-
Peter Simons
-
Tomasz Zielonka
-
Wolfgang Thaller