1 /* packet-aruba-erm.c
2  * Routines for the disassembly of Aruba encapsulated remote mirroring frames
3  * (Adapted from packet-hp-erm.c and packet-cisco-erspan.c)
4  *
5  * Copyright 2010  Alexis La Goutte <alexis.lagoutte at gmail dot com>
6  *
7  * ERM Radio-Format added by Hadriel Kaplan
8  *
9  * Type 6 added by Jeffrey Goff <jgoff at arubanetworks dot com>
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * SPDX-License-Identifier: GPL-2.0-or-later
16  */
17 
18 /*
19  * See
20  *
21  *    http://community.arubanetworks.com/t5/Unified-Wired-Wireless-Access/Bug-in-ArubaOS-Packet-Capture/td-p/237984
22  *
23  *    http://kjspgd.net/?p=30
24  *
25  * for more information.
26  */
27 
28 /*
29  * Formats:
30  *
31  * Pcap (type 0):
32  *
33  * Payload contains a pcap record header:
34  *
35  * typedef struct pcaprec_hdr_s {
36  *       guint32 ts_sec;          timestamp seconds
37  *       guint32 ts_usec;         timestamp microseconds
38  *       guint32 incl_len;        number of octets of packet saved in file
39  *       guint32 orig_len;        actual length of packet
40  * } pcaprec_hdr_t;
41  *
42  * followed by the packet data, starting with an 802.11 header.
43  *
44  * Peek (type 1):
45  *
46  * Payload contains a "Peek remote" packet, as supported by
47  * EtherPeek/AiroPeek/OmniPeek.
48  *
49  * Airmagnet (type 2):
50  *
51  * Unknown payload format.
52  *
53  * Pcap + radio header (type 3):
54  *
55  * Payload contains a pcap record header, as per the above, followed
56  * by a header with radio information:
57  *
58  *  struct radio_hdr {
59  *   __u16  rate_per_half_mhz;
60  *   __u8   channel;
61  *   __u8   signal_percent;
62  *  } __attribute__ ((packed));
63  *
64  * followed by the packet data, starting with an 802.11 header.
65  *
66  * PPI (type 4):
67  *
68  * Payload contains a PPI header followed by the packet data, starting
69  * with an 802.11 header.
70  *
71  * Peek 11n/11ac (type 5):
72  *
73  * This is probably the "new" "Peek remote" format.  The "Peek remote"
74  * dissector should probably be able to distinguish this from type 1,
75  * as the "new" format has a magic number in it.  Given that there's
76  * a heuristic "Peek remote new" dissector, those packets might
77  * automatically be recognized without setting any preference whatsoever.
78  *
79  * Radiotap (type 6):
80  *
81  * As part of 802.11ax developement, Aruba has added radiotap capture
82  * encapsulation. This new format can be used with any model of AP
83  * be it 11ax, 11ac or 11n.
84  * Note: type 6 is _only_ supported in ArubaOS 8.6 and higher.
85  *
86  */
87 
88 #include "config.h"
89 
90 #include <wiretap/wtap.h>
91 
92 #include <epan/packet.h>
93 #include <epan/expert.h>
94 #include <epan/prefs.h>
95 #include <epan/decode_as.h>
96 
97 #include <wsutil/802_11-utils.h>
98 
99 #define PROTO_SHORT_NAME "ARUBA_ERM"
100 #define PROTO_LONG_NAME  "Aruba Networks encapsulated remote mirroring"
101 
102 #define TYPE_PCAP 0
103 #define TYPE_PEEK 1
104 #define TYPE_AIRMAGNET 2
105 #define TYPE_PCAPPLUSRADIO 3
106 #define TYPE_PPI 4
107 
108 #define IS_ARUBA 0x01
109 
110 #if 0
111 static const value_string aruba_erm_type_vals[] = {
112     { TYPE_PCAP,            "pcap (type 0)" },
113     { TYPE_PEEK,            "peek (type 1)" },
114     { TYPE_AIRMAGNET,       "Airmagnet (type 2)" },
115     { TYPE_PCAPPLUSRADIO,   "pcap + radio header (type 3)" },
116     { TYPE_PPI,             "PPI (type 4)" },
117     { 0, NULL }
118 };
119 #endif
120 
121 void proto_register_aruba_erm(void);
122 void proto_reg_handoff_aruba_erm(void);
123 void proto_reg_handoff_aruba_erm_radio(void);
124 
125 #if 0
126 static gint  aruba_erm_type         = 0;
127 #endif
128 
129 static int  proto_aruba_erm       = -1;
130 static int  proto_aruba_erm_type0 = -1;
131 static int  proto_aruba_erm_type1 = -1;
132 static int  proto_aruba_erm_type2 = -1;
133 static int  proto_aruba_erm_type3 = -1;
134 static int  proto_aruba_erm_type4 = -1;
135 static int  proto_aruba_erm_type5 = -1;
136 static int  proto_aruba_erm_type6 = -1;
137 
138 static int  hf_aruba_erm_time             = -1;
139 static int  hf_aruba_erm_incl_len         = -1;
140 static int  hf_aruba_erm_orig_len         = -1;
141 static int  hf_aruba_erm_data_rate        = -1;
142 static int  hf_aruba_erm_data_rate_gen    = -1;
143 static int  hf_aruba_erm_channel          = -1;
144 static int  hf_aruba_erm_signal_strength  = -1;
145 
146 static gint ett_aruba_erm = -1;
147 
148 static expert_field ei_aruba_erm_airmagnet = EI_INIT;
149 static expert_field ei_aruba_erm_decode = EI_INIT;
150 
151 static dissector_handle_t aruba_erm_handle;
152 static dissector_handle_t aruba_erm_handle_type0;
153 static dissector_handle_t aruba_erm_handle_type1;
154 static dissector_handle_t aruba_erm_handle_type2;
155 static dissector_handle_t aruba_erm_handle_type3;
156 static dissector_handle_t aruba_erm_handle_type4;
157 static dissector_handle_t aruba_erm_handle_type5;
158 static dissector_handle_t aruba_erm_handle_type6;
159 static dissector_handle_t wlan_radio_handle;
160 static dissector_handle_t wlan_withfcs_handle;
161 static dissector_handle_t peek_handle;
162 static dissector_handle_t ppi_handle;
163 static dissector_handle_t radiotap_handle;
164 
165 static dissector_table_t aruba_erm_subdissector_table;
166 
167 static int
dissect_aruba_erm_pcap(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * aruba_erm_tree,gint offset)168 dissect_aruba_erm_pcap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *aruba_erm_tree, gint offset)
169 {
170     proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_time, tvb, offset, 8, ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN);
171     offset +=8;
172 
173     proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_incl_len, tvb, 8, 4, ENC_BIG_ENDIAN);
174     offset +=4;
175 
176     proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_orig_len, tvb, 12, 4, ENC_BIG_ENDIAN);
177     offset +=4;
178 
179     return offset;
180 }
181 
182 static proto_tree *
dissect_aruba_erm_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int * offset _U_)183 dissect_aruba_erm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset _U_)
184 {
185 
186     proto_item *ti;
187     proto_tree *aruba_erm_tree;
188 
189     col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME);
190     col_set_str(pinfo->cinfo, COL_INFO, PROTO_SHORT_NAME);
191 
192 
193     ti = proto_tree_add_item(tree, proto_aruba_erm, tvb, 0, 0, ENC_NA);
194     aruba_erm_tree = proto_item_add_subtree(ti, ett_aruba_erm);
195 
196     return aruba_erm_tree;
197 
198 
199 }
200 
201 
202 static int
dissect_aruba_erm(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)203 dissect_aruba_erm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
204 {
205     int offset = 0;
206 
207     if (!dissector_try_payload(aruba_erm_subdissector_table, tvb, pinfo, tree)) {
208 
209         dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
210         /* Add Expert info how decode...*/
211         proto_tree_add_expert(tree, pinfo, &ei_aruba_erm_decode, tvb, offset, -1);
212         call_data_dissector(tvb, pinfo, tree);
213     }
214 
215     return tvb_captured_length(tvb);
216 }
217 
218 
219 static int
dissect_aruba_erm_type0(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)220 dissect_aruba_erm_type0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
221 {
222     tvbuff_t * next_tvb;
223     int offset = 0;
224     proto_tree *aruba_erm_tree;
225 
226     aruba_erm_tree = dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
227 
228     offset = dissect_aruba_erm_pcap(tvb, pinfo, aruba_erm_tree, offset);
229     proto_item_set_len(aruba_erm_tree, offset);
230 
231     next_tvb = tvb_new_subset_remaining(tvb, offset);
232     /* No way to determine if TX or RX packet... (TX = no FCS, RX = FCS...)*/
233     call_dissector(wlan_withfcs_handle, next_tvb, pinfo, tree);
234 
235     return tvb_captured_length(tvb);
236 }
237 
238 static int
dissect_aruba_erm_type1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)239 dissect_aruba_erm_type1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
240 {
241     int offset = 0;
242 
243     dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
244 
245     /* Say to PEEK dissector, it is a Aruba PEEK packet */
246     call_dissector_with_data(peek_handle, tvb, pinfo, tree, GUINT_TO_POINTER(IS_ARUBA));
247 
248     return tvb_captured_length(tvb);
249 }
250 
251 static int
dissect_aruba_erm_type2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)252 dissect_aruba_erm_type2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
253 {
254     int offset = 0;
255 
256     dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
257 
258     /* Not (yet) supported launch data dissector */
259     proto_tree_add_expert(tree, pinfo, &ei_aruba_erm_airmagnet, tvb, offset, -1);
260     call_data_dissector(tvb, pinfo, tree);
261 
262     return tvb_captured_length(tvb);
263 }
264 
265 static int
dissect_aruba_erm_type3(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)266 dissect_aruba_erm_type3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
267 {
268     tvbuff_t * next_tvb;
269     int offset = 0;
270     proto_tree *aruba_erm_tree;
271     struct ieee_802_11_phdr phdr;
272     guint32 signal_strength;
273     proto_item *ti_data_rate;
274     guint16 data_rate;
275     guint channel;
276 
277     aruba_erm_tree = dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
278 
279     offset = dissect_aruba_erm_pcap(tvb, pinfo, aruba_erm_tree, offset);
280 
281     memset(&phdr, 0, sizeof(phdr));
282     phdr.decrypted = FALSE;
283     phdr.datapad = FALSE;
284     phdr.phy = PHDR_802_11_PHY_UNKNOWN;
285     phdr.has_data_rate = TRUE;
286     data_rate = tvb_get_ntohs(tvb, offset);
287     phdr.data_rate = data_rate;
288     proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_data_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
289     ti_data_rate = proto_tree_add_float_format(aruba_erm_tree, hf_aruba_erm_data_rate_gen,
290                                                 tvb, 16, 2,
291                                                 (float)data_rate / 2,
292                                                 "Data Rate: %.1f Mb/s",
293                                                 (float)data_rate / 2);
294     proto_item_set_generated(ti_data_rate);
295     offset += 2;
296 
297     proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_channel, tvb, offset, 1, ENC_BIG_ENDIAN, &channel);
298     phdr.has_channel = TRUE;
299     phdr.channel = channel;
300     offset += 1;
301 
302     proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_signal_strength, tvb, offset, 1, ENC_BIG_ENDIAN, &signal_strength);
303     phdr.has_signal_percent = TRUE;
304     phdr.signal_percent = signal_strength;
305     offset += 1;
306 
307     proto_item_set_len(aruba_erm_tree, offset);
308     next_tvb = tvb_new_subset_remaining(tvb, offset);
309 
310     /*
311      * We don't know they PHY, but we do have the data rate;
312      * try to guess the PHY based on the data rate and channel.
313      */
314     if (RATE_IS_DSSS(phdr.data_rate)) {
315         /* 11b */
316         phdr.phy = PHDR_802_11_PHY_11B;
317         phdr.phy_info.info_11b.has_short_preamble = FALSE;
318     } else if (RATE_IS_OFDM(phdr.data_rate)) {
319         /* 11a or 11g, depending on the band. */
320         if (CHAN_IS_BG(phdr.channel)) {
321             /* 11g */
322             phdr.phy = PHDR_802_11_PHY_11G;
323             phdr.phy_info.info_11g.has_mode = FALSE;
324         } else {
325             /* 11a */
326             phdr.phy = PHDR_802_11_PHY_11A;
327             phdr.phy_info.info_11a.has_channel_type = FALSE;
328             phdr.phy_info.info_11a.has_turbo_type = FALSE;
329         }
330     }
331 
332     if(signal_strength == 100){ /* When signal = 100 %, it is TX packet and there is no FCS */
333         phdr.fcs_len = 0; /* TX packet, no FCS */
334     } else {
335         phdr.fcs_len = 4; /* We have an FCS */
336     }
337     call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr);
338     return tvb_captured_length(tvb);
339 }
340 
341 static int
dissect_aruba_erm_type4(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)342 dissect_aruba_erm_type4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
343 {
344     int offset = 0;
345 
346     dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
347 
348     call_dissector(ppi_handle, tvb, pinfo, tree);
349 
350     return tvb_captured_length(tvb);
351 }
352 
353 /* Type 5 is the same of type 1 but with Peek Header version = 2, named internaly Peekremote -ng */
354 static int
dissect_aruba_erm_type5(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)355 dissect_aruba_erm_type5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
356 {
357     int offset = 0;
358 
359     dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
360 
361     /* Say to PEEK dissector, it is a Aruba PEEK  packet */
362     call_dissector_with_data(peek_handle, tvb, pinfo, tree, GUINT_TO_POINTER(IS_ARUBA));
363 
364     return tvb_captured_length(tvb);
365 }
366 
367 static int
dissect_aruba_erm_type6(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)368 dissect_aruba_erm_type6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
369 {
370     int offset = 0;
371 
372     dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
373 
374     /* Note: In a similar manner to type 3, packets transmitted by the capturing
375        AP will be passed with no FCS and a hardcoded 'antenna signal' of -30dBm.
376        However, unlike type 3 we don't need to do anything about this because the
377        radiotap header flag "FCS at end" will be correctly set to "False" in this case
378        which is handled transparently by the radiotap dissector. All other received
379        frames are expected to have a FCS and "FCS at end" set to "True".
380      */
381     call_dissector(radiotap_handle, tvb, pinfo, tree);
382 
383     return tvb_captured_length(tvb);
384 }
385 
386 static void
aruba_erm_prompt(packet_info * pinfo _U_,gchar * result)387 aruba_erm_prompt(packet_info *pinfo _U_, gchar* result)
388 {
389     g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Aruba ERM payload as");
390 }
391 
392 void
proto_register_aruba_erm(void)393 proto_register_aruba_erm(void)
394 {
395 
396     static hf_register_info hf[] = {
397 
398         { &hf_aruba_erm_time,
399           { "Packet Capture Timestamp", "aruba_erm.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL,
400             0x00, NULL, HFILL }},
401         { &hf_aruba_erm_incl_len,
402           { "Packet Captured Length", "aruba_erm.incl_len", FT_UINT32, BASE_DEC, NULL,
403             0x00, NULL, HFILL }},
404         { &hf_aruba_erm_orig_len,
405           { "Packet Length", "aruba_erm.orig_len", FT_UINT32, BASE_DEC, NULL,
406             0x00, NULL, HFILL }},
407         { &hf_aruba_erm_data_rate,
408           { "Data Rate", "aruba_erm.data_rate", FT_UINT16, BASE_DEC, NULL,
409             0x00, "Data rate (1/2 Mb/s)", HFILL }},
410         { &hf_aruba_erm_data_rate_gen,
411           { "Data Rate", "aruba_erm.data_rate_gen", FT_FLOAT, BASE_NONE, NULL,
412             0x00, "Data rate (1/2 Mb/s)", HFILL }},
413         { &hf_aruba_erm_channel,
414           { "Channel", "aruba_erm.channel", FT_UINT8, BASE_DEC, NULL,
415             0x00, "802.11 channel number that this frame was sent/received on", HFILL }},
416         { &hf_aruba_erm_signal_strength,
417           { "Signal Strength [percent]", "aruba_erm.signal_strength", FT_UINT8, BASE_DEC, NULL,
418             0x00, "Signal strength (Percentage)", HFILL }},
419     };
420 
421     /* both formats share the same tree */
422     static gint *ett[] = {
423         &ett_aruba_erm,
424     };
425 
426     static ei_register_info ei[] = {
427         { &ei_aruba_erm_airmagnet, { "aruba_erm.airmagnet", PI_UNDECODED, PI_ERROR, "Airmagnet (type 2) is no yet supported (Please use other type)", EXPFILL }},
428         { &ei_aruba_erm_decode, { "aruba_erm.decode", PI_UNDECODED, PI_NOTE, "Use Decode AS (Aruba ERM Type) for decoding payload", EXPFILL }}
429     };
430 
431 #if 0
432     static const enum_val_t aruba_erm_types[] = {
433         { "pcap_type_0", "pcap (type 0)", TYPE_PCAP},
434         { "peek_type_1", "peek (type 1)", TYPE_PEEK},
435         { "airmagnet_type_2", "Airmagnet (type 2)", TYPE_AIRMAGNET},
436         { "pcapplusradio_type_3", "pcap + radio header (type 3)", TYPE_PCAPPLUSRADIO},
437         { "ppi_type_4", "PPI (type 4)", TYPE_PPI},
438         { NULL, NULL, -1}
439     };
440 #endif
441 
442     module_t *aruba_erm_module;
443 
444     expert_module_t* expert_aruba_erm;
445 
446     proto_aruba_erm = proto_register_protocol(PROTO_LONG_NAME, "ARUBA_ERM" , "aruba_erm");
447     proto_aruba_erm_type0 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - PCAP (Type 0)", "ARUBA ERM PCAP (Type 0)", "aruba_erm_type0", proto_aruba_erm, FT_PROTOCOL);
448     proto_aruba_erm_type1 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - PEEK (Type 1)", "ARUBA ERM PEEK (type 1)", "aruba_erm_type1", proto_aruba_erm, FT_PROTOCOL);
449     proto_aruba_erm_type2 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - AIRMAGNET (Type 2)", "ARUBA ERM AIRMAGNET (Type 2)", "aruba_erm_type2", proto_aruba_erm, FT_PROTOCOL);
450     proto_aruba_erm_type3 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - PCAP+RADIO (Type 3)", "ARUBA ERM PCAP+RADIO (Type 3)", "aruba_erm_type3", proto_aruba_erm, FT_PROTOCOL);
451     proto_aruba_erm_type4 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - PPI (Type 4)", "ARUBA ERM PPI (Type 4)", "aruba_erm_type4", proto_aruba_erm, FT_PROTOCOL);
452     proto_aruba_erm_type5 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - PEEK (Type 5)", "ARUBA ERM PEEK-NG (type 5)", "aruba_erm_type5", proto_aruba_erm, FT_PROTOCOL);
453     proto_aruba_erm_type6 = proto_register_protocol_in_name_only("Aruba Networks encapsulated remote mirroring - RADIOTAP (Type 6)", "ARUBA ERM RADIOTAP (type 6)", "aruba_erm_type6", proto_aruba_erm, FT_PROTOCOL);
454 
455     aruba_erm_module = prefs_register_protocol(proto_aruba_erm, NULL);
456 
457 #if 0
458     /* Obso...*/
459     prefs_register_enum_preference(aruba_erm_module, "type.captured",
460                        "Type of formats for captured packets",
461                        "Type of formats for captured packets",
462                        &aruba_erm_type, aruba_erm_types, FALSE);
463 #endif
464     prefs_register_obsolete_preference(aruba_erm_module, "type.captured");
465 
466     proto_register_field_array(proto_aruba_erm, hf, array_length(hf));
467     proto_register_subtree_array(ett, array_length(ett));
468     expert_aruba_erm = expert_register_protocol(proto_aruba_erm);
469     expert_register_field_array(expert_aruba_erm, ei, array_length(ei));
470 
471     register_dissector("aruba_erm", dissect_aruba_erm, proto_aruba_erm);
472 
473     aruba_erm_subdissector_table = register_decode_as_next_proto(proto_aruba_erm, "aruba_erm.type",
474                                                                 "Aruba ERM Type", aruba_erm_prompt);
475 }
476 
477 void
proto_reg_handoff_aruba_erm(void)478 proto_reg_handoff_aruba_erm(void)
479 {
480     wlan_radio_handle = find_dissector_add_dependency("wlan_radio", proto_aruba_erm);
481     wlan_withfcs_handle = find_dissector_add_dependency("wlan_withfcs", proto_aruba_erm);
482     ppi_handle = find_dissector_add_dependency("ppi", proto_aruba_erm);
483     peek_handle = find_dissector_add_dependency("peekremote", proto_aruba_erm);
484     radiotap_handle = find_dissector_add_dependency("radiotap", proto_aruba_erm);
485     aruba_erm_handle = create_dissector_handle(dissect_aruba_erm, proto_aruba_erm);
486     aruba_erm_handle_type0 = create_dissector_handle(dissect_aruba_erm_type0, proto_aruba_erm_type0);
487     aruba_erm_handle_type1 = create_dissector_handle(dissect_aruba_erm_type1, proto_aruba_erm_type1);
488     aruba_erm_handle_type2 = create_dissector_handle(dissect_aruba_erm_type2, proto_aruba_erm_type2);
489     aruba_erm_handle_type3 = create_dissector_handle(dissect_aruba_erm_type3, proto_aruba_erm_type3);
490     aruba_erm_handle_type4 = create_dissector_handle(dissect_aruba_erm_type4, proto_aruba_erm_type4);
491     aruba_erm_handle_type5 = create_dissector_handle(dissect_aruba_erm_type5, proto_aruba_erm_type5);
492     aruba_erm_handle_type6 = create_dissector_handle(dissect_aruba_erm_type6, proto_aruba_erm_type6);
493 
494     dissector_add_uint_range_with_preference("udp.port", "", aruba_erm_handle);
495     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type0);
496     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type1);
497     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type2);
498     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type3);
499     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type4);
500     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type5);
501     dissector_add_for_decode_as("aruba_erm.type", aruba_erm_handle_type6);
502 }
503 
504 /*
505  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
506  *
507  * Local variables:
508  * c-basic-offset: 4
509  * tab-width: 8
510  * indent-tabs-mode: nil
511  * End:
512  *
513  * vi: set shiftwidth=4 tabstop=8 expandtab:
514  * :indentSize=4:tabSize=8:noTabs=true:
515  */
516