1 /* packet-mka.c
2  * Routines for EAPOL-MKA IEEE 802.1X-2010 / IEEE 802.1bx-2014 /
3  * IEEE Std 802.1Xck-2018 / IEEE 802.1X-2020 MKPDU dissection
4  * Copyright 2014, Hitesh K Maisheri <maisheri.hitesh@gmail.com>
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "config.h"
14 
15 #include <epan/packet.h>
16 #include <epan/expert.h>
17 
18 #include "packet-eapol.h"
19 
20 #define LIVE_PEER_LIST_TYPE          1
21 #define POTENTIAL_PEER_LIST_TYPE     2
22 #define MACSEC_SAK_USE_TYPE          3
23 #define DISTRIBUTED_SAK_TYPE         4
24 #define DISTRIBUTED_CAK_TYPE         5
25 #define KMD_TYPE                     6
26 #define ANNOUNCEMENT_TYPE            7
27 #define XPN_TYPE                     8
28 #define ICV_TYPE                     255
29 
30 void proto_register_mka(void);
31 void proto_reg_handoff_mka(void);
32 
33 static int proto_mka = -1;
34 
35 static int hf_mka_version_id = -1;
36 static int hf_mka_basic_param_set = -1;
37 static int hf_mka_live_peer_list_set = -1;
38 static int hf_mka_potential_peer_list_set = -1;
39 static int hf_mka_macsec_sak_use_set = -1;
40 static int hf_mka_distributed_sak_set = -1;
41 static int hf_mka_distributed_cak_set = -1;
42 static int hf_mka_kmd_set = -1;
43 static int hf_mka_announcement_set = -1;
44 static int hf_mka_xpn_set = -1;
45 static int hf_mka_icv_set = -1;
46 static int hf_mka_param_set_type = -1;
47 
48 static int hf_mka_keyserver_priority = -1;
49 static int hf_mka_key_server = -1;
50 static int hf_mka_macsec_desired = -1;
51 static int hf_mka_macsec_capability = -1;
52 static int hf_mka_param_body_length = -1;
53 static int hf_mka_sci = -1;
54 static int hf_mka_actor_mi = -1;
55 static int hf_mka_actor_mn = -1;
56 static int hf_mka_algo_agility = -1;
57 static int hf_mka_cak_name = -1;
58 
59 static int hf_mka_padding = -1;
60 
61 static int hf_mka_key_server_ssci = -1;
62 static int hf_mka_peer_mi = -1;
63 static int hf_mka_peer_mn = -1;
64 
65 static int hf_mka_latest_key_an = -1;
66 static int hf_mka_latest_key_tx = -1;
67 static int hf_mka_latest_key_rx = -1;
68 static int hf_mka_old_key_an = -1;
69 static int hf_mka_old_key_tx = -1;
70 static int hf_mka_old_key_rx = -1;
71 static int hf_mka_plain_tx = -1;
72 static int hf_mka_plain_rx = -1;
73 static int hf_mka_delay_protect = -1;
74 static int hf_mka_latest_key_server_mi = -1;
75 static int hf_mka_latest_key_number = -1;
76 static int hf_mka_latest_lowest_acceptable_pn = -1;
77 static int hf_mka_old_key_server_mi = -1;
78 static int hf_mka_old_key_number = -1;
79 static int hf_mka_old_lowest_acceptable_pn = -1;
80 
81 static int hf_mka_distributed_an = -1;
82 static int hf_mka_confidentiality_offset = -1;
83 static int hf_mka_key_number = -1;
84 static int hf_mka_aes_key_wrap_sak = -1;
85 static int hf_mka_macsec_cipher_suite = -1;
86 static int hf_mka_aes_key_wrap_cak = -1;
87 
88 static int hf_mka_kmd = -1;
89 
90 static int hf_mka_suspension_time = -1;
91 
92 static int hf_mka_unknown_set = -1;
93 static int hf_mka_unknown_param_set = -1;
94 
95 static int hf_mka_icv = -1;
96 
97 static int hf_mka_tlv_entry = -1;
98 static int hf_mka_tlv_type = -1;
99 static int hf_mka_tlv_info_string_length = -1;
100 static int hf_mka_tlv_data = -1;
101 static int hf_mka_tlv_cipher_suite_impl_cap = -1;
102 
103 static expert_field ei_mka_undecoded = EI_INIT;
104 static expert_field ei_unexpected_data = EI_INIT;
105 static expert_field ei_mka_unimplemented = EI_INIT;
106 
107 static gint ett_mka = -1;
108 static gint ett_mka_basic_param_set = -1;
109 static gint ett_mka_peer_list_set = -1;
110 static gint ett_mka_sak_use_set = -1;
111 static gint ett_mka_distributed_sak_set = -1;
112 static gint ett_mka_distributed_cak_set = -1;
113 static gint ett_mka_kmd_set = -1;
114 static gint ett_mka_announcement_set = -1;
115 static gint ett_mka_xpn_set = -1;
116 static gint ett_mka_unknown_set = -1;
117 static gint ett_mka_icv_set = -1;
118 static gint ett_mka_tlv = -1;
119 static gint ett_mka_cipher_suite_entry = -1;
120 
121 static const value_string param_set_type_vals[] = {
122   { LIVE_PEER_LIST_TYPE,       "Live Peer List" },
123   { POTENTIAL_PEER_LIST_TYPE,  "Potential Peer List" },
124   { MACSEC_SAK_USE_TYPE,       "MACsec SAK Use" },
125   { DISTRIBUTED_SAK_TYPE,      "Distributed SAK" },
126   { DISTRIBUTED_CAK_TYPE,      "Distributed CAK" },
127   { KMD_TYPE,                  "KMD" },
128   { ANNOUNCEMENT_TYPE,         "Announcement" },
129   { XPN_TYPE,                  "XPN" },
130   { ICV_TYPE,                  "ICV Indicator" },
131   { 0, NULL }
132 };
133 
134 static const value_string macsec_capability_type_vals[] = {
135   { 0,                     "MACsec not implemented" },
136   { 1,                     "MACsec Integrity without confidentiality" },
137   { 2,                     "MACsec Integrity with no confidentiality offset" },
138   { 3,                     "MACsec Integrity with confidentiality offset" },
139   { 0, NULL }
140 };
141 
142 static const value_string algo_agility_vals[] = {
143   { 0x0080C201, "IEEE Std 802.1X-2010" },
144   { 0, NULL }
145 };
146 
147 static const value_string confidentiality_offset_vals[] = {
148   { 0, "No confidentiality" },
149   { 1, "No confidentiality offset" },
150   { 2, "Confidentiality offset 30 octets" },
151   { 3, "Confidentiality offset 50 octets" },
152   { 0, NULL }
153 };
154 
155 static const val64_string macsec_cipher_suite_vals[] = {
156   { G_GINT64_CONSTANT(0x0080020001000001),           "GCM-AES-128" }, // Original, incorrect value in IEEE 802.1AE-2006 and IEEE 802.1X-2010
157   { G_GINT64_CONSTANT(0x0080C20001000001),           "GCM-AES-128" },
158   { G_GINT64_CONSTANT(0x0080C20001000002),           "GCM-AES-256" },
159   { G_GINT64_CONSTANT(0x0080C20001000003),           "GCM-AES-XPN-128" },
160   { G_GINT64_CONSTANT(0x0080C20001000004),           "GCM-AES-XPN-256" },
161   { 0, NULL }
162 };
163 
164 
165 static const value_string macsec_tlvs[] = {
166   // 0 - 110 reserved
167   { 111, "Access Information" },
168   { 112, "MACsec Cipher Suites" },
169   { 113, "Key Management Domain" },
170   { 114, "NID (Network Identifier)" },
171   // 115 - 125 reserved
172   { 126, "Organizationally Specific Set TLV" },
173   { 127, "Organizationally Specific TLVs" },
174   { 0, NULL }
175 };
176 
177 static void
dissect_basic_paramset(proto_tree * mka_tree,packet_info * pinfo,tvbuff_t * tvb,int * offset_ptr)178 dissect_basic_paramset(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, int *offset_ptr)
179 {
180   int offset = *offset_ptr;
181   proto_tree *basic_param_set_tree;
182   proto_tree *ti;
183   guint16 basic_param_set_len;
184   guint16 cak_len;
185 
186   basic_param_set_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
187   ti = proto_tree_add_item(mka_tree, hf_mka_basic_param_set, tvb, offset, basic_param_set_len + 4, ENC_NA);
188   basic_param_set_tree = proto_item_add_subtree(ti, ett_mka_basic_param_set);
189 
190   proto_tree_add_item(basic_param_set_tree, hf_mka_version_id,
191                       tvb, offset, 1, ENC_BIG_ENDIAN);
192   offset += 1;
193 
194   proto_tree_add_item(basic_param_set_tree, hf_mka_keyserver_priority,
195                       tvb, offset, 1, ENC_BIG_ENDIAN);
196   offset += 1;
197 
198   proto_tree_add_item(basic_param_set_tree, hf_mka_key_server,
199                       tvb, offset, 1, ENC_BIG_ENDIAN);
200   proto_tree_add_item(basic_param_set_tree, hf_mka_macsec_desired,
201                       tvb, offset, 1, ENC_BIG_ENDIAN);
202   proto_tree_add_item(basic_param_set_tree, hf_mka_macsec_capability,
203                       tvb, offset, 1, ENC_BIG_ENDIAN);
204 
205   if (tvb_get_guint8(tvb, offset) & 0x80)
206   {
207     col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Key Server");
208   }
209 
210   proto_tree_add_uint(basic_param_set_tree, hf_mka_param_body_length,
211                       tvb, offset, 2, basic_param_set_len);
212   offset += 2;
213 
214   proto_tree_add_item(basic_param_set_tree, hf_mka_sci,
215                       tvb, offset, 8, ENC_NA);
216   offset += 8;
217 
218   proto_tree_add_item(basic_param_set_tree, hf_mka_actor_mi,
219                       tvb, offset, 12, ENC_NA);
220   offset += 12;
221 
222   proto_tree_add_item(basic_param_set_tree, hf_mka_actor_mn,
223                       tvb, offset, 4, ENC_NA);
224   offset += 4;
225 
226   proto_tree_add_item(basic_param_set_tree, hf_mka_algo_agility,
227                       tvb, offset, 4, ENC_NA);
228   offset += 4;
229 
230   cak_len = basic_param_set_len - 28;
231   proto_tree_add_item(basic_param_set_tree, hf_mka_cak_name,
232                       tvb, offset, cak_len, ENC_NA);
233   offset += cak_len;
234 
235   if (basic_param_set_len%4) {
236     int padding_len = (4 - (basic_param_set_len % 4));
237 
238     proto_tree_add_item(basic_param_set_tree, hf_mka_padding,
239                         tvb, offset, padding_len, ENC_NA);
240 
241     offset += padding_len;
242   }
243 
244   *offset_ptr = offset;
245 }
246 
247 static void
dissect_peer_list(proto_tree * mka_tree,packet_info * pinfo,tvbuff_t * tvb,int * offset_ptr,gboolean key_server_ssci_flag)248 dissect_peer_list(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, int *offset_ptr, gboolean key_server_ssci_flag)
249 {
250   int offset = *offset_ptr;
251   proto_tree *peer_list_set_tree;
252   proto_tree *ti;
253   int hf_peer = -1;
254   gint16 peer_list_len;
255 
256   if (tvb_get_guint8(tvb, offset) == LIVE_PEER_LIST_TYPE) {
257     hf_peer = hf_mka_live_peer_list_set;
258   } else {
259     hf_peer = hf_mka_potential_peer_list_set;
260   }
261 
262   peer_list_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
263   ti = proto_tree_add_item(mka_tree, hf_peer, tvb, offset, peer_list_len + 4, ENC_NA);
264   peer_list_set_tree = proto_item_add_subtree(ti, ett_mka_peer_list_set);
265 
266   proto_tree_add_item(peer_list_set_tree, hf_mka_param_set_type,
267                       tvb, offset, 1, ENC_BIG_ENDIAN);
268   offset += 1;
269 
270   if (key_server_ssci_flag && (hf_peer == hf_mka_live_peer_list_set))
271   {
272     /* XXX - The presence of this field is non-trivial to find out. See IEEE 802.1X-2020, Section 11.11.3
273      * Only present in MKPDU's with:
274      * - MKA version 3 (that's covered), and
275      * - In Live Peer list parameter set (that's covered), and
276      * - A Distributed SAK parameter set present (which could be before or after this parameter set), but only
277      * - A Distributed SAK parameter set with XPN Cipher suites (requires to look into the contents),
278      * otherwise 0.
279      */
280     proto_tree_add_item(peer_list_set_tree, hf_mka_key_server_ssci,
281                         tvb, offset, 1, ENC_BIG_ENDIAN);
282   }
283 
284   offset += 1;
285 
286   proto_tree_add_uint(peer_list_set_tree, hf_mka_param_body_length,
287                       tvb, offset, 2, peer_list_len);
288   offset += 2;
289 
290   while (peer_list_len >= 16) {
291     proto_tree_add_item(peer_list_set_tree, hf_mka_peer_mi,
292                         tvb, offset, 12, ENC_NA);
293     offset += 12;
294 
295     proto_tree_add_item(peer_list_set_tree, hf_mka_peer_mn,
296                         tvb, offset, 4, ENC_NA);
297     offset += 4;
298 
299     peer_list_len -= 16;
300   }
301 
302   if (peer_list_len != 0) {
303     proto_tree_add_expert(peer_list_set_tree, pinfo, &ei_mka_undecoded, tvb, offset, peer_list_len);
304     offset += peer_list_len;
305   }
306 
307   *offset_ptr = offset;
308 }
309 
310 static void
dissect_sak_use(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr)311 dissect_sak_use(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr)
312 {
313   int offset = *offset_ptr;
314   proto_tree *sak_use_set_tree;
315   proto_tree *ti;
316   guint16 sak_use_len;
317 
318   sak_use_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
319   ti = proto_tree_add_item(mka_tree, hf_mka_macsec_sak_use_set, tvb, offset, sak_use_len + 4, ENC_NA);
320   sak_use_set_tree = proto_item_add_subtree(ti, ett_mka_sak_use_set);
321 
322   proto_tree_add_item(sak_use_set_tree, hf_mka_param_set_type,
323                       tvb, offset, 1, ENC_BIG_ENDIAN);
324   offset += 1;
325 
326   proto_tree_add_item(sak_use_set_tree, hf_mka_latest_key_an,
327                       tvb, offset, 1, ENC_BIG_ENDIAN);
328   proto_tree_add_item(sak_use_set_tree, hf_mka_latest_key_tx,
329                       tvb, offset, 1, ENC_BIG_ENDIAN);
330   proto_tree_add_item(sak_use_set_tree, hf_mka_latest_key_rx,
331                       tvb, offset, 1, ENC_BIG_ENDIAN);
332 
333 
334   proto_tree_add_item(sak_use_set_tree, hf_mka_old_key_an,
335                       tvb, offset, 1, ENC_BIG_ENDIAN);
336   proto_tree_add_item(sak_use_set_tree, hf_mka_old_key_tx,
337                       tvb, offset, 1, ENC_BIG_ENDIAN);
338   proto_tree_add_item(sak_use_set_tree, hf_mka_old_key_rx,
339                       tvb, offset, 1, ENC_BIG_ENDIAN);
340 
341   offset += 1;
342 
343   proto_tree_add_item(sak_use_set_tree, hf_mka_plain_tx,
344                       tvb, offset, 1, ENC_BIG_ENDIAN);
345   proto_tree_add_item(sak_use_set_tree, hf_mka_plain_rx,
346                       tvb, offset, 1, ENC_BIG_ENDIAN);
347 
348   proto_tree_add_item(sak_use_set_tree, hf_mka_delay_protect,
349                       tvb, offset, 1, ENC_BIG_ENDIAN);
350 
351   proto_tree_add_uint(sak_use_set_tree, hf_mka_param_body_length,
352                       tvb, offset, 2, sak_use_len);
353 
354   offset += 2;
355 
356   /*
357    * 802.1X-2020 specifies only 0 or 40 are valid! See Figure 11-10 Note d
358    */
359   if (sak_use_len == 0) /* MACsec not supported */
360   {
361     /* Nothing */
362   }
363   else if (sak_use_len == 40) /* MACsec supported */
364   {
365     proto_tree_add_item(sak_use_set_tree, hf_mka_latest_key_server_mi,
366                         tvb, offset, 12, ENC_NA);
367     offset += 12;
368 
369     proto_tree_add_item(sak_use_set_tree, hf_mka_latest_key_number,
370                         tvb, offset, 4, ENC_NA);
371     offset += 4;
372 
373     proto_tree_add_item(sak_use_set_tree, hf_mka_latest_lowest_acceptable_pn,
374                         tvb, offset, 4, ENC_NA);
375     offset += 4;
376 
377     proto_tree_add_item(sak_use_set_tree, hf_mka_old_key_server_mi,
378                         tvb, offset, 12, ENC_NA);
379     offset += 12;
380 
381     proto_tree_add_item(sak_use_set_tree, hf_mka_old_key_number,
382                         tvb, offset, 4, ENC_NA);
383     offset += 4;
384 
385     proto_tree_add_item(sak_use_set_tree, hf_mka_old_lowest_acceptable_pn,
386                         tvb, offset, 4, ENC_NA);
387     offset += 4;
388   }
389   else
390   {
391     proto_tree_add_expert(sak_use_set_tree, pinfo, &ei_mka_undecoded, tvb, offset, sak_use_len);
392     offset += sak_use_len;
393   }
394 
395   *offset_ptr = offset;
396 }
397 
398 static void
dissect_distributed_sak(proto_tree * mka_tree,packet_info * pinfo,tvbuff_t * tvb,int * offset_ptr)399 dissect_distributed_sak(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, int *offset_ptr)
400 {
401   int offset = *offset_ptr;
402   guint16 distributed_sak_len;
403   proto_tree *distributed_sak_tree;
404   proto_tree *ti;
405 
406   distributed_sak_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
407   ti = proto_tree_add_item(mka_tree, hf_mka_distributed_sak_set, tvb, offset, distributed_sak_len + 4, ENC_NA);
408   distributed_sak_tree = proto_item_add_subtree(ti, ett_mka_distributed_sak_set);
409 
410   proto_tree_add_item(distributed_sak_tree, hf_mka_param_set_type,
411                       tvb, offset, 1, ENC_BIG_ENDIAN);
412   offset += 1;
413 
414   proto_tree_add_item(distributed_sak_tree, hf_mka_distributed_an,
415                       tvb, offset, 1, ENC_BIG_ENDIAN);
416   proto_tree_add_item(distributed_sak_tree, hf_mka_confidentiality_offset,
417                       tvb, offset, 1, ENC_BIG_ENDIAN);
418   offset += 1;
419 
420   proto_tree_add_uint(distributed_sak_tree, hf_mka_param_body_length,
421                       tvb, offset, 2, distributed_sak_len);
422   offset += 2;
423 
424   if (distributed_sak_len == 0) // Plain text
425   {
426       // Nothing
427   }
428   else if (distributed_sak_len == 28) // GCM-AES-128
429   {
430     proto_tree_add_item(distributed_sak_tree, hf_mka_key_number,
431                         tvb, offset, 4, ENC_NA);
432     offset += 4;
433 
434     proto_tree_add_item(distributed_sak_tree, hf_mka_aes_key_wrap_sak,
435                         tvb, offset, 24, ENC_NA);
436     offset += 24;
437   }
438   else if (distributed_sak_len >= 36) // Other than default cipher
439   {
440     proto_tree_add_item(distributed_sak_tree, hf_mka_key_number,
441                         tvb, offset, 4, ENC_NA);
442     offset += 4;
443 
444     proto_tree_add_item(distributed_sak_tree, hf_mka_macsec_cipher_suite,
445                         tvb, offset, 8, ENC_NA);
446     offset += 8;
447 
448     proto_tree_add_item(distributed_sak_tree, hf_mka_aes_key_wrap_sak,
449                         tvb, offset, distributed_sak_len - 12, ENC_NA);
450     offset += (distributed_sak_len - 12);
451   }
452   else
453   {
454     proto_tree_add_expert(distributed_sak_tree, pinfo, &ei_mka_undecoded, tvb, offset, distributed_sak_len);
455     offset += distributed_sak_len;
456   }
457 
458   if (distributed_sak_len%4) {
459     int padding_len = (4 - (distributed_sak_len % 4));
460 
461     proto_tree_add_item(distributed_sak_tree, hf_mka_padding,
462                         tvb, offset, padding_len, ENC_NA);
463 
464     offset += padding_len;
465   }
466 
467   *offset_ptr = offset;
468 }
469 
470 static void
dissect_distributed_cak(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr)471 dissect_distributed_cak(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr)
472 {
473   int offset = *offset_ptr;
474   guint16 distributed_cak_len;
475   proto_tree *distributed_cak_tree;
476   proto_tree *ti;
477   guint16 cak_len;
478 
479   distributed_cak_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
480   ti = proto_tree_add_item(mka_tree, hf_mka_distributed_cak_set, tvb, offset, distributed_cak_len + 4, ENC_NA);
481   distributed_cak_tree = proto_item_add_subtree(ti, ett_mka_distributed_cak_set);
482 
483   proto_tree_add_item(distributed_cak_tree, hf_mka_param_set_type,
484                       tvb, offset, 1, ENC_BIG_ENDIAN);
485   offset += 2;
486 
487   proto_tree_add_uint(distributed_cak_tree, hf_mka_param_body_length,
488                       tvb, offset, 2, distributed_cak_len);
489   offset += 2;
490 
491   proto_tree_add_item(distributed_cak_tree, hf_mka_aes_key_wrap_cak,
492                       tvb, offset, 24, ENC_NA);
493   offset += 24;
494 
495   cak_len = distributed_cak_len - 24;
496   proto_tree_add_item(distributed_cak_tree, hf_mka_cak_name,
497                       tvb, offset, cak_len, ENC_NA);
498   offset += cak_len;
499 
500   if (distributed_cak_len%4) {
501     int padding_len = (4 - (distributed_cak_len % 4));
502 
503     proto_tree_add_item(distributed_cak_tree, hf_mka_padding,
504                         tvb, offset, padding_len, ENC_NA);
505 
506     offset += padding_len;
507   }
508 
509   *offset_ptr = offset;
510 }
511 
512 static void
dissect_kmd(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr)513 dissect_kmd(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr)
514 {
515   int offset = *offset_ptr;
516   guint16 kmd_len;
517   proto_tree *kmd_set_tree;
518   proto_tree *ti;
519 
520   kmd_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
521   ti = proto_tree_add_item(mka_tree, hf_mka_kmd_set, tvb, offset, kmd_len + 4, ENC_NA);
522   kmd_set_tree = proto_item_add_subtree(ti, ett_mka_kmd_set);
523 
524   proto_tree_add_item(kmd_set_tree, hf_mka_param_set_type,
525                       tvb, offset, 1, ENC_BIG_ENDIAN);
526   offset += 2;
527 
528   proto_tree_add_uint(kmd_set_tree, hf_mka_param_body_length,
529                       tvb, offset, 2, kmd_len);
530   offset += 2;
531 
532   proto_tree_add_item(kmd_set_tree, hf_mka_kmd,
533                       tvb, offset, kmd_len, ENC_NA);
534   offset += kmd_len;
535 
536   *offset_ptr = offset;
537 }
538 
539 static void
dissect_announcement(proto_tree * mka_tree,packet_info * pinfo,tvbuff_t * tvb,int * offset_ptr)540 dissect_announcement(proto_tree *mka_tree, packet_info *pinfo, tvbuff_t *tvb, int *offset_ptr)
541 {
542   int offset = *offset_ptr;
543   guint16 announcement_len;
544   proto_tree *announcement_set_tree;
545   proto_tree *ti;
546   int offset2;
547 
548   announcement_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
549   ti = proto_tree_add_item(mka_tree, hf_mka_announcement_set, tvb, offset, announcement_len + 4, ENC_NA);
550   announcement_set_tree = proto_item_add_subtree(ti, ett_mka_announcement_set);
551 
552   proto_tree_add_item(announcement_set_tree, hf_mka_param_set_type,
553                       tvb, offset, 1, ENC_BIG_ENDIAN);
554 
555   offset += 2;
556 
557   proto_tree_add_uint(announcement_set_tree, hf_mka_param_body_length,
558                       tvb, offset, 2, announcement_len);
559   offset += 2;
560 
561   offset2 = 0;
562   while (offset2 + 2 <= announcement_len) {
563     proto_tree *tlv_tree;
564     guint8 tlv_type = ((tvb_get_guint8(tvb, offset + offset2)) & 0xfe ) >> 1;
565     guint16 tlv_length = (tvb_get_ntohs(tvb, offset + offset2)) & 0x01ff;
566     guint16 tlv_item_offset;
567 
568     if (offset2 + 2 + tlv_length > announcement_len) {
569       offset2 = announcement_len;
570       break;
571     }
572 
573     ti = proto_tree_add_none_format(announcement_set_tree, hf_mka_tlv_entry, tvb, offset + offset2, tlv_length + 2, "TLV entry: %s",
574                                     val_to_str(tlv_type, macsec_tlvs, "unknown TLV type: %d"));
575     tlv_tree = proto_item_add_subtree(ti, ett_mka_tlv);
576 
577     proto_tree_add_item(tlv_tree, hf_mka_tlv_type, tvb, offset + offset2, 1, ENC_NA);
578     proto_tree_add_item(tlv_tree, hf_mka_tlv_info_string_length, tvb, offset + offset2, 2, ENC_NA);
579     offset2 += 2;
580 
581     if (tlv_length > 0) {
582       switch (tlv_type) {
583       case 112: // MACsec Cipher Suites
584         tlv_item_offset = 0;
585         while (tlv_item_offset + 10 <= tlv_length) {
586           proto_tree *cipher_suite_entry;
587           guint64 cipher_suite_id = tvb_get_guint64(tvb, offset + offset2 + tlv_item_offset + 2, ENC_BIG_ENDIAN);
588           guint16 cipher_suite_cap = tvb_get_guint16(tvb, offset + offset2 + tlv_item_offset, ENC_BIG_ENDIAN) & 0x0003;
589 
590           ti = proto_tree_add_none_format(tlv_tree, hf_mka_tlv_entry, tvb, offset + offset2, tlv_length + 2, "Cipher Suite: %s, %s",
591                                           val64_to_str(cipher_suite_id, macsec_cipher_suite_vals, "Unknown Cipher Suite (0x%" G_GINT64_MODIFIER "x)"),
592                                           val_to_str(cipher_suite_cap, macsec_capability_type_vals, "Unknown Capability (%d)"));
593           cipher_suite_entry = proto_item_add_subtree(ti, ett_mka_cipher_suite_entry);
594 
595           proto_tree_add_item(cipher_suite_entry, hf_mka_tlv_cipher_suite_impl_cap, tvb, offset + offset2 + tlv_item_offset, 2, ENC_NA);
596           tlv_item_offset += 2;
597           proto_tree_add_item(cipher_suite_entry, hf_mka_macsec_cipher_suite, tvb, offset + offset2 + tlv_item_offset, 8, ENC_NA);
598           tlv_item_offset += 8;
599         }
600         break;
601 
602       case 111: // Access Information
603       case 113: // Key Management Domain
604       case 114: // NID (Network Identifier)
605         // See IEEE 802.1X-2010, Section 11.11.1, Figure 11-15 and Section 11.12
606         proto_tree_add_expert(tlv_tree, pinfo, &ei_mka_unimplemented, tvb, offset + offset2, tlv_length);
607         proto_tree_add_item(tlv_tree, hf_mka_tlv_data, tvb, offset + offset2, tlv_length, ENC_NA);
608         break;
609 
610       default:
611         proto_tree_add_item(tlv_tree, hf_mka_tlv_data, tvb, offset + offset2, tlv_length, ENC_NA);
612       }
613       offset2 += tlv_length;
614     }
615   }
616 
617   offset += announcement_len;
618 
619   if (announcement_len%4) {
620     int padding_len = (4 - (announcement_len % 4));
621 
622     proto_tree_add_item(announcement_set_tree, hf_mka_padding,
623                         tvb, offset, padding_len, ENC_NA);
624 
625     offset += padding_len;
626   }
627 
628   *offset_ptr = offset;
629 }
630 
631 static void
dissect_xpn(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr)632 dissect_xpn(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr)
633 {
634   int offset = *offset_ptr;
635   guint16 xpn_len;
636   proto_tree *xpn_set_tree;
637   proto_tree *ti;
638 
639   xpn_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
640   ti = proto_tree_add_item(mka_tree, hf_mka_xpn_set, tvb, offset, xpn_len + 4, ENC_NA);
641   xpn_set_tree = proto_item_add_subtree(ti, ett_mka_xpn_set);
642 
643   proto_tree_add_item(xpn_set_tree, hf_mka_param_set_type,
644                       tvb, offset, 1, ENC_BIG_ENDIAN);
645   offset += 1;
646 
647   proto_tree_add_item(xpn_set_tree, hf_mka_suspension_time,
648                       tvb, offset, 1, ENC_NA);
649   offset += 1;
650 
651   proto_tree_add_uint(xpn_set_tree, hf_mka_param_body_length,
652                       tvb, offset, 2, xpn_len);
653   offset += 2;
654 
655   proto_tree_add_item(xpn_set_tree, hf_mka_latest_lowest_acceptable_pn,
656                       tvb, offset, 4, ENC_NA);
657   offset += 4;
658 
659   proto_tree_add_item(xpn_set_tree, hf_mka_old_lowest_acceptable_pn,
660                       tvb, offset, 4, ENC_NA);
661   offset += 4;
662 
663   *offset_ptr = offset;
664 }
665 
666 static void
dissect_icv(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr,guint16 * icv_len)667 dissect_icv(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr, guint16 *icv_len)
668 {
669   int offset = *offset_ptr;
670   proto_tree *icv_set_tree;
671   proto_tree *ti;
672 
673   *icv_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
674   ti = proto_tree_add_item(mka_tree, hf_mka_icv_set, tvb, offset, 4, ENC_NA);
675   icv_set_tree = proto_item_add_subtree(ti, ett_mka_icv_set);
676 
677   proto_tree_add_item(icv_set_tree, hf_mka_param_set_type,
678                       tvb, offset, 1, ENC_BIG_ENDIAN);
679   offset += 2;
680 
681   proto_tree_add_uint(icv_set_tree, hf_mka_param_body_length,
682                       tvb, offset, 2, *icv_len);
683   offset += 2;
684 
685   *offset_ptr = offset;
686 }
687 
688 static void
dissect_unknown_param_set(proto_tree * mka_tree,packet_info * pinfo _U_,tvbuff_t * tvb,int * offset_ptr)689 dissect_unknown_param_set(proto_tree *mka_tree, packet_info *pinfo _U_, tvbuff_t *tvb, int *offset_ptr)
690 {
691   int offset = *offset_ptr;
692   guint16 param_set_len;
693   proto_tree *param_set_tree;
694   proto_tree *ti;
695 
696   param_set_len = (tvb_get_ntohs(tvb, offset + 2)) & 0x0fff;
697   ti = proto_tree_add_item(mka_tree, hf_mka_unknown_set, tvb, offset, param_set_len + 4, ENC_NA);
698   param_set_tree = proto_item_add_subtree(ti, ett_mka_unknown_set);
699 
700   proto_tree_add_item(param_set_tree, hf_mka_param_set_type,
701                       tvb, offset, 1, ENC_BIG_ENDIAN);
702   offset += 2;
703 
704   proto_tree_add_uint(param_set_tree, hf_mka_param_body_length,
705                       tvb, offset, 2, param_set_len);
706   offset += 2;
707 
708   proto_tree_add_item(param_set_tree, hf_mka_unknown_param_set,
709                       tvb, offset, param_set_len, ENC_NA);
710 
711   offset += param_set_len;
712 
713   if (param_set_len%4) {
714     int padding_len = (4 - (param_set_len % 4));
715 
716     proto_tree_add_item(param_set_tree, hf_mka_padding,
717                         tvb, offset, padding_len, ENC_NA);
718 
719     offset += padding_len;
720   }
721 
722   *offset_ptr = offset;
723 }
724 
725 static int
dissect_mka(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)726 dissect_mka(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
727 {
728   int         offset = 0;
729   guint8      mka_version_type;
730   guint16     icv_len = 16; // Default ICV length, see IEEE 802.1X-2010, Section 11.11
731   proto_tree *ti;
732   proto_tree *mka_tree;
733 
734   col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPOL-MKA");
735   col_clear(pinfo->cinfo, COL_INFO);
736 
737   ti = proto_tree_add_item(tree, proto_mka, tvb, 0, -1, ENC_NA);
738   mka_tree = proto_item_add_subtree(ti, ett_mka);
739 
740   /*
741    * The 802.1X-2010 spec specifies support for MKA version 1 only.
742    * The 802.1Xbx-2014 spec specifies support for MKA version 2.
743    * The 802.1Xck-2018 spec specifies support for MKA version 3.
744    */
745   mka_version_type = tvb_get_guint8(tvb, offset);
746   if ((mka_version_type < 1) || (mka_version_type > 3)) {
747     expert_add_info(pinfo, ti, &ei_unexpected_data);
748   }
749 
750   /*
751    * Basic Parameter set is always the first parameter set, dissect it first !
752    */
753   dissect_basic_paramset(mka_tree, pinfo, tvb, &offset);
754 
755   while(tvb_reported_length_remaining(tvb, offset) > icv_len) {
756     col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
757                         val_to_str_const(tvb_get_guint8(tvb, offset), param_set_type_vals, "Unknown"));
758     switch (tvb_get_guint8(tvb, offset)) {
759     case LIVE_PEER_LIST_TYPE:
760     case POTENTIAL_PEER_LIST_TYPE:
761       dissect_peer_list(mka_tree, pinfo, tvb, &offset, (mka_version_type == 3));
762       break;
763 
764     case MACSEC_SAK_USE_TYPE:
765       dissect_sak_use(mka_tree, pinfo, tvb, &offset);
766       break;
767 
768     case DISTRIBUTED_SAK_TYPE:
769       dissect_distributed_sak(mka_tree, pinfo, tvb, &offset);
770       break;
771 
772     case DISTRIBUTED_CAK_TYPE:
773       dissect_distributed_cak(mka_tree, pinfo, tvb, &offset);
774       break;
775 
776     case KMD_TYPE:
777       dissect_kmd(mka_tree, pinfo, tvb, &offset);
778       break;
779 
780     case ANNOUNCEMENT_TYPE:
781       dissect_announcement(mka_tree, pinfo, tvb, &offset);
782       break;
783 
784     case XPN_TYPE:
785       dissect_xpn(mka_tree, pinfo, tvb, &offset);
786       break;
787 
788     case ICV_TYPE:
789       // This ICV indicator does not include the ICV itself, see IEEE 802.1X-2010, Section 11.11.1
790       dissect_icv(mka_tree, pinfo, tvb, &offset, &icv_len);
791       break;
792 
793     default:
794       dissect_unknown_param_set(mka_tree, pinfo, tvb, &offset);
795       break;
796     }
797   }
798 
799   proto_tree_add_item(mka_tree, hf_mka_icv, tvb, offset, icv_len, ENC_NA);
800 
801   return tvb_captured_length(tvb);
802 }
803 
804 void
proto_register_mka(void)805 proto_register_mka(void)
806 {
807   expert_module_t  *expert_mka = NULL;
808 
809   static ei_register_info ei[] = {
810     { &ei_mka_undecoded, {
811         "mka.expert.undecoded_data", PI_UNDECODED, PI_WARN, "Undecoded data", EXPFILL }},
812     { &ei_unexpected_data, {
813         "mka.expert.unexpected_data", PI_PROTOCOL, PI_WARN, "Unexpected data", EXPFILL }},
814     { &ei_mka_unimplemented, {
815         "mka.expert.unimplemented", PI_UNDECODED, PI_WARN, "Announcement TLV not handled, if you want this implemented please contact the wireshark developers", EXPFILL }}
816   };
817 
818   static hf_register_info hf[] = {
819     { &hf_mka_version_id, {
820         "MKA Version Identifier", "mka.version_id",
821         FT_UINT8, BASE_DEC, NULL, 0x0,
822         NULL, HFILL }},
823 
824     { &hf_mka_basic_param_set, {
825         "Basic Parameter set", "mka.basic_param_set",
826         FT_NONE, BASE_NONE, NULL, 0x0,
827         NULL, HFILL }},
828 
829     { &hf_mka_live_peer_list_set, {
830         "Live Peer List Parameter set", "mka.live_peer_list_set",
831         FT_NONE, BASE_NONE, NULL, 0x0,
832         NULL, HFILL }},
833 
834     { &hf_mka_potential_peer_list_set, {
835         "Potential Peer List Parameter set", "mka.potential_peer_list_set",
836         FT_NONE, BASE_NONE, NULL, 0x0,
837         NULL, HFILL }},
838 
839     { &hf_mka_macsec_sak_use_set, {
840         "MACsec SAK Use parameter set", "mka.macsec_sak_use_set",
841         FT_NONE, BASE_NONE, NULL, 0x0,
842         NULL, HFILL }},
843 
844     { &hf_mka_distributed_sak_set, {
845         "Distributed SAK parameter set", "mka.distributed_sak_set",
846         FT_NONE, BASE_NONE, NULL, 0x0,
847         NULL, HFILL }},
848 
849     { &hf_mka_distributed_cak_set, {
850         "Distributed CAK parameter set", "mka.distributed_cak_set",
851         FT_NONE, BASE_NONE, NULL, 0x0,
852         NULL, HFILL }},
853 
854     { &hf_mka_kmd_set, {
855         "Key Management Domain set", "mka.kmd_set",
856         FT_NONE, BASE_NONE, NULL, 0x0,
857         NULL, HFILL }},
858 
859     { &hf_mka_announcement_set, {
860         "Announcement parameter set", "mka.announcement_set",
861         FT_NONE, BASE_NONE, NULL, 0x0,
862         NULL, HFILL }},
863 
864     { &hf_mka_xpn_set, {
865         "Extended Packet Numbering set", "mka.xpn_set",
866         FT_NONE, BASE_NONE, NULL, 0x0,
867         NULL, HFILL }},
868 
869     { &hf_mka_unknown_set, {
870         "Unknown parameter set", "mka.unknown_set",
871         FT_NONE, BASE_NONE, NULL, 0x0,
872         NULL, HFILL }},
873 
874     { &hf_mka_unknown_param_set, {
875         "Unknown parameter set", "mka.unknown_param_set",
876         FT_BYTES, BASE_NONE, NULL, 0x0,
877         NULL, HFILL }},
878 
879     { &hf_mka_icv_set, {
880         "Integrity Check Value Indicator", "mka.icv_indicator",
881         FT_NONE, BASE_NONE, NULL, 0x0,
882         NULL, HFILL }},
883 
884     { &hf_mka_param_set_type, {
885         "Parameter set type", "mka.param_set_type",
886         FT_UINT8, BASE_DEC, VALS(param_set_type_vals), 0x0,
887         NULL, HFILL }},
888 
889     { &hf_mka_keyserver_priority, {
890         "Key Server Priority", "mka.ks_prio",
891         FT_UINT8, BASE_DEC, NULL, 0x0,
892         NULL, HFILL }},
893 
894     { &hf_mka_key_server, {
895         "Key Server", "mka.key_server",
896         FT_BOOLEAN, 8, NULL, 0x80,
897         NULL, HFILL }},
898 
899     { &hf_mka_macsec_desired, {
900         "MACsec Desired", "mka.macsec_desired",
901         FT_BOOLEAN, 8, NULL, 0x40,
902         NULL, HFILL }},
903 
904     { &hf_mka_macsec_capability, {
905         "MACsec Capability", "mka.macsec_capability",
906         FT_UINT8, BASE_DEC, VALS(macsec_capability_type_vals), 0x30,
907         NULL, HFILL }},
908 
909     { &hf_mka_param_body_length, {
910         "Parameter set body length", "mka.param_body_length",
911         FT_UINT16, BASE_DEC, NULL, 0x0fff,
912         NULL, HFILL }},
913 
914     { &hf_mka_sci, {
915         "SCI", "mka.sci",
916         FT_BYTES, BASE_NONE, NULL, 0x0,
917         NULL, HFILL }},
918 
919     { &hf_mka_actor_mi, {
920         "Actor Member Identifier", "mka.actor_mi",
921         FT_BYTES, BASE_NONE, NULL, 0x0,
922         NULL, HFILL }},
923 
924     { &hf_mka_actor_mn, {
925         "Actor Message Number", "mka.actor_mn",
926         FT_BYTES, BASE_NONE, NULL, 0x0,
927         NULL, HFILL }},
928 
929     { &hf_mka_algo_agility, {
930         "Algorithm Agility", "mka.algo_agility",
931         FT_UINT32, BASE_HEX, VALS(algo_agility_vals), 0x0,
932         NULL, HFILL }},
933 
934     { &hf_mka_cak_name, {
935         "CAK Name", "mka.cak_name",
936         FT_BYTES, BASE_NONE, NULL, 0x0,
937         NULL, HFILL }},
938 
939     { &hf_mka_padding, {
940         "Padding", "mka.padding",
941         FT_BYTES, BASE_NONE, NULL, 0x0,
942         NULL, HFILL }},
943 
944     { &hf_mka_key_server_ssci, {
945         "Key Server SSCI (LSB)", "mka.key_server_ssci",
946         FT_UINT8, BASE_HEX, NULL, 0x0,
947         "Only present combined with Distributed SAK parameter set with XPN cipher suite", HFILL }},
948 
949     { &hf_mka_peer_mi, {
950         "Peer Member Identifier", "mka.peer_mi",
951         FT_BYTES, BASE_NONE, NULL, 0x0,
952         NULL, HFILL }},
953 
954     { &hf_mka_peer_mn, {
955         "Peer Message Number", "mka.peer_mn",
956         FT_BYTES, BASE_NONE, NULL, 0x0,
957         NULL, HFILL }},
958 
959     { &hf_mka_latest_key_an, {
960         "Latest Key AN", "mka.latest_key_an",
961         FT_UINT8, BASE_DEC, NULL, 0xc0,
962         NULL, HFILL }},
963 
964     { &hf_mka_latest_key_tx, {
965         "Latest Key tx", "mka.latest_key_tx",
966         FT_BOOLEAN, 8, NULL, 0x20,
967         NULL, HFILL }},
968 
969     { &hf_mka_latest_key_rx, {
970         "Latest Key rx", "mka.latest_key_rx",
971         FT_BOOLEAN, 8, NULL, 0x10,
972         NULL, HFILL }},
973 
974     { &hf_mka_old_key_an, {
975         "Old Key AN", "mka.old_key_an",
976         FT_UINT8, BASE_DEC, NULL, 0x0c,
977         NULL, HFILL }},
978 
979     { &hf_mka_old_key_tx, {
980         "Old Key tx", "mka.old_key_tx",
981         FT_BOOLEAN, 8, NULL, 0x02,
982         NULL, HFILL }},
983 
984     { &hf_mka_old_key_rx, {
985         "Old Key rx", "mka.old_key_rx",
986         FT_BOOLEAN, 8, NULL, 0x01,
987         NULL, HFILL }},
988 
989     { &hf_mka_plain_tx, {
990         "Plain tx", "mka.plain_tx",
991         FT_BOOLEAN, 8, NULL, 0x80,
992         NULL, HFILL }},
993 
994     { &hf_mka_plain_rx, {
995         "Plain rx", "mka.plain_rx",
996         FT_BOOLEAN, 8, NULL, 0x40,
997         NULL, HFILL }},
998 
999     { &hf_mka_delay_protect, {
1000         "Delay protect", "mka.delay_protect",
1001         FT_BOOLEAN, 8, NULL, 0x10,
1002         NULL, HFILL }},
1003 
1004     { &hf_mka_latest_key_server_mi, {
1005         "Latest Key: Key Server Member Identifier", "mka.latest_key_server_mi",
1006         FT_BYTES, BASE_NONE, NULL, 0x0,
1007         NULL, HFILL }},
1008 
1009     { &hf_mka_latest_key_number, {
1010         "Latest Key: Key Number", "mka.latest_key_number",
1011         FT_BYTES, BASE_NONE, NULL, 0x0,
1012         NULL, HFILL }},
1013 
1014     { &hf_mka_latest_lowest_acceptable_pn, {
1015         "Latest Key: Lowest Acceptable PN", "mka.latest_lowest_acceptable_pn",
1016         FT_BYTES, BASE_NONE, NULL, 0x0,
1017         NULL, HFILL }},
1018 
1019     { &hf_mka_old_key_server_mi, {
1020         "Old Key: Key Server Member Identifier", "mka.old_key_server_mi",
1021         FT_BYTES, BASE_NONE, NULL, 0x0,
1022         NULL, HFILL }},
1023 
1024     { &hf_mka_old_key_number, {
1025         "Old Key: Key Number", "mka.old_key_number",
1026         FT_BYTES, BASE_NONE, NULL, 0x0,
1027         NULL, HFILL }},
1028 
1029     { &hf_mka_old_lowest_acceptable_pn, {
1030         "Old Key: Lowest Acceptable PN", "mka.old_lowest_acceptable_pn",
1031         FT_BYTES, BASE_NONE, NULL, 0x0,
1032         NULL, HFILL }},
1033 
1034     { &hf_mka_distributed_an, {
1035         "Distributed AN", "mka.distributed_an",
1036         FT_UINT8, BASE_DEC, NULL, 0xc0,
1037         NULL, HFILL }},
1038 
1039     { &hf_mka_confidentiality_offset, {
1040         "Confidentiality Offset", "mka.confidentiality_offset",
1041         FT_UINT8, BASE_DEC, VALS(confidentiality_offset_vals), 0x30,
1042         NULL, HFILL }},
1043 
1044     { &hf_mka_key_number, {
1045         "Key Number", "mka.key_number",
1046         FT_BYTES, BASE_NONE, NULL, 0x0,
1047         NULL, HFILL }},
1048 
1049     { &hf_mka_aes_key_wrap_sak, {
1050         "AES Key Wrap of SAK", "mka.aes_key_wrap_sak",
1051         FT_BYTES, BASE_NONE, NULL, 0x0,
1052         NULL, HFILL }},
1053 
1054     { &hf_mka_aes_key_wrap_cak, {
1055         "AES Key Wrap of CAK", "mka.aes_key_wrap_cak",
1056         FT_BYTES, BASE_NONE, NULL, 0x0,
1057         NULL, HFILL }},
1058 
1059     { &hf_mka_macsec_cipher_suite, {
1060         "MACsec Cipher Suite", "mka.macsec_cipher_suite",
1061         FT_UINT64, BASE_HEX|BASE_VAL64_STRING, VALS64(macsec_cipher_suite_vals), 0x0,
1062         NULL, HFILL }},
1063 
1064     { &hf_mka_kmd, {
1065         "Key Management Domain", "mka.kmd",
1066         FT_BYTES, BASE_NONE, NULL, 0x0,
1067         NULL, HFILL }},
1068 
1069     { &hf_mka_suspension_time, {
1070         "Suspension time", "mka.suspension_time",
1071         FT_UINT8, BASE_DEC, NULL, 0x0,
1072         NULL, HFILL }},
1073 
1074     { &hf_mka_icv, {
1075         "Integrity Check Value", "mka.icv",
1076         FT_BYTES, BASE_NONE, NULL, 0x0,
1077         NULL, HFILL }},
1078 
1079     { &hf_mka_tlv_entry, {
1080         "TLV Entry", "mka.tlv_entry",
1081         FT_NONE, BASE_NONE, NULL, 0x0,
1082         NULL, HFILL }},
1083 
1084     { &hf_mka_tlv_type, {
1085         "TLV Type", "mka.tlv_type",
1086         FT_UINT8, BASE_DEC, VALS(macsec_tlvs), 0xfe,
1087         NULL, HFILL }},
1088 
1089     { &hf_mka_tlv_info_string_length, {
1090         "TLV Info String Length", "mka.tlv_info_string_len",
1091         FT_UINT16, BASE_DEC, NULL, 0x01ff,
1092         NULL, HFILL }},
1093 
1094     { &hf_mka_tlv_data, {
1095         "TLV Data", "mka.tlv_data",
1096         FT_BYTES, BASE_NONE, NULL, 0x0,
1097         NULL, HFILL }},
1098 
1099     { &hf_mka_tlv_cipher_suite_impl_cap, {
1100         "Cipher Suite Implementation Cababilities", "mka.tlv.cipher_suite_impl_cap",
1101         FT_UINT16, BASE_DEC, VALS(macsec_capability_type_vals), 0x0003,
1102         NULL, HFILL }},
1103   };
1104 
1105   static gint *ett[] = {
1106     &ett_mka,
1107     &ett_mka_basic_param_set,
1108     &ett_mka_peer_list_set,
1109     &ett_mka_sak_use_set,
1110     &ett_mka_distributed_sak_set,
1111     &ett_mka_distributed_cak_set,
1112     &ett_mka_kmd_set,
1113     &ett_mka_announcement_set,
1114     &ett_mka_xpn_set,
1115     &ett_mka_unknown_set,
1116     &ett_mka_icv_set,
1117     &ett_mka_tlv,
1118     &ett_mka_cipher_suite_entry
1119   };
1120 
1121   proto_mka = proto_register_protocol("MACsec Key Agreement", "EAPOL-MKA", "mka");
1122   register_dissector("mka", dissect_mka, proto_mka);
1123 
1124   proto_register_field_array(proto_mka, hf, array_length(hf));
1125   proto_register_subtree_array(ett, array_length(ett));
1126 
1127   expert_mka = expert_register_protocol(proto_mka);
1128   expert_register_field_array(expert_mka, ei, array_length(ei));
1129 
1130 }
1131 
1132 void
proto_reg_handoff_mka(void)1133 proto_reg_handoff_mka(void)
1134 {
1135   static dissector_handle_t mka_handle;
1136 
1137   mka_handle = create_dissector_handle(dissect_mka, proto_mka);
1138   dissector_add_uint("eapol.type", EAPOL_MKA, mka_handle);
1139 }
1140 
1141 /*
1142  * Editor modelines
1143  *
1144  * Local Variables:
1145  * c-basic-offset: 2
1146  * tab-width: 8
1147  * indent-tabs-mode: nil
1148  * End:
1149  *
1150  * ex: set shiftwidth=2 tabstop=8 expandtab:
1151  * :indentSize=2:tabSize=8:noTabs=true:
1152  */
1153