我正在尝试解码pcap file并且除了几件事以外它的工作正常。
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文件并逐字节读取]但我无法进一步。有些人可以把这个项目的指南地图放在一起,比如读什么,怎么接近,你觉得有什么用处。
编辑: 我开始编写这个应用程序但是有些东西丢失了。我读了这个文件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
问候
Mukesh Tiwari
答案 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只是一个整体,您可以使用Char
从Int
获取toEnum
个:
print (toEnum (fromIntegral q) :: Char)
至于在纯粹的Haskell中这样做,我认为你需要退一步,了解更多关于Haskell作为一种语言,或许来自像learnyouahaskell这样的教诲。如果您决心继续前进,请阅读binary包,该包在邮件列表中被提及为非公共pcap Haskell库的首选库。
答案 1 :(得分:2)
您可以使用Data.Time
模块将hdrSeconds
返回的基于UNIX纪元的时间转换为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 :(得分:0)
有a Haskell library for reading pcap files,它可以解析文件头和数据包记录头,因此您不必自己动手。但是,您仍在自己解析数据包数据。