Декодирование файла Pcap в Haskell - PullRequest
1 голос
/ 13 октября 2011

Я пытаюсь декодировать файл 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 [Дата: Месяц: Год Час: Мин: сек], и возвращались данные по переменной q в формате Ascii. Пожалуйста, скажите мне, как это сделать этот.
На самом деле я пытался проанализировать файл pcap, чтобы отобразить его содержимое почти таким же образом, как и Wireshark без библиотеки libpcap [чисто в haskell, открыв файл pcap в двоичном формате и прочитав побайтово], но я не смог продолжить. Могли бы вы, пожалуйста, поставить карту-руководство для этого проекта, например, что читать, как подойти, любую вещь, которая, по вашему мнению, будет полезна.

Edit: Я начал писать это приложение, но чего-то не хватает. Я прочитал этот файл 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 


С уважением
Мукеш Тивари

Ответы [ 3 ]

2 голосов
/ 13 октября 2011

Вы можете использовать модуль Data.Time для преобразования времени эпохи UNIX, возвращаемого hdrSeconds, в объект LocalTime, который затем можно отформатировать в строку с formatTime.

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
2 голосов
/ 13 октября 2011

Я хочу, чтобы время вернулось через hdrSeconds p [время захвата] в том же формате, что и в wireshark [Дата: Месяц: Год Час: Мин: сек]

Ну, вы можете использовать пакет time и преобразовать его в UTCTime. Это упрощает извлечение месяца, дня, года и т. Д. Посмотрите на пикшу времени , чтобы узнать больше.

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

Из того, что я могу сказать, привязки Хаскелла не дают эпоху, но как только вы обнаружите, что это должно быть хорошо. Я бы отправил сопровождающему письмо по электронной почте, чтобы добавить беседу непосредственно в UTCTime.

и возврат данных по переменной q в формате Ascii

Ну, q просто интеграл, и вы можете получить Char с из Int с, используя toEnum:

print (toEnum (fromIntegral q) :: Char)

Как сделать это в чистом Haskell, я думаю, что вы должны сделать шаг назад немного и узнать больше о Haskell как язык, возможно, из tutuorial, таких как learnyouahaskell . Если вы полны решимости продвинуться вперед, прочитайте пакет binary , который был упомянут в списке рассылки в качестве библиотеки выбора для их непубличной библиотеки pcap Haskell.

0 голосов
/ 05 января 2016

Есть библиотека Haskell для чтения файлов pcap , которая выполняет синтаксический анализ заголовка файла и заголовка записи пакета, поэтому вам не придется делать это самостоятельно.Вы все еще самостоятельно разбираете пакет data , однако.

...