Skip to content

Instantly share code, notes, and snippets.

@mikma
Last active October 26, 2020 00:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikma/1ff4a24c6b267dadfed6a4cafe6b438b to your computer and use it in GitHub Desktop.
Save mikma/1ff4a24c6b267dadfed6a4cafe6b438b to your computer and use it in GitHub Desktop.
DHCPv4-over-DHCPv6 Wireshark dissector
--
-- DHCPv4-over-DHCPv6 Wireshark dissector
-- Copyright (C) 2020 Mikael Magnusson
--
-- This work is licensed under the terms of GPLv2 (or any later version).
--
do
local DHCPV6_OPTION_DHCPV4_MSG = 87
local DHCPV6_OPTION_6O4_SERVER = 88
local original_dhcpv6_dissector = Dissector.get("dhcpv6")
local dhcpv4_dissector = Dissector.get("dhcp") -- was bootp
local dhcpv6_wrapper_proto = Proto("dhcpv6_4o6", "DHCPv4-over-DHCPv6");
local F_4o6server = ProtoField.ipv6("dhcpv6.4o6.server", "DHCP 4o6 Server Address")
dhcpv6_wrapper_proto.fields = {F_4o6server}
-- declare the fields we need to read
local f_option_type = Field.new("dhcpv6.option.type")
local f_option_length = Field.new("dhcpv6.option.length")
local f_option_value = Field.new("dhcpv6.option.value")
function dhcpv6_wrapper_proto.dissector(tvbuffer, pinfo, treeitem)
-- we've replaced the original dhcpv6 dissector in the dissector table,
-- but we still want the original to run, especially because we need to read its data
original_dhcpv6_dissector:call(tvbuffer, pinfo, treeitem)
local subtreeitem
local option_types = {f_option_type()}
local option_lengths = {f_option_length()}
local option_values = {f_option_value()}
local pos = 0
for i, _ in pairs(option_types) do
local option_type = option_types[i].value
local option_length = option_lengths[i].value
local option_value
-- The option_values table doesn't contain options with empty values
if option_length > 0 then
pos = pos + 1
option_value = option_values[pos]
end
if option_value then
if option_type == DHCPV6_OPTION_6O4_SERVER then
if not subtreeitem then
subtreeitem = treeitem:add(dhcpv6_wrapper_proto, tvbuffer)
end
server_tvb = option_value.range:tvb()
offset = 0
length = 16
while offset < server_tvb:len() do
subtreeitem:add(F_4o6server, server_tvb:range(offset, length))
offset = offset + length
end
else if option_type == DHCPV6_OPTION_DHCPV4_MSG then
if not subtreeitem then
subtreeitem = treeitem:add(dhcpv6_wrapper_proto, tvbuffer)
end
dhcpv4_dissector:call(option_value.range:tvb(), pinfo, subtreeitem)
end
end
end
end
end
local udp_dissector_table = DissectorTable.get("udp.port")
udp_dissector_table:add(546, dhcpv6_wrapper_proto)
udp_dissector_table:add(547, dhcpv6_wrapper_proto)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment