2011-10-12 29 views
1

我想解碼一個pcap file及其工作正常,除了幾件事。Haskell中的Pcap文件解碼

import Network.Pcap 
import System.IO 
import Control.Monad 

callfun f = do 
    (p , q) <- next f 
    print $ hdrSeconds p 
    print $ hdrCaptureLength p 
    print $ hdrWireLength p 
    print q 
    when (hdrWireLength p /= 0) $ callfun f  

main = do 
    f <- openOffline "udp_lite_full_coverage_0.pcap" 
    callfun f 

我想hdrSeconds P中的時間返回[時間捕捉到在相同的格式Wireshark的[日期:月:年時:分:秒],並以ASCII format.Kindly可變Q數據告訴回報我如何做到這一點。
其實我試圖解析pcap文件,以與wireshark幾乎類似的方式顯示其內容,而沒有libpcap庫[純粹通過以二進制格式打開pcap文件並逐字節讀取]在haskell中,但我無法得到任何進一步的信息。有些人可以把這個項目的指導地圖放在什麼地方閱讀,如何處理,任何你認爲會有幫助的東西。

編輯: 我開始寫這個應用程序,但有一些東西丟失。我讀這個文件http://www.viste.com/Linux/Server/WireShark/libpcapformat.pdf,它說,前24個字節是全局標題,然後每個數據包包含pcap本地標題。我想要做的是,首先嚐試通過閱讀本地頭部中的第三個 字段incl_len來獲取每個數據包中的數據字節,但是我的代碼不像它假設的那樣工作。我的測試libcap file

--http://www.viste.com/Linux/Server/WireShark/libpcapformat.pdf 
import Data.List 
import qualified Data.ByteString.Lazy as BS 
import qualified Data.ByteString.Lazy.Char8 as B 
import Control.Monad 
import Text.Printf 
import Data.Word 
import Data.Char 
import System.Time 
import Numeric 
import System.Environment 
hexTodec :: BS.ByteString -> Integer 
hexTodec lst = read $ "0x" ++ ( concatMap (\x -> showHex x "") $ BS.unpack lst ) 
parseFile :: BS.ByteString -> Bool -> IO [ BS.ByteString ] 
parseFile xs revflag 
    | BS.null xs = return [] 
    | otherwise = do 
    let ind =if revflag then hexTodec . BS.reverse . BS.take 4 . BS.drop 8 $ xs 
       else hexTodec . BS.take 4 . BS.drop 8 $ xs 
    print ind 
    let (x , ys) = BS.splitAt (fromIntegral ind ) xs 
    --BS.putStrLn $ x 
    tmp <- parseFile ys revflag 
    return $ x : tmp 
main = do 
    [ file ] <- getArgs 
    contents <- BS.readFile file 
    let (a , rest) = BS.splitAt 24 contents --strip global header 
    let revflag = case BS.unpack $ BS.take 4 a of 
        [ 0xd4 , 0xc3 , 0xb2 , 0xa1 ] -> True 
        _ -> False 
    p <- parseFile rest revflag 
    print $ p !! 0 
    BS.putStr $ p !! 0 


問候
穆克什·蒂瓦里

回答

2

我想hdrSeconds P中的時間返回[時間捕捉到在相同的格式Wireshark的[日期:月:年時:分:秒]

那麼你可以使用time包,並將其轉換爲UTCTime。這使得提取月份,日期,年份等變得微不足道。查看time package的黑線鱈更多。

let epoch = pcapEpochTimeThatYouFindInOnlineDocumentation 
diff <- hdrDiffTime p 
let date = addUTCTime (realToFrac diff) epoch 

從我可以告訴Haskell綁定不提供時代,但一旦你發現這應該沒問題。我會通過電子郵件發送給維護人員直接向UTCTime添加會話。

,並以ASCII格式由變量q數據返回

那麼q是隻是一個可積,你可以從Int S使用toEnum得到Char S:

print (toEnum (fromIntegral q) :: Char) 

至於這樣做在純粹的Haskell中,我認爲你需要退後一步,並更多地瞭解Haskell作爲一種語言,可能來自於例如learnyouahaskell的tutuorial。如果您決心進取,那麼請閱讀binary軟件包,該軟件包在郵件列表中被提及爲非公開pcap Haskell庫的首選庫。

2

可以使用Data.Time模塊通過hdrSeconds返回,然後可以格式化成與formatTime一個字符串LocalTime對象的基於UNIX時代時間轉換。

import Data.Time.Clock.POSIX 
import Data.Time.Format 
import Data.Time.LocalTime 
import System.Locale 
import Data.Word (Word32) 

data MockPCap = MockPCap { hdrSeconds :: Word32 } 

toPosixTime :: Word32 -> POSIXTime 
toPosixTime = fromIntegral 

localHdrTime p = do tz <- getCurrentTimeZone 
        return $ utcToLocalTime tz $ posixSecondsToUTCTime $ toPosixTime $ hdrSeconds p 

main = let p = MockPCap 1318464165 {-- Mock a PCap object --} 
     in do hTime <- localHdrTime p 
      print $ formatTime defaultTimeLocale "%c" hTime