Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Apr 10th, 2007, 9:48 PM   #1
Mad_guy
Hobbyist Programmer
 
Mad_guy's Avatar
 
Join Date: Oct 2004
Location: Sandstorm, Techno Club
Posts: 239
Rep Power: 4 Mad_guy is on a distinguished road
Send a message via AIM to Mad_guy Send a message via MSN to Mad_guy
Haskell tutorial: writing a blacklist engine using the Writer Monad

I just got done the other day writing a tutorial on the Writer monad as I think I finally understand Monads ultimately (or as far as I know,) and I was wondering what some of you would think of it:

http://austin.youareinferior.net/?q=node/22

That's the link. I would appreciate any feedback and suggestions on it, since it's kinda my first real shot at doing using Monads, writing over it especially.
__________________
os: mac os 10.5.4
revision control: git
editor: emacs

site
Mad_guy is offline   Reply With Quote
Old Apr 12th, 2007, 11:37 AM   #2
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
It looks pretty good, though I'm not sure why you used the Writer monad if you only have one piece of output. Is this going to tie into the packet sniffer later on? Or did you choose to use the Writer monad merely as a challenge?
Arevos is offline   Reply With Quote
Old Apr 13th, 2007, 2:28 PM   #3
Mad_guy
Hobbyist Programmer
 
Mad_guy's Avatar
 
Join Date: Oct 2004
Location: Sandstorm, Techno Club
Posts: 239
Rep Power: 4 Mad_guy is on a distinguished road
Send a message via AIM to Mad_guy Send a message via MSN to Mad_guy
The writer monad was merely a challenge, really. Plus since the Writer monad is particularly accustomed to accumulating results over the lifetime of a computation, and given the way the blacklist filter takes arrays in both parameters (and how it matched them), I used the Writer monad. So really, I used the Writer monad because I found it practical, and in the middle I figured out a great deal and had a lot of fun. The packet sniffer right now is being worked on in another article (and it is long, comparatively at least.)

The Blister library was going to tie into the packet sniffer, and it still might at this point. I added in support for berkeley packet filter programs to be specified (a la tcpdump,) so i figured that would be plenty robust for the beginning builds and much later versions (right now the program and article are still being worked on in juxtaposition. I've hit a bump right now so I might need to revise the tutorial and the code some, but it works really well and I'm happy with the results.) Currently I'm working on the program's argument handling and accepting options, many of which are cribbed from tcpdump's man page. So there's the possibility I may add a parameter to allow you to specify multiple regular expressions for a packet's ASCII to abide by. So that'll be fun.

If you want the code for the packet sniffer, it's on the web. Run a:

darcs get --set-scripts-executable http://anapnea.net/~thoughtpolice/hsns

Currently it handles no options other than a berkely packet filter, but it captures packets (with filter applied, so you do have flexibility in terms of what to capture) and prints them out readably in both Hex and ASCII. And only in about 70 lines of code.

The system administrator was nice enough to install darcs so I could use it to publish my code on the web (finally; nice considering it's a free shell too from apapnea.net.) If you just want the source code it's here: http://hpaste.org/1368. There's no tarball or executable, so you'll have to pull the repo and compile (not like that's hard.) Just be sure to run the resulting executable as root.


As a self satisfying tidbit, search results for "writer monad" on google bring my article on my blog as the #2 result.
__________________
os: mac os 10.5.4
revision control: git
editor: emacs

site

Last edited by Mad_guy; Apr 13th, 2007 at 2:43 PM.
Mad_guy is offline   Reply With Quote
Old Apr 13th, 2007, 4:13 PM   #4
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
It looks pretty good. A few quick points though:

The following code:
let x = map (\i -> (PCap.ifName i)) devs
net  <- PCap.lookupNet (x !! 0)
spy  <- PCap.openLive (x !! 0) 512 True 100000
Could probably be more cleanly expressed as:
let (x:_) = map PCap.ifName devs
net <- PCap.lookupNet x
spy <- PCap.openLive x 512 True 100000
And:
s  <- return $ map (\x -> if (x >= 32 && x <= 126) then x else 46) a
s' <- return $ map (\x -> chr (read $ show x)) s
Could probably be expressed as:
let s = [if x >= 32 && x <= 126 then chr x else '.' | x <- a]
("s <- return $ ..." is the same as "let s = ...")
Arevos is offline   Reply With Quote
Old Apr 13th, 2007, 11:57 PM   #5
Mad_guy
Hobbyist Programmer
 
Mad_guy's Avatar
 
Join Date: Oct 2004
Location: Sandstorm, Techno Club
Posts: 239
Rep Power: 4 Mad_guy is on a distinguished road
Send a message via AIM to Mad_guy Send a message via MSN to Mad_guy
Thanks for the tip. On the second piece of code though, you can't directly convert a Word8 to a Char. Example:

[austin@continuum ~]$ ghci
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.6, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Prelude> :m + Data.Word
Prelude Data.Word> let x = 48 :: Word8
Prelude Data.Word> :m + Data.Char
Prelude Data.Word Data.Char> chr x

<interactive>:1:4:
    Couldn't match expected type `Int' against inferred type `Word8'
    In the first argument of `chr', namely `x'
    In the expression: chr x
    In the definition of `it': it = chr x
Prelude Data.Word Data.Char> Leaving GHCi.
[austin@continuum ~]$

I don't like the code I had to use to get a Character out of a Word8, perhaps there's a more efficient way using Data.ByteString, for right now it works though (I may add a function to convert a word to a character since I need it several places in the code.)
For example, something like this:

let s = [if x >= 32 && x <= 126 then word2char x else '.' | x <- a]

I'll most likely add that to the tutorial. Thanks for both tips too.
__________________
os: mac os 10.5.4
revision control: git
editor: emacs

site
Mad_guy is offline   Reply With Quote
Old Apr 14th, 2007, 8:30 AM   #6
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
Quote:
Originally Posted by Mad_guy View Post
Thanks for the tip. On the second piece of code though, you can't directly convert a Word8 to a Char.
I did wonder about that, which is why I put "probably" in my sentence

I did a bit more digging, and it turns out that the "fromIntegral" function is your man, as it converts from one integral type to another (presumably it's integral as in integer, not as in integration):

import Data.Char

char :: Integral a => a -> Char
char = chr . fromIntegral
There: a much more universal char function.
Arevos is offline   Reply With Quote
Old Apr 14th, 2007, 3:14 PM   #7
Mad_guy
Hobbyist Programmer
 
Mad_guy's Avatar
 
Join Date: Oct 2004
Location: Sandstorm, Techno Club
Posts: 239
Rep Power: 4 Mad_guy is on a distinguished road
Send a message via AIM to Mad_guy Send a message via MSN to Mad_guy
Thanks.

I just updated the code and it now includes Command line options, TCPdump filters, and it formats the packets nicely. And at only 170 lines of code, that's not bad. You can check the latest version like all the rest.
__________________
os: mac os 10.5.4
revision control: git
editor: emacs

site
Mad_guy is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:37 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC