/src/wireshark/epan/dissectors/packet-kink.c
Line | Count | Source |
1 | | /* packet-kink.c |
2 | | * Routines for KINK packet disassembly |
3 | | * It is referenced draft-ietf-kink-kink-jp-04.txt,v 1.14 2003/02/10 |
4 | | * |
5 | | * Copyright 2004, Takeshi Nakashima <T.Nakashima@jp.yokogawa.com> |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/expert.h> |
19 | | #include <epan/asn1.h> |
20 | | #include "packet-kerberos.h" |
21 | | #include "packet-ike.h" |
22 | | |
23 | | void proto_register_kink(void); |
24 | | void proto_reg_handoff_kink(void); |
25 | | |
26 | | static dissector_handle_t kink_handle; |
27 | | |
28 | 15 | #define KINK_PORT 910 |
29 | | |
30 | 31 | #define KINK_ISAKMP_PAYLOAD_BASE 14 |
31 | | |
32 | | static int proto_kink; |
33 | | |
34 | | /* Argument for proto_tree_add_uint() */ |
35 | | static int hf_kink_type; |
36 | | static int hf_kink_length; |
37 | | static int hf_kink_transactionId; |
38 | | static int hf_kink_checkSumLength; |
39 | | static int hf_kink_A; |
40 | | static int hf_kink_version; |
41 | | static int hf_kink_domain_of_interpretation; |
42 | | static int hf_kink_qmversion; |
43 | | static int hf_kink_error_code; |
44 | | static int hf_kink_reserved8; |
45 | | static int hf_kink_reserved15; |
46 | | static int hf_kink_reserved16; |
47 | | static int hf_kink_reserved24; |
48 | | static int hf_kink_checkSum; |
49 | | static int hf_kink_next_payload; |
50 | | static int hf_kink_payload_length; |
51 | | static int hf_kink_epoch; |
52 | | static int hf_kink_inner_next_pload; |
53 | | static int hf_kink_realm_name_length; |
54 | | static int hf_kink_realm_name; |
55 | | static int hf_kink_princ_name_length; |
56 | | static int hf_kink_princ_name; |
57 | | static int hf_kink_tgt_length; |
58 | | static int hf_kink_tgt; |
59 | | static int hf_kink_payload; |
60 | | |
61 | | /* Argument for making the subtree */ |
62 | | static int ett_kink; |
63 | | /*static int ett_kink_version;*/ |
64 | | static int ett_kink_payload; |
65 | | static int ett_payload_kink_ap_req; |
66 | | static int ett_payload_kink_ap_rep; |
67 | | static int ett_payload_kink_krb_error; |
68 | | static int ett_payload_kink_tgt_req; |
69 | | static int ett_payload_kink_tgt_rep; |
70 | | static int ett_payload_kink_isakmp; |
71 | | static int ett_payload_kink_encrypt; |
72 | | static int ett_payload_kink_error; |
73 | | static int ett_payload_not_defined; |
74 | | static int ett_decrypt_kink_encrypt; |
75 | | |
76 | | static expert_field ei_kink_payload_length_small; |
77 | | static expert_field ei_kink_payload_length_mismatch; |
78 | | |
79 | | |
80 | | /* Define the kink type value */ |
81 | | #define KINK_TYPE_RESERVED 0 |
82 | | #define KINK_TYPE_CREATE 1 |
83 | | #define KINK_TYPE_DELETE 2 |
84 | | #define KINK_TYPE_REPLY 3 |
85 | | #define KINK_TYPE_GETTGT 4 |
86 | | #define KINK_TYPE_ACK 5 |
87 | | #define KINK_TYPE_STATUS 6 |
88 | | |
89 | | static const value_string kink_type_vals[]={ |
90 | | {KINK_TYPE_RESERVED,"RESERVED"}, |
91 | | {KINK_TYPE_CREATE,"CREATE"}, |
92 | | {KINK_TYPE_DELETE,"DELETE"}, |
93 | | {KINK_TYPE_REPLY,"REPLY"}, |
94 | | {KINK_TYPE_GETTGT,"GETTGT"}, |
95 | | {KINK_TYPE_ACK,"ACK"}, |
96 | | {KINK_TYPE_STATUS,"STATUS"}, |
97 | | {0, NULL}, |
98 | | }; |
99 | | |
100 | | /* Define the kink A value */ |
101 | | #define KINK_A_NOT_REQUEST_ACK 0 |
102 | | #define KINK_A_REQUEST_ACK 1 |
103 | | |
104 | | static const value_string kink_A_vals[]={ |
105 | | {KINK_A_NOT_REQUEST_ACK,"Not Request ACK"}, |
106 | | {KINK_A_REQUEST_ACK,"Request ACK"}, |
107 | | {0, NULL}, |
108 | | }; |
109 | | |
110 | | /* Define the kink payload */ |
111 | 1 | #define KINK_DONE 0 |
112 | 0 | #define KINK_AP_REQ KINK_ISAKMP_PAYLOAD_BASE+0 |
113 | 1 | #define KINK_AP_REP KINK_ISAKMP_PAYLOAD_BASE+1 |
114 | 0 | #define KINK_KRB_ERROR KINK_ISAKMP_PAYLOAD_BASE+2 |
115 | 1 | #define KINK_TGT_REQ KINK_ISAKMP_PAYLOAD_BASE+3 |
116 | 1 | #define KINK_TGT_REP KINK_ISAKMP_PAYLOAD_BASE+4 |
117 | 9 | #define KINK_ISAKMP KINK_ISAKMP_PAYLOAD_BASE+5 |
118 | 0 | #define KINK_ENCRYPT KINK_ISAKMP_PAYLOAD_BASE+6 |
119 | 19 | #define KINK_ERROR KINK_ISAKMP_PAYLOAD_BASE+7 |
120 | | |
121 | | static const value_string kink_next_payload[]={ |
122 | | {KINK_DONE, "KINK_DONE"}, |
123 | | {KINK_AP_REQ, "KINK_AP_REQ"}, |
124 | | {KINK_AP_REP, "KINK_AP_REP"}, |
125 | | {KINK_KRB_ERROR, "KINK_KRB_ERROR"}, |
126 | | {KINK_TGT_REQ, "KINK_TGT_REQ"}, |
127 | | {KINK_TGT_REP, "KINK_TGT_REP"}, |
128 | | {KINK_ISAKMP, "KINK_ISAKMP"}, |
129 | | {KINK_ENCRYPT, "KINK_ENCRYPT"}, |
130 | | {KINK_ERROR, "KINK_ERROR"}, |
131 | | {0, NULL}, |
132 | | }; |
133 | | |
134 | | /* Define the magic number |
135 | | * Using at the kink error |
136 | | */ |
137 | | #define KINK_OK 0 |
138 | | #define KINK_PROTOERR 1 |
139 | | #define KINK_INVDOI 2 |
140 | | #define KINK_INVMAJ 3 |
141 | | #define KINK_INVMIN 4 |
142 | | #define KINK_INTERR 5 |
143 | | #define KINK_BADQMVERS 6 |
144 | | #define BOTTOM_RESERVED 7 |
145 | | #define TOP_RESERVED 8191 |
146 | | #define BOTTOM_PRIVATE_USE 8192 |
147 | | #define TOP_PRIVATE_USE 16383 |
148 | | |
149 | | /* Using at the kink header */ |
150 | 20 | #define IPSEC 1 |
151 | 0 | #define VERSION_BIT_SHIFT 4 |
152 | 20 | #define A_BIT_SHIFT 7 |
153 | | #define FROM_TYPE_TO_RESERVED 16 |
154 | | |
155 | | /* Using at the payload */ |
156 | 48 | #define TO_PAYLOAD_LENGTH 2 |
157 | 94 | #define PADDING 4 |
158 | 0 | #define KINK_KRB_ERROR_HEADER 4 |
159 | | #define FROM_NP_TO_PL 4 |
160 | 1 | #define TO_REALM_NAME_LENGTH 4 |
161 | | #define KINK_TGT_REQ_HEADER 6 |
162 | 2 | #define FRONT_TGT_REP_HEADER 6 |
163 | 27 | #define PAYLOAD_HEADER 8 |
164 | 38 | #define KINK_ERROR_LENGTH 8 |
165 | | |
166 | | |
167 | | /* define hexadecimal */ |
168 | 0 | #define FRONT_FOUR_BIT 0xf0 |
169 | 0 | #define SECOND_FOUR_BIT 0x0f |
170 | 20 | #define FRONT_ONE_BIT 0x80 |
171 | 15 | #define SECOND_FIFTEEN_BIT 0x7fff |
172 | | |
173 | | /* decrypt element */ |
174 | | static uint32_t keytype; |
175 | | |
176 | | static void control_payload(packet_info *pinfo, tvbuff_t *tvb, int offset, uint8_t next_payload, proto_tree *kink_payload_tree); |
177 | | static void dissect_payload_kink_ap_req(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
178 | | static void dissect_payload_kink_ap_rep(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
179 | | static void dissect_payload_kink_krb_error(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
180 | | static void dissect_payload_kink_tgt_req(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
181 | | static void dissect_payload_kink_tgt_rep(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
182 | | static void dissect_payload_kink_isakmp(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
183 | | static void dissect_payload_kink_encrypt(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
184 | | static void dissect_payload_kink_error(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
185 | | static void dissect_payload_kink_not_defined(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree); |
186 | | #ifdef HAVE_KERBEROS |
187 | | static void dissect_decrypt_kink_encrypt(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, int payload_length); |
188 | | #endif |
189 | | |
190 | | /* This function is dissecting the kink header. */ |
191 | | static int |
192 | 20 | dissect_kink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_){ |
193 | 20 | proto_item *ti = NULL; |
194 | 20 | proto_tree *kink_tree = NULL; |
195 | 20 | uint8_t type; |
196 | 20 | uint32_t doi; |
197 | 20 | unsigned chsumlen; |
198 | 20 | uint8_t next_payload; |
199 | 20 | uint8_t value_a_and_front_reserved; |
200 | 20 | uint8_t value_a; |
201 | 20 | int offset=0; |
202 | | |
203 | 20 | type = tvb_get_uint8(tvb,offset); |
204 | | |
205 | 20 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "KINK"); |
206 | | |
207 | | /* It shows kink type by the type value. */ |
208 | 20 | col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(type, kink_type_vals, "unknown")); |
209 | | |
210 | | /* Make the kink tree */ |
211 | 20 | ti = proto_tree_add_item(tree, proto_kink, tvb, offset, -1, ENC_NA); |
212 | 20 | kink_tree = proto_item_add_subtree(ti, ett_kink); |
213 | | |
214 | 20 | proto_tree_add_uint(kink_tree, hf_kink_type, tvb, offset, 1, type); |
215 | 20 | offset++; |
216 | | |
217 | 20 | proto_tree_add_item(kink_tree, hf_kink_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
218 | 20 | offset++; |
219 | | |
220 | 20 | proto_tree_add_item(kink_tree, hf_kink_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
221 | 20 | offset += 2; |
222 | | |
223 | 20 | doi = tvb_get_ntohl(tvb, offset); |
224 | | |
225 | 20 | if(doi == IPSEC){ |
226 | 0 | proto_tree_add_uint_format_value(kink_tree, hf_kink_domain_of_interpretation, tvb, offset, 4, doi, "IPsec (%u)", doi); |
227 | 0 | } |
228 | 20 | else{ |
229 | 20 | proto_tree_add_uint_format_value(kink_tree, hf_kink_domain_of_interpretation, tvb, offset, 4, doi, "Not IPsec (%u)", doi); |
230 | 20 | } |
231 | 20 | offset += 4; |
232 | | |
233 | 20 | proto_tree_add_item(kink_tree, hf_kink_transactionId, tvb, offset, 4, ENC_BIG_ENDIAN); |
234 | 20 | offset += 4; |
235 | | |
236 | 20 | chsumlen = tvb_get_uint8(tvb, offset); |
237 | 20 | proto_tree_add_item(kink_tree, hf_kink_checkSumLength, tvb, offset, 1, ENC_BIG_ENDIAN); |
238 | 20 | offset ++; |
239 | | |
240 | 20 | next_payload = tvb_get_uint8(tvb, offset); |
241 | 20 | proto_tree_add_uint(kink_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
242 | 20 | offset ++; |
243 | | |
244 | | /* A is 1bit field. The calculation of A is shown below. |
245 | | * The logical product of 1octet value and 0x80 is performed. |
246 | | * And It is performed 7bit right shift. |
247 | | */ |
248 | 20 | value_a_and_front_reserved = tvb_get_uint8(tvb, offset); |
249 | 20 | value_a = (value_a_and_front_reserved & FRONT_ONE_BIT) >> A_BIT_SHIFT; |
250 | 20 | proto_tree_add_uint(kink_tree, hf_kink_A, tvb, offset, 1, value_a); |
251 | | |
252 | | /* The reserved field is 15bit. |
253 | | * The logical product of 2octet value and 0x7fff is performed. |
254 | | */ |
255 | 20 | proto_tree_add_item(kink_tree, hf_kink_reserved15, tvb, offset, 2, ENC_BIG_ENDIAN); |
256 | 20 | offset += 2; |
257 | | |
258 | 20 | proto_tree_add_item(kink_tree, hf_kink_checkSum, tvb, offset, chsumlen, ENC_NA); |
259 | | |
260 | | /* This part consider the padding. Chsumlen don't contain the padding. */ |
261 | 20 | if((chsumlen % PADDING) != 0){ |
262 | 15 | chsumlen += (PADDING - (chsumlen % PADDING)); |
263 | 15 | offset += chsumlen; |
264 | 15 | } |
265 | 5 | else{ |
266 | 5 | offset += chsumlen; |
267 | 5 | } |
268 | | |
269 | 20 | control_payload(pinfo, tvb, offset, next_payload, kink_tree); |
270 | | |
271 | 20 | return tvb_captured_length(tvb); |
272 | 20 | } |
273 | | |
274 | | /* This part call the dissect payload function by next_payload value. |
275 | | * This function called by the respective function again. |
276 | | */ |
277 | | static void |
278 | | // NOLINTNEXTLINE(misc-no-recursion) |
279 | 49 | control_payload(packet_info *pinfo, tvbuff_t *tvb, int offset, uint8_t next_payload, proto_tree *kink_tree){ |
280 | 49 | switch(next_payload){ |
281 | 1 | case KINK_DONE: |
282 | 1 | break; |
283 | 0 | case KINK_AP_REQ: |
284 | 0 | dissect_payload_kink_ap_req(pinfo, tvb, offset, kink_tree); |
285 | 0 | break; |
286 | 1 | case KINK_AP_REP: |
287 | 1 | dissect_payload_kink_ap_rep(pinfo, tvb, offset, kink_tree); |
288 | 1 | break; |
289 | 0 | case KINK_KRB_ERROR: |
290 | 0 | dissect_payload_kink_krb_error(pinfo, tvb, offset, kink_tree); |
291 | 0 | break; |
292 | 1 | case KINK_TGT_REQ: |
293 | 1 | dissect_payload_kink_tgt_req(pinfo, tvb, offset, kink_tree); |
294 | 1 | break; |
295 | 1 | case KINK_TGT_REP: |
296 | 1 | dissect_payload_kink_tgt_rep(pinfo, tvb, offset, kink_tree); |
297 | 1 | break; |
298 | 9 | case KINK_ISAKMP: |
299 | 9 | dissect_payload_kink_isakmp(pinfo, tvb, offset, kink_tree); |
300 | 9 | break; |
301 | 0 | case KINK_ENCRYPT: |
302 | 0 | dissect_payload_kink_encrypt(pinfo, tvb, offset, kink_tree); |
303 | 0 | break; |
304 | 19 | case KINK_ERROR: |
305 | 19 | dissect_payload_kink_error(pinfo, tvb, offset, kink_tree); |
306 | 19 | break; |
307 | 17 | default: |
308 | 17 | dissect_payload_kink_not_defined(pinfo, tvb, offset, kink_tree); |
309 | 17 | break; |
310 | 49 | } |
311 | 49 | } |
312 | | |
313 | | static void |
314 | | // NOLINTNEXTLINE(misc-no-recursion) |
315 | 0 | dissect_payload_kink_ap_req(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
316 | 0 | proto_tree *payload_kink_ap_req_tree; |
317 | 0 | proto_item *ti; |
318 | 0 | uint8_t next_payload; |
319 | 0 | unsigned payload_length; |
320 | 0 | uint16_t krb_ap_req_length; |
321 | 0 | int start_payload_offset = 0; /* Keep beginning of payload offset */ |
322 | |
|
323 | 0 | start_payload_offset = offset; |
324 | 0 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
325 | | |
326 | | /* Make the subtree. */ |
327 | 0 | payload_kink_ap_req_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
328 | 0 | ett_payload_kink_ap_req, NULL, "KINK_AP_REQ"); |
329 | |
|
330 | 0 | next_payload = tvb_get_uint8(tvb, offset); |
331 | 0 | proto_tree_add_uint(payload_kink_ap_req_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
332 | 0 | offset ++; |
333 | |
|
334 | 0 | proto_tree_add_item(payload_kink_ap_req_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
335 | 0 | offset ++; |
336 | |
|
337 | 0 | ti = proto_tree_add_uint(payload_kink_ap_req_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
338 | 0 | if(payload_length <= PAYLOAD_HEADER){ |
339 | 0 | expert_add_info(pinfo, ti, &ei_kink_payload_length_small); |
340 | 0 | } |
341 | 0 | offset += 2; |
342 | | |
343 | | /* Show time as UTC, not local time. */ |
344 | 0 | proto_tree_add_item(payload_kink_ap_req_tree, hf_kink_epoch, tvb, offset, 4, ENC_BIG_ENDIAN); |
345 | 0 | offset += 4; |
346 | |
|
347 | 0 | if(payload_length > PAYLOAD_HEADER){ |
348 | 0 | tvbuff_t *krb_tvb; |
349 | |
|
350 | 0 | krb_ap_req_length = payload_length - PAYLOAD_HEADER; |
351 | 0 | krb_tvb=tvb_new_subset_length(tvb, offset, krb_ap_req_length); |
352 | 0 | keytype=kerberos_output_keytype(); |
353 | 0 | dissect_kerberos_main(krb_tvb, pinfo, payload_kink_ap_req_tree, false, NULL); |
354 | | /*offset += krb_ap_req_length;*/ |
355 | 0 | } |
356 | | |
357 | | /* This part consider padding the padding. Payload_length don't contain the padding. */ |
358 | 0 | if(payload_length % PADDING != 0){ |
359 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
360 | 0 | } |
361 | 0 | offset = start_payload_offset + payload_length; |
362 | |
|
363 | 0 | if(payload_length > 0) { |
364 | 0 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
365 | 0 | } |
366 | 0 | } |
367 | | |
368 | | |
369 | | static void |
370 | | // NOLINTNEXTLINE(misc-no-recursion) |
371 | 1 | dissect_payload_kink_ap_rep(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
372 | 1 | proto_tree *payload_kink_ap_rep_tree; |
373 | 1 | proto_item *ti; |
374 | 1 | uint8_t next_payload; |
375 | 1 | unsigned payload_length; |
376 | 1 | uint16_t krb_ap_rep_length; |
377 | 1 | int start_payload_offset = 0; /* Keep beginning of payload offset */ |
378 | | |
379 | 1 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
380 | 1 | start_payload_offset = offset; |
381 | | |
382 | | /* Make the subtree */ |
383 | 1 | payload_kink_ap_rep_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
384 | 1 | ett_payload_kink_ap_rep, NULL, "KINK_AP_REP"); |
385 | | |
386 | 1 | next_payload = tvb_get_uint8(tvb, offset); |
387 | 1 | proto_tree_add_uint(payload_kink_ap_rep_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
388 | 1 | offset ++; |
389 | | |
390 | 1 | proto_tree_add_item(payload_kink_ap_rep_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
391 | 1 | offset ++; |
392 | | |
393 | 1 | ti = proto_tree_add_uint(payload_kink_ap_rep_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
394 | 1 | if(payload_length <= PAYLOAD_HEADER){ |
395 | 1 | expert_add_info(pinfo, ti, &ei_kink_payload_length_small); |
396 | 1 | } |
397 | 1 | offset += 2; |
398 | | |
399 | | /* Show time as UTC, not local time. */ |
400 | 1 | proto_tree_add_item(payload_kink_ap_rep_tree, hf_kink_epoch, tvb, offset, 4, ENC_BIG_ENDIAN); |
401 | 1 | offset += 4; |
402 | | |
403 | 1 | if(payload_length > PAYLOAD_HEADER){ |
404 | 0 | tvbuff_t *krb_tvb; |
405 | |
|
406 | 0 | krb_ap_rep_length = payload_length - PAYLOAD_HEADER; |
407 | 0 | krb_tvb=tvb_new_subset_length(tvb, offset, krb_ap_rep_length); |
408 | 0 | keytype=kerberos_output_keytype(); |
409 | 0 | dissect_kerberos_main(krb_tvb, pinfo, payload_kink_ap_rep_tree, false, NULL); |
410 | | |
411 | | /*offset += krb_ap_rep_length;*/ |
412 | 0 | } |
413 | | |
414 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
415 | 1 | if(payload_length % PADDING != 0){ |
416 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
417 | 0 | } |
418 | 1 | offset = start_payload_offset + payload_length; |
419 | | |
420 | 1 | if(payload_length > 0) { |
421 | 0 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
422 | 0 | } |
423 | 1 | } |
424 | | |
425 | | static void |
426 | | // NOLINTNEXTLINE(misc-no-recursion) |
427 | 0 | dissect_payload_kink_krb_error(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
428 | 0 | proto_tree *payload_kink_krb_error_tree; |
429 | 0 | proto_item *ti; |
430 | 0 | uint8_t next_payload; |
431 | 0 | unsigned payload_length; |
432 | 0 | uint16_t krb_error_length; |
433 | 0 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
434 | |
|
435 | 0 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
436 | 0 | start_payload_offset = offset; |
437 | | |
438 | | /* Make the subtree */ |
439 | 0 | payload_kink_krb_error_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
440 | 0 | ett_payload_kink_krb_error, NULL, "KINK_KRB_ERROR"); |
441 | |
|
442 | 0 | next_payload = tvb_get_uint8(tvb, offset); |
443 | 0 | proto_tree_add_uint(payload_kink_krb_error_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
444 | 0 | offset ++; |
445 | |
|
446 | 0 | proto_tree_add_item(payload_kink_krb_error_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
447 | 0 | offset ++; |
448 | |
|
449 | 0 | ti = proto_tree_add_uint(payload_kink_krb_error_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
450 | 0 | if(payload_length <= KINK_KRB_ERROR_HEADER){ |
451 | 0 | expert_add_info(pinfo, ti, &ei_kink_payload_length_small); |
452 | 0 | } |
453 | 0 | else { |
454 | 0 | offset += 2; |
455 | 0 | } |
456 | |
|
457 | 0 | if(payload_length > KINK_KRB_ERROR_HEADER){ |
458 | 0 | tvbuff_t *krb_tvb; |
459 | |
|
460 | 0 | krb_error_length = payload_length - KINK_KRB_ERROR_HEADER; |
461 | 0 | krb_tvb=tvb_new_subset_length(tvb, offset, krb_error_length); |
462 | |
|
463 | 0 | dissect_kerberos_main(krb_tvb, pinfo, payload_kink_krb_error_tree, false, NULL); |
464 | | /*offset += krb_error_length;*/ |
465 | 0 | } |
466 | | |
467 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
468 | 0 | if(payload_length % PADDING != 0){ |
469 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
470 | 0 | } |
471 | 0 | offset = start_payload_offset + payload_length; |
472 | |
|
473 | 0 | if(payload_length > 0) { |
474 | 0 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
475 | 0 | } |
476 | 0 | } |
477 | | |
478 | | static void |
479 | | // NOLINTNEXTLINE(misc-no-recursion) |
480 | 1 | dissect_payload_kink_tgt_req(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
481 | 1 | proto_tree *payload_kink_tgt_req_tree; |
482 | 1 | uint8_t next_payload; |
483 | 1 | unsigned payload_length; |
484 | 1 | uint16_t realm_name_length; |
485 | 1 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
486 | | |
487 | 1 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
488 | 1 | realm_name_length = tvb_get_ntohs(tvb, offset + TO_REALM_NAME_LENGTH); |
489 | 1 | start_payload_offset = offset; |
490 | | |
491 | | /* Make the subtree */ |
492 | 1 | payload_kink_tgt_req_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
493 | 1 | ett_payload_kink_tgt_req, NULL, "KINK_TGT_REQ"); |
494 | | |
495 | 1 | next_payload = tvb_get_uint8(tvb, offset); |
496 | 1 | proto_tree_add_uint(payload_kink_tgt_req_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
497 | 1 | offset ++; |
498 | | |
499 | 1 | proto_tree_add_item(payload_kink_tgt_req_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
500 | 1 | offset ++; |
501 | | |
502 | 1 | proto_tree_add_uint(payload_kink_tgt_req_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
503 | 1 | offset += 2; |
504 | | |
505 | 1 | proto_tree_add_uint(payload_kink_tgt_req_tree, hf_kink_realm_name_length, tvb, offset, 2, realm_name_length); |
506 | 1 | offset += 2; |
507 | | |
508 | 1 | proto_tree_add_item(payload_kink_tgt_req_tree, hf_kink_realm_name, tvb, offset, realm_name_length, ENC_ASCII); |
509 | | |
510 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
511 | 1 | if(payload_length % PADDING != 0){ |
512 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
513 | 0 | } |
514 | 1 | offset = start_payload_offset + payload_length; |
515 | | |
516 | 1 | if(payload_length > 0) { |
517 | 1 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
518 | 1 | } |
519 | 1 | } |
520 | | |
521 | | static void |
522 | | // NOLINTNEXTLINE(misc-no-recursion) |
523 | 1 | dissect_payload_kink_tgt_rep(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
524 | 1 | proto_tree *payload_kink_tgt_rep_tree; |
525 | 1 | uint8_t next_payload; |
526 | 1 | unsigned payload_length; |
527 | 1 | unsigned princ_name_length; |
528 | 1 | uint16_t tgt_length; |
529 | 1 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
530 | | |
531 | 1 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
532 | 1 | start_payload_offset = offset; |
533 | | |
534 | | /* Make the subtree */ |
535 | 1 | payload_kink_tgt_rep_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
536 | 1 | ett_payload_kink_tgt_rep, NULL, "KINK_TGT_REP"); |
537 | | |
538 | 1 | next_payload = tvb_get_uint8(tvb, offset); |
539 | 1 | proto_tree_add_uint(payload_kink_tgt_rep_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
540 | 1 | offset ++; |
541 | | |
542 | 1 | proto_tree_add_item(payload_kink_tgt_rep_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
543 | 1 | offset ++; |
544 | | |
545 | 1 | proto_tree_add_uint(payload_kink_tgt_rep_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
546 | 1 | offset += 2; |
547 | | |
548 | 1 | princ_name_length = tvb_get_ntohs(tvb, offset); |
549 | 1 | proto_tree_add_uint(payload_kink_tgt_rep_tree, hf_kink_princ_name_length, tvb, offset, 2, princ_name_length); |
550 | 1 | offset += 2; |
551 | | |
552 | 1 | proto_tree_add_item(payload_kink_tgt_rep_tree, hf_kink_princ_name, tvb, offset, princ_name_length, ENC_ASCII); |
553 | | |
554 | | /* This part consider the padding. Princ_name_length don't contain the padding. */ |
555 | 1 | if((princ_name_length + FRONT_TGT_REP_HEADER) % PADDING != 0){ |
556 | 1 | offset += (princ_name_length + PADDING - ((princ_name_length + FRONT_TGT_REP_HEADER) % PADDING)); |
557 | 1 | } |
558 | 0 | else{ |
559 | 0 | offset += princ_name_length; |
560 | 0 | } |
561 | | |
562 | 1 | tgt_length = tvb_get_ntohs(tvb, offset); |
563 | 1 | proto_tree_add_uint(payload_kink_tgt_rep_tree, hf_kink_tgt_length, tvb, offset, 2, tgt_length); |
564 | 1 | offset += 2; |
565 | | |
566 | 1 | proto_tree_add_item(payload_kink_tgt_rep_tree, hf_kink_tgt, tvb, offset, tgt_length, ENC_ASCII); |
567 | | /*offset += tgt_length;*/ |
568 | | |
569 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
570 | 1 | if(payload_length % PADDING!=0){ |
571 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
572 | 0 | } |
573 | 1 | offset = start_payload_offset + payload_length; |
574 | | |
575 | 1 | if(payload_length > 0) { |
576 | 0 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
577 | 0 | } |
578 | 1 | } |
579 | | |
580 | | static void |
581 | | // NOLINTNEXTLINE(misc-no-recursion) |
582 | 9 | dissect_payload_kink_isakmp(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
583 | 9 | proto_tree *payload_kink_isakmp_tree; |
584 | 9 | proto_item *ti; |
585 | 9 | uint8_t next_payload; |
586 | 9 | unsigned payload_length,isakmp_length; |
587 | 9 | int reported_length; |
588 | 9 | uint8_t inner_next_pload; |
589 | 9 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
590 | 9 | tvbuff_t *isakmp_tvb; |
591 | | |
592 | 9 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
593 | 9 | start_payload_offset = offset; |
594 | | |
595 | | /* Make the subtree. */ |
596 | 9 | payload_kink_isakmp_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
597 | 9 | ett_payload_kink_isakmp, NULL, "KINK_ISAKMP"); |
598 | | |
599 | 9 | next_payload = tvb_get_uint8(tvb, offset); |
600 | 9 | proto_tree_add_uint(payload_kink_isakmp_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
601 | 9 | offset ++; |
602 | | |
603 | 9 | proto_tree_add_item(payload_kink_isakmp_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
604 | 9 | offset ++; |
605 | | |
606 | 9 | ti = proto_tree_add_uint(payload_kink_isakmp_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
607 | 9 | if(payload_length <= PAYLOAD_HEADER){ |
608 | 2 | expert_add_info(pinfo, ti, &ei_kink_payload_length_small); |
609 | 2 | } |
610 | 9 | offset += 2; |
611 | | |
612 | 9 | inner_next_pload = tvb_get_uint8(tvb, offset); |
613 | 9 | proto_tree_add_uint(payload_kink_isakmp_tree, hf_kink_inner_next_pload, tvb, offset, 1, inner_next_pload); |
614 | 9 | offset += 1; |
615 | | |
616 | 9 | proto_tree_add_item(payload_kink_isakmp_tree, hf_kink_qmversion, tvb, offset, 1, ENC_BIG_ENDIAN); |
617 | 9 | offset += 1; |
618 | | |
619 | 9 | proto_tree_add_item(payload_kink_isakmp_tree, hf_kink_reserved16, tvb, offset, 2, ENC_BIG_ENDIAN); |
620 | 9 | offset += 2; |
621 | | |
622 | 9 | if(payload_length > PAYLOAD_HEADER){ |
623 | 7 | isakmp_length = payload_length - PAYLOAD_HEADER; |
624 | 7 | reported_length = tvb_reported_length_remaining(tvb, offset); |
625 | 7 | if (reported_length > (int)isakmp_length) |
626 | 1 | reported_length = isakmp_length; |
627 | 7 | isakmp_tvb = tvb_new_subset_length(tvb, offset, reported_length); |
628 | 7 | isakmp_dissect_payloads(isakmp_tvb, payload_kink_isakmp_tree, 1, inner_next_pload, 0, isakmp_length, pinfo); |
629 | 7 | } |
630 | | |
631 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
632 | 9 | if(payload_length % PADDING != 0){ |
633 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
634 | 0 | } |
635 | 9 | offset = start_payload_offset + payload_length; |
636 | | |
637 | 9 | if(payload_length > 0) { |
638 | 1 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
639 | 1 | } |
640 | 9 | } |
641 | | |
642 | | static void |
643 | | // NOLINTNEXTLINE(misc-no-recursion) |
644 | 0 | dissect_payload_kink_encrypt(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
645 | 0 | proto_tree *payload_kink_encrypt_tree; |
646 | 0 | proto_item *ti; |
647 | 0 | uint8_t next_payload; |
648 | 0 | unsigned payload_length; |
649 | | #ifdef HAVE_KERBEROS |
650 | | int encrypt_length; |
651 | | #endif |
652 | 0 | uint8_t inner_next_pload; |
653 | 0 | uint16_t inner_payload_length; |
654 | 0 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
655 | |
|
656 | 0 | payload_length = tvb_get_ntohs(tvb,offset + TO_PAYLOAD_LENGTH); |
657 | 0 | start_payload_offset = offset; |
658 | |
|
659 | | #ifdef HAVE_KERBEROS |
660 | | encrypt_length = payload_length - FROM_NP_TO_PL; |
661 | | #endif |
662 | | /* Make the subtree */ |
663 | 0 | payload_kink_encrypt_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
664 | 0 | ett_payload_kink_encrypt, NULL, "KINK_ENCRYPT"); |
665 | |
|
666 | 0 | next_payload = tvb_get_uint8(tvb, offset); |
667 | 0 | proto_tree_add_uint(payload_kink_encrypt_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
668 | 0 | offset ++; |
669 | |
|
670 | 0 | proto_tree_add_item(payload_kink_encrypt_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
671 | 0 | offset ++; |
672 | |
|
673 | 0 | ti = proto_tree_add_uint(payload_kink_encrypt_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
674 | 0 | if(payload_length <= PAYLOAD_HEADER){ |
675 | 0 | expert_add_info(pinfo, ti, &ei_kink_payload_length_small); |
676 | 0 | } |
677 | 0 | offset += 2; |
678 | | |
679 | | /* decrypt kink encrypt */ |
680 | |
|
681 | 0 | if(keytype != 0){ |
682 | | #ifdef HAVE_KERBEROS |
683 | | tvbuff_t *next_tvb; |
684 | | uint8_t *plaintext=NULL; |
685 | | |
686 | | next_tvb=tvb_new_subset_length(tvb, offset, encrypt_length); |
687 | | plaintext=decrypt_krb5_data(tree, pinfo, 0, next_tvb, keytype, NULL); |
688 | | if(plaintext){ |
689 | | next_tvb=tvb_new_child_real_data(tvb, plaintext, encrypt_length, encrypt_length); |
690 | | add_new_data_source(pinfo, next_tvb, "decrypted kink encrypt"); |
691 | | dissect_decrypt_kink_encrypt(pinfo, next_tvb, tree, encrypt_length); |
692 | | } |
693 | | #endif |
694 | 0 | } |
695 | 0 | else{ |
696 | 0 | inner_next_pload = tvb_get_uint8(tvb, offset); |
697 | 0 | proto_tree_add_uint(payload_kink_encrypt_tree, hf_kink_inner_next_pload, tvb, offset, 1, inner_next_pload); |
698 | 0 | offset += 1; |
699 | |
|
700 | 0 | proto_tree_add_item(payload_kink_encrypt_tree, hf_kink_reserved24, tvb, offset, 3, ENC_BIG_ENDIAN); |
701 | 0 | offset += 3; |
702 | |
|
703 | 0 | if(payload_length > PAYLOAD_HEADER){ |
704 | 0 | inner_payload_length = payload_length - PAYLOAD_HEADER; |
705 | 0 | proto_tree_add_item(payload_kink_encrypt_tree, hf_kink_payload, tvb, offset, inner_payload_length, ENC_NA); |
706 | | /*offset += inner_payload_length;*/ |
707 | 0 | } |
708 | 0 | } |
709 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
710 | 0 | if(payload_length % PADDING !=0){ |
711 | 0 | payload_length += (PADDING - (payload_length % PADDING)); |
712 | 0 | } |
713 | 0 | offset = start_payload_offset + payload_length; |
714 | |
|
715 | 0 | if(payload_length > 0) { |
716 | 0 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
717 | 0 | } |
718 | 0 | } |
719 | | |
720 | | #ifdef HAVE_KERBEROS |
721 | | static void |
722 | | // NOLINTNEXTLINE(misc-no-recursion) |
723 | | dissect_decrypt_kink_encrypt(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, int payload_length){ |
724 | | |
725 | | proto_tree *decrypt_kink_encrypt_tree; |
726 | | int offset=0; |
727 | | uint8_t next_payload; |
728 | | |
729 | | decrypt_kink_encrypt_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
730 | | ett_decrypt_kink_encrypt, NULL, "decrypted data"); |
731 | | |
732 | | next_payload = tvb_get_uint8(tvb, offset); |
733 | | |
734 | | proto_tree_add_uint(decrypt_kink_encrypt_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
735 | | offset ++; |
736 | | |
737 | | proto_tree_add_item(decrypt_kink_encrypt_tree, hf_kink_reserved24, tvb, offset, 3, ENC_BIG_ENDIAN); |
738 | | offset += 3; |
739 | | |
740 | | control_payload(pinfo, tvb, offset, next_payload, decrypt_kink_encrypt_tree); |
741 | | } |
742 | | #endif |
743 | | |
744 | | static const range_string kink_error_rvals[] = { |
745 | | { 0, 0, "KINK_OK" }, |
746 | | { 1, 1, "KINK_PROTOERR" }, |
747 | | { 2, 2, "KINK_INVDOI" }, |
748 | | { 3, 3, "KINK_INVMAJ" }, |
749 | | { 4, 4, "KINK_INVMIN" }, |
750 | | { 5, 5, "KINK_INTERR" }, |
751 | | { 6, 6, "KINK_BADQMVERS" }, |
752 | | { BOTTOM_RESERVED, TOP_RESERVED, "RESERVED" }, |
753 | | { BOTTOM_PRIVATE_USE, TOP_PRIVATE_USE, "PRIVATE USE" }, |
754 | | { TOP_PRIVATE_USE+1, 0xffffffff, "This Error Code is not Defined." }, |
755 | | { 0, 0, NULL } |
756 | | }; |
757 | | |
758 | | static void |
759 | | // NOLINTNEXTLINE(misc-no-recursion) |
760 | 19 | dissect_payload_kink_error(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
761 | 19 | proto_tree *payload_kink_error_tree; |
762 | 19 | proto_item *ti; |
763 | 19 | uint8_t next_payload; |
764 | 19 | uint16_t payload_length; |
765 | 19 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
766 | | |
767 | 19 | payload_length = tvb_get_ntohs(tvb,offset + TO_PAYLOAD_LENGTH); |
768 | 19 | start_payload_offset = offset; |
769 | | |
770 | | /* Make the subtree */ |
771 | 19 | payload_kink_error_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
772 | 19 | ett_payload_kink_error, NULL, "KINK_ERROR"); |
773 | | |
774 | 19 | next_payload = tvb_get_uint8(tvb, offset); |
775 | 19 | proto_tree_add_uint(payload_kink_error_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
776 | 19 | offset ++; |
777 | | |
778 | 19 | proto_tree_add_item(payload_kink_error_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
779 | 19 | offset ++; |
780 | | |
781 | 19 | ti = proto_tree_add_uint(payload_kink_error_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
782 | 19 | if(payload_length != KINK_ERROR_LENGTH){ |
783 | 18 | expert_add_info(pinfo, ti, &ei_kink_payload_length_mismatch); |
784 | 18 | } |
785 | 19 | offset += 2; |
786 | | |
787 | 19 | proto_tree_add_item(payload_kink_error_tree, hf_kink_error_code, tvb, offset, 4, ENC_BIG_ENDIAN); |
788 | | |
789 | 19 | offset = start_payload_offset + KINK_ERROR_LENGTH; |
790 | 19 | control_payload(pinfo, tvb, offset, next_payload, tree); /* Recur control_payload() */ |
791 | 19 | } |
792 | | |
793 | | static void |
794 | | // NOLINTNEXTLINE(misc-no-recursion) |
795 | 17 | dissect_payload_kink_not_defined(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree){ |
796 | 17 | proto_tree *payload_kink_not_defined_tree; |
797 | 17 | uint8_t next_payload; |
798 | 17 | unsigned payload_length; |
799 | 17 | int start_payload_offset = 0; /* Keep the beginning of the payload offset */ |
800 | | |
801 | 17 | start_payload_offset = offset; |
802 | 17 | payload_length = tvb_get_ntohs(tvb, offset + TO_PAYLOAD_LENGTH); |
803 | | |
804 | | /* Make the subtree */ |
805 | 17 | payload_kink_not_defined_tree = proto_tree_add_subtree(tree, tvb, offset, payload_length, |
806 | 17 | ett_payload_not_defined, NULL, "UNKNOWN PAYLOAD"); |
807 | | |
808 | 17 | next_payload = tvb_get_uint8(tvb, offset); |
809 | 17 | proto_tree_add_uint(payload_kink_not_defined_tree, hf_kink_next_payload, tvb, offset, 1, next_payload); |
810 | 17 | offset ++; |
811 | | |
812 | 17 | proto_tree_add_item(payload_kink_not_defined_tree, hf_kink_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); |
813 | 17 | offset ++; |
814 | | |
815 | 17 | proto_tree_add_uint(payload_kink_not_defined_tree, hf_kink_payload_length, tvb, offset, 2, payload_length); |
816 | | |
817 | | /* This part consider the padding. Payload_length don't contain the padding. */ |
818 | 17 | if(payload_length % PADDING != 0){ |
819 | 6 | payload_length += (PADDING - (payload_length % PADDING)); |
820 | 6 | } |
821 | 17 | offset = start_payload_offset + payload_length; |
822 | | |
823 | | /* XXX - prevent an endless loop if payload_length is 0, don't know the correct way to handle this! */ |
824 | 17 | if(payload_length > 0) { |
825 | 12 | control_payload(pinfo, tvb, offset, next_payload, tree); |
826 | 12 | } |
827 | 17 | } |
828 | | |
829 | | static void |
830 | | kink_fmt_version( char *result, uint32_t version ) |
831 | 0 | { |
832 | 0 | uint8_t major_version, minor_version; |
833 | | |
834 | | /* This part is the version. Consider less than 1 octet value. |
835 | | * Major version and minor version is 4bit. Front half of 1octet |
836 | | * is major version, and second half of 1octet is minor version. |
837 | | * The calculation of major version is shown below. |
838 | | * The logical product of the value of 1octet and 0xf0 is performed. |
839 | | * And It is performed 4bit right shift. |
840 | | * Secondarily, the calculation of minor version is shown below. |
841 | | * The logical product of the value of 1octet and 0x0f is performed. |
842 | | */ |
843 | 0 | major_version = (uint8_t)((version & FRONT_FOUR_BIT) >> VERSION_BIT_SHIFT); |
844 | 0 | minor_version = (uint8_t)(version & SECOND_FOUR_BIT); |
845 | |
|
846 | 0 | snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", major_version, minor_version); |
847 | 0 | } |
848 | | |
849 | | /* Output part */ |
850 | | void |
851 | 15 | proto_register_kink(void) { |
852 | | |
853 | 15 | static hf_register_info hf[] = { |
854 | 15 | { &hf_kink_type, |
855 | 15 | { "Type", "kink.type", |
856 | 15 | FT_UINT8, BASE_DEC, VALS(kink_type_vals), 0x0, |
857 | 15 | NULL, HFILL }}, |
858 | 15 | { &hf_kink_length, |
859 | 15 | { "Length", "kink.length", |
860 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
861 | 15 | NULL, HFILL }}, |
862 | 15 | { &hf_kink_transactionId, |
863 | 15 | { "Transaction ID", "kink.transactionId", |
864 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
865 | 15 | NULL, HFILL }}, |
866 | 15 | { &hf_kink_checkSumLength, |
867 | 15 | { "Checksum Length", "kink.checkSumLength", |
868 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
869 | 15 | NULL, HFILL }}, |
870 | 15 | { &hf_kink_A, |
871 | 15 | { "A", "kink.A", |
872 | 15 | FT_UINT8, BASE_DEC, VALS(kink_A_vals), 0x0, |
873 | 15 | NULL, HFILL }}, |
874 | 15 | { &hf_kink_version, |
875 | 15 | { "Version", "kink.version", |
876 | 15 | FT_UINT8, BASE_CUSTOM, CF_FUNC(kink_fmt_version), 0x0, |
877 | 15 | NULL, HFILL }}, |
878 | 15 | { &hf_kink_domain_of_interpretation, |
879 | 15 | { "Domain Of Interpretation", "kink.domain_of_interpretation", |
880 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
881 | 15 | NULL, HFILL }}, |
882 | 15 | { &hf_kink_qmversion, |
883 | 15 | { "QMVersion", "kink.qmversion", |
884 | 15 | FT_UINT8, BASE_CUSTOM, CF_FUNC(kink_fmt_version), 0x0, |
885 | 15 | NULL, HFILL }}, |
886 | 15 | { &hf_kink_error_code, |
887 | 15 | { "ErrorCode", "kink.error_code", |
888 | 15 | FT_UINT32, BASE_DEC|BASE_RANGE_STRING, RVALS(kink_error_rvals), 0x0, |
889 | 15 | NULL, HFILL }}, |
890 | 15 | { &hf_kink_reserved8, |
891 | 15 | { "Reserved", "kink.reserved", |
892 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
893 | 15 | NULL, HFILL }}, |
894 | 15 | { &hf_kink_reserved15, |
895 | 15 | { "Reserved", "kink.reserved", |
896 | 15 | FT_UINT16, BASE_DEC, NULL, SECOND_FIFTEEN_BIT, |
897 | 15 | NULL, HFILL }}, |
898 | 15 | { &hf_kink_reserved16, |
899 | 15 | { "Reserved", "kink.reserved", |
900 | 15 | FT_UINT16, BASE_DEC, NULL, 0, |
901 | 15 | NULL, HFILL }}, |
902 | 15 | { &hf_kink_reserved24, |
903 | 15 | { "Reserved", "kink.reserved", |
904 | 15 | FT_UINT24, BASE_DEC, NULL, 0, |
905 | 15 | NULL, HFILL }}, |
906 | 15 | { &hf_kink_checkSum, |
907 | 15 | { "Checksum", "kink.checkSum", |
908 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
909 | 15 | NULL, HFILL }}, |
910 | 15 | { &hf_kink_next_payload, |
911 | 15 | { "Next Payload", "kink.nextPayload", |
912 | 15 | FT_UINT8, BASE_DEC, VALS(kink_next_payload), 0x0, |
913 | 15 | NULL, HFILL }}, |
914 | 15 | { &hf_kink_payload_length, |
915 | 15 | { "Payload Length", "kink.payloadLength", |
916 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
917 | 15 | NULL, HFILL }}, |
918 | 15 | { &hf_kink_epoch, |
919 | 15 | { "EPOCH", "kink.epoch", |
920 | 15 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, |
921 | 15 | NULL, HFILL }}, |
922 | 15 | { &hf_kink_inner_next_pload, |
923 | 15 | { "InnerNextPload", "kink.innerNextPload", |
924 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
925 | 15 | NULL, HFILL }}, |
926 | 15 | { &hf_kink_realm_name_length, |
927 | 15 | { "RealmNameLength", "kink.realmNameLength", |
928 | 15 | FT_UINT16, BASE_DEC, NULL, 0, |
929 | 15 | NULL, HFILL }}, |
930 | 15 | { &hf_kink_realm_name, |
931 | 15 | { "RealmName", "kink.realmName", |
932 | 15 | FT_STRING, BASE_NONE, NULL, 0, |
933 | 15 | NULL, HFILL }}, |
934 | 15 | { &hf_kink_princ_name_length, |
935 | 15 | { "PrincNameLength", "kink.princNameLength", |
936 | 15 | FT_UINT16, BASE_DEC, NULL, 0, |
937 | 15 | NULL, HFILL }}, |
938 | 15 | { &hf_kink_princ_name, |
939 | 15 | { "PrincName", "kink.princName", |
940 | 15 | FT_STRING, BASE_NONE, NULL, 0, |
941 | 15 | NULL, HFILL }}, |
942 | 15 | { &hf_kink_tgt_length, |
943 | 15 | { "TGT Length", "kink.tgtLength", |
944 | 15 | FT_UINT16, BASE_DEC, NULL, 0, |
945 | 15 | NULL, HFILL }}, |
946 | 15 | { &hf_kink_tgt, |
947 | 15 | { "TGT", "kink.tgt", |
948 | 15 | FT_STRING, BASE_NONE, NULL, 0, |
949 | 15 | NULL, HFILL }}, |
950 | 15 | { &hf_kink_payload, |
951 | 15 | { "Payload", "kink.payload", |
952 | 15 | FT_BYTES, BASE_NONE, NULL, 0, |
953 | 15 | NULL, HFILL }}, |
954 | 15 | }; |
955 | | |
956 | | /* Argument for making the subtree. */ |
957 | 15 | static int *ett[] = { |
958 | 15 | &ett_kink, |
959 | | /* &ett_kink_version, */ |
960 | 15 | &ett_kink_payload, |
961 | 15 | &ett_payload_kink_ap_req, |
962 | 15 | &ett_payload_kink_ap_rep, |
963 | 15 | &ett_payload_kink_krb_error, |
964 | 15 | &ett_payload_kink_tgt_req, |
965 | 15 | &ett_payload_kink_tgt_rep, |
966 | 15 | &ett_payload_kink_isakmp, |
967 | 15 | &ett_payload_kink_encrypt, |
968 | 15 | &ett_payload_kink_error, |
969 | 15 | &ett_payload_not_defined, |
970 | 15 | &ett_decrypt_kink_encrypt, |
971 | | |
972 | 15 | }; |
973 | | |
974 | 15 | static ei_register_info ei[] = { |
975 | 15 | { &ei_kink_payload_length_small, { "kink.payload_length_small", PI_PROTOCOL, PI_WARN, "This Payload Length is too small", EXPFILL }}, |
976 | 15 | { &ei_kink_payload_length_mismatch, { "kink.payload_length_mismatch", PI_PROTOCOL, PI_WARN, "This Payload Length is mismatch", EXPFILL }}, |
977 | 15 | }; |
978 | | |
979 | 15 | expert_module_t* expert_kink; |
980 | | |
981 | 15 | proto_kink = proto_register_protocol("Kerberized Internet Negotiation of Key", "KINK", "kink"); |
982 | 15 | proto_register_field_array(proto_kink, hf, array_length(hf)); |
983 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
984 | 15 | expert_kink = expert_register_protocol(proto_kink); |
985 | 15 | expert_register_field_array(expert_kink, ei, array_length(ei)); |
986 | | |
987 | 15 | kink_handle = register_dissector("kink", dissect_kink, proto_kink); |
988 | 15 | } |
989 | | |
990 | 15 | void proto_reg_handoff_kink(void) { |
991 | | // If this is ever streamed (transported over TCP) we need to add recursion checks. |
992 | 15 | dissector_add_uint_with_preference("udp.port", KINK_PORT, kink_handle); |
993 | 15 | } |
994 | | |
995 | | /* |
996 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
997 | | * |
998 | | * Local Variables: |
999 | | * c-basic-offset: 2 |
1000 | | * tab-width: 8 |
1001 | | * indent-tabs-mode: nil |
1002 | | * End: |
1003 | | * |
1004 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
1005 | | * :indentSize=2:tabSize=8:noTabs=true: |
1006 | | */ |