import Control.Monad.State
import Control.Concurrent
import System.Environment
import System.Process
import qualified Network.Pcap as PCap
import Text.Printf
import System.IO
import Data.List
import Data.Char
import Foreign
data PacketFmt = PacketFmt {
ascii :: String,
hexadecimal :: [Word8]
}
deriving (Eq,Show)
initPktFmt a h =
PacketFmt {
ascii = a,
hexadecimal = h
}
formatData :: PacketFmt -> IO ()
formatData pf = do
let (x,x') = splitAt 10 a
(y,y') = splitAt 10 h
unless (x' == [] && y' == []) $ do
mapM_ (printf "%02.2x ") (fmtHex y)
printf "\t\t%s\n" x
formatData (initPktFmt x' y')
return ()
where
a = ascii pf
h = hexadecimal pf
fmtHex :: [Word8] -> [Int]
fmtHex bytes = [ (read $ show y) | y <- bytes] :: [Int]
captcha :: PCap.PktHdr -> Ptr Word8 -> IO ()
captcha pkth datap = do
a <- peekArray (fromIntegral (PCap.caplen pkth)) datap
s <- return $ map (\x -> if (x >= 32 && x <= 126) then x else 46) a
s' <- return $ map (\x -> chr (read $ show x)) s
formatData (initPktFmt s' a)
printf "\n"
hFlush stdout
main = do
a <- getArgs
devs <- PCap.findAllDevs
let x = map (\i -> (PCap.ifName i)) devs
net <- PCap.lookupNet (x !! 0)
spy <- PCap.openLive (x !! 0) 512 True 100000
withForeignPtr spy $ \ptr -> do
if a == [] then return () else PCap.setFilter ptr (head a) False (PCap.netMask net)
PCap.loop ptr 5 captcha
s <- PCap.statistics ptr
putStrLn ("Packets recieved: " ++ (show $ PCap.recv s))
putStrLn ("Packets dropped: " ++ (show $ PCap.drop s))
putStrLn ("Packets dropped by interface: " ++ (show $ PCap.ifdrop s))
return ()