import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.ByteString.Char8 (pack)
import System.Environment (getArgs)
import System.IO.Error
import Data.Serialize
import Text.CSV
import Data.List as L
import Network.Pcap
import Data.Word
import Foreign.Ptr
import Foreign.ForeignPtr
import Control.Monad
import System.Directory
import Dust.Model.TrafficModel
import Dust.Model.PacketLength
import Dust.Model.Content
import Dust.Model.Observations
import Dust.Model.Packet
main = do
args <- getArgs
case args of
("--live":device:countStr:port:modelpath:_) -> do
let count = (read countStr)::(Int)
updateLive device count port modelpath
(pcappath:port:modelpath:_) -> updateOffline pcappath port modelpath
otherwise -> putStrLn "Usage: update [pcap-file | --live device count] [port] [observation-file]"
updateOffline :: FilePath -> String -> FilePath -> IO()
updateOffline pcappath port modelpath = do
pcap <- openOffline pcappath
putStrLn "Opened pcap file"
let ipmask = (fromIntegral 0)::Word32
setFilter pcap ("tcp port " ++ port) True ipmask
putStrLn $ "Set filter to port " ++ port
let iport = (read port)::Int
obs <- ensureObservations modelpath
let obs' = observePort obs iport
obs'' <- processOffline True pcap obs'
saveObservations modelpath obs''
updateLive :: String -> Int -> String -> FilePath -> IO()
updateLive device count port modelpath = do
pcap <- openLive device 1500 False (1000) -- 1 second
putStrLn $ "Opened " ++ device ++ " in live capture mode"
let ipmask = (fromIntegral 0)::Word32
setFilter pcap ("tcp port " ++ port) True ipmask
putStrLn $ "Set filter to port " ++ port
let iport = (read port)::Int
obs <- ensureObservations modelpath
let obs' = observePort obs iport
obs'' <- processLive True pcap obs' count
saveObservations modelpath obs''
processLive :: Bool -> PcapHandle -> Observations -> Int -> IO Observations
processLive first pcap obs 0 = return obs
processLive first pcap obs count = do
(hdr, body) <- nextBS pcap
if hdrWireLength hdr /= 0
then do
let eitherPacket = parsePacket body
case eitherPacket of
Left error -> do
putStrLn $ "Error parsing packet"
processLive first pcap obs count
Right (Packet _ _ _ payload) -> do
let obs' = observePacket obs payload
let obs'' = if first then (observeSubstrings obs payload) else obs'
processLive False pcap obs'' (count-1)
else return obs
processOffline :: Bool -> PcapHandle -> Observations -> IO Observations
processOffline first pcap obs = do
(hdr, body) <- nextBS pcap
if hdrWireLength hdr /= 0
then do
let eitherPacket = parsePacket body
case eitherPacket of
Left error -> do
putStrLn $ "Error parsing packet"
processOffline first pcap obs
Right (Packet _ _ _ payload) -> do
let obs' = observePacket obs payload
let obs'' = observeSubstrings obs payload
processOffline False pcap obs''
else return obs