Interpreting fields in a buffer

Gregory, I don't know if this helps but I ended creating functions like the ones below (I didn't need to use the C structures because the IP definition is language independent). I'm sure there are better ways and I didn't test the throughput but I was able to develop a Haskell version of ping and traceroute (both multi-threaded). It would be nice if there were a library so that we didn't end up re-inventing the wheel. Dominic. ipHeaderLength :: String -> Int ipHeaderLength s = (fromIntegral (ord (s !! 0)) .&. 0x0f) * 4 ipTTL :: String -> Int ipTTL s = fromIntegral (ord (s !! 8)) ipProtocol :: String -> IPProto ipProtocol s = toEnum (ord (s !! 9)) ipDestAddr :: String -> HostAddress ipDestAddr s = fromIntegral (ord (s !! 16)) `shiftL` 24 + fromIntegral (ord (s !! 17)) `shiftL` 16 + fromIntegral (ord (s !! 18)) `shiftL` 8 + fromIntegral (ord (s !! 19)) ----- Original Message -----
Date: Sun, 25 Jan 2004 22:44:58 -0500 From: Gregory Wright
To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Interpreting fields in a buffer Message-ID: <0356DB09-4FB2-11D8-A3D2-00039398F084@antiope.com> Content-Type: text/plain; charset=US-ASCII; format=flowed MIME-Version: 1.0 (Apple Message framework v609) Content-Transfer-Encoding: 7bit Precedence: list Message: 1 Hi,
I have a question related to a program I'm writing. I have to handle IP packets, which will be read into a buffer. What is the best haskell idiom for getting access to the fields in the buffer?
The IP header has a number of fixed format fields. In C, I would define a struct, then cast the pointer to the beginning of the buffer to a pointer to the struct. I would then be able to access each field in the header as
-> <field>. Is there a way in haskell to declare the format of the header, then access the components of the buffer as elements of those types? I'm only going to do read access on the buffer (an unboxed array). Most fields won't be examined but I can't tell in advance which ones will have to be looked at.
I've not seen an example of this kind and was wondering if this was especially awkward.
Thanks.
Best Wishes, Greg
Gregory Wright Antiope Associates LLC 18 Clay Street Fair Haven, New Jersey 07704
gwright@antiope.com

Hi Dominic, First, thanks to everyone for their help. RIght now, I'm leaning toward Dominic's solution of a collection of helper functions, but I have the feeling that we should be generating them automatically. After all, given a buffer that consists of packed, fixed width fields, if we specify a name and width of the field, making the helper functions should be straightforward. (I understand the network byte order issues. Since I won't always have to examine each field, I wasn't going to convert all fields to host byte order, rather only convert the ones I needed to examine.) It's a little strange that we seem to have to use template haskell or some other preprocessor to do this. Rather like using a sledgehammer to crack a walnut. I'll try to come up with something of general use. I'm very interested to see Tom's (de)serialization framework. As long as this problem is going to require TH, we may as well solve more than one problem. And now I let you return to your discussion of the tab character ;-) Best Wishes, Greg On Jan 26, 2004, at 11:13 AM, Dominic Steinitz wrote:
Gregory,
I don't know if this helps but I ended creating functions like the ones below (I didn't need to use the C structures because the IP definition is language independent). I'm sure there are better ways and I didn't test the throughput but I was able to develop a Haskell version of ping and traceroute (both multi-threaded). It would be nice if there were a library so that we didn't end up re-inventing the wheel.
Dominic.
ipHeaderLength :: String -> Int ipHeaderLength s = (fromIntegral (ord (s !! 0)) .&. 0x0f) * 4
ipTTL :: String -> Int ipTTL s = fromIntegral (ord (s !! 8))
ipProtocol :: String -> IPProto ipProtocol s = toEnum (ord (s !! 9))
ipDestAddr :: String -> HostAddress ipDestAddr s = fromIntegral (ord (s !! 16)) `shiftL` 24 + fromIntegral (ord (s !! 17)) `shiftL` 16 + fromIntegral (ord (s !! 18)) `shiftL` 8 + fromIntegral (ord (s !! 19))

On mån, 2004-01-26 at 12:22 -0500, Gregory Wright wrote:
Hi Dominic,
First, thanks to everyone for their help.
RIght now, I'm leaning toward Dominic's solution of a collection of helper functions, but I have the feeling that we should be generating them automatically. After all, given a buffer that consists of packed, fixed width fields, if we specify a name and width of the field, making the helper functions should be straightforward. (I understand the network byte order issues. Since I won't always have to examine each field, I wasn't going to convert all fields to host byte order, rather only convert the ones I needed to examine.)
It's a little strange that we seem to have to use template haskell or some other preprocessor to do this. Rather like using a sledgehammer to crack a walnut.
I'll try to come up with something of general use. I'm very interested to see Tom's (de)serialization framework. As long as this problem is going to require TH, we may as well solve more than one problem.
And now I let you return to your discussion of the tab character ;-)
Best Wishes, Greg
You'll probably want to take a look at Erlang's so called ``bit syntax'' at http://www.erlang.se/euc/00/bit_syntax.html. It's very nifty, and I'd love to see it (or something equally convenient) as a Haskell extension. Hugs and kisses, Mikael Brockman

Mikael, Thanks, that's very helpful and seems to be just the sort of thing I'm looking for. Greg On Jan 26, 2004, at 6:05 PM, Mikael Brockman wrote:
You'll probably want to take a look at Erlang's so called ``bit syntax'' at http://www.erlang.se/euc/00/bit_syntax.html. It's very nifty, and I'd love to see it (or something equally convenient) as a Haskell extension.
Hugs and kisses, Mikael Brockman
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
Dominic Steinitz
-
Gregory Wright
-
Mikael Brockman