Last active
October 26, 2020 00:24
-
-
Save mikma/1ff4a24c6b267dadfed6a4cafe6b438b to your computer and use it in GitHub Desktop.
DHCPv4-over-DHCPv6 Wireshark dissector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | |
-- 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