]> git.sur5r.net Git - ngadmin/blob - nsdp.lua
Added a dissector plugin for Wireshark.
[ngadmin] / nsdp.lua
1
2 p_nsdp=Proto("nsdp", "Netgear Switch Description Protocol")
3 local f_version=ProtoField.uint8("nsdp.version", "Version", base.DEC)
4 local f_code=ProtoField.uint8("nsdp.code", "Operation Code", base.DEC)
5 local f_error=ProtoField.uint8("nsdp.error", "Error Code", base.DEC)
6 local f_errattr=ProtoField.uint16("nsdp.errattr", "Erroneous Attribute", base.HEX)
7 local f_clientmac=ProtoField.ether("nsdp.clientmac", "Client MAC")
8 local f_switchmac=ProtoField.ether("nsdp.switchmac", "Switch MAC")
9 local f_seqnum=ProtoField.uint32("nsdp.seqnum", "Sequence Number", base.DEC)
10
11 local f_attr=ProtoField.uint16("", "Attribute", base.HEX)
12 local f_attr_code=ProtoField.uint16("", "Attribute Code", base.HEX)
13 local f_attr_length=ProtoField.uint16("", "Attribute Length", base.DEC)
14 local f_attr_data=ProtoField.bytes("", "Attribute Data")
15
16 local f_attr_product=ProtoField.string("", "Product")
17 local f_attr_name=ProtoField.string("", "Name")
18 local f_attr_mac=ProtoField.ether("", "MAC")
19 local f_attr_ip=ProtoField.ipv4("", "IP")
20 local f_attr_mask=ProtoField.ipv4("", "Mask")
21 local f_attr_gateway=ProtoField.ipv4("", "Gateway")
22 local f_attr_newpassword=ProtoField.string("", "New Password")
23 local f_attr_password=ProtoField.string("", "Password")
24 local f_attr_dhcp=ProtoField.bool("", "DHCP")
25 local f_attr_firmver=ProtoField.string("", "Firmare Version")
26 local f_attr_portscount=ProtoField.uint8("", "Ports Count", base.DEC)
27 local f_attr_port=ProtoField.uint8("", "Port", base.DEC)
28 local f_attr_port_status=ProtoField.uint8("", "Port Status", base.DEC)
29
30 p_nsdp.fields={
31  f_version, f_code, f_error, f_errattr, f_clientmac, f_switchmac, f_seqnum, 
32  f_attr, f_attr_code, f_attr_length, f_attr_data, 
33  f_attr_product, f_attr_name, f_attr_mac, f_attr_ip, f_attr_mask, f_attr_gateway, f_attr_newpassword, f_attr_password, f_attr_portscount, 
34  f_attr_dhcp, f_attr_port, f_attr_port_status, f_attr_firmver
35 }
36
37
38
39 local op_codes={
40  [1]="Read Request", 
41  [2]="Read Reply", 
42  [3]="Write Request", 
43  [4]="Write Reply"
44 }
45
46
47 local error_codes={
48  [0]="OK", 
49  [5]="Invalid Value", 
50  [7]="Invalid Password"
51 }
52
53
54 local status_codes={
55  [0]="down", 
56  [4]="100M", 
57  [5]="1000M"
58 }
59
60
61
62
63
64 function dissect_port_status (buffer, offset, subtree)
65  
66  subtree:add(f_attr_port, buffer(offset+4, 1))
67  subtree:add(f_attr_port_status, buffer(offset+5, 1)):append_text(" ("..(status_codes[buffer(offset+5, 1):uint()] or "unk")..")")
68  
69 end
70
71
72
73
74
75 local attributes={
76  [0x0001]={name="Product", dissect=f_attr_product}, 
77  [0x0003]={name="Name", dissect=f_attr_name}, 
78  [0x0004]={name="MAC", dissect=f_attr_mac}, 
79  [0x0006]={name="IP", dissect=f_attr_ip}, 
80  [0x0007]={name="Mask", dissect=f_attr_mask}, 
81  [0x0008]={name="Gateway", dissect=f_attr_gateway}, 
82  [0x0009]={name="New Password", dissect=f_attr_newpassword}, 
83  [0x000A]={name="Password", dissect=f_attr_password}, 
84  [0x000B]={name="DHCP", dissect=f_attr_dhcp}, 
85  [0x000D]={name="Firmware Version", dissect=f_attr_firmver}, 
86  [0x0C00]={name="Port Status", dissect=dissect_port_status}, 
87  [0x6000]={name="Ports Count", dissect=f_attr_portscount}
88 }
89
90
91
92
93
94 function dissect_header (buffer, subtree)
95  
96  subtree:add(f_version, buffer(0, 1))
97  
98  subtree:add(f_code, buffer(1, 1)):append_text(" ("..(op_codes[buffer(1, 1):uint()] or "unknown")..")")
99  
100  local errcode=buffer(2, 1):uint()
101  subtree:add(f_error, buffer(2, 1)):append_text(" ("..(error_codes[errcode] or "unknown")..")")
102  
103  -- print the erroneous attribute if an error occurred
104  if ( errcode~=0 ) then
105   local atf=attributes[buffer(4, 2):uint()]
106   subtree:add(f_errattr, buffer(4, 2)):append_text(" ("..(atf and atf.name or "unk")..")")
107  end
108  
109  subtree:add(f_clientmac, buffer(8, 6))
110  
111  subtree:add(f_switchmac, buffer(14, 6))
112  
113  subtree:add(f_seqnum, buffer(20, 4))
114  
115  
116 end
117
118
119
120 function dissect_attributes (buffer, subtree)
121  
122  local offset=32
123  
124  while ( offset<buffer:len() ) do
125   
126   local code=buffer(offset, 2):uint()
127   local len=buffer(offset+2, 2):uint()
128   local atf=attributes[code]
129   
130   local attr=subtree:add(f_attr, buffer(offset, 4+len), code)
131   attr:append_text(" ("..(atf and atf.name or "unk")..")")
132   
133   attr:add(f_attr_code, buffer(offset, 2))
134   
135   attr:add(f_attr_length, buffer(offset+2, 2))
136   
137   if ( len<=0 ) then
138    -- no data, display nothing
139   elseif ( atf==nil ) then
140    -- unknown attribute, display raw bytes
141    attr:add(f_attr_data, buffer(offset+4, len))
142   elseif ( type(atf.dissect)=="function" ) then
143    -- custom sub-dissector for complex type
144    atf.dissect(buffer, offset, attr)
145   else
146    -- simple type, directly use field
147    attr:add(atf.dissect, buffer(offset+4, len))
148   end
149   
150   offset=offset+4+len
151   
152  end
153  
154 end
155
156
157
158 function p_nsdp.dissector (buffer, pinfo, tree)
159  
160  pinfo.cols.protocol=p_nsdp.name
161  local subtree=tree:add(p_nsdp, buffer())
162  
163  -- stop if the packet is too small to be valid
164  if ( buffer:len()<32 ) then return end
165  
166  dissect_header(buffer, subtree)
167  
168  -- stop if it is just a header
169  if ( buffer:len()<=32 ) then return end
170  
171  local attr_list=subtree:add(buffer(32), "Attributes list")
172  dissect_attributes(buffer, attr_list)
173  
174 end
175
176
177
178 function p_nsdp.init ()
179 end
180
181
182
183 local udp_dissector_table=DissectorTable.get("udp.port")
184 dissector=udp_dissector_table:get_dissector(63322)
185 udp_dissector_table:add(63322, p_nsdp)
186
187