1require "bit32" 2--[[ 3SPDX-License-Identifier: GPL-2.0-or-later 4Copyright (c) 2022 Huawei Device Co., Ltd. 5 6Description: wireshark lua configure for NewIP protocol stack 7 8Author: Yang Yanjun <yangyanjun@huawei.com> 9 10Data: 2022-05-27 11--]] 12 13do -- lua begin 14 15--协议名称为NewIP,在Packet Details窗格显示为NewIP 16-- create a new protocol 17local nip_proto_name = "NewIP" 18local nip_proto_desc = "NewIP Protocol" 19local nip_proto_obj = Proto(nip_proto_name, nip_proto_desc) 20 21--[[ 22NewIP协议字段定义 23 ProtoField 参数: 24 para1 [必选] - 字段的缩写名称(过滤器中使用的字符串) 25 para2 [可选] - 字段的实际名称(出现在树中的字符串) 26 para3 [可选] - 字段类型 27--]] 28--[[ 29ProtoField.{type}(abbr, [name], [base], [valuestring], [mask], [desc]) 30·type包括:uint8, uint16, uint24, uint32, uint64, framenum, float, double, string, stringz, bytes, bool, ipv4, ipv6, ether,oid, guid 31 32abbr 字段的缩写名称(过滤器中使用的字符串)。 33name (optional) 字段的实际名称(出现在树中的字符串)。 34base (optional) base.DEC,base.HEX或base.OCT,base.DEC_HEX,base.HEX_DEC,base.UNIT_STRING或base.RANGE_STRING。 35valuestring (optional) 包含与值对应的文本的表,或包含与值 ({min, max, “string”}) 对应的范围字符串值表的表(如果基数为 )base.RANGE_STRING, 36 或包含单位名称的表如果 base 是base.UNIT_STRING. 37mask (optional) 此字段的整数掩码。 38desc (optional) 字段说明。 39 40--]] 41local _ttl = ProtoField.uint8 (nip_proto_name .. ".ttl", "ttl ( 1 Byte)", base.DEC) 42local _total_len = ProtoField.uint16(nip_proto_name .. ".total_len", "total_len ( 2 Byte)", base.DEC) 43local _nexthdr = ProtoField.uint8 (nip_proto_name .. ".nexthdr", "nexthdr ( 1 Byte)", base.DEC) 44local _daddr = ProtoField.bytes (nip_proto_name .. ".daddr", "daddr (1~8 Byte)", base.SPACE) 45local _saddr = ProtoField.bytes (nip_proto_name .. ".saddr", "saddr (1~8 Byte)", base.SPACE) 46local _hdr_len = ProtoField.uint8 (nip_proto_name .. ".hdr_len", "hdr_len ( 1 Byte)", base.DEC) 47local _trans_data = ProtoField.bytes (nip_proto_name .. ".trans_data", "trans_data", base.SPACE) 48 49-- 将字段添加都协议中 50nip_proto_obj.fields = { 51 _ttl, 52 _total_len, 53 _nexthdr, 54 _daddr, 55 _saddr, 56 _hdr_len, 57 _trans_data 58} 59--获取 _trans_data 解析器 60local _unknown_data_dis = Dissector.get("data") 61 62--定义 bitmap1 子菜单 63-- create a new protocol 64local bitmap1_name = "bitmap1" 65local bitmap1_desc = "bitmap1" 66local bitmap1_obj = Proto(bitmap1_name, bitmap1_desc) 67 68--[[ 69bitmap1 子菜单字段定义 70 ProtoField 参数: 71 para1 [必选] - 字段的缩写名称(过滤器中使用的字符串) 72 para2 [可选] - 字段的实际名称(出现在树中的字符串) 73 para3 [可选] - 字段类型 74--]] 75local _bitmap1 = ProtoField.uint8(bitmap1_name .. ".bitmap1", "bitmap1", base.HEX) 76local _pkt_hdr_type = ProtoField.uint8(bitmap1_name .. ".pkt_hdr_type", "pkt_hdr_type ", base.DEC, Payload_type, 0x80) --_bitmap1的8bit 77local _include_ttl = ProtoField.uint8(bitmap1_name .. ".include_ttl", "include_ttl ", base.DEC, Payload_type, 0x40) --_bitmap1的7bit 78local _include_total_len = ProtoField.uint8(bitmap1_name .. ".include_total_len", "include_total_len", base.DEC, Payload_type, 0x20) --_bitmap1的6bit 79local _include_nexthdr = ProtoField.uint8(bitmap1_name .. ".include_nexthdr", "include_nexthdr ", base.DEC, Payload_type, 0x10) --_bitmap1的5bit 80local _include_reserve1 = ProtoField.uint8(bitmap1_name .. ".include_reserve1", "include_reserve1 ", base.DEC, Payload_type, 0x08) --_bitmap1的4bit 81local _include_daddr = ProtoField.uint8(bitmap1_name .. ".include_daddr", "include_daddr ", base.DEC, Payload_type, 0x04) --_bitmap1的3bit 82local _include_saddr = ProtoField.uint8(bitmap1_name .. ".include_saddr", "include_saddr ", base.DEC, Payload_type, 0x02) --_bitmap1的2bit 83local _include_bitmap2 = ProtoField.uint8(bitmap1_name .. ".include_bitmap2", "include_bitmap2 ", base.DEC, Payload_type, 0x01) --_bitmap1的1bit 84 85-- 将字段添加都协议中 86bitmap1_obj.fields = { 87 _bitmap1, _pkt_hdr_type, _include_ttl, _include_total_len, _include_nexthdr, 88 _include_reserve1, _include_daddr, _include_saddr, _include_bitmap2 89} 90 91--定义 bitmap2 子菜单 92-- create a new protocol 93local bitmap2_name = "bitmap2" 94local bitmap2_desc = "bitmap2" 95local bitmap2_obj = Proto(bitmap2_name, bitmap2_desc) 96 97--[[ 98bitmap2 子菜单字段定义 99 ProtoField 参数: 100 para1 [必选] - 字段的缩写名称(过滤器中使用的字符串) 101 para2 [可选] - 字段的实际名称(出现在树中的字符串) 102 para3 [可选] - 字段类型 103--]] 104local _bitmap2 = ProtoField.uint8(bitmap2_name .. ".bitmap2", "bitmap2", base.HEX) 105local _include_hdr_len = ProtoField.uint8(bitmap2_name .. ".include_hdr_len", "include_hdr_len ", base.DEC, Payload_type, 0x80) --_bitmap2的8bit 106local _include_reserve2 = ProtoField.uint8(bitmap2_name .. ".include_reserve2", "include_reserve2", base.DEC, Payload_type, 0x40) --_bitmap2的7bit 107local _include_reserve3 = ProtoField.uint8(bitmap2_name .. ".include_reserve3", "include_reserve3", base.DEC, Payload_type, 0x20) --_bitmap2的6bit 108local _include_reserve4 = ProtoField.uint8(bitmap2_name .. ".include_reserve4", "include_reserve4", base.DEC, Payload_type, 0x10) --_bitmap2的5bit 109local _include_reserve5 = ProtoField.uint8(bitmap2_name .. ".include_reserve5", "include_reserve5", base.DEC, Payload_type, 0x08) --_bitmap2的4bit 110local _include_reserve6 = ProtoField.uint8(bitmap2_name .. ".include_reserve6", "include_reserve6", base.DEC, Payload_type, 0x04) --_bitmap2的3bit 111local _include_reserve7 = ProtoField.uint8(bitmap2_name .. ".include_reserve7", "include_reserve7", base.DEC, Payload_type, 0x02) --_bitmap2的2bit 112local _include_bitmap3 = ProtoField.uint8(bitmap2_name .. ".include_bitmap3", "include_bitmap3 ", base.DEC, Payload_type, 0x01) --_bitmap2的1bit 113 114-- 将字段添加都协议中 115bitmap2_obj.fields = { 116 _bitmap2, _include_hdr_len, _include_reserve2, _include_reserve3, _include_reserve4, 117 _include_reserve5, _include_reserve6, _include_reserve7, _include_bitmap3 118} 119 120--定义 nd icmp 子菜单 121-- create a new protocol 122local nd_icmp_name = "nd_icmp" 123local nd_icmp_desc = "nd_icmp" 124local nd_icmp_obj = Proto(nd_icmp_name, nd_icmp_desc) 125 126--[[ 127nd_icmp 子菜单字段定义 128 ProtoField 参数: 129 para1 [必选] - 字段的缩写名称(过滤器中使用的字符串) 130 para2 [可选] - 字段的实际名称(出现在树中的字符串) 131 para3 [可选] - 字段类型 132--]] 133local _type = ProtoField.uint8 (nd_icmp_name .. ".type", "type ( 1 Byte)", base.DEC) 134local _code = ProtoField.uint8 (nd_icmp_name .. ".code", "code ( 1 Byte)", base.DEC) 135local _checksum = ProtoField.uint16(nd_icmp_name .. ".checksum", "checksum( 2 Byte)", base.HEX) 136local _rs_daddr = ProtoField.bytes (nd_icmp_name .. ".rs_daddr", "rs_daddr(1~8 Byte)", base.SPACE) 137local _mac_len = ProtoField.uint8 (nd_icmp_name .. ".mac_len", "mac_len ( 1 Byte)", base.DEC) 138local _mac = ProtoField.bytes (nd_icmp_name .. ".mac", "mac ( 6 Byte)", base.SPACE) 139 140-- 将字段添加都协议中 141nd_icmp_obj.fields = { 142 _type, _code, _checksum, _rs_daddr, _mac_len, _mac 143} 144 145--[[ 146 下面定义 newip 解析器的主函数 147 第一个参数是 tvb 类型,表示的是需要此解析器解析的数据 148 第二个参数是 pinfo 类型,是协议解析树上的信息,包括 UI 上的显示 149 第三个参数是 treeitem 类型,表示上一级解析树 150--]] 151function nip_dissector(tvb, pinfo, treeitem) 152 --设置一些 UI 上面的信息 153 pinfo.cols.protocol:set(nip_proto_name) 154 pinfo.cols.info:set(nip_proto_desc) 155 156 local offset = 0 157 local tvb_len = tvb:len() 158 local nexthdr = 0 159 160 -- 在上一级解析树上创建 nip 的根节点 161 local nip_tree = treeitem:add(nip_proto_obj, tvb:range(tvb_len)) 162 163 local bitmap1 = tvb(offset, 1):uint() --表示从报文缓冲区0开始取1个字节 164 local pkt_hdr_type = bit.band(bit.rshift(bitmap1, 7), 0x00000001) --右移 7 位 与 0x01 相与,获取 pkt_hdr_type 位 165 local include_ttl = bit.band(bit.rshift(bitmap1, 6), 0x00000001) --右移 6 位 与 0x01 相与,获取 include_ttl 位 166 local include_total_len = bit.band(bit.rshift(bitmap1, 5), 0x00000001) --右移 5 位 与 0x01 相与,获取 include_total_len 位 167 local include_nexthdr = bit.band(bit.rshift(bitmap1, 4), 0x00000001) --右移 4 位 与 0x01 相与,获取 include_nexthdr 位 168 local include_daddr = bit.band(bit.rshift(bitmap1, 2), 0x00000001) --右移 2 位 与 0x01 相与,获取 include_daddr 位 169 local include_saddr = bit.band(bit.rshift(bitmap1, 1), 0x00000001) --右移 1 位 与 0x01 相与,获取 include_saddr 位 170 local include_bitmap2 = bit.band(bitmap1, 0x00000001) --获取 include_bitmap2 位 171 172 --nip报头无效(0表示有效) 173 if pkt_hdr_type ~= 0 then 174 return false 175 else 176 --bitmap1子菜单 177 local bitmap1_tree = nip_tree:add(bitmap1_obj, tvb:range(tvb_len)) 178 bitmap1_tree:add(_bitmap1, bitmap1) 179 bitmap1_tree:add(_pkt_hdr_type, bitmap1):append_text(" (".."0-New IP; 1-Reserve"..")") 180 bitmap1_tree:add(_include_ttl, bitmap1) 181 bitmap1_tree:add(_include_total_len, bitmap1) 182 bitmap1_tree:add(_include_nexthdr, bitmap1) 183 bitmap1_tree:add(_include_reserve1, bitmap1) 184 bitmap1_tree:add(_include_daddr, bitmap1) 185 bitmap1_tree:add(_include_saddr, bitmap1) 186 bitmap1_tree:add(_include_bitmap2, bitmap1) 187 offset = offset + 1 --_bitmap1 占用1字节 188 end 189 190 local include_hdr_len = 0 191 if include_bitmap2 ~= 0 then 192 --bitmap2子菜单 193 local bitmap2_tree = nip_tree:add(bitmap2_obj, tvb:range(tvb_len)) 194 local bitmap2 = tvb(offset, 1):uint() 195 include_hdr_len = bit.band(bit.rshift(bitmap2, 7), 0x00000001) --右移 7 位 与 0x01 相与,获取 include_hdr_len 位 196 offset = offset + 1 --_bitmap2 占用1字节 197 198 bitmap2_tree:add(_bitmap2, bitmap2) 199 bitmap2_tree:add(_include_hdr_len, bitmap2) 200 bitmap2_tree:add(_include_reserve2, bitmap2) 201 bitmap2_tree:add(_include_reserve3, bitmap2) 202 bitmap2_tree:add(_include_reserve4, bitmap2) 203 bitmap2_tree:add(_include_reserve5, bitmap2) 204 bitmap2_tree:add(_include_reserve6, bitmap2) 205 bitmap2_tree:add(_include_reserve7, bitmap2) 206 bitmap2_tree:add(_include_bitmap3, bitmap2) 207 end 208 209 if include_ttl ~= 0 then 210 nip_tree:add(_ttl, tvb(offset, 1)) 211 offset = offset + 1 --_ttl 占用1字节 212 end 213 214 if include_total_len ~= 0 then 215 nip_tree:add(_total_len, tvb(offset, 2)) 216 offset = offset + 2 --_total_len 占用2字节 217 end 218 219 if include_nexthdr ~= 0 then 220 nexthdr = tvb(offset, 1):uint() 221 nip_tree:add(_nexthdr, tvb(offset, 1)) 222 offset = offset + 1 --_nexthdr 占用1字节 223 end 224 225 if include_daddr ~= 0 then 226 local first_addr = tvb(offset, 1):uint() 227 local addr_len = get_nip_addr_len (first_addr) 228 if addr_len == 0 then 229 return false 230 end 231 nip_tree:add(_daddr, tvb(offset, addr_len)) 232 offset = offset + addr_len --_daddr 占用 addr_len 字节 233 end 234 235 if include_saddr ~= 0 then 236 local first_addr = tvb(offset, 1):uint() 237 local addr_len = get_nip_addr_len (first_addr) 238 if addr_len == 0 then 239 return false 240 end 241 nip_tree:add(_saddr, tvb(offset, addr_len)) 242 offset = offset + addr_len --_daddr 占用 addr_len 字节 243 end 244 245 if include_hdr_len ~= 0 then 246 nip_tree:add(_hdr_len, tvb(offset, 1)) 247 offset = offset + 1 --_hdr_len 占用1字节 248 end 249 250 --根据next header 确定上层协议 251 local trans_data = tvb(offset, tvb_len - offset) 252 if (nexthdr == 177) then 253 local nd_icmp_tree = nip_tree:add(nd_icmp_obj, tvb:range(tvb_len)) 254 local type = tvb(offset, 1):uint() 255 nd_icmp_tree:add(_type, tvb(offset, 1)) 256 offset = offset + 1 257 nd_icmp_tree:add(_code, tvb(offset, 1)) 258 offset = offset + 1 259 nd_icmp_tree:add(_checksum, tvb(offset, 2)) 260 offset = offset + 2 261 if type == 1 then 262 local first_addr = tvb(offset, 1):uint() 263 local addr_len = get_nip_addr_len (first_addr) 264 if addr_len == 0 then 265 return false 266 end 267 nd_icmp_tree:add(_rs_daddr, tvb(offset, addr_len)) 268 offset = offset + addr_len --_rs_daddr 占用 addr_len 字节 269 pinfo.cols.protocol = "ND request based NewIP" 270 else 271 nd_icmp_tree:add(_mac_len, tvb(offset, 1)) 272 offset = offset + 1 273 nd_icmp_tree:add(_mac, tvb(offset, 6)) 274 offset = offset + 6 275 pinfo.cols.protocol = "ND response based NewIP" 276 end 277 elseif (nexthdr == 6) then 278 Dissector.get("tcp"):call(trans_data:tvb(), pinfo, treeitem) 279 pinfo.cols.protocol = "TCP based NewIP" 280 elseif (nexthdr == 17) then 281 Dissector.get("udp"):call(trans_data:tvb(), pinfo, treeitem) 282 pinfo.cols.protocol = "UDP based NewIP" 283 else 284 nip_tree:add(_trans_data, trans_data) 285 end 286end 287 288--[[ 289 下面定义 NewIP 解析器的主函数,这个函数由 wireshark调用 290 第一个参数是 Tvb 类型,表示的是需要此解析器解析的数据 291 第二个参数是 Pinfo 类型,是协议解析树上的信息,包括 UI 上的显示 292 第三个参数是 TreeItem 类型,表示上一级解析树 293--]] 294function nip_proto_obj.dissector(tvb, pinfo, treeitem) 295 if nip_dissector(tvb, pinfo, treeitem) then 296 --valid NewIP diagram 297 else 298 --不是NewIP协议(其他未知协议)时,直接输出报文数据 299 _unknown_data_dis:call(tvb, pinfo, treeitem) 300 end 301 302end 303 304 305--向 wireshark 注册协议插件被调用的条件 306local ipn_encap_table = DissectorTable.get("ethertype") 307ipn_encap_table:add(0xEADD, nip_proto_obj) 308 309--NewIP地址长度计算 310function get_nip_addr_len (first_addr) 311 if first_addr <= 0xDC then 312 return 1 313 elseif first_addr >= 0xDD and first_addr <= 0xF0 then 314 return 2 315 elseif first_addr == 0xF1 then 316 return 3 317 elseif first_addr == 0xF2 then 318 return 5 319 elseif first_addr == 0xF3 then 320 return 7 321 elseif first_addr == 0xFE then 322 return 8 323 elseif first_addr == 0xFF then 324 return 2 325 else 326 return 0 327 end 328end 329 330end -- lua end 331