packages feed

Dust-tools-pcap-1.3.1: Dust/Model/convert.hs

import System.IO
import qualified Data.ByteString as B
import Data.ByteString.Char8 (pack)
import Data.Serialize
import Text.Printf (printf)
import Data.List as L
import Control.Concurrent
import Network.Socket hiding (recv, Stream)
import Network.Socket.ByteString (recv, sendAll)
import System.Entropy
import Control.Exception
import Data.Word (Word16)
import Network.Pcap
import System.Environment (getArgs)
import Data.Word (Word32)

import Dust.Network.Util
import Dust.Model.Packet
import Dust.Model.TrafficModel
import Dust.Model.Observations
import Dust.Services.Replay.Replay

main :: IO()
main = do
    args <- getArgs

    case args of
        (pcappath:protocol:port:pspath:_) -> convert pcappath protocol port pspath
        otherwise                         -> do
          putStrLn "replay-convert converts .pcap files into the packetstream format for use in replay-server and replay-client"
          putStrLn "Usage: replay-convert [pcap-file] [tcp|udp] [port] [packetstream-file]"

convert :: FilePath -> String -> String -> FilePath -> IO()
convert pcappath protocol sport pspath = do
    let rport = (read sport)::Word16
    case protocol of
      "tcp" -> do
          let config = TCPConfig (PortNum rport) False
          pcap <- openPcap pcappath config
          stream <- convertStream config pcap $ Stream ProtocolTCP rport []
          putStrLn "---------------------------"
          putStrLn $ show stream
          let bs = encode stream
          B.writeFile pspath bs
      "udp" -> do
          let config = UDPConfig (PortNum rport) False "" True
          pcap <- openPcap pcappath config
          stream <- convertStream config pcap $ Stream ProtocolUDP rport []
          putStrLn $ show stream
          let bs = encode stream
          B.writeFile pspath bs
      otherwise -> putStrLn $ "Unknown protocol " ++ protocol

convertStream :: ReplayConfig -> PcapHandle -> Stream -> IO Stream
convertStream config pcap stream@(Stream protocol rport packets) = do
    (hdr, body) <- nextBS pcap
    if hdrWireLength hdr /= 0
        then do
            let eitherHeaders = parsePacket body

            case eitherHeaders of
                Left error -> do
                  putStrLn "Error parsing [TCP|UDP]/IP headers"
                  return stream
                Right packet@(Packet _ _ _ payload) -> do
                    putStrLn $ show packet
	            if (B.length payload) > 0
        	        then convertStream config pcap $ Stream protocol rport $ packets ++ [packet]
        		else convertStream config pcap stream
        else return stream

openPcap :: FilePath -> ReplayConfig -> IO PcapHandle
openPcap pcappath config = do
    pcap <- openOffline pcappath
    putStrLn "Opened pcap file"
    let ipmask = (fromIntegral 0)::Word32
    case config of
      (TCPConfig (PortNum port) _)     -> setFilter pcap ("tcp port " ++ (show port)) True ipmask
      (UDPConfig (PortNum port) _ _ _) -> setFilter pcap ("udp port " ++ (show port)) True ipmask
    return pcap