2 * Routines for KINK packet disassembly
3 * It is referrenced draft-ietf-kink-kink-jp-04.txt,v 1.14 2003/02/10
5 * Copyright 2004, Takeshi Nakashima <T.Nakashima@jp.yokogawa.com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/expert.h>
34 #include <epan/asn1.h>
35 #include "packet-kerberos.h"
36 #include "packet-isakmp.h"
38 #define KINK_PORT 57203
40 #define KINK_ISAKMP_PAYLOAD_BASE 14
42 static int proto_kink
= -1;
44 /* Argument for proto_tree_add_uint() */
45 static int hf_kink_type
= -1;
46 static int hf_kink_length
= -1;
47 static int hf_kink_transactionId
= -1;
48 static int hf_kink_checkSumLength
= -1;
49 static int hf_kink_A
= -1;
50 static int hf_kink_reserved8
= -1;
51 static int hf_kink_reserved15
= -1;
52 static int hf_kink_reserved16
= -1;
53 static int hf_kink_reserved24
= -1;
54 static int hf_kink_checkSum
= -1;
55 static int hf_kink_next_payload
= -1;
56 static int hf_kink_payload_length
= -1;
57 static int hf_kink_epoch
= -1;
58 static int hf_kink_inner_next_pload
= -1;
59 static int hf_kink_realm_name_length
= -1;
60 static int hf_kink_realm_name
= -1;
61 static int hf_kink_princ_name_length
= -1;
62 static int hf_kink_princ_name
= -1;
63 static int hf_kink_tgt_length
= -1;
64 static int hf_kink_tgt
= -1;
66 /* Argument for making the subtree */
67 static gint ett_kink
= -1;
68 /*static gint ett_kink_version = -1;*/
69 static gint ett_kink_payload
= -1;
70 static gint ett_payload_kink_ap_req
= -1;
71 static gint ett_payload_kink_ap_rep
= -1;
72 static gint ett_payload_kink_krb_error
= -1;
73 static gint ett_payload_kink_tgt_req
= -1;
74 static gint ett_payload_kink_tgt_rep
= -1;
75 static gint ett_payload_kink_isakmp
= -1;
76 static gint ett_payload_kink_encrypt
= -1;
77 static gint ett_payload_kink_error
= -1;
78 static gint ett_payload_not_defined
= -1;
79 static gint ett_decrypt_kink_encrypt
= -1;
81 static expert_field ei_kink_payload_length_small
= EI_INIT
;
82 static expert_field ei_kink_payload_length_mismatch
= EI_INIT
;
85 /* Define the kink type value */
86 #define KINK_TYPE_RESERVED 0
87 #define KINK_TYPE_CREATE 1
88 #define KINK_TYPE_DELETE 2
89 #define KINK_TYPE_REPLY 3
90 #define KINK_TYPE_GETTGT 4
91 #define KINK_TYPE_ACK 5
92 #define KINK_TYPE_STATUS 6
94 static const value_string kink_type_vals
[]={
95 {KINK_TYPE_RESERVED
,"RESERVED"},
96 {KINK_TYPE_CREATE
,"CREATE"},
97 {KINK_TYPE_DELETE
,"DELETE"},
98 {KINK_TYPE_REPLY
,"REPLY"},
99 {KINK_TYPE_GETTGT
,"GETTGT"},
100 {KINK_TYPE_ACK
,"ACK"},
101 {KINK_TYPE_STATUS
,"STATUS"},
105 /* Define the kink A value */
106 #define KINK_A_NOT_REQUEST_ACK 0
107 #define KINK_A_REQUEST_ACK 1
109 static const value_string kink_A_vals
[]={
110 {KINK_A_NOT_REQUEST_ACK
,"Not Request ACK"},
111 {KINK_A_REQUEST_ACK
,"Request ACK"},
115 /* Define the kink payload */
117 #define KINK_AP_REQ KINK_ISAKMP_PAYLOAD_BASE+0
118 #define KINK_AP_REP KINK_ISAKMP_PAYLOAD_BASE+1
119 #define KINK_KRB_ERROR KINK_ISAKMP_PAYLOAD_BASE+2
120 #define KINK_TGT_REQ KINK_ISAKMP_PAYLOAD_BASE+3
121 #define KINK_TGT_REP KINK_ISAKMP_PAYLOAD_BASE+4
122 #define KINK_ISAKMP KINK_ISAKMP_PAYLOAD_BASE+5
123 #define KINK_ENCRYPT KINK_ISAKMP_PAYLOAD_BASE+6
124 #define KINK_ERROR KINK_ISAKMP_PAYLOAD_BASE+7
126 static const value_string kink_next_payload
[]={
127 {KINK_DONE
, "KINK_DONE"},
128 {KINK_AP_REQ
, "KINK_AP_REQ"},
129 {KINK_AP_REP
, "KINK_AP_REP"},
130 {KINK_KRB_ERROR
, "KINK_KRB_ERROR"},
131 {KINK_TGT_REQ
, "KINK_TGT_REQ"},
132 {KINK_TGT_REP
, "KINK_TGT_REP"},
133 {KINK_ISAKMP
, "KINK_ISAKMP"},
134 {KINK_ENCRYPT
, "KINK_ENCRYPT"},
135 {KINK_ERROR
, "KINK_ERROR"},
139 /* Define the magic number
140 * Using at the kink error
143 #define KINK_PROTOERR 1
144 #define KINK_INVDOI 2
145 #define KINK_INVMAJ 3
146 #define KINK_INVMIN 4
147 #define KINK_INTERR 5
148 #define KINK_BADQMVERS 6
149 #define BOTTOM_RESERVED 7
150 #define TOP_RESERVED 8191
151 #define BOTTOM_PRIVATE_USE 8192
152 #define TOP_PRIVATE_USE 16383
154 /* Using at the kink header */
156 #define VERSION_BIT_SHIFT 4
157 #define A_BIT_SHIFT 7
158 #define FROM_TYPE_TO_RESERVED 16
160 /* Using at the payload */
161 #define TO_PAYLOAD_LENGTH 2
163 #define KINK_KRB_ERROR_HEADER 4
164 #define FROM_NP_TO_PL 4
165 #define TO_REALM_NAME_LENGTH 4
166 #define KINK_TGT_REQ_HEADER 6
167 #define FRONT_TGT_REP_HEADER 6
168 #define PAYLOAD_HEADER 8
169 #define KINK_ERROR_LENGTH 8
172 /* define hexadecimal */
173 #define FRONT_FOUR_BIT 0xf0
174 #define SECOND_FOUR_BIT 0x0f
175 #define FRONT_ONE_BIT 0x80
176 #define SECOND_FIFTEEN_BIT 0x7fff
178 /* decrypt element */
179 static guint32 keytype
;
181 static void control_payload(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, guint8 next_payload
, proto_tree
*kink_payload_tree
);
182 static void dissect_payload_kink_ap_req(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
183 static void dissect_payload_kink_ap_rep(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
184 static void dissect_payload_kink_krb_error(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
185 static void dissect_payload_kink_tgt_req(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
186 static void dissect_payload_kink_tgt_rep(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
187 static void dissect_payload_kink_isakmp(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
188 static void dissect_payload_kink_encrypt(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
189 static void dissect_payload_kink_error(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
190 static void dissect_payload_kink_not_defined(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
192 static void dissect_decrypt_kink_encrypt(packet_info
*pinfo
, tvbuff_t
*tvb
, proto_tree
*tree
, int payload_length
);
195 /* This function is dissecting the kink header. */
197 dissect_kink(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
){
198 proto_item
*ti
= NULL
;
199 proto_tree
*kink_tree
= NULL
;
201 guint8 major_version
, minor_version
, version
;
205 guint8 value_a_and_front_reserved
;
209 type
= tvb_get_guint8(tvb
,offset
);
211 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "KINK");
213 /* It shows kink type by the type value. */
214 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(type
, kink_type_vals
, "unknown"));
216 /* Make the kink tree */
217 ti
= proto_tree_add_item(tree
, proto_kink
, tvb
, offset
, -1, ENC_NA
);
218 kink_tree
= proto_item_add_subtree(ti
, ett_kink
);
220 proto_tree_add_uint(kink_tree
, hf_kink_type
, tvb
, offset
, 1, type
);
223 /* This part is the version. Consider less than 1 octet value.
224 * Major version and minor version is 4bit. Front half of 1octet
225 * is major version, and second half of 1octet is minor version.
226 * The calculation of major version is shown below.
227 * The logical product of the value of 1octet and 0xf0 is performed.
228 * And It is performed 4bit right shift.
229 * Secondarily, the calculation of minor version is shown below.
230 * The logical product of the value of 1octet and 0x0f is performed.
232 version
= tvb_get_guint8(tvb
,offset
);
233 major_version
= (version
& FRONT_FOUR_BIT
) >> VERSION_BIT_SHIFT
;
234 minor_version
= version
& SECOND_FOUR_BIT
;
235 proto_tree_add_text(kink_tree
, tvb
, offset
, 1, "version: %u.%u", major_version
, minor_version
);
238 proto_tree_add_item(kink_tree
, hf_kink_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
241 doi
= tvb_get_ntohl(tvb
, offset
);
244 proto_tree_add_text(kink_tree
, tvb
, offset
, 4, "Domain Of Interpretation: %s (%u)", "IPsec", doi
);
247 proto_tree_add_text(kink_tree
, tvb
, offset
, 4, "Domain Of Interpretation: %s (%u)", "Not IPsec", doi
);
251 proto_tree_add_item(kink_tree
, hf_kink_transactionId
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
254 chsumlen
= tvb_get_guint8(tvb
, offset
);
255 proto_tree_add_item(kink_tree
, hf_kink_checkSumLength
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
258 next_payload
= tvb_get_guint8(tvb
, offset
);
259 proto_tree_add_uint(kink_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
262 /* A is 1bit field. The caluculation of A is shown below.
263 * The logical product of 1octet value and 0x80 is performed.
264 * And It is performed 7bit right shift.
266 value_a_and_front_reserved
= tvb_get_guint8(tvb
, offset
);
267 value_a
= (value_a_and_front_reserved
& FRONT_ONE_BIT
) >> A_BIT_SHIFT
;
268 proto_tree_add_uint(kink_tree
, hf_kink_A
, tvb
, offset
, 1, value_a
);
270 /* The reserved field is 15bit.
271 * The logical product of 2octet value and 0x7fff is performed.
273 proto_tree_add_item(kink_tree
, hf_kink_reserved15
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
276 proto_tree_add_item(kink_tree
, hf_kink_checkSum
, tvb
, offset
, chsumlen
, ENC_NA
);
278 /* This part consider the padding. Chsumlen don't contain the padding. */
279 if((chsumlen
% PADDING
) != 0){
280 chsumlen
+= (PADDING
- (chsumlen
% PADDING
));
287 control_payload(pinfo
, tvb
, offset
, next_payload
, kink_tree
);
291 /* This part call the dissect payload function by next_payload value.
292 * This function called by the respective function again.
295 control_payload(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, guint8 next_payload
, proto_tree
*kink_tree
){
296 switch(next_payload
){
300 dissect_payload_kink_ap_req(pinfo
, tvb
, offset
, kink_tree
);
303 dissect_payload_kink_ap_rep(pinfo
, tvb
, offset
, kink_tree
);
306 dissect_payload_kink_krb_error(pinfo
, tvb
, offset
, kink_tree
);
309 dissect_payload_kink_tgt_req(pinfo
, tvb
, offset
, kink_tree
);
312 dissect_payload_kink_tgt_rep(pinfo
, tvb
, offset
, kink_tree
);
315 dissect_payload_kink_isakmp(pinfo
, tvb
, offset
, kink_tree
);
318 dissect_payload_kink_encrypt(pinfo
, tvb
, offset
, kink_tree
);
321 dissect_payload_kink_error(pinfo
, tvb
, offset
, kink_tree
);
324 dissect_payload_kink_not_defined(pinfo
, tvb
, offset
, kink_tree
);
330 dissect_payload_kink_ap_req(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
331 proto_tree
*payload_kink_ap_req_tree
;
334 guint payload_length
;
335 guint16 krb_ap_req_length
;
336 int start_payload_offset
= 0; /* Keep beginning of payload offset */
338 start_payload_offset
= offset
;
339 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
341 /* Make the subtree. */
342 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
, "KINK_AP_REQ");
343 payload_kink_ap_req_tree
= proto_item_add_subtree(ti
, ett_payload_kink_ap_req
);
345 next_payload
= tvb_get_guint8(tvb
, offset
);
346 proto_tree_add_uint(payload_kink_ap_req_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
349 proto_tree_add_item(payload_kink_ap_req_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
352 ti
= proto_tree_add_uint(payload_kink_ap_req_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
353 if(payload_length
<= PAYLOAD_HEADER
){
354 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_small
);
358 /* Show time as UTC, not local time. */
359 proto_tree_add_item(payload_kink_ap_req_tree
, hf_kink_epoch
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
362 if(payload_length
> PAYLOAD_HEADER
){
365 krb_ap_req_length
= payload_length
- PAYLOAD_HEADER
;
366 krb_tvb
=tvb_new_subset(tvb
, offset
, (krb_ap_req_length
>tvb_length_remaining(tvb
, offset
))?tvb_length_remaining(tvb
, offset
):krb_ap_req_length
, krb_ap_req_length
);
367 keytype
=kerberos_output_keytype();
368 dissect_kerberos_main(krb_tvb
, pinfo
, payload_kink_ap_req_tree
, FALSE
, NULL
);
369 /*offset += krb_ap_req_length;*/
372 /* This part consider padding the padding. Payload_length don't contain the padding. */
373 if(payload_length
% PADDING
!= 0){
374 payload_length
+= (PADDING
- (payload_length
% PADDING
));
376 offset
= start_payload_offset
+ payload_length
;
378 if(payload_length
> 0) {
379 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
385 dissect_payload_kink_ap_rep(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
386 proto_tree
*payload_kink_ap_rep_tree
;
389 guint payload_length
;
390 guint16 krb_ap_rep_length
;
391 int start_payload_offset
= 0; /* Keep beginning of payload offset */
393 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
394 start_payload_offset
= offset
;
396 /* Make the subtree */
397 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_AP_REP");
398 payload_kink_ap_rep_tree
= proto_item_add_subtree(ti
, ett_payload_kink_ap_rep
);
400 next_payload
= tvb_get_guint8(tvb
, offset
);
401 proto_tree_add_uint(payload_kink_ap_rep_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
404 proto_tree_add_item(payload_kink_ap_rep_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
407 ti
= proto_tree_add_uint(payload_kink_ap_rep_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
408 if(payload_length
<= PAYLOAD_HEADER
){
409 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_small
);
413 /* Show time as UTC, not local time. */
414 proto_tree_add_item(payload_kink_ap_rep_tree
, hf_kink_epoch
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
417 if(payload_length
> PAYLOAD_HEADER
){
420 krb_ap_rep_length
= payload_length
- PAYLOAD_HEADER
;
421 krb_tvb
=tvb_new_subset(tvb
, offset
, (krb_ap_rep_length
>tvb_length_remaining(tvb
, offset
))?tvb_length_remaining(tvb
, offset
):krb_ap_rep_length
, krb_ap_rep_length
);
422 keytype
=kerberos_output_keytype();
423 dissect_kerberos_main(krb_tvb
, pinfo
, payload_kink_ap_rep_tree
, FALSE
, NULL
);
425 /*offset += krb_ap_rep_length;*/
428 /* This part consider the padding. Payload_length don't contain the padding. */
429 if(payload_length
% PADDING
!= 0){
430 payload_length
+= (PADDING
- (payload_length
% PADDING
));
432 offset
= start_payload_offset
+ payload_length
;
434 if(payload_length
> 0) {
435 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
440 dissect_payload_kink_krb_error(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
441 proto_tree
*payload_kink_krb_error_tree
;
444 guint payload_length
;
445 guint16 krb_error_length
;
446 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
448 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
449 start_payload_offset
= offset
;
451 /* Make the subtree */
452 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_KRB_ERROR");
453 payload_kink_krb_error_tree
= proto_item_add_subtree(ti
, ett_payload_kink_krb_error
);
455 next_payload
= tvb_get_guint8(tvb
, offset
);
456 proto_tree_add_uint(payload_kink_krb_error_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
459 proto_tree_add_item(payload_kink_krb_error_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
462 ti
= proto_tree_add_uint(payload_kink_krb_error_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
463 if(payload_length
<= KINK_KRB_ERROR_HEADER
){
464 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_small
);
470 if(payload_length
> KINK_KRB_ERROR_HEADER
){
473 krb_error_length
= payload_length
- KINK_KRB_ERROR_HEADER
;
474 krb_tvb
=tvb_new_subset(tvb
, offset
, (krb_error_length
>tvb_length_remaining(tvb
, offset
))?tvb_length_remaining(tvb
, offset
):krb_error_length
, krb_error_length
);
476 dissect_kerberos_main(krb_tvb
, pinfo
, payload_kink_krb_error_tree
, FALSE
, NULL
);
477 /*offset += krb_error_length;*/
480 /* This part consider the padding. Payload_length don't contain the padding. */
481 if(payload_length
% PADDING
!= 0){
482 payload_length
+= (PADDING
- (payload_length
% PADDING
));
484 offset
= start_payload_offset
+ payload_length
;
486 if(payload_length
> 0) {
487 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
492 dissect_payload_kink_tgt_req(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
493 proto_tree
*payload_kink_tgt_req_tree
;
496 guint payload_length
;
497 guint16 realm_name_length
;
498 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
500 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
501 realm_name_length
= tvb_get_ntohs(tvb
, offset
+ TO_REALM_NAME_LENGTH
);
502 start_payload_offset
= offset
;
504 /* Make the subtree */
505 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_TGT_REQ");
506 payload_kink_tgt_req_tree
= proto_item_add_subtree(ti
, ett_payload_kink_tgt_req
);
508 next_payload
= tvb_get_guint8(tvb
, offset
);
509 proto_tree_add_uint(payload_kink_tgt_req_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
512 proto_tree_add_item(payload_kink_tgt_req_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
515 proto_tree_add_uint(payload_kink_tgt_req_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
518 proto_tree_add_uint(payload_kink_tgt_req_tree
, hf_kink_realm_name_length
, tvb
, offset
, 2, realm_name_length
);
521 proto_tree_add_item(payload_kink_tgt_req_tree
, hf_kink_realm_name
, tvb
, offset
, realm_name_length
, ENC_NA
|ENC_ASCII
);
523 /* This part consider the padding. Payload_length don't contain the padding. */
524 if(payload_length
% PADDING
!= 0){
525 payload_length
+= (PADDING
- (payload_length
% PADDING
));
527 offset
= start_payload_offset
+ payload_length
;
529 if(payload_length
> 0) {
530 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
535 dissect_payload_kink_tgt_rep(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
536 proto_tree
*payload_kink_tgt_rep_tree
;
539 guint payload_length
;
540 guint princ_name_length
;
542 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
544 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
545 start_payload_offset
= offset
;
547 /* Make the subtree */
548 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_TGT_REP");
549 payload_kink_tgt_rep_tree
= proto_item_add_subtree(ti
, ett_payload_kink_tgt_rep
);
551 next_payload
= tvb_get_guint8(tvb
, offset
);
552 proto_tree_add_uint(payload_kink_tgt_rep_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
555 proto_tree_add_item(payload_kink_tgt_rep_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
558 proto_tree_add_uint(payload_kink_tgt_rep_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
561 princ_name_length
= tvb_get_ntohs(tvb
, offset
);
562 proto_tree_add_uint(payload_kink_tgt_rep_tree
, hf_kink_princ_name_length
, tvb
, offset
, 2, princ_name_length
);
565 proto_tree_add_item(payload_kink_tgt_rep_tree
, hf_kink_princ_name
, tvb
, offset
, princ_name_length
, ENC_NA
|ENC_ASCII
);
567 /* This part consider the padding. Princ_name_length don't contain the padding. */
568 if((princ_name_length
+ FRONT_TGT_REP_HEADER
) % PADDING
!= 0){
569 offset
+= (princ_name_length
+ PADDING
- ((princ_name_length
+ FRONT_TGT_REP_HEADER
) % PADDING
));
572 offset
+= princ_name_length
;
575 tgt_length
= tvb_get_ntohs(tvb
, offset
);
576 proto_tree_add_uint(payload_kink_tgt_rep_tree
, hf_kink_tgt_length
, tvb
, offset
, 2, tgt_length
);
579 proto_tree_add_item(payload_kink_tgt_rep_tree
, hf_kink_tgt
, tvb
, offset
, tgt_length
, ENC_NA
|ENC_ASCII
);
580 /*offset += tgt_length;*/
582 /* This part consider the padding. Payload_length don't contain the padding. */
583 if(payload_length
% PADDING
!=0){
584 payload_length
+= (PADDING
- (payload_length
% PADDING
));
586 offset
= start_payload_offset
+ payload_length
;
588 if(payload_length
> 0) {
589 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
594 dissect_payload_kink_isakmp(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
595 proto_tree
*payload_kink_isakmp_tree
;
598 guint payload_length
,isakmp_length
;
599 int length
, reported_length
;
600 guint8 inner_next_pload
;
601 guint8 qm
, qmmaj
, qmmin
;
602 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
603 tvbuff_t
*isakmp_tvb
;
605 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
606 start_payload_offset
= offset
;
608 /* Make the subtree. */
609 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_ISAKMP");
610 payload_kink_isakmp_tree
= proto_item_add_subtree(ti
, ett_payload_kink_isakmp
);
612 next_payload
= tvb_get_guint8(tvb
, offset
);
613 proto_tree_add_uint(payload_kink_isakmp_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
616 proto_tree_add_item(payload_kink_isakmp_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
619 ti
= proto_tree_add_uint(payload_kink_isakmp_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
620 if(payload_length
<= PAYLOAD_HEADER
){
621 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_small
);
625 inner_next_pload
= tvb_get_guint8(tvb
, offset
);
626 proto_tree_add_uint(payload_kink_isakmp_tree
, hf_kink_inner_next_pload
, tvb
, offset
, 1, inner_next_pload
);
629 /* The qmmaj is first half 4bit field of the octet. Therefore, the logical product
630 * of the 1octet value and 0xf0 is performed, and performed 4bit right shift.
631 * The qmmin is second half 4bit field of the octet. Therefore, the logical product
632 * of the 1octet value and 0x0f is performed.
634 qm
= tvb_get_guint8(tvb
,offset
);
635 qmmaj
= (qm
& FRONT_FOUR_BIT
) >> VERSION_BIT_SHIFT
;
636 qmmin
= qm
& SECOND_FOUR_BIT
;
638 proto_tree_add_text(payload_kink_isakmp_tree
, tvb
, offset
, 1, "QMVersion: %u.%u", qmmaj
, qmmin
);
641 proto_tree_add_item(payload_kink_isakmp_tree
, hf_kink_reserved16
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
644 if(payload_length
> PAYLOAD_HEADER
){
645 isakmp_length
= payload_length
- PAYLOAD_HEADER
;
646 length
= tvb_length_remaining(tvb
, offset
);
647 if (length
> (int)isakmp_length
)
648 length
= isakmp_length
;
649 reported_length
= tvb_reported_length_remaining(tvb
, offset
);
650 if (reported_length
> (int)isakmp_length
)
651 reported_length
= isakmp_length
;
652 isakmp_tvb
= tvb_new_subset(tvb
, offset
, length
, reported_length
);
653 isakmp_dissect_payloads(isakmp_tvb
, payload_kink_isakmp_tree
, 1, inner_next_pload
, 0, isakmp_length
, pinfo
);
656 /* This part consider the padding. Payload_length don't contain the padding. */
657 if(payload_length
% PADDING
!= 0){
658 payload_length
+= (PADDING
- (payload_length
% PADDING
));
660 offset
= start_payload_offset
+ payload_length
;
662 if(payload_length
> 0) {
663 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
668 dissect_payload_kink_encrypt(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
669 proto_tree
*payload_kink_encrypt_tree
;
672 guint payload_length
;
676 guint8 inner_next_pload
;
677 guint16 inner_payload_length
;
678 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
680 payload_length
= tvb_get_ntohs(tvb
,offset
+ TO_PAYLOAD_LENGTH
);
681 start_payload_offset
= offset
;
684 encrypt_length
= payload_length
- FROM_NP_TO_PL
;
686 /* Make the subtree */
687 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_ENCRYPT");
688 payload_kink_encrypt_tree
= proto_item_add_subtree(ti
, ett_payload_kink_encrypt
);
690 next_payload
= tvb_get_guint8(tvb
, offset
);
691 proto_tree_add_uint(payload_kink_encrypt_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
694 proto_tree_add_item(payload_kink_encrypt_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
697 ti
= proto_tree_add_uint(payload_kink_encrypt_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
698 if(payload_length
<= PAYLOAD_HEADER
){
699 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_small
);
703 /* decrypt kink encrypt */
708 guint8
*plaintext
=NULL
;
710 next_tvb
=tvb_new_subset(tvb
, offset
, MIN(tvb_length_remaining(tvb
, offset
), encrypt_length
), encrypt_length
);
711 plaintext
=decrypt_krb5_data(tree
, pinfo
, 0, next_tvb
, keytype
, NULL
);
713 next_tvb
=tvb_new_child_real_data(tvb
, plaintext
, encrypt_length
, encrypt_length
);
714 tvb_set_free_cb(next_tvb
, g_free
);
715 add_new_data_source(pinfo
, next_tvb
, "decrypted kink encrypt");
716 dissect_decrypt_kink_encrypt(pinfo
, next_tvb
, tree
, encrypt_length
);
721 inner_next_pload
= tvb_get_guint8(tvb
, offset
);
722 proto_tree_add_uint(payload_kink_encrypt_tree
, hf_kink_inner_next_pload
, tvb
, offset
, 1, inner_next_pload
);
725 proto_tree_add_item(payload_kink_encrypt_tree
, hf_kink_reserved24
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
728 if(payload_length
> PAYLOAD_HEADER
){
729 inner_payload_length
= payload_length
- PAYLOAD_HEADER
;
730 proto_tree_add_text(payload_kink_encrypt_tree
, tvb
, offset
, inner_payload_length
, "Payload");
731 /*offset += inner_payload_length;*/
734 /* This part consider the padding. Payload_length don't contain the padding. */
735 if(payload_length
% PADDING
!=0){
736 payload_length
+= (PADDING
- (payload_length
% PADDING
));
738 offset
= start_payload_offset
+ payload_length
;
740 if(payload_length
> 0) {
741 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
747 dissect_decrypt_kink_encrypt(packet_info
*pinfo
, tvbuff_t
*tvb
, proto_tree
*tree
, int payload_length
){
749 proto_tree
*decrypt_kink_encrypt_tree
;
754 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
, "decrypted data");
755 decrypt_kink_encrypt_tree
= proto_item_add_subtree(ti
, ett_decrypt_kink_encrypt
);
757 next_payload
= tvb_get_guint8(tvb
, offset
);
759 proto_tree_add_uint(decrypt_kink_encrypt_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
762 proto_tree_add_item(decrypt_kink_encrypt_tree
, hf_kink_reserved24
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
765 control_payload(pinfo
, tvb
, offset
, next_payload
, decrypt_kink_encrypt_tree
);
770 dissect_payload_kink_error(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
771 proto_tree
*payload_kink_error_tree
;
774 guint16 payload_length
;
776 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
777 static const char *char_error_code
[] = {
787 payload_length
= tvb_get_ntohs(tvb
,offset
+ TO_PAYLOAD_LENGTH
);
788 start_payload_offset
= offset
;
790 /* Make the subtree */
791 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
,"KINK_ERROR");
792 payload_kink_error_tree
= proto_item_add_subtree(ti
, ett_payload_kink_error
);
794 next_payload
= tvb_get_guint8(tvb
, offset
);
795 proto_tree_add_uint(payload_kink_error_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
798 proto_tree_add_item(payload_kink_error_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
801 ti
= proto_tree_add_uint(payload_kink_error_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
802 if(payload_length
!= KINK_ERROR_LENGTH
){
803 expert_add_info(pinfo
, ti
, &ei_kink_payload_length_mismatch
);
807 error_code
= tvb_get_ntohl(tvb
, offset
);
809 /* Choosed the error code by erro_code */
818 proto_tree_add_text(payload_kink_error_tree
, tvb
, offset
, 4, "ErrorCode: %s (%u)", char_error_code
[error_code
], error_code
);
821 if(BOTTOM_RESERVED
<= error_code
&& TOP_RESERVED
>= error_code
){
822 proto_tree_add_text(payload_kink_error_tree
, tvb
, offset
, 4, "ErrorCode: %s (%u)", "RESERVED", error_code
);
824 else if(BOTTOM_PRIVATE_USE
<= error_code
&& TOP_PRIVATE_USE
>= error_code
){
825 proto_tree_add_text(payload_kink_error_tree
, tvb
, offset
, 4, "ErrorCode: %s (%u)", "PRIVATE USE", error_code
);
828 proto_tree_add_text(payload_kink_error_tree
, tvb
, offset
, 4, "ErrorCode: %s (%u)", "This Error Code is not Defined.", error_code
);
833 offset
= start_payload_offset
+ KINK_ERROR_LENGTH
;
834 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
); /* Recur control_payload() */
838 dissect_payload_kink_not_defined(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*tree
){
839 proto_tree
*payload_kink_not_defined_tree
;
842 guint payload_length
;
843 int start_payload_offset
= 0; /* Keep the beginning of the payload offset */
845 start_payload_offset
= offset
;
846 payload_length
= tvb_get_ntohs(tvb
, offset
+ TO_PAYLOAD_LENGTH
);
848 /* Make the subtree */
849 ti
= proto_tree_add_text(tree
, tvb
, offset
, payload_length
, "UNKNOWN PAYLOAD");
850 payload_kink_not_defined_tree
= proto_item_add_subtree(ti
, ett_payload_not_defined
);
852 next_payload
= tvb_get_guint8(tvb
, offset
);
853 proto_tree_add_uint(payload_kink_not_defined_tree
, hf_kink_next_payload
, tvb
, offset
, 1, next_payload
);
856 proto_tree_add_item(payload_kink_not_defined_tree
, hf_kink_reserved8
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
859 proto_tree_add_uint(payload_kink_not_defined_tree
, hf_kink_payload_length
, tvb
, offset
, 2, payload_length
);
861 /* This part consider the padding. Payload_length don't contain the padding. */
862 if(payload_length
% PADDING
!= 0){
863 payload_length
+= (PADDING
- (payload_length
% PADDING
));
865 offset
= start_payload_offset
+ payload_length
;
867 /* XXX - prevent an endless loop if payload_length is 0, don't know the correct way to handle this! */
868 if(payload_length
> 0) {
869 control_payload(pinfo
, tvb
, offset
, next_payload
, tree
);
875 proto_register_kink(void) {
877 static hf_register_info hf
[] = {
879 { "Type", "kink.type",
880 FT_UINT8
, BASE_DEC
, VALS(kink_type_vals
), 0x0,
881 "the type of the kink", HFILL
}},
883 { "Length", "kink.length",
884 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
885 "the length of the kink length", HFILL
}},
886 { &hf_kink_transactionId
,
887 { "Transaction ID", "kink.transactionId",
888 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
889 "the transactionID of kink", HFILL
}},
890 { &hf_kink_checkSumLength
,
891 { "Checksum Length", "kink.checkSumLength",
892 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
893 "the check sum length of kink", HFILL
}},
896 FT_UINT8
, BASE_DEC
, VALS(kink_A_vals
), 0x0,
897 "the A of kink", HFILL
}},
898 { &hf_kink_reserved8
,
899 { "Reserved", "kink.reserved",
900 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
901 "the reserved of kink", HFILL
}},
902 { &hf_kink_reserved15
,
903 { "Reserved", "kink.reserved",
904 FT_UINT16
, BASE_DEC
, NULL
, SECOND_FIFTEEN_BIT
,
905 "the reserved of kink", HFILL
}},
906 { &hf_kink_reserved16
,
907 { "Reserved", "kink.reserved",
908 FT_UINT16
, BASE_DEC
, NULL
, 0,
909 "the reserved of kink", HFILL
}},
910 { &hf_kink_reserved24
,
911 { "Reserved", "kink.reserved",
912 FT_UINT24
, BASE_DEC
, NULL
, 0,
913 "the reserved of kink", HFILL
}},
915 { "Checksum", "kink.checkSum",
916 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
917 "the checkSum of kink", HFILL
}},
918 { &hf_kink_next_payload
,
919 { "Next Payload", "kink.nextPayload",
920 FT_UINT8
, BASE_DEC
, VALS(kink_next_payload
), 0x0,
921 "the next payload of kink", HFILL
}},
922 { &hf_kink_payload_length
,
923 { "Payload Length", "kink.payloadLength",
924 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
927 { "EPOCH", "kink.epoch",
928 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0x0,
930 { &hf_kink_inner_next_pload
,
931 { "InnerNextPload", "kink.innerNextPload",
932 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
934 { &hf_kink_realm_name_length
,
935 { "RealmNameLength", "kink.realmNameLength",
936 FT_UINT16
, BASE_DEC
, NULL
, 0,
938 { &hf_kink_realm_name
,
939 { "RealmName", "kink.realmName",
940 FT_STRING
, BASE_NONE
, NULL
, 0,
942 { &hf_kink_princ_name_length
,
943 { "PrincNameLength", "kink.princNameLength",
944 FT_UINT16
, BASE_DEC
, NULL
, 0,
946 { &hf_kink_princ_name
,
947 { "PrincName", "kink.princName",
948 FT_STRING
, BASE_NONE
, NULL
, 0,
950 { &hf_kink_tgt_length
,
951 { "TGT Length", "kink.tgtLength",
952 FT_UINT16
, BASE_DEC
, NULL
, 0,
956 FT_STRING
, BASE_NONE
, NULL
, 0,
960 /* Argument for making the subtree. */
961 static gint
*ett
[] = {
963 /* &ett_kink_version, */
965 &ett_payload_kink_ap_req
,
966 &ett_payload_kink_ap_rep
,
967 &ett_payload_kink_krb_error
,
968 &ett_payload_kink_tgt_req
,
969 &ett_payload_kink_tgt_rep
,
970 &ett_payload_kink_isakmp
,
971 &ett_payload_kink_encrypt
,
972 &ett_payload_kink_error
,
973 &ett_payload_not_defined
,
974 &ett_decrypt_kink_encrypt
,
978 static ei_register_info ei
[] = {
979 { &ei_kink_payload_length_small
, { "kink.payload_length_small", PI_PROTOCOL
, PI_WARN
, "This Payload Length is too small", EXPFILL
}},
980 { &ei_kink_payload_length_mismatch
, { "kink.payload_length_mismatch", PI_PROTOCOL
, PI_WARN
, "This Payload Length is mismatch", EXPFILL
}},
983 expert_module_t
* expert_kink
;
985 proto_kink
= proto_register_protocol("Kerberized Internet Negotiation of Key", "KINK", "kink");
986 proto_register_field_array(proto_kink
, hf
, array_length(hf
));
987 proto_register_subtree_array(ett
, array_length(ett
));
988 expert_kink
= expert_register_protocol(proto_kink
);
989 expert_register_field_array(expert_kink
, ei
, array_length(ei
));
993 void proto_reg_handoff_kink(void) {
995 dissector_handle_t kink_handle
= NULL
;
997 kink_handle
= create_dissector_handle(dissect_kink
, proto_kink
);
999 dissector_add_uint("udp.port", KINK_PORT
, kink_handle
);