Haskell 中的 Pcap 文件解码
我正在尝试解码 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 文件以与不带 libpcap 库的wireshark 几乎类似的方式显示其内容[纯粹在 haskell 中通过以二进制格式打开 pcap 文件并逐字节读取],但我无法进一步。请有人提供这个项目的指南,比如读什么,如何进行,任何你认为有帮助的东西。
编辑: 我开始编写这个应用程序,但缺少一些东西。我读了这个文件 http://www.viste.com/Linux/Server/WireShark /libpcapformat.pdf 它说前 24 个字节是全局标头,之后每个数据包都包含 pcap 本地标头。我想做的是,首先尝试通过读取第三个数据包来获取每个数据包中的数据字节 本地标头中的 incl_len 字段,但我的代码的行为并不像它想象的那样。我的测试 libcap 文件。
--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
问候
穆克什·蒂瓦里
I am trying to decode a pcap file and its working fine except couple of things.
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
I want the time return by hdrSeconds p [ time to capture ] in same format as in wireshark [ Date : Month : Year Hour : Min : Sec ] and data return by variable q in Ascii format.Kindly tell me how to do this.
Actually i was trying to parse pcap file to display its content in almost similar manner to wireshark without libpcap library [ purely in haskell by opening the pcap file in binary format and read byte by byte ] but i could not get any further. Could some please put the guide map for this project like what to read , how to approach , any thing which you feel would be helpful .
Edit:
I started writing this application but there is some thing missing. I read this file http://www.viste.com/Linux/Server/WireShark/libpcapformat.pdf and it say that first 24 bytes are global headers , after that every packet contains pcap local header . What i am trying to do is , first trying to get the bytes of data in each packet by reading the third
field incl_len in local header but my code is not behaving as it suppose . My test 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
Regards
Mukesh Tiwari
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
time
包并将其转换为UTC 时间
。这使得提取月、日、年等变得微不足道。查看 时间包 的黑线鳕更多。据我所知,Haskell 绑定不提供纪元,但一旦你发现这应该没问题。我会通过电子邮件将补丁发送给维护者,以将转换直接添加到 UTCTime。
q 只是一个积分,您可以使用
toEnum
从Int
中获取Char
:那么 在纯 Haskell 中执行此操作,我认为您需要退后一步,了解有关 Haskell 作为一种语言的更多信息,也许可以从诸如 学习你哈斯克尔。如果您决心继续前进,请阅读邮件中提到的二进制包列为其非公共 pcap Haskell 库的首选库。
Well you can use the
time
package and convert this to aUTCTime
. This makes it trivial to extract month, day, year, etc. Look at the time package's haddock for more.From what I can tell the Haskell bindings don't provide the epoch, but once you find that this should be fine. I'd e-mail in a patch to the maintainer to add a converstion directly to UTCTime.
Well q is just an intergral and you can get
Char
s fromInt
s usingtoEnum
:As for doing this in pure Haskell, I think you need to step back a bit and learn more about Haskell as a language, perhaps from a tutuorial such as learnyouahaskell. If you are determined to forge ahead then read up on the binary package, which was mentioned on the mailing list as the library of choice for their non-public pcap Haskell library.
您可以使用
Data.Time
模块将hdrSeconds
返回的基于 UNIX 纪元的时间转换为LocalTime
对象,然后将其格式化为带有formatTime
的字符串。You can use the
Data.Time
module to convert the UNIX epoch-based time returned byhdrSeconds
to aLocalTime
object that can then be formatted into a string withformatTime
.一个用于读取 pcap 文件的 Haskell 库,它负责解析文件头和数据包记录头的工作,因此您不必自己执行此操作。然而,您仍然需要自己解析数据包数据。
There's a Haskell library for reading pcap files, which does the work of parsing the file header and packet record headers, so you don't have to do that on your own. You're still on your own parsing the packet data, however.