1 /* packet-waveagent.c
2  * Routines for WaveAgent dissection
3  * Copyright 2009-2011, Tom Cook <tcook@ixiacom.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  * *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include <epan/packet.h>
15 #define ETHERNET_INTERFACE      1
16 #define WLAN_INTERFACE          2
17 
18 #define IPV4_TYPE               2
19 #define IPV6_TYPE               10
20 
21 #define NUM_STATE_CHANGES       8
22 #define NUM_BSS                 8
23 #define SHORT_STR               256
24 
25 #define WA_V2_PAYLOAD_OFFSET    40
26 #define WA_V3_PAYLOAD_OFFSET    44
27 
28 void proto_register_waveagent(void);
29 void proto_reg_handoff_waveagent(void);
30 
31 /* Initialize the protocol and registered fields */
32 static int proto_waveagent = -1;
33 static int hf_waveagent_controlword = -1;
34 static int hf_waveagent_payloadlen = -1;
35 static int hf_waveagent_transnum = -1;
36 static int hf_waveagent_rtoken = -1;
37 static int hf_waveagent_flowid = -1;
38 static int hf_waveagent_capstatus = -1;
39 static int hf_waveagent_protocolversion = -1;
40 static int hf_waveagent_capimpl = -1;
41 static int hf_waveagent_id = -1;
42 static int hf_waveagent_bindtag = -1;
43 static int hf_waveagent_version = -1;
44 static int hf_waveagent_brokerip = -1;
45 static int hf_waveagent_brokerport = -1;
46 static int hf_waveagent_bindlevel = -1;
47 static int hf_waveagent_bindport = -1;
48 static int hf_waveagent_numinterfaces = -1;
49 static int hf_waveagent_capabilities2 = -1;
50 static int hf_waveagent_ifmask = -1;
51 static int hf_waveagent_commandstatus = -1;
52 static int hf_waveagent_syserrno = -1;
53 static int hf_waveagent_statusstring = -1;
54 static int hf_waveagent_rxdatapckts = -1;
55 static int hf_waveagent_rxdatabytes = -1;
56 static int hf_waveagent_rxpcktrate = -1;
57 static int hf_waveagent_rxbyterate = -1;
58 static int hf_waveagent_txdatapckts = -1;
59 static int hf_waveagent_txdatabytes = -1;
60 static int hf_waveagent_txpcktrate = -1;
61 static int hf_waveagent_txbyterate = -1;
62 static int hf_waveagent_looppckts = -1;
63 static int hf_waveagent_loopbytes = -1;
64 static int hf_waveagent_rxctlpckts = -1;
65 static int hf_waveagent_rxctlbytes = -1;
66 static int hf_waveagent_txctlpckts = -1;
67 static int hf_waveagent_txctlbytes = -1;
68 static int hf_waveagent_unknowncmds = -1;
69 static int hf_waveagent_snap = -1;
70 static int hf_waveagent_state = -1;
71 static int hf_waveagent_appstate = -1;
72 static int hf_waveagent_rx1pl = -1;
73 static int hf_waveagent_rx2pl = -1;
74 static int hf_waveagent_rx3pl = -1;
75 static int hf_waveagent_rx4pl = -1;
76 static int hf_waveagent_rx5pl = -1;
77 static int hf_waveagent_rxoospkts = -1;
78 /* static int hf_waveagent_rxmeanlatency = -1; */
79 /* static int hf_waveagent_rxminlatency = -1; */
80 /* static int hf_waveagent_rxmaxlatency = -1; */
81 static int hf_waveagent_latencysum = -1;
82 static int hf_waveagent_latencycount = -1;
83 static int hf_waveagent_txflowstop = -1;
84 static int hf_waveagent_jitter = -1;
85 static int hf_waveagent_remoteport = -1;
86 static int hf_waveagent_remoteaddr = -1;
87 static int hf_waveagent_dscp = -1;
88 static int hf_waveagent_fsflags = -1;
89 static int hf_waveagent_fscbrflag = -1;
90 static int hf_waveagent_fscombinedsetupflag = -1;
91 /* static int hf_waveagent_totalbytes = -1; */
92 static int hf_waveagent_payfill = -1;
93 static int hf_waveagent_paysize = -1;
94 static int hf_waveagent_avgrate = -1;
95 static int hf_waveagent_rxflownum = -1;
96 static int hf_waveagent_mode = -1;
97 static int hf_waveagent_endpointtype = -1;
98 static int hf_waveagent_totalframes = -1;
99 static int hf_waveagent_bssidstartindex = -1;
100 static int hf_waveagent_bssidstopindex = -1;
101 static int hf_waveagent_ifindex = -1;
102 static int hf_waveagent_iftype = -1;
103 static int hf_waveagent_ifdescription = -1;
104 static int hf_waveagent_ifmacaddr = -1;
105 static int hf_waveagent_iflinkspeed = -1;
106 static int hf_waveagent_ifdhcp = -1;
107 static int hf_waveagent_ifwlanbssid = -1;
108 static int hf_waveagent_ifwlanssid = -1;
109 static int hf_waveagent_ifiptype = -1;
110 static int hf_waveagent_ifipv4 = -1;
111 static int hf_waveagent_ifipv6 = -1;
112 static int hf_waveagent_ifdhcpserver = -1;
113 static int hf_waveagent_ifgateway = -1;
114 static int hf_waveagent_ifdnsserver = -1;
115 static int hf_waveagent_ifethl2status = -1;
116 static int hf_waveagent_ifwlanl2status = -1;
117 static int hf_waveagent_ifl3status = -1;
118 static int hf_waveagent_totalbssid = -1;
119 static int hf_waveagent_returnedbssid = -1;
120 static int hf_waveagent_scanbssid = -1;
121 static int hf_waveagent_scanssid = -1;
122 static int hf_waveagent_ifwlanrssi = -1;
123 static int hf_waveagent_ifwlansupprates = -1;
124 static int hf_waveagent_ifwlancapabilities = -1;
125 static int hf_waveagent_ifwlanchannel = -1;
126 static int hf_waveagent_ifwlanprivacy = -1;
127 static int hf_waveagent_ifwlanbssmode = -1;
128 static int hf_waveagent_ifwlannoise = -1;
129 static int hf_waveagent_ifphytypes = -1;
130 static int hf_waveagent_ifphytypebit0 = -1;
131 static int hf_waveagent_ifphytypebit1 = -1;
132 static int hf_waveagent_ifphytypebit2 = -1;
133 static int hf_waveagent_ifphytypebit3 = -1;
134 /* static int hf_waveagent_ifphytypebit4 = -1; */
135 static int hf_waveagent_ifwlanauthentication = -1;
136 static int hf_waveagent_ifwlancipher = -1;
137 static int hf_waveagent_delayfactor = -1;
138 static int hf_waveagent_medialossrate = -1;
139 static int hf_waveagent_txstartts = -1;
140 static int hf_waveagent_txendts = -1;
141 static int hf_waveagent_rxstartts = -1;
142 static int hf_waveagent_rxendts = -1;
143 static int hf_waveagent_oidcode = -1;
144 static int hf_waveagent_oidvalue = -1;
145 static int hf_waveagent_destip = -1;
146 static int hf_waveagent_destport = -1;
147 static int hf_waveagent_connectflags = -1;
148 static int hf_waveagent_connecttype = -1;
149 static int hf_waveagent_minrssi = -1;
150 static int hf_waveagent_connecttimeout = -1;
151 static int hf_waveagent_connectattempts = -1;
152 static int hf_waveagent_reason = -1;
153 static int hf_waveagent_sigsequencenum = -1;
154 static int hf_waveagent_relaydestid = -1;
155 static int hf_waveagent_relaysrcid = -1;
156 static int hf_waveagent_relaymessagest = -1;
157 
158 /* Initialize the subtree pointers */
159 static gint ett_waveagent = -1;
160 static gint ett_statechange = -1;
161 static gint ett_phytypes = -1;
162 static gint ett_fsflags = -1;
163 static gint ett_scindex[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };  /* NUM_STATE_CHANGES */
164 static gint ett_bss[8]     = { -1, -1, -1, -1, -1, -1, -1, -1 };  /* NUM_BSS           */
165 static gint ett_relaymessage = -1;
166 
167 
168 static const value_string control_words[] = {
169     { 0x01, "Receive, Count, Discard"},
170     { 0x02, "Receive, Count, Loopback"},
171     { 0x03, "Receive, Count, Push timestamp, Discard"},
172     { 0x04, "Receive, Count, Push timestamp, Loopback"},
173     { 0x08, "Transmit"},
174     { 0x11, "Start Flow"},
175     { 0x12, "Stop Flow"},
176     { 0x20, "Stats Reset"},
177     { 0x21, "Stats Request"},
178     { 0x22, "Flow Stats Reset"},
179     { 0x23, "Scan Results Request"},
180     { 0x24, "Interface Info Request"},
181     { 0x25, "Interface Change Info Request"},
182     { 0x26, "OID Request"},
183     { 0x2e, "Scan Results Response"},
184     { 0x2f, "Stats Response"},
185     { 0x30, "Interface Info Response"},
186     { 0x31, "Interface Change Info Response"},
187     { 0x32, "OID Response"},  /* XXX: is this correct ? entry originally located after 0x41 */
188     { 0x3e, "Relay Message"},
189     { 0x3f, "Relay Response"},
190     { 0x40, "Client Connect Request"},
191     { 0x41, "Client Disconnect Request"},
192     { 0x80, "Capabilities Request"},
193     { 0x81, "Capabilities Response"},
194     { 0x82, "Reserve Request"},
195     { 0x84, "Release Request"},
196     { 0x85, "Flow Setup"},
197     { 0x86, "Flow Destroy"},
198     { 0x87, "Flow Connect"},
199     { 0x88, "Flow Disconnect"},
200     { 0x89, "Flow Listen"},
201     { 0x8a, "Scan Request"},
202     { 0x8b, "Learning Message"},
203     { 0x8f, "Command Response"},
204     { 0, NULL},
205 };
206 static value_string_ext control_words_ext = VALUE_STRING_EXT_INIT(control_words);
207 
208 /* Dissects the WLAN interface stats structure */
dissect_wlan_if_stats(guint32 starting_offset,proto_item * parent_tree,tvbuff_t * tvb)209 static void dissect_wlan_if_stats(guint32 starting_offset, proto_item *parent_tree, tvbuff_t *tvb)
210 {
211     proto_item *phy_types;
212     proto_tree *phy_types_tree;
213     guint32     phy_types_bitfield, noise_floor;
214 
215     proto_tree_add_item(parent_tree,
216         hf_waveagent_ifwlanbssid, tvb, starting_offset, 6, ENC_NA);
217 
218     /* two bytes of pad go here */
219 
220     proto_tree_add_item(parent_tree,
221         hf_waveagent_ifwlanssid, tvb, starting_offset + 8, 32, ENC_ASCII|ENC_NA);
222 
223     /* 4 byte SSID length field not reported */
224 
225     proto_tree_add_item(parent_tree,
226         hf_waveagent_ifwlanrssi, tvb, starting_offset + 44, 4, ENC_BIG_ENDIAN);
227 
228     noise_floor = tvb_get_ntohl(tvb, starting_offset + 48);
229 
230     if (noise_floor != 0x7fffffff) {
231         proto_tree_add_item(parent_tree,
232             hf_waveagent_ifwlannoise, tvb, starting_offset + 48, 4, ENC_BIG_ENDIAN);
233     }
234     else {
235         proto_tree_add_int_format_value(parent_tree,
236             hf_waveagent_ifwlannoise, tvb, starting_offset + 48, 4, noise_floor,
237             "Not Reported");
238     }
239 
240     phy_types_bitfield = tvb_get_ntohl(tvb, starting_offset + 52);
241 
242     phy_types = proto_tree_add_uint(parent_tree, hf_waveagent_ifphytypes,
243                                 tvb, starting_offset + 52, 4, phy_types_bitfield);
244 
245     phy_types_tree = proto_item_add_subtree(phy_types, ett_phytypes);
246 
247     proto_tree_add_item(phy_types_tree,
248             hf_waveagent_ifphytypebit0, tvb, starting_offset + 55, 1, ENC_LITTLE_ENDIAN);
249 
250     proto_tree_add_item(phy_types_tree,
251             hf_waveagent_ifphytypebit1, tvb, starting_offset + 55, 1, ENC_LITTLE_ENDIAN);
252 
253     proto_tree_add_item(phy_types_tree,
254             hf_waveagent_ifphytypebit2, tvb, starting_offset + 55, 1, ENC_LITTLE_ENDIAN);
255 
256     proto_tree_add_item(phy_types_tree,
257             hf_waveagent_ifphytypebit3, tvb, starting_offset + 55, 1, ENC_LITTLE_ENDIAN);
258 
259     proto_tree_add_item(parent_tree,
260         hf_waveagent_ifwlanauthentication, tvb, starting_offset + 56, 4, ENC_BIG_ENDIAN);
261 
262     proto_tree_add_item(parent_tree,
263         hf_waveagent_ifwlancipher, tvb, starting_offset + 60, 4, ENC_BIG_ENDIAN);
264 }
265 
dissect_wa_payload(guint32 starting_offset,proto_item * parent_tree,tvbuff_t * tvb,guint32 control_word,guint8 version)266 static void dissect_wa_payload(guint32 starting_offset, proto_item *parent_tree, tvbuff_t *tvb, guint32 control_word, guint8 version)
267 {
268     switch (control_word)
269     {
270         case 0x11:   /* Flow start message */
271             proto_tree_add_item(parent_tree,
272                 hf_waveagent_payfill, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
273 
274             proto_tree_add_item(parent_tree,
275                 hf_waveagent_paysize, tvb, starting_offset+4, 4, ENC_BIG_ENDIAN);
276 
277             proto_tree_add_item(parent_tree,
278                 hf_waveagent_avgrate, tvb, starting_offset+8, 4, ENC_BIG_ENDIAN);
279 
280             proto_tree_add_item(parent_tree,
281                 hf_waveagent_totalframes, tvb, starting_offset+12, 4, ENC_BIG_ENDIAN);
282 
283             break;
284 
285         case 0x23:   /* Scan results request */
286             proto_tree_add_item(parent_tree,
287                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
288 
289             proto_tree_add_item(parent_tree,
290                 hf_waveagent_bssidstartindex, tvb, starting_offset+4, 4, ENC_BIG_ENDIAN);
291 
292             proto_tree_add_item(parent_tree,
293                 hf_waveagent_bssidstopindex, tvb, starting_offset+8, 4, ENC_BIG_ENDIAN);
294 
295             break;
296 
297         case 0x24:   /* Interface info request */
298         case 0x25:   /* Interface change info request */
299         case 0x8a:   /* Scan request */
300             proto_tree_add_item(parent_tree,
301                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
302 
303             break;
304 
305         case 0x26:   /* OID request */
306             proto_tree_add_item(parent_tree,
307                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
308 
309             proto_tree_add_item(parent_tree,
310                 hf_waveagent_oidcode, tvb, starting_offset+4, 4, ENC_BIG_ENDIAN);
311 
312             break;
313 
314         case 0x30: {  /* Interface stats response */
315             guint32 if_type;
316 
317             proto_tree_add_item(parent_tree,
318                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
319 
320             if_type = tvb_get_ntohl(tvb, starting_offset + 4);
321 
322             proto_tree_add_item(parent_tree,
323                 hf_waveagent_iftype, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
324 
325             proto_tree_add_item(parent_tree,
326                 hf_waveagent_ifdhcp, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
327 
328             proto_tree_add_item(parent_tree,
329                 hf_waveagent_ifmacaddr, tvb, starting_offset + 12, 6, ENC_NA);
330 
331             /* 2 bytes of pad go here */
332 
333             proto_tree_add_item(parent_tree,
334                 hf_waveagent_iflinkspeed, tvb, starting_offset + 20, 4, ENC_BIG_ENDIAN);
335 
336             proto_tree_add_item(parent_tree,
337                 hf_waveagent_ifdescription, tvb, starting_offset + 24, 128, ENC_ASCII|ENC_NA);
338 
339             /* 4 byte length field goes here - skip it */
340 
341             /* two bytes of pad go here */
342 
343             /* If we have WLAN interface, then report the following */
344             if (if_type == WLAN_INTERFACE)
345                 dissect_wlan_if_stats(starting_offset + 156, parent_tree, tvb);
346 
347             /* Next come the BindingAddress fields (for each address):
348                 2 bytes:  IP type (v4 or v6)
349                 2 bytes:  address length
350                 4 bytes:  service number (not used)
351                 16 bytes: IP address     */
352 
353             /* for the bound IP address, report both IP type and address */
354 
355             proto_tree_add_item(parent_tree,
356                 hf_waveagent_ifiptype, tvb, starting_offset + 252, 2, ENC_BIG_ENDIAN);
357 
358             if (tvb_get_ntohs(tvb, starting_offset + 252) == IPV4_TYPE) {
359                 proto_tree_add_item(parent_tree,
360                     hf_waveagent_ifipv4, tvb, starting_offset + 260, 4, ENC_BIG_ENDIAN);  /* grab the last 4 bytes of the IP address field */
361             }
362             else {
363                 proto_tree_add_item(parent_tree,
364                     hf_waveagent_ifipv6, tvb, starting_offset + 260, 16, ENC_NA);
365             }
366 
367             proto_tree_add_item(parent_tree,
368                 hf_waveagent_ifdhcpserver, tvb, starting_offset + 284, 4, ENC_BIG_ENDIAN);
369 
370             proto_tree_add_item(parent_tree,
371                 hf_waveagent_ifgateway,    tvb, starting_offset + 308, 4, ENC_BIG_ENDIAN);
372 
373             proto_tree_add_item(parent_tree,
374                 hf_waveagent_ifdnsserver,  tvb, starting_offset + 332, 4, ENC_BIG_ENDIAN);
375 
376             break;
377         }
378 
379         case 0x31:  {  /* Interface change info response */
380             guint32 offset;
381             guint32 if_type;
382             guint32 delta;
383             guint32 iLoop;
384 
385             proto_tree_add_item(parent_tree,
386                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
387 
388             if_type = tvb_get_ntohl(tvb, starting_offset + 4);
389 
390             proto_tree_add_item(parent_tree,
391                 hf_waveagent_iftype, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
392 
393             offset = starting_offset + 8;
394             delta = 156;
395 
396             for (iLoop = 0; iLoop < NUM_STATE_CHANGES; iLoop++) {
397                 proto_item *stIndex;
398                 proto_tree *st_change_index_tree;
399                 guint32     if_status;
400                 int         current_offset;
401 
402                 current_offset = offset + iLoop * delta;
403 
404                 /* Check to see if the interface entry is valid */
405                 if_status = tvb_get_ntohl(tvb, current_offset);
406                 if (if_status == 0) continue;  /* No entry at this index, keep going */
407 
408                 /* Add index specific trees to hide the details */
409                 stIndex = proto_tree_add_uint_format_value(parent_tree,
410                     hf_waveagent_ifwlanl2status, tvb, current_offset, 4, if_status, "Interface state change %d", iLoop);
411 
412                 st_change_index_tree = proto_item_add_subtree(stIndex, ett_scindex[iLoop]);
413 
414                 if (if_type == WLAN_INTERFACE) {
415                     proto_tree_add_item(st_change_index_tree,
416                         hf_waveagent_ifwlanl2status, tvb, current_offset, 4, ENC_BIG_ENDIAN);
417                 } else {
418                     proto_tree_add_item(st_change_index_tree,
419                         hf_waveagent_ifethl2status, tvb, current_offset, 4, ENC_BIG_ENDIAN);
420                 }
421 
422                 proto_tree_add_item(st_change_index_tree,
423                     hf_waveagent_ifl3status, tvb, current_offset + 4, 4, ENC_BIG_ENDIAN);
424 
425                 proto_tree_add_item(st_change_index_tree,
426                     hf_waveagent_iflinkspeed, tvb, current_offset + 8, 4, ENC_BIG_ENDIAN);
427 
428                 if (if_type == WLAN_INTERFACE) {
429                     dissect_wlan_if_stats(current_offset + 12, st_change_index_tree, tvb);
430                 }
431 
432                 proto_tree_add_item(st_change_index_tree,
433                     hf_waveagent_snap, tvb, current_offset + 108, 8, ENC_BIG_ENDIAN);
434 
435                 proto_tree_add_item(st_change_index_tree,
436                     hf_waveagent_ifiptype, tvb, current_offset + 116, 2, ENC_BIG_ENDIAN);
437 
438                 if (tvb_get_ntohs(tvb, current_offset + 116) == IPV4_TYPE) {
439                     proto_tree_add_item(st_change_index_tree,
440                         hf_waveagent_ifipv4, tvb, current_offset + 124, 4, ENC_BIG_ENDIAN);  /* grab the last 4 bytes of the IP address field */
441                 }
442                 else {
443                     proto_tree_add_item(st_change_index_tree,
444                         hf_waveagent_ifipv6, tvb, current_offset + 124, 16, ENC_NA);
445                 }
446 
447                 /* 16 bytes of padding */
448             }
449 
450             break;
451         }
452 
453         case 0x32:   /* OID response */
454             proto_tree_add_item(parent_tree,
455                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
456 
457             proto_tree_add_item(parent_tree,
458                 hf_waveagent_oidcode, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
459 
460             proto_tree_add_item(parent_tree,
461                 hf_waveagent_oidvalue, tvb, starting_offset + 12, 1024, ENC_ASCII|ENC_NA);
462 
463             break;
464 
465         case 0x2e: {  /* scan results response message */
466             guint32        offset;
467             proto_item    *pi;
468             guint32        num_bss_entries;
469             guint32        tag_len;
470             guint32        delta;
471             guint32        iLoop;
472             wmem_strbuf_t *sb;
473 
474             proto_tree_add_item(parent_tree,
475                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
476 
477 
478             proto_tree_add_item(parent_tree,
479                 hf_waveagent_totalbssid, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
480 
481             pi = proto_tree_add_item(parent_tree,
482                 hf_waveagent_returnedbssid, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
483 
484             num_bss_entries = tvb_get_ntohl(tvb, starting_offset + 8);
485 
486             if (num_bss_entries > NUM_BSS) {
487                 proto_item_append_text(pi, " [**Too large: Limiting to " G_STRINGIFY(NUM_BSS) "]");
488                 num_bss_entries = NUM_BSS;
489             }
490             /* Add 4 bytes of pad for the offset */
491 
492             offset = starting_offset + 16;
493             delta  = 148;
494 
495             sb = wmem_strbuf_sized_new(wmem_packet_scope(), 8, SHORT_STR);
496 
497             for (iLoop = 0; iLoop < num_bss_entries; iLoop++)
498             {
499                 proto_item *bssIndex;
500                 proto_tree *bss_tree;
501                 int         current_offset;
502 
503                 wmem_strbuf_truncate(sb, 0);
504 
505                 current_offset = offset + iLoop * delta;
506 
507                 bssIndex = proto_tree_add_item(parent_tree,
508                     hf_waveagent_scanssid, tvb, current_offset, 32, ENC_ASCII|ENC_NA);
509 
510                 bss_tree = proto_item_add_subtree(bssIndex, ett_bss[iLoop]);
511 
512                 tag_len = tvb_get_ntohl(tvb, current_offset + 52);
513 
514                 if (tag_len != 0) {
515                     guint32       isr;
516                     guint8        isr_value;
517 
518                     for (isr = 0; isr < tag_len; isr++) {
519                         isr_value = tvb_get_guint8(tvb, offset + 36 + isr);
520                         if (isr_value == 0xFF){
521                             proto_tree_add_string (bss_tree, hf_waveagent_ifwlansupprates, tvb, offset + 36 + isr,
522                                                    1,
523                                                    "BSS requires support for mandatory features of HT PHY (IEEE 802.11"
524                                                    " - Clause 20)");
525                         } else {
526                             wmem_strbuf_append_printf(sb, "%2.1f%s ",
527                                       (isr_value & 0x7F) * 0.5,
528                                       (isr_value & 0x80) ? "(B)" : "");
529 
530                         }
531                     }
532                     wmem_strbuf_append(sb, " [Mbit/sec]");
533                 }
534                 else {
535                     wmem_strbuf_append(sb, "Not defined");
536                 }
537 
538                 proto_tree_add_string (bss_tree, hf_waveagent_ifwlansupprates, tvb, offset + 36,
539                     tag_len, wmem_strbuf_get_str(sb));
540 
541                 proto_tree_add_item(bss_tree,
542                     hf_waveagent_scanbssid, tvb, current_offset + 56, 6, ENC_NA);
543 
544                 proto_tree_add_item(bss_tree,
545                     hf_waveagent_ifwlancapabilities, tvb, current_offset + 62, 2, ENC_BIG_ENDIAN);
546 
547                 proto_tree_add_item(bss_tree,
548                     hf_waveagent_ifwlanrssi, tvb, current_offset + 64, 4, ENC_BIG_ENDIAN);
549 
550                 /*  For now this is just a 4 byte pad, so comment it out...  */
551 #if 0
552                 proto_tree_add_item(bss_tree,
553                     hf_waveagent_ifwlansigquality, tvb, current_offset + 68, 4, ENC_BIG_ENDIAN);
554 #endif
555                 proto_tree_add_item(bss_tree,
556                     hf_waveagent_ifwlanchannel, tvb, current_offset + 72, 4, ENC_BIG_ENDIAN);
557 
558                 proto_tree_add_item(bss_tree,
559                     hf_waveagent_ifwlanprivacy, tvb, current_offset + 76, 4, ENC_BIG_ENDIAN);
560 
561                 proto_tree_add_item(bss_tree,
562                     hf_waveagent_ifwlanbssmode, tvb, current_offset + 80, 4, ENC_BIG_ENDIAN);
563             }
564             break;
565         }
566 
567         case 0x2f:   /* Stats response message */
568             if (version < 3) {
569                 /* For version 2 WA protocol the capability status is not in the header but in the CAP
570                    RESPONSE.  Need to read it here and then advance the payload offset.  This is a
571                    packet that had a structure change in the beginning of the packet when moving
572                    to v3 */
573                 proto_tree_add_item(parent_tree,
574                     hf_waveagent_capstatus, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
575 
576                 proto_tree_add_item(parent_tree,
577                     hf_waveagent_protocolversion, tvb, starting_offset, 1, ENC_BIG_ENDIAN);
578 
579                 starting_offset += 4;
580             }
581 
582             proto_tree_add_item(parent_tree,
583                 hf_waveagent_capimpl, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
584 
585             proto_tree_add_item(parent_tree,
586                        hf_waveagent_state, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
587 
588             proto_tree_add_item(parent_tree,
589                        hf_waveagent_appstate, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
590 
591             proto_tree_add_item(parent_tree,
592                 hf_waveagent_rxdatapckts, tvb, starting_offset + 12, 8, ENC_BIG_ENDIAN);
593 
594             proto_tree_add_item(parent_tree,
595                 hf_waveagent_rxdatabytes, tvb, starting_offset + 20, 8, ENC_BIG_ENDIAN);
596 
597             proto_tree_add_item(parent_tree,
598                 hf_waveagent_rxpcktrate, tvb, starting_offset + 28, 8, ENC_BIG_ENDIAN);
599 
600             proto_tree_add_item(parent_tree,
601                 hf_waveagent_rxbyterate, tvb, starting_offset + 36, 8, ENC_BIG_ENDIAN);
602 
603             proto_tree_add_item(parent_tree,
604                 hf_waveagent_txdatapckts, tvb, starting_offset + 44, 8, ENC_BIG_ENDIAN);
605 
606             proto_tree_add_item(parent_tree,
607                 hf_waveagent_txdatabytes, tvb, starting_offset + 52, 8, ENC_BIG_ENDIAN);
608 
609             proto_tree_add_item(parent_tree,
610                 hf_waveagent_txpcktrate, tvb, starting_offset + 60, 8, ENC_BIG_ENDIAN);
611 
612             proto_tree_add_item(parent_tree,
613                 hf_waveagent_txbyterate, tvb, starting_offset + 68, 8, ENC_BIG_ENDIAN);
614 
615             proto_tree_add_item(parent_tree,
616                 hf_waveagent_looppckts, tvb, starting_offset + 76, 8, ENC_BIG_ENDIAN);
617 
618             proto_tree_add_item(parent_tree,
619                 hf_waveagent_loopbytes, tvb, starting_offset + 84, 8, ENC_BIG_ENDIAN);
620 
621             proto_tree_add_item(parent_tree,
622                 hf_waveagent_rxctlpckts, tvb, starting_offset + 92, 8, ENC_BIG_ENDIAN);
623 
624             proto_tree_add_item(parent_tree,
625                 hf_waveagent_rxctlbytes, tvb, starting_offset + 100, 8, ENC_BIG_ENDIAN);
626 
627             proto_tree_add_item(parent_tree,
628                 hf_waveagent_txctlpckts, tvb, starting_offset + 108, 8, ENC_BIG_ENDIAN);
629 
630             proto_tree_add_item(parent_tree,
631                 hf_waveagent_txctlbytes, tvb, starting_offset + 116, 8, ENC_BIG_ENDIAN);
632 
633             proto_tree_add_item(parent_tree,
634                 hf_waveagent_unknowncmds, tvb, starting_offset + 124, 8, ENC_BIG_ENDIAN);
635 
636             proto_tree_add_item(parent_tree,
637                 hf_waveagent_snap, tvb, starting_offset + 132, 8, ENC_BIG_ENDIAN);
638 
639 #if 0
640             proto_tree_add_item(parent_tree,
641                 hf_waveagent_tstamp1, tvb, 140, 4, ENC_BIG_ENDIAN);
642 
643             proto_tree_add_item(parent_tree,
644                 hf_waveagent_tstamp2, tvb, 144, 4, ENC_BIG_ENDIAN);
645 
646             proto_tree_add_item(parent_tree,
647                 hf_waveagent_tstamp3, tvb, 148, 4, ENC_BIG_ENDIAN);
648 
649             proto_tree_add_item(parent_tree,
650                 hf_waveagent_tstamp4, tvb, 152, 4, ENC_BIG_ENDIAN);
651 
652             proto_tree_add_item(parent_tree,
653                 hf_waveagent_tstamp5, tvb, 156, 4, ENC_BIG_ENDIAN);
654 
655             proto_tree_add_item(parent_tree,
656                 hf_waveagent_tstamp6, tvb, 160, 4, ENC_BIG_ENDIAN);
657 
658             proto_tree_add_item(parent_tree,
659                 hf_waveagent_tstamp7, tvb, 164, 4, ENC_BIG_ENDIAN);
660 
661             proto_tree_add_item(parent_tree,
662                 hf_waveagent_tstamp8, tvb, 168, 4, ENC_BIG_ENDIAN);
663 
664             proto_tree_add_item(parent_tree,
665                 hf_waveagent_minlcldelta, tvb, 172, 4, ENC_BIG_ENDIAN);
666 
667             proto_tree_add_item(parent_tree,
668                 hf_waveagent_maxlcldelta, tvb, 176, 4, ENC_BIG_ENDIAN);
669 
670             proto_tree_add_item(parent_tree,
671                 hf_waveagent_avglcldelta, tvb, 180, 4, ENC_BIG_ENDIAN);
672 
673             proto_tree_add_item(parent_tree,
674                 hf_waveagent_minremdelta, tvb, 184, 4, ENC_BIG_ENDIAN);
675 
676             proto_tree_add_item(parent_tree,
677                 hf_waveagent_maxremdelta, tvb, 188, 4, ENC_BIG_ENDIAN);
678 
679             proto_tree_add_item(parent_tree,
680                 hf_waveagent_avgremdelta, tvb, 192, 4, ENC_BIG_ENDIAN);
681 #endif
682             proto_tree_add_item(parent_tree,
683                 hf_waveagent_rx1pl, tvb, starting_offset + 284, 8, ENC_BIG_ENDIAN);
684 
685             proto_tree_add_item(parent_tree,
686                 hf_waveagent_rx2pl, tvb, starting_offset + 292, 8, ENC_BIG_ENDIAN);
687 
688             proto_tree_add_item(parent_tree,
689                 hf_waveagent_rx3pl, tvb, starting_offset + 300, 8, ENC_BIG_ENDIAN);
690 
691             proto_tree_add_item(parent_tree,
692                 hf_waveagent_rx4pl, tvb, starting_offset + 308, 8, ENC_BIG_ENDIAN);
693 
694             proto_tree_add_item(parent_tree,
695                 hf_waveagent_rx5pl, tvb, starting_offset + 316, 8, ENC_BIG_ENDIAN);
696 
697             proto_tree_add_item(parent_tree,
698                 hf_waveagent_rxoospkts, tvb, starting_offset + 324, 8, ENC_BIG_ENDIAN);
699 
700             proto_tree_add_item(parent_tree,
701                 hf_waveagent_jitter, tvb, starting_offset + 356, 8, ENC_BIG_ENDIAN);
702 
703             if (version >= 3) {
704                 proto_tree_add_item(parent_tree,
705                     hf_waveagent_delayfactor, tvb, starting_offset + 364, 8, ENC_BIG_ENDIAN);
706 
707                 proto_tree_add_item(parent_tree,
708                     hf_waveagent_medialossrate, tvb, starting_offset + 372, 8, ENC_BIG_ENDIAN);
709 
710                 proto_tree_add_item(parent_tree,
711                     hf_waveagent_txstartts, tvb, starting_offset + 380, 8, ENC_BIG_ENDIAN);
712 
713                 proto_tree_add_item(parent_tree,
714                     hf_waveagent_txendts, tvb, starting_offset + 388, 8, ENC_BIG_ENDIAN);
715 
716                 proto_tree_add_item(parent_tree,
717                     hf_waveagent_rxstartts, tvb, starting_offset + 396, 8, ENC_BIG_ENDIAN);
718 
719                 proto_tree_add_item(parent_tree,
720                     hf_waveagent_rxendts, tvb, starting_offset + 404, 8, ENC_BIG_ENDIAN);
721 
722                 proto_tree_add_item(parent_tree,
723                     hf_waveagent_latencysum, tvb, starting_offset + 412, 8, ENC_BIG_ENDIAN);
724 
725                 proto_tree_add_item(parent_tree,
726                     hf_waveagent_latencycount, tvb, starting_offset + 420, 8, ENC_BIG_ENDIAN);
727 
728                 proto_tree_add_item(parent_tree,
729                     hf_waveagent_txflowstop, tvb, starting_offset + 428, 8, ENC_BIG_ENDIAN);
730             }
731 
732             break;
733 
734         case 0x40: {
735             guint32 offset;
736             guint32 delta;
737             guint32 iLoop;
738             guint32 num_bss_entries;
739 
740             proto_tree_add_item(parent_tree,
741                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
742 
743             proto_tree_add_item(parent_tree,
744                 hf_waveagent_connectflags, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
745 
746             proto_tree_add_item(parent_tree,
747                 hf_waveagent_connecttype, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
748 
749             proto_tree_add_item(parent_tree,
750                 hf_waveagent_scanssid, tvb, starting_offset + 12, 32, ENC_ASCII|ENC_NA);
751 
752             num_bss_entries = tvb_get_ntohl(tvb, starting_offset + 142);
753 
754             offset = starting_offset + 46;
755             delta = 6;
756             for (iLoop = 0; iLoop < num_bss_entries; iLoop++)
757             {
758                 int current_offset;
759                 current_offset = offset + iLoop * delta;
760 
761                 proto_tree_add_item(parent_tree,
762                     hf_waveagent_scanbssid, tvb, current_offset, 6, ENC_NA);
763             }
764 
765             proto_tree_add_item(parent_tree,
766                 hf_waveagent_minrssi, tvb, starting_offset + 146, 4, ENC_BIG_ENDIAN);
767 
768             proto_tree_add_item(parent_tree,
769                 hf_waveagent_connecttimeout, tvb, starting_offset + 150, 4, ENC_BIG_ENDIAN);
770 
771             proto_tree_add_item(parent_tree,
772                 hf_waveagent_connectattempts, tvb, starting_offset + 154, 4, ENC_BIG_ENDIAN);
773 
774             break;
775         }
776 
777         case 0x41:
778             proto_tree_add_item(parent_tree,
779                 hf_waveagent_ifindex, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
780 
781             proto_tree_add_item(parent_tree,
782                 hf_waveagent_reason, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
783 
784             break;
785 
786         case 0x81:   /* Capabilities response */
787             if (version < 3) {
788                 /* For version 2 WA protocol the capability status is not in the header but in the CAP
789                    RESPONSE.  Need to read it here and then advance the payload offset.  This is a
790                    packet that had a structure change in the beginning of the packet when moving
791                    to v3 */
792                 proto_tree_add_item(parent_tree,
793                     hf_waveagent_capstatus, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
794 
795                 proto_tree_add_item(parent_tree,
796                     hf_waveagent_protocolversion, tvb, starting_offset, 1, ENC_BIG_ENDIAN);
797 
798                 starting_offset += 4;
799             }
800 
801             proto_tree_add_item(parent_tree,
802                 hf_waveagent_capimpl, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
803 
804             proto_tree_add_item(parent_tree,
805                 hf_waveagent_id, tvb, starting_offset + 4, 128, ENC_ASCII|ENC_NA);
806 
807             proto_tree_add_item(parent_tree,
808                 hf_waveagent_bindtag, tvb, starting_offset + 136, 128, ENC_ASCII|ENC_NA);
809 
810             proto_tree_add_item(parent_tree,
811                 hf_waveagent_version, tvb, starting_offset + 268, 128, ENC_ASCII|ENC_NA);
812 
813             proto_tree_add_item(parent_tree,
814                 hf_waveagent_brokerip, tvb, starting_offset + 400, 4, ENC_BIG_ENDIAN);
815 
816             proto_tree_add_item(parent_tree,
817                 hf_waveagent_brokerport, tvb, starting_offset + 404, 4, ENC_BIG_ENDIAN);
818 
819             proto_tree_add_item(parent_tree,
820                 hf_waveagent_bindlevel, tvb, starting_offset + 408, 4, ENC_BIG_ENDIAN);
821 
822             proto_tree_add_item(parent_tree,
823                 hf_waveagent_bindport, tvb, starting_offset + 412, 4, ENC_BIG_ENDIAN);
824 
825             if (version >= 3) {
826                 proto_tree_add_item(parent_tree,
827                     hf_waveagent_capabilities2, tvb, starting_offset + 416, 4, ENC_BIG_ENDIAN);
828 
829                 proto_tree_add_item(parent_tree,
830                     hf_waveagent_numinterfaces, tvb, starting_offset + 420, 4, ENC_BIG_ENDIAN);
831 
832                 proto_tree_add_item(parent_tree,
833                     hf_waveagent_ifmask, tvb, starting_offset + 424, 4, ENC_BIG_ENDIAN);
834             }
835 
836             break;
837 
838         case 0x82:    /* Reserve request */
839             proto_tree_add_item(parent_tree,
840                 hf_waveagent_bindtag, tvb, starting_offset, 128, ENC_ASCII|ENC_NA);
841 
842             proto_tree_add_item(parent_tree,
843                 hf_waveagent_brokerip, tvb, starting_offset + 132, 4, ENC_BIG_ENDIAN);
844 
845             proto_tree_add_item(parent_tree,
846                 hf_waveagent_brokerport, tvb, starting_offset + 136, 4, ENC_BIG_ENDIAN);
847 
848             break;
849 
850         case 0x85: {   /* Flow setup */
851             proto_tree *fs_flags;
852             proto_tree *fs_flags_tree;
853             guint32     flags_bitfield;
854 
855             if (version < 3) {
856                 proto_tree_add_item(parent_tree,
857                     hf_waveagent_rxflownum, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
858             }
859 
860             proto_tree_add_item(parent_tree,
861                 hf_waveagent_mode, tvb, starting_offset + 7, 1, ENC_BIG_ENDIAN);
862 
863             proto_tree_add_item(parent_tree,
864                 hf_waveagent_endpointtype, tvb, starting_offset + 7, 1, ENC_BIG_ENDIAN);
865 
866             proto_tree_add_item(parent_tree,
867                 hf_waveagent_bindport, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
868 
869             proto_tree_add_item(parent_tree,
870                 hf_waveagent_bindlevel, tvb, starting_offset + 12, 4, ENC_BIG_ENDIAN);
871 
872             proto_tree_add_item(parent_tree,
873                 hf_waveagent_remoteport, tvb, starting_offset + 16, 4, ENC_BIG_ENDIAN);
874 
875             proto_tree_add_item(parent_tree,
876                 hf_waveagent_remoteaddr, tvb, starting_offset + 24, 4, ENC_BIG_ENDIAN);
877 
878             proto_tree_add_item(parent_tree,
879                 hf_waveagent_dscp, tvb, starting_offset + 40, 4, ENC_BIG_ENDIAN);
880 
881             flags_bitfield = tvb_get_ntohl(tvb, starting_offset + 44);
882 
883             fs_flags = proto_tree_add_uint(parent_tree, hf_waveagent_fsflags,
884                                         tvb, starting_offset + 44, 4, flags_bitfield);
885 
886             fs_flags_tree = proto_item_add_subtree(fs_flags, ett_fsflags);
887 
888             proto_tree_add_item(fs_flags_tree,
889                     hf_waveagent_fscbrflag, tvb, starting_offset + 47, 1, ENC_LITTLE_ENDIAN);
890 
891             proto_tree_add_item(fs_flags_tree,
892                     hf_waveagent_fscombinedsetupflag, tvb, starting_offset + 47, 1, ENC_LITTLE_ENDIAN);
893 
894             if (version >= 3) {
895                 proto_tree_add_item(parent_tree,
896                     hf_waveagent_ifindex, tvb, starting_offset + 48, 4, ENC_BIG_ENDIAN);
897 
898                 proto_tree_add_item(parent_tree,
899                     hf_waveagent_payfill, tvb, starting_offset + 52, 4, ENC_BIG_ENDIAN);
900 
901                 proto_tree_add_item(parent_tree,
902                     hf_waveagent_paysize, tvb, starting_offset + 56, 4, ENC_BIG_ENDIAN);
903 
904                 proto_tree_add_item(parent_tree,
905                     hf_waveagent_avgrate, tvb, starting_offset + 60, 4, ENC_BIG_ENDIAN);
906 
907                 proto_tree_add_item(parent_tree,
908                     hf_waveagent_totalframes, tvb, starting_offset + 64, 4, ENC_BIG_ENDIAN);
909             }
910 
911             break;
912         }
913 
914         case 0x8b:
915             proto_tree_add_item(parent_tree,
916                 hf_waveagent_destip, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
917 
918             proto_tree_add_item(parent_tree,
919                 hf_waveagent_destport, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
920 
921             proto_tree_add_item(parent_tree,
922                 hf_waveagent_connectflags, tvb, starting_offset + 8, 4, ENC_BIG_ENDIAN);
923 
924             break;
925 
926         case 0x3f:  /* Relay response */
927         case 0x8f:  /* Command Response */
928             proto_tree_add_item(parent_tree,
929                 hf_waveagent_commandstatus, tvb, starting_offset, 4, ENC_BIG_ENDIAN);
930 
931             proto_tree_add_item(parent_tree,
932                 hf_waveagent_syserrno, tvb, starting_offset + 4, 4, ENC_BIG_ENDIAN);
933 
934             proto_tree_add_item(parent_tree,
935                 hf_waveagent_statusstring, tvb, starting_offset + 8, 128, ENC_ASCII|ENC_NA);
936 
937             break;
938     }
939 }
940 
941 
942 
dissect_wa_header(guint32 starting_offset,proto_item * parent_tree,tvbuff_t * tvb,guint8 version)943 static guint32 dissect_wa_header(guint32 starting_offset, proto_item *parent_tree, tvbuff_t *tvb, guint8 version)
944 {
945     guint32 wa_payload_offset;
946 
947     proto_tree_add_item(parent_tree,
948         hf_waveagent_controlword, tvb, 30+starting_offset, 2, ENC_BIG_ENDIAN);
949 
950     proto_tree_add_item(parent_tree,
951         hf_waveagent_payloadlen, tvb, 20+starting_offset, 4, ENC_BIG_ENDIAN);
952 
953     proto_tree_add_item(parent_tree,
954         hf_waveagent_transnum, tvb, 24+starting_offset, 4, ENC_BIG_ENDIAN);
955 
956     proto_tree_add_item(parent_tree,
957         hf_waveagent_rtoken, tvb, 32+starting_offset, 4, ENC_BIG_ENDIAN);
958 
959     proto_tree_add_item(parent_tree,
960         hf_waveagent_flowid, tvb, 36+starting_offset, 4, ENC_BIG_ENDIAN);
961 
962     if (version >= 3) {
963         proto_tree_add_item(parent_tree,
964             hf_waveagent_capstatus, tvb, 40+starting_offset, 4, ENC_BIG_ENDIAN);
965 
966         proto_tree_add_item(parent_tree,
967             hf_waveagent_protocolversion, tvb, 40+starting_offset, 1, ENC_BIG_ENDIAN);
968 
969         wa_payload_offset = WA_V3_PAYLOAD_OFFSET + starting_offset;
970     }
971     else {
972         wa_payload_offset = WA_V2_PAYLOAD_OFFSET + starting_offset;
973     }
974 
975     proto_tree_add_item(parent_tree,
976         hf_waveagent_sigsequencenum, tvb, 4+starting_offset, 1, ENC_BIG_ENDIAN);
977 
978     return wa_payload_offset;
979 }
980 
981 /* Dissect the packets */
dissect_waveagent(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)982 static int dissect_waveagent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
983 {
984     proto_item *ti, *rmi;
985     proto_tree *waveagent_tree, *relay_message_tree, *payload_tree;
986     guint8      signature_start, signature_end;
987     guint8      version;
988     guint32     magic_number;
989     guint32     control_word, paylen;
990     guint32     wa_payload_offset;
991 
992     /* Check that there's enough data */
993     if (tvb_captured_length(tvb) < 52 )
994         return 0;
995 
996     magic_number    = tvb_get_ntohl(tvb, 16) & 0x0FFFFFFF;  /* Mask magic number off */
997     if(magic_number != 0x0F87C3A5){
998         return 0;
999     }
1000 
1001     signature_start = tvb_get_guint8(tvb, 0);
1002     signature_end   = tvb_get_guint8(tvb, 15);
1003 
1004     if ( ((signature_start != 0xcc) && (signature_start !=0xdd)) ||
1005          (signature_end != 0xE2))
1006         /*  This packet does not appear to belong to WaveAgent.
1007          *  Return 0 to give another dissector a chance to dissect it.
1008          */
1009         return 0;
1010 
1011     version         = ((tvb_get_ntohl(tvb, 16) & 0xF0000000) >> 28 == 1) ? 3 : 2;       /* Mask version bit off */
1012 
1013     col_set_str(pinfo->cinfo, COL_PROTOCOL, "WA");
1014     col_clear(pinfo->cinfo, COL_INFO);
1015 
1016     /* Grab the control word, parse the WaveAgent payload accordingly */
1017 
1018     control_word = tvb_get_ntohl(tvb, 28);
1019     paylen       = tvb_get_ntohl(tvb, 20);
1020 
1021     col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%x)",
1022         val_to_str_ext_const(control_word, &control_words_ext, "Unknown"), control_word);
1023 
1024     if (tree) {
1025         /* create display subtree for the protocol */
1026         ti = proto_tree_add_protocol_format(tree, proto_waveagent, tvb, 0, -1,
1027                         "WaveAgent, %s (0x%x), Payload Length %u Bytes",
1028                         val_to_str_ext_const(control_word, &control_words_ext, "Unknown"), control_word, paylen);
1029 
1030         waveagent_tree = proto_item_add_subtree(ti, ett_waveagent);
1031 
1032         wa_payload_offset = dissect_wa_header(0, waveagent_tree, tvb, version);
1033 
1034         payload_tree = waveagent_tree;
1035 
1036         /* Need to check for a relay message.  If so, parse the extra fields and then parse the WA packet */
1037         if (control_word == 0x3e)
1038         {
1039             proto_tree_add_item(waveagent_tree,
1040                 hf_waveagent_relaydestid, tvb, wa_payload_offset, 4, ENC_BIG_ENDIAN);
1041             proto_tree_add_item(waveagent_tree,
1042                 hf_waveagent_relaysrcid, tvb, wa_payload_offset+4, 4, ENC_BIG_ENDIAN);
1043 
1044             /* Parse control_word of the relay message */
1045             control_word = tvb_get_ntohl(tvb, wa_payload_offset+12+28);
1046                 rmi = proto_tree_add_none_format(waveagent_tree, hf_waveagent_relaymessagest,
1047                                                  tvb, wa_payload_offset+12+28, 0,
1048                                                  "Relayed WaveAgent Message, %s (0x%x)",
1049                                                  val_to_str_ext_const(control_word, &control_words_ext, "Unknown"),
1050                                                  control_word);
1051 
1052             relay_message_tree = proto_item_add_subtree(rmi, ett_relaymessage);
1053 
1054             wa_payload_offset = dissect_wa_header(wa_payload_offset+12, relay_message_tree, tvb, version);
1055             payload_tree = relay_message_tree;
1056         }
1057 
1058         dissect_wa_payload(wa_payload_offset, payload_tree, tvb, control_word, version);
1059     }
1060 
1061     /* Return the amount of data this dissector was able to dissect */
1062     return tvb_captured_length(tvb);
1063 }
1064 
dissect_waveagent_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1065 static gboolean dissect_waveagent_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1066 {
1067     return (dissect_waveagent(tvb, pinfo, tree) > 0) ? TRUE : FALSE;
1068 }
1069 
1070 
1071 #if 0
1072 static const value_string status_values[] = {
1073     { 0, "OK" },
1074     { 1, "In Use" },
1075     { 0, NULL }
1076 };
1077 #endif
1078 
1079 /* Register the protocol with Wireshark */
1080 
proto_register_waveagent(void)1081 void proto_register_waveagent(void)
1082 {
1083     static const value_string tcp_states[] = {
1084         {  0, "Closed" },
1085         {  1, "Listen" },
1086         {  2, "SYN Sent" },
1087         {  3, "SYN received" },
1088         {  4, "Established" },
1089         {  5, "FIN Wait 1" },
1090         {  6, "FIN Wait 2" },
1091         {  7, "Close Wait" },
1092         {  8, "Closing" },
1093         {  9, "Last ACK" },
1094         { 10, "Time Wait" },
1095         {  0, NULL },
1096     };
1097 
1098     static const value_string app_states[] = {
1099         {  0, "IDLE" },
1100         {  1, "READY" },
1101         {  0, NULL },
1102     };
1103 
1104     static const value_string wa_modes[] = {
1105         {  0, "In-band" },
1106         {  1, "Source" },
1107         {  2, "Sink" },
1108         {  3, "Loopback" },
1109         {  0, NULL },
1110     };
1111 
1112     static const value_string wa_endpointtypes[] = {
1113         {  0, "Undefined" },
1114         {  1, "Server" },
1115         {  2, "Client" },
1116         {  0, NULL },
1117     };
1118 
1119     static const value_string binding_levels[] = {
1120         {  0, "WLAN" },
1121         {  1, "Ethernet" },
1122         {  2, "IP" },
1123         {  3, "UDP" },
1124         {  4, "TCP" },
1125         {  5, "FIN Wait 1" },
1126         {  6, "FIN Wait 2" },
1127         {  7, "Close Wait" },
1128         {  8, "Closing" },
1129         {  9, "Last ACK" },
1130         { 10, "Time Wait" },
1131         {  0, NULL },
1132     };
1133 
1134     static const value_string if_types[] = {
1135         {  ETHERNET_INTERFACE, "Ethernet" },
1136         {  WLAN_INTERFACE, "WLAN" },
1137         {  0, NULL },
1138     };
1139 
1140     static const value_string no_yes[] = {
1141         {  0, "No" },
1142         {  1, "Yes" },
1143         {  0, NULL },
1144     };
1145 
1146     static const value_string ip_types[] = {
1147         {  0,  "Unspecified" },
1148         {  IPV4_TYPE,  "IPv4" },
1149         {  IPV6_TYPE, "IPv6" },
1150         {  0, NULL },
1151     };
1152 
1153     static const value_string if_l3_states[] = {
1154         {  0, "Uninitialized" },
1155         {  1, "Disconnected" },
1156         {  2, "Connected" },
1157         {  3, "Error" },
1158         {  0, NULL },
1159     };
1160 
1161     static const value_string if_wlan_states[] = {
1162         {  0, "Uninitialized" },
1163         {  1, "Not ready" },
1164         {  2, "Connected" },
1165         {  3, "Ad Hoc network formed" },
1166         {  4, "Disconnecting" },
1167         {  5, "Disconnected" },
1168         {  6, "Associating" },
1169         {  7, "Discovering" },
1170         {  8, "Authenticating" },
1171         {  0, NULL },
1172     };
1173 
1174     static const value_string if_eth_states[] = {
1175         {  0, "Uninitialized" },
1176         {  1, "Not Operational" },
1177         {  2, "Unreachable" },
1178         {  3, "Disconnected" },
1179         {  4, "Connecting" },
1180         {  5, "Connected" },
1181         {  6, "Operational" },
1182         {  7, "Error" },
1183         {  0, NULL },
1184     };
1185 
1186     static const value_string bss_modes[] = {
1187         {  0, "Infrastructure" },
1188         {  1, "IBSS" },
1189         {  2, "Unknown" },
1190         {  0, NULL },
1191     };
1192 
1193     static const value_string auth_algs[] = {
1194         {  0,  "Open" },
1195         {  1,  "Shared Key" },
1196         {  2,  "WPA" },
1197         {  4,  "WPA PSK" },
1198         {  8,  "WPA2" },
1199         { 16, "WPA2 PSK" },
1200         {  0, NULL },
1201     };
1202 
1203     static const value_string cipher_algs[] = {
1204         {  0,  "None" },
1205         {  1,  "WEP 40" },
1206         {  2,  "WEP 104" },
1207         {  4,  "WEP" },
1208         {  8,  "TKIP" },
1209         { 16, "CCMP" },
1210         {  0, NULL },
1211     };
1212 
1213     /* Setup list of header fields  See Section 1.6.1 for details*/
1214     static hf_register_info hf[] = {
1215 
1216     /* START: General purpose message fields - used in multiple messages */
1217         { &hf_waveagent_controlword,
1218         { "Control Word", "waveagent.cword",
1219         FT_UINT16, BASE_HEX | BASE_EXT_STRING, &control_words_ext, 0x0,
1220         NULL, HFILL } },
1221 
1222         { &hf_waveagent_payloadlen,
1223         { "Payload Length", "waveagent.paylen",
1224         FT_UINT32, BASE_DEC, NULL, 0x0,
1225         NULL, HFILL } },
1226 
1227         { &hf_waveagent_transnum,
1228         { "Transaction Number", "waveagent.transnum",
1229         FT_UINT32, BASE_DEC, NULL, 0x0,
1230         NULL, HFILL } },
1231 
1232         { &hf_waveagent_rtoken,
1233         { "Reservation Token", "waveagent.rtoken",
1234         FT_UINT32, BASE_HEX, NULL, 0x0,
1235         NULL, HFILL } },
1236 
1237         { &hf_waveagent_flowid,
1238         { "Flow ID", "waveagent.flowid",
1239         FT_UINT32, BASE_DEC, NULL, 0x0,
1240         NULL, HFILL } },
1241 
1242         { &hf_waveagent_capstatus,
1243         { "Capabilities Status", "waveagent.capstatus",
1244         FT_UINT32, BASE_HEX, NULL, 0x0,
1245         NULL, HFILL } },
1246 
1247         { &hf_waveagent_protocolversion,
1248         { "Protocol Version", "waveagent.protocolversion",
1249         FT_UINT8, BASE_DEC, NULL, 0x0,
1250         NULL, HFILL } },
1251 
1252         { &hf_waveagent_capimpl,
1253         { "Capabilities Implementation", "waveagent.capimpl",
1254         FT_UINT32, BASE_HEX, NULL, 0x0,
1255         NULL, HFILL } },
1256 
1257         { &hf_waveagent_sigsequencenum,
1258         { "Signature Sequence Number", "waveagent.sigsequencenum",
1259         FT_UINT8, BASE_DEC, NULL, 0x0,
1260         NULL, HFILL } },
1261 
1262         { &hf_waveagent_id,
1263         { "ID", "waveagent.id",
1264         FT_STRING, 0, NULL, 0x0,
1265         NULL, HFILL } },
1266 
1267         { &hf_waveagent_bindtag,
1268         { "Binding Tag", "waveagent.bindtag",
1269         FT_STRING, 0, NULL, 0x0,
1270         NULL, HFILL } },
1271 
1272         { &hf_waveagent_version,
1273         { "Version", "waveagent.version",
1274         FT_STRING, 0, NULL, 0x0,
1275         NULL, HFILL } },
1276 
1277         { &hf_waveagent_brokerip,
1278         { "Broker IP address", "waveagent.brokerip",
1279         FT_IPv4, BASE_NONE, NULL, 0x0,
1280         NULL, HFILL } },
1281 
1282         { &hf_waveagent_brokerport,
1283         { "Broker Port", "waveagent.brokerport",
1284         FT_UINT32, BASE_DEC, NULL, 0x0,
1285         NULL, HFILL } },
1286 
1287         { &hf_waveagent_bindlevel,
1288         { "Binding Level", "waveagent.bindlevel",
1289         FT_UINT32, BASE_DEC, VALS(binding_levels), 0x0,
1290         NULL, HFILL } },
1291 
1292         { &hf_waveagent_bindport,
1293         { "Binding Port", "waveagent.bindport",
1294         FT_UINT32, BASE_DEC, NULL, 0x0,
1295         NULL, HFILL } },
1296 
1297         { &hf_waveagent_ifindex,
1298         { "Interface Index", "waveagent.ifindex",
1299         FT_UINT32, BASE_DEC, NULL, 0x0,
1300         NULL, HFILL } },
1301     /* END: General purpose message fields - used in multiple messages */
1302 
1303     /* START: Capabilities response fields (specific to this message, other general fields are also used) */
1304         { &hf_waveagent_capabilities2,
1305         { "Additional Capabilities", "waveagent.capabilities2",
1306         FT_UINT32, BASE_HEX, NULL, 0x0,
1307         NULL, HFILL } },
1308 
1309         { &hf_waveagent_numinterfaces,
1310         { "Number of WA Interfaces", "waveagent.numinterfaces",
1311         FT_UINT32, BASE_DEC, NULL, 0x0,
1312         NULL, HFILL } },
1313 
1314         { &hf_waveagent_ifmask,
1315         { "Mask of Active Interfaces", "waveagent.ifmask",
1316         FT_UINT32, BASE_HEX, NULL, 0x0,
1317         NULL, HFILL } },
1318     /* END: Capabilities response fields (specific to this message, other general fields are also used) */
1319 
1320     /* START: Command response message fields */
1321         { &hf_waveagent_commandstatus,
1322         { "Status of Previous Command", "waveagent.cmdstat",
1323         FT_INT32, BASE_DEC, NULL, 0x0,
1324         NULL, HFILL } },
1325 
1326         { &hf_waveagent_syserrno,
1327         { "System Error Number", "waveagent.syserrno",
1328         FT_INT32, BASE_DEC, NULL, 0x0,
1329         NULL, HFILL } },
1330 
1331         { &hf_waveagent_statusstring,
1332         { "Status Message", "waveagent.statmsg",
1333         FT_STRING, 0, NULL, 0x0,
1334         NULL, HFILL } },
1335     /* END: Command response message fields */
1336 
1337     /* START: Stats response message fields */
1338         { &hf_waveagent_rxdatapckts,
1339         { "Received Data Packets", "waveagent.rxdpkts",
1340         FT_UINT64, BASE_DEC, NULL, 0x0,
1341         NULL, HFILL } },
1342 
1343         { &hf_waveagent_rxdatabytes,
1344         { "Received Data Bytes", "waveagent.rxdbytes",
1345         FT_UINT64, BASE_DEC, NULL, 0x0,
1346         NULL, HFILL } },
1347 
1348         { &hf_waveagent_rxpcktrate,
1349         { "Received Data Packet Rate (pps)", "waveagent.rxpktrate",
1350         FT_UINT64, BASE_DEC, NULL, 0x0,
1351         NULL, HFILL } },
1352 
1353         { &hf_waveagent_rxbyterate,
1354         { "Received Byte Rate", "waveagent.rxbyterate",
1355         FT_UINT64, BASE_DEC, NULL, 0x0,
1356         NULL, HFILL } },
1357 
1358         { &hf_waveagent_txdatapckts,
1359         { "Transmitted Data Packets", "waveagent.txdpkts",
1360         FT_UINT64, BASE_DEC, NULL, 0x0,
1361         NULL, HFILL } },
1362 
1363         { &hf_waveagent_txdatabytes,
1364         { "Transmitted Data Bytes", "waveagent.txdbytes",
1365         FT_UINT64, BASE_DEC, NULL, 0x0,
1366         NULL, HFILL } },
1367 
1368         { &hf_waveagent_txpcktrate,
1369         { "Transmitted Data Packet Rate (pps)", "waveagent.txpktrate",
1370         FT_UINT64, BASE_DEC, NULL, 0x0,
1371         NULL, HFILL } },
1372 
1373         { &hf_waveagent_txbyterate,
1374         { "Transmitted Byte Rate", "waveagent.txbyterate",
1375         FT_UINT64, BASE_DEC, NULL, 0x0,
1376         NULL, HFILL } },
1377 
1378         { &hf_waveagent_looppckts,
1379         { "Loopback Packets", "waveagent.looppckts",
1380         FT_UINT64, BASE_DEC, NULL, 0x0,
1381         NULL, HFILL } },
1382 
1383         { &hf_waveagent_loopbytes,
1384         { "Loopback Bytes", "waveagent.loopbytes",
1385         FT_UINT64, BASE_DEC, NULL, 0x0,
1386         NULL, HFILL } },
1387 
1388         { &hf_waveagent_rxctlpckts,
1389         { "Received Control Packets", "waveagent.rxctlpkts",
1390         FT_UINT64, BASE_DEC, NULL, 0x0,
1391         NULL, HFILL } },
1392 
1393         { &hf_waveagent_rxctlbytes,
1394         { "Received Control Bytes", "waveagent.rxctlbytes",
1395         FT_UINT64, BASE_DEC, NULL, 0x0,
1396         NULL, HFILL } },
1397 
1398         { &hf_waveagent_txctlpckts,
1399         { "Transmitted Control Packets", "waveagent.txctlpkts",
1400         FT_UINT64, BASE_DEC, NULL, 0x0,
1401         NULL, HFILL } },
1402 
1403         { &hf_waveagent_txctlbytes,
1404         { "Transmitted Control Bytes", "waveagent.txctlbytes",
1405         FT_UINT64, BASE_DEC, NULL, 0x0,
1406         NULL, HFILL } },
1407 
1408         { &hf_waveagent_unknowncmds,
1409         { "Unknown Commands", "waveagent.unkcmds",
1410         FT_UINT64, BASE_DEC, NULL, 0x0,
1411         NULL, HFILL } },
1412 
1413         { &hf_waveagent_snap,
1414         { "Time Snap for Counters", "waveagent.snap",
1415         FT_UINT64, BASE_DEC, NULL, 0x0,
1416         NULL, HFILL } },
1417 
1418         { &hf_waveagent_appstate,
1419         { "TCP State", "waveagent.state",
1420         FT_UINT32, BASE_DEC, VALS(tcp_states), 0x0,
1421         NULL, HFILL } },
1422 
1423         { &hf_waveagent_state,
1424         { "Application State", "waveagent.appstate",
1425         FT_UINT32, BASE_DEC, VALS(app_states), 0x0,
1426         NULL, HFILL } },
1427 
1428         { &hf_waveagent_rx1pl,
1429         { "Instances of single packet loss", "waveagent.rx1pl",
1430         FT_UINT64, BASE_DEC, NULL, 0x0,
1431         NULL, HFILL } },
1432 
1433         { &hf_waveagent_rx2pl,
1434         { "Instances of 2 sequential packets lost", "waveagent.rx2pl",
1435         FT_UINT64, BASE_DEC, NULL, 0x0,
1436         NULL, HFILL } },
1437 
1438         { &hf_waveagent_rx3pl,
1439         { "Instances of 3 sequential packets lost", "waveagent.rx3pl",
1440         FT_UINT64, BASE_DEC, NULL, 0x0,
1441         NULL, HFILL } },
1442 
1443         { &hf_waveagent_rx4pl,
1444         { "Instances of 4 sequential packets lost", "waveagent.rx4pl",
1445         FT_UINT64, BASE_DEC, NULL, 0x0,
1446         NULL, HFILL } },
1447 
1448         { &hf_waveagent_rx5pl,
1449         { "Instances of 5 sequential packets lost", "waveagent.rx5pl",
1450         FT_UINT64, BASE_DEC, NULL, 0x0,
1451         NULL, HFILL } },
1452 
1453         { &hf_waveagent_rxoospkts,
1454         { "Instances of out-of-sequence packets", "waveagent.rxoospkts",
1455         FT_UINT64, BASE_DEC, NULL, 0x0,
1456         NULL, HFILL } },
1457 
1458 #if 0
1459         { &hf_waveagent_rxmeanlatency,
1460         { "Rx Mean latency", "waveagent.rxmeanlatency",
1461         FT_UINT64, BASE_DEC, NULL, 0x0,
1462         NULL, HFILL } },
1463 #endif
1464 
1465 #if 0
1466         { &hf_waveagent_rxminlatency,
1467         { "Rx Minimum latency", "waveagent.rxminlatency",
1468         FT_UINT64, BASE_DEC, NULL, 0x0,
1469         NULL, HFILL } },
1470 #endif
1471 
1472 #if 0
1473         { &hf_waveagent_rxmaxlatency,
1474         { "Rx Maximum latency", "waveagent.rxmaxlatency",
1475         FT_UINT64, BASE_DEC, NULL, 0x0,
1476         NULL, HFILL } },
1477 #endif
1478 
1479         { &hf_waveagent_jitter,
1480         { "Jitter (microseconds)", "waveagent.jitter",
1481         FT_UINT64, BASE_DEC, NULL, 0x0,
1482         NULL, HFILL } },
1483 
1484         { &hf_waveagent_delayfactor,
1485         { "Delay Factor", "waveagent.delayfactor",
1486         FT_UINT64, BASE_DEC, NULL, 0x0,
1487         NULL, HFILL } },
1488 
1489         { &hf_waveagent_medialossrate,
1490         { "Media Loss Rate", "waveagent.medialossrate",
1491         FT_UINT64, BASE_DEC, NULL, 0x0,
1492         NULL, HFILL } },
1493 
1494         { &hf_waveagent_txstartts,
1495         { "Timestamp for first Tx flow packet", "waveagent.txstartts",
1496         FT_UINT64, BASE_DEC, NULL, 0x0,
1497         NULL, HFILL } },
1498 
1499         { &hf_waveagent_txendts,
1500         { "Timestamp for last Tx flow packet", "waveagent.txendts",
1501         FT_UINT64, BASE_DEC, NULL, 0x0,
1502         NULL, HFILL } },
1503 
1504         { &hf_waveagent_rxstartts,
1505         { "Timestamp for first Rx flow packet", "waveagent.rxstartts",
1506         FT_UINT64, BASE_DEC, NULL, 0x0,
1507         NULL, HFILL } },
1508 
1509         { &hf_waveagent_rxendts,
1510         { "Timestamp for last Rx flow packet", "waveagent.rxendts",
1511         FT_UINT64, BASE_DEC, NULL, 0x0,
1512         NULL, HFILL } },
1513 
1514         { &hf_waveagent_latencysum,
1515         { "Sum of latencies across all received packets", "waveagent.latencysum",
1516         FT_UINT64, BASE_DEC, NULL, 0x0,
1517         NULL, HFILL } },
1518 
1519         { &hf_waveagent_latencycount,
1520         { "Count of packets included in the latency sum", "waveagent.latencycount",
1521         FT_UINT64, BASE_DEC, NULL, 0x0,
1522         NULL, HFILL } },
1523 
1524         { &hf_waveagent_txflowstop,
1525         { "Timestamp for Tx flow stop message", "waveagent.txflowstop",
1526         FT_UINT64, BASE_DEC, NULL, 0x0,
1527         NULL, HFILL } },
1528     /* END Stats response message fields */
1529 
1530     /* START: Flow setup message */
1531         { &hf_waveagent_rxflownum,
1532         { "Received Flow Number", "waveagent.rxflownum",
1533         FT_UINT32, BASE_DEC, NULL, 0x0,
1534         NULL, HFILL } },
1535 
1536         { &hf_waveagent_mode,
1537         { "WaveAgent Mode", "waveagent.trafficmode",
1538         FT_UINT8, BASE_DEC, VALS(wa_modes), 0x03,
1539         NULL, HFILL } },
1540 
1541         { &hf_waveagent_endpointtype,
1542         { "WaveAgent Endpoint Type", "waveagent.endpointtype",
1543         FT_UINT8, BASE_DEC, VALS(wa_endpointtypes), 0x0c,
1544         NULL, HFILL } },
1545 
1546         { &hf_waveagent_remoteport,
1547         { "Remote port", "waveagent.remoteport",
1548         FT_UINT32, BASE_DEC, NULL, 0x0,
1549         NULL, HFILL } },
1550 
1551         { &hf_waveagent_remoteaddr,
1552         { "Remote address", "waveagent.remoteaddr",
1553         FT_IPv4, BASE_NONE, NULL, 0x0,
1554         NULL, HFILL } },
1555 
1556         { &hf_waveagent_dscp,
1557         { "DSCP Setting", "waveagent.dscp",
1558         FT_UINT32, BASE_DEC, NULL, 0x0,
1559         NULL, HFILL } },
1560 
1561         { &hf_waveagent_fsflags,
1562         { "Flow Setup Flags", "waveagent.fsflags",
1563         FT_UINT32, BASE_HEX, NULL, 0x0,
1564         NULL, HFILL } },
1565 
1566         { &hf_waveagent_fscbrflag,
1567         { "CBR Transmit Mode", "waveagent.fscbrflag",
1568         FT_BOOLEAN, 4, NULL, 0x01, NULL, HFILL } },
1569 
1570         { &hf_waveagent_fscombinedsetupflag,
1571         { "Setup, Connect/Listen, Start Combined", "waveagent.fscombinedsetupflag",
1572         FT_BOOLEAN, 4, NULL, 0x02, NULL, HFILL } },
1573 
1574     /* END: Flow setup message */
1575 
1576     /* START: Flow start message fields */
1577         { &hf_waveagent_payfill,
1578         { "Payload Fill", "waveagent.payfill",
1579         FT_UINT32, BASE_DEC, NULL, 0x0,
1580         NULL, HFILL } },
1581 
1582         { &hf_waveagent_paysize,
1583         { "WaveAgent Payload Size (bytes)", "waveagent.paysize",
1584         FT_UINT32, BASE_DEC, NULL, 0x0,
1585         NULL, HFILL } },
1586 
1587         { &hf_waveagent_avgrate,
1588         { "Average Rate (header + payload + trailer bytes/s)", "waveagent.avgrate",
1589         FT_UINT32, BASE_DEC, NULL, 0x0,
1590         NULL, HFILL } },
1591 
1592         { &hf_waveagent_totalframes,
1593         { "Total Frames", "waveagent.totalframes",
1594         FT_UINT32, BASE_DEC, NULL, 0x0,
1595         NULL, HFILL } },
1596 
1597     /* END: Flow start message fields */
1598 
1599     /* START: Scan results request (0x23) fields */
1600         { &hf_waveagent_bssidstartindex,
1601         { "Starting Index of BSSID list for reporting", "waveagent.bssidstartindex",
1602         FT_UINT32, BASE_DEC, NULL, 0x0,
1603         NULL, HFILL } },
1604 
1605         { &hf_waveagent_bssidstopindex,
1606         { "Ending Index of BSSID list for reporting", "waveagent.bssidstopindex",
1607         FT_UINT32, BASE_DEC, NULL, 0x0,
1608         NULL, HFILL } },
1609 
1610     /* END: Scan results request (0x23) fields */
1611 
1612     /* START: WLAN Interface stats fields */
1613         { &hf_waveagent_ifwlanbssid,
1614         { "WLAN Interface Connected to BSSID", "waveagent.ifwlanbssid",
1615         FT_ETHER, 0, NULL, 0x0,
1616         NULL, HFILL } },
1617 
1618         { &hf_waveagent_ifwlanssid,
1619         { "WLAN Interface Connected to SSID", "waveagent.ifwlanssid",
1620         FT_STRING, 0, NULL, 0x0,
1621         NULL, HFILL } },
1622 
1623         { &hf_waveagent_ifwlanrssi,
1624         { "WLAN Interface RSSI", "waveagent.ifwlanrssi",
1625         FT_INT32, BASE_DEC, NULL, 0x0,
1626         NULL, HFILL } },
1627 
1628         { &hf_waveagent_ifwlannoise,
1629         { "WLAN Interface Noise Floor (dBm)", "waveagent.ifwlannoise",
1630         FT_INT32, BASE_DEC, NULL, 0x0,
1631         NULL, HFILL } },
1632 
1633         { &hf_waveagent_ifphytypes,
1634         { "WLAN Interface Supported PHY Types", "waveagent.ifphytypes",
1635         FT_UINT32, BASE_DEC, NULL, 0x0,
1636         NULL, HFILL } },
1637 
1638         { &hf_waveagent_ifphytypebit0,
1639         { "11b", "waveagent.ifphytypebit0",
1640         FT_BOOLEAN, 4, NULL, 0x01, NULL, HFILL } },
1641 
1642         { &hf_waveagent_ifphytypebit1,
1643         { "11g", "waveagent.ifphytypebit1",
1644         FT_BOOLEAN, 4, NULL, 0x02, NULL, HFILL } },
1645 
1646         { &hf_waveagent_ifphytypebit2,
1647         { "11a", "waveagent.ifphytypebit2",
1648         FT_BOOLEAN, 4, NULL, 0x04, NULL, HFILL } },
1649 
1650         { &hf_waveagent_ifphytypebit3,
1651         { "11n", "waveagent.ifphytypebit3",
1652         FT_BOOLEAN, 4, NULL, 0x08, NULL, HFILL } },
1653 
1654         { &hf_waveagent_ifwlanauthentication,
1655         { "WLAN Interface Authentication Algorithm", "waveagent.ifwlanauthentication",
1656         FT_UINT32, BASE_DEC, VALS(auth_algs), 0x0,
1657         NULL, HFILL } },
1658 
1659         { &hf_waveagent_ifwlancipher,
1660         { "WLAN Interface Encryption/Cipher Algorithm", "waveagent.ifwlancipher",
1661         FT_UINT32, BASE_DEC, VALS(cipher_algs), 0x0,
1662         NULL, HFILL } },
1663     /* END: WLAN Interface stats fields */
1664 
1665     /* START: Interface stats response (0x2d) fields */
1666         { &hf_waveagent_iftype,
1667         { "Interface type", "waveagent.iftype",
1668         FT_UINT32, BASE_DEC, VALS(if_types), 0x0,
1669         NULL, HFILL } },
1670 
1671         { &hf_waveagent_ifdescription,
1672         { "Name/Description of the adapter", "waveagent.ifdescription",
1673         FT_STRING, 0, NULL, 0x0,
1674         NULL, HFILL } },
1675 
1676         { &hf_waveagent_ifmacaddr,
1677         { "Interface MAC Address", "waveagent.ifmacaddr",
1678         FT_ETHER, 0, NULL, 0x0,
1679         NULL, HFILL } },
1680 
1681         { &hf_waveagent_iflinkspeed,
1682         { "Interface Link Speed (kbps)", "waveagent.iflinkspeed",
1683         FT_UINT32, BASE_DEC, NULL, 0x0,
1684         NULL, HFILL } },
1685 
1686         { &hf_waveagent_ifdhcp,
1687         { "Interface DHCP Enabled", "waveagent.ifdhcp",
1688         FT_UINT32, BASE_DEC, VALS(no_yes), 0x0,
1689         NULL, HFILL } },
1690 
1691         { &hf_waveagent_ifiptype,
1692         { "Interface IP Type", "waveagent.ifiptype",
1693         FT_UINT32, BASE_DEC, VALS(ip_types), 0x0,
1694         NULL, HFILL } },
1695 
1696         { &hf_waveagent_ifipv4,
1697         { "Interface Bound to IP Address", "waveagent.ifipv4",
1698         FT_IPv4, BASE_NONE, NULL, 0x0,
1699         NULL, HFILL } },
1700 
1701         { &hf_waveagent_ifipv6,
1702         { "Interface Bound to IP Address", "waveagent.ifipv6",
1703         FT_IPv6, BASE_NONE, NULL, 0x0,
1704         NULL, HFILL } },
1705 
1706         { &hf_waveagent_ifdhcpserver,
1707         { "Interface DHCP Server Address", "waveagent.ifdhcpserver",
1708         FT_IPv4, BASE_NONE, NULL, 0x0,
1709         NULL, HFILL } },
1710 
1711         { &hf_waveagent_ifgateway,
1712         { "Interface Gateway", "waveagent.ifgateway",
1713         FT_IPv4, BASE_NONE, NULL, 0x0,
1714         NULL, HFILL } },
1715 
1716         { &hf_waveagent_ifdnsserver,
1717         { "Interface DNS Server Address", "waveagent.ifdnsserver",
1718         FT_IPv4, BASE_NONE, NULL, 0x0,
1719         NULL, HFILL } },
1720 
1721         { &hf_waveagent_ifethl2status,
1722         { "Ethernet L2 Interface Status", "waveagent.ifethl2status",
1723         FT_UINT32, BASE_DEC, VALS(if_eth_states), 0x0,
1724         NULL, HFILL } },
1725 
1726         { &hf_waveagent_ifwlanl2status,
1727         { "WLAN L2 Interface Status", "waveagent.ifwlanl2status",
1728         FT_UINT32, BASE_DEC, VALS(if_wlan_states), 0x0,
1729         NULL, HFILL } },
1730 
1731         { &hf_waveagent_ifl3status,
1732         { "L3 Interface Status", "waveagent.ifl3status",
1733         FT_UINT32, BASE_DEC, VALS(if_l3_states), 0x0,
1734         NULL, HFILL } },
1735 
1736     /* END: Interface stats response (0x2d) fields */
1737 
1738     /* START: Scan results response (0x2e) fields */
1739         { &hf_waveagent_totalbssid,
1740         { "Number of Found BSSID", "waveagent.totalbssid",
1741         FT_UINT32, BASE_DEC, NULL, 0x0,
1742         NULL, HFILL } },
1743 
1744         { &hf_waveagent_returnedbssid,
1745         { "Number of BSSID Reported in This Response", "waveagent.returnedbssid",
1746         FT_UINT32, BASE_DEC, NULL, 0x0,
1747         NULL, HFILL } },
1748 
1749         { &hf_waveagent_scanbssid,
1750         { "BSSID", "waveagent.scanbssid",
1751         FT_ETHER, 0, NULL, 0x0,
1752         NULL, HFILL } },
1753 
1754         { &hf_waveagent_scanssid,
1755         { "SSID", "waveagent.scanssid",
1756         FT_STRING, 0, NULL, 0x0,
1757         NULL, HFILL } },
1758 
1759         { &hf_waveagent_ifwlansupprates,
1760         { "Supported Rates", "waveagent.ifwlansupportedrates",
1761         FT_STRING, BASE_NONE, NULL, 0x0,
1762         NULL, HFILL } },
1763 
1764         { &hf_waveagent_ifwlancapabilities,
1765         { "Capabilities field", "waveagent.ifwlancapabilities",
1766         FT_UINT16, BASE_HEX, NULL, 0x0,
1767         NULL, HFILL } },
1768 
1769         { &hf_waveagent_ifwlanchannel,
1770         { "Channel", "waveagent.ifwlanchannel",
1771         FT_UINT32, BASE_DEC, NULL, 0x0,
1772         NULL, HFILL } },
1773 
1774         { &hf_waveagent_ifwlanprivacy,
1775         { "Privacy Enabled", "waveagent.ifwlanprivacy",
1776         FT_UINT32, BASE_DEC, VALS(no_yes), 0x0,
1777         NULL, HFILL } },
1778 
1779         { &hf_waveagent_ifwlanbssmode,
1780         { "BSS Mode", "waveagent.ifwlanbssmode",
1781         FT_UINT32, BASE_DEC, VALS(bss_modes), 0x0,
1782         NULL, HFILL } },
1783     /* END: Scan results response (0x2e) fields */
1784 
1785     /* START: OID fields */
1786         { &hf_waveagent_oidcode,
1787         { "OID Code", "waveagent.oidcode",
1788         FT_UINT32, BASE_DEC, NULL, 0x0,
1789         NULL, HFILL } },
1790 
1791         { &hf_waveagent_oidvalue,
1792         { "OID Value", "waveagent.oidvalue",
1793         FT_STRING, 0, NULL, 0x0,
1794         NULL, HFILL } },
1795     /* END: OID fields */
1796 
1797     /* START: Learning Message fields */
1798         { &hf_waveagent_destip,
1799         { "Destination IP", "waveagent.destip",
1800         FT_IPv4, BASE_NONE, NULL, 0x0,
1801         NULL, HFILL } },
1802 
1803         { &hf_waveagent_destport,
1804         { "Destination Port", "waveagent.destport",
1805         FT_UINT32, BASE_DEC, NULL, 0x0,
1806         NULL, HFILL } },
1807 
1808         { &hf_waveagent_connectflags,
1809         { "Connect Flags", "waveagent.connectflags",
1810         FT_UINT32, BASE_HEX, NULL, 0x0,
1811         NULL, HFILL } },
1812     /* END: Learning Message fields */
1813 
1814     /* START: client connect fields */
1815         { &hf_waveagent_connecttype,
1816         { "Connect Type", "waveagent.connecttype",
1817         FT_UINT32, BASE_HEX, NULL, 0x0,
1818         NULL, HFILL } },
1819 
1820         { &hf_waveagent_minrssi,
1821         { "Minimum RSSI", "waveagent.minrssi",
1822         FT_INT32, BASE_DEC, NULL, 0x0,
1823         NULL, HFILL } },
1824 
1825         { &hf_waveagent_connecttimeout,
1826         { "Connect timeout (s)", "waveagent.connecttimeout",
1827         FT_UINT32, BASE_DEC, NULL, 0x0,
1828         NULL, HFILL } },
1829 
1830         { &hf_waveagent_connectattempts,
1831         { "Connect attempts", "waveagent.connectattempt",
1832         FT_UINT32, BASE_DEC, NULL, 0x0,
1833         NULL, HFILL } },
1834 
1835         { &hf_waveagent_reason,
1836         { "Reason", "waveagent.reason",
1837         FT_UINT32, BASE_DEC, NULL, 0x0,
1838         NULL, HFILL } },
1839     /* END: client connect fields */
1840 
1841     /* START: relay server fields */
1842         { &hf_waveagent_relaydestid,
1843         { "ID of destination client (assigned by relay server)", "waveagent.relaydestid",
1844         FT_UINT32, BASE_DEC, NULL, 0x0,
1845         NULL, HFILL } },
1846 
1847         { &hf_waveagent_relaysrcid,
1848         { "ID of source client (assigned by relay server)", "waveagent.relaysrcid",
1849         FT_UINT32, BASE_DEC, NULL, 0x0,
1850         NULL, HFILL } },
1851 
1852         { &hf_waveagent_relaymessagest,
1853         { "Relayed WaveAgent Message", "waveagent.relaymessagest",
1854         FT_NONE, BASE_NONE, NULL, 0x0,
1855         "This is a relayed WaveAgent message", HFILL } },
1856 
1857 /* END: relay server fields */
1858 
1859     };
1860 
1861 /* Setup protocol subtree array */
1862     static gint *ett[] = {
1863         &ett_waveagent,
1864         &ett_statechange,
1865         &ett_phytypes,
1866         &ett_fsflags,
1867         &ett_scindex[0],
1868         &ett_scindex[1],
1869         &ett_scindex[2],
1870         &ett_scindex[3],
1871         &ett_scindex[4],
1872         &ett_scindex[5],
1873         &ett_scindex[6],
1874         &ett_scindex[7],
1875         &ett_bss[0],
1876         &ett_bss[1],
1877         &ett_bss[2],
1878         &ett_bss[3],
1879         &ett_bss[4],
1880         &ett_bss[5],
1881         &ett_bss[6],
1882         &ett_bss[7],
1883         &ett_relaymessage,
1884     };
1885 
1886     proto_waveagent = proto_register_protocol(
1887         "WaveAgent", "waveagent", "waveagent");
1888 
1889     proto_register_field_array(proto_waveagent, hf, array_length(hf));
1890     proto_register_subtree_array(ett, array_length(ett));
1891 }
1892 
1893 
proto_reg_handoff_waveagent(void)1894 void proto_reg_handoff_waveagent(void)
1895 {
1896     heur_dissector_add("udp", dissect_waveagent_heur, "WaveAgent over UDP", "waveagent_udp", proto_waveagent, HEURISTIC_ENABLE);
1897 }
1898 
1899 
1900 /*
1901  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1902  *
1903  * Local variables:
1904  * c-basic-offset: 4
1905  * tab-width: 8
1906  * indent-tabs-mode: nil
1907  * End:
1908  *
1909  * vi: set shiftwidth=4 tabstop=8 expandtab:
1910  * :indentSize=4:tabSize=8:noTabs=true:
1911  */
1912