aboutsummaryrefslogtreecommitdiff
path: root/plugins/pcap.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pcap.lua')
-rw-r--r--plugins/pcap.lua178
1 files changed, 178 insertions, 0 deletions
diff --git a/plugins/pcap.lua b/plugins/pcap.lua
new file mode 100644
index 0000000..1b8d791
--- /dev/null
+++ b/plugins/pcap.lua
@@ -0,0 +1,178 @@
+--
+-- pcap.lua: libpcap file format
+--
+-- Copyright (c) 2017, Přemysl Janouch <p.janouch@gmail.com>
+--
+-- Permission to use, copy, modify, and/or distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+local detect = function (c)
+ local magic = c:read (4)
+ return magic == "\xa1\xb2\xc3\xd4" or magic == "\xd4\xc3\xb2\xa1"
+end
+
+-- Specified in http://www.tcpdump.org/linktypes.html
+local link_types = {
+ [0] = "NULL",
+ [1] = "ETHERNET",
+ [3] = "AX25",
+ [6] = "IEEE802_5",
+ [7] = "ARCNET_BSD",
+ [8] = "SLIP",
+ [9] = "PPP",
+ [10] = "FDDI",
+ [50] = "PPP_HDLC",
+ [51] = "PPP_ETHER",
+ [100] = "ATM_RFC1483",
+ [101] = "RAW",
+ [104] = "C_HDLC",
+ [105] = "IEEE802_11",
+ [107] = "FRELAY",
+ [108] = "LOOP",
+ [113] = "LINUX_SLL",
+ [114] = "LTALK",
+ [117] = "PFLOG",
+ [119] = "IEEE802_11_PRISM",
+ [122] = "IP_OVER_FC",
+ [123] = "SUNATM",
+ [127] = "IEEE802_11_RADIOTAP",
+ [129] = "ARCNET_LINUX",
+ [138] = "APPLE_IP_OVER_IEEE1394",
+ [139] = "MTP2_WITH_PHDR",
+ [140] = "MTP2",
+ [141] = "MTP3",
+ [142] = "SCCP",
+ [143] = "DOCSIS",
+ [144] = "LINUX_IRDA",
+ [147] = "USER0",
+ [148] = "USER1",
+ [149] = "USER2",
+ [150] = "USER3",
+ [151] = "USER4",
+ [152] = "USER5",
+ [153] = "USER6",
+ [154] = "USER7",
+ [155] = "USER8",
+ [156] = "USER9",
+ [157] = "USER10",
+ [158] = "USER11",
+ [159] = "USER12",
+ [160] = "USER13",
+ [161] = "USER14",
+ [162] = "USER15",
+ [163] = "IEEE802_11_AVS",
+ [165] = "BACNET_MS_TP",
+ [166] = "PPP_PPPD",
+ [169] = "GPRS_LLC",
+ [170] = "GPF_T",
+ [171] = "GPF_F",
+ [177] = "LINUX_LAPD",
+ [187] = "BLUETOOTH_HCI_H4",
+ [189] = "USB_LINUX",
+ [192] = "PPI",
+ [195] = "IEEE802_15_4",
+ [196] = "SITA",
+ [197] = "ERF",
+ [201] = "BLUETOOTH_HCI_H4_WITH_PHDR",
+ [202] = "AX25_KISS",
+ [203] = "LAPD",
+ [204] = "PPP_WITH_DIR",
+ [205] = "C_HDLC_WITH_DIR",
+ [206] = "FRELAY_WITH_DIR",
+ [209] = "IPMB_LINUX",
+ [215] = "IEEE802_15_4_NONASK_PHY",
+ [220] = "USB_LINUX_MMAPPED",
+ [224] = "FC_2",
+ [225] = "FC_2_WITH_FRAME_DELIMS",
+ [226] = "IPNET",
+ [227] = "CAN_SOCKETCAN",
+ [228] = "IPV4",
+ [229] = "IPV6",
+ [230] = "IEEE802_15_4_NOFCS",
+ [231] = "DBUS",
+ [235] = "DVB_CI",
+ [236] = "MUX27010",
+ [237] = "STANAG_5066_D_PDU",
+ [239] = "NFLOG",
+ [240] = "NETANALYZER",
+ [241] = "NETANALYZER_TRANSPARENT",
+ [242] = "IPOIB",
+ [243] = "MPEG_2_TS",
+ [244] = "NG40",
+ [245] = "NFC_LLCP",
+ [247] = "INFINIBAND",
+ [248] = "SCTP",
+ [249] = "USBPCAP",
+ [250] = "RTAC_SERIAL",
+ [251] = "BLUETOOTH_LE_LL",
+ [253] = "NETLINK",
+ [254] = "BLUETOOTH_LINUX_MONITOR",
+ [255] = "BLUETOOTH_BREDR_BB",
+ [256] = "BLUETOOTH_LE_LL_WITH_PHDR",
+ [257] = "PROFIBUS_DL",
+ [258] = "PKTAP",
+ [259] = "EPON",
+ [260] = "IPMI_HPM_2",
+ [261] = "ZWAVE_R1_R2",
+ [262] = "ZWAVE_R3",
+ [263] = "WATTSTOPPER_DLM",
+ [264] = "ISO_14443",
+ [265] = "RDS",
+ [266] = "USB_DARWIN"
+}
+
+-- As described by https://wiki.wireshark.org/Development/LibpcapFileFormat
+local decode = function (c)
+ if not detect (c ()) then error ("not a PCAP file") end
+
+ c.endianity = "le"
+ c:u32 ("PCAP magic: %s", function (u32)
+ if u32 == 0xa1b2c3d4 then return "little-endian" end
+
+ c.endianity = "be"
+ return "big-endian"
+ end)
+
+ local p, vmajor, vminor = c.position, c:u16 (), c:u16 ()
+ c (p, c.position - 1):mark ("PCAP version: %d.%d", vmajor, vminor)
+
+ local zone = c:i32 ("UTC to local TZ correction: %d seconds")
+ local sigfigs = c:u32 ("timestamp accuracy")
+ local snaplen = c:u32 ("max. length of captured packets")
+
+ local network = c:u32 ("data link type: %s", function (u32)
+ name = link_types[u32]
+ if name then return name end
+ return "unknown: %d", u32
+ end)
+
+ local i = 0
+ while not c.eof do
+ c (c.position, c.position + 23):mark ("PCAP record %d header", i)
+ i = i + 1
+
+ local p, ts_sec, ts_usec = p, c:u32 (), c:u32 ()
+ c (p, c.position - 1):mark ("timestamp: %s.%06d",
+ os.date ("!%F %T", ts_sec + zonen), ts_usec)
+ local incl_len = c:u32 ("included record length")
+ local orig_len = c:u32 ("original record length")
+
+ local p = c.position
+ c.position = c.position + incl_len
+ -- TODO: also decode record contents as per the huge table
+ c (p, c.position - 1):mark ("PCAP record %d data", i)
+ end
+end
+
+hex.register { type="pcap", detect=detect, decode=decode }
+