Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-knet.c
blobb07aa1a462c11bbbeccd9ab707f7adb01e81c018
1 /* packet-knet.c
2 * Routines for the KristalliNet (kNet) protocol.
3 * Kari Vatjus-Anttila <kari.vatjus-anttila@cie.fi>
4 * Ville Saarinen <ville.saarinen@cie.fi>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include "packet-tcp.h"
19 void proto_register_knet(void);
20 void proto_reg_handoff_knet(void);
22 #define PROTO_TAG_KNET "KNET" /*!< Definition of kNet Protocol */
23 #define PORT 2345 /* Not IANA registered */
25 #define KNET_SCTP_PACKET 1000
26 #define KNET_TCP_PACKET 1001
27 #define KNET_UDP_PACKET 1002
29 /**
30 * @addtogroup messageids kNet Message ID:s
31 * Message ID:s of the kNet protocol
33 /**@{*/
34 #define PINGREQUEST 1 /*!< Message ID definition: Ping Request */
35 #define PINGREPLY 2 /*!< Message ID definition: Ping Reply */
36 #define FLOWCONTROLREQUEST 3 /*!< Message ID definition: Flow Control Request */
37 #define PACKETACK 4 /*!< Message ID definition: Packet Acknowledge */
38 #define DISCONNECT 255 /*!< Message ID definition: Disconnect */
39 #define DISCONNECTACK 254 /*!< Message ID definition: Disconnect Ack */
40 #define CONNECTSYN 253 /*!< Message ID definition: Connect Syn */
41 #define CONNECTSYNACK 252 /*!< Message ID definition: Connect Syn Acknowledge */
42 #define CONNECTACK 251 /*!< Message ID definition: Connect Acknowledge */
43 /**@}*/
45 #define UDP_DATAGRAM_RELIABLE_FLAG 0x40
46 #define UDP_MSG_BLOCK_RELIABLE_FLAG 0x10
48 /**
49 * @addtogroup protocols Protocol Variables
50 * Protocol variables.
52 /**@{*/
53 static int proto_knet;
54 /**@}*/
56 /**
57 * @addtogroup headerfields Dissector Header Fields
58 * Header fields of the kNet datagram
60 /* *@{*/
62 /* Fields used by the TCP/SCTP dissector */
63 static int hf_knet_message_tree; /*!< Message tree */
64 static int hf_knet_content_length_vle; /*!< Content Length */
66 /* Fields used by the UDP dissector */
67 static int hf_knet_content_length; /*!< Content Length */
68 static int hf_knet_datagram_tree; /*!< Datagram subtree */
69 static int hf_knet_flags; /*!< UDP Flags subtree */
70 static int hf_knet_inorder; /*!< Inorder Flag */
71 static int hf_knet_reliable; /*!< Reliable Flag */
72 static int hf_knet_packetid; /*!< PacketID */
73 static int hf_knet_rmib; /*!< Reliable Message Index Base */
74 static int hf_knet_msg_flags; /*!< Message Block Flags subtree */
75 static int hf_knet_msg_fs; /*!< Fragment Start */
76 static int hf_knet_msg_ff; /*!< Fragment Flag */
77 static int hf_knet_msg_inorder; /*!< Inorder Flag */
78 static int hf_knet_msg_reliable; /*!< Reliable Flag */
79 static int hf_knet_msg_reliable_message_number; /*!< Reliable Message Number */
81 static int hf_knet_payload_tree; /*!< Payload subtree */
82 static int hf_knet_payload; /*!< Payload subtree */
83 static int hf_knet_messageid; /*!< MessageID of the packet */
84 static int hf_knet_pingid;
85 static int hf_knet_flowctrlreq;
86 static int hf_knet_packetack;
87 static int hf_knet_seqnumber;
88 /**@}*/
90 /**
91 * @addtogroup trees Subtrees used by the dissectors
93 /* *@{*/
95 /*Knet Subtrees */
96 static int ett_knet_main; /*!< Main kNet tree */
97 static int ett_knet_message; /*!< Message tree */
98 static int ett_knet_payload; /*!< Payload tree */
99 static int ett_knet_message_flags; /*!< Message flags tree */
100 static int ett_knet_datagram;
101 static int ett_knet_flags;
102 /**@}*/
104 static dissector_handle_t knet_handle_sctp;
105 static dissector_handle_t knet_handle_tcp;
106 static dissector_handle_t knet_handle_udp;
108 static const value_string packettypenames[] = { /*!< Messageid List */
109 { PINGREQUEST, "Ping Request" },
110 { PINGREPLY, "Ping Reply" },
111 { FLOWCONTROLREQUEST, "Flowcontrol Request" },
112 { PACKETACK, "Packet Ack" },
113 { DISCONNECT, "Disconnect" },
114 { DISCONNECTACK, "Disconnect Ack" },
115 { CONNECTSYN, "Connect Syn" },
116 { CONNECTSYNACK, "Connect Syn Ack" },
117 { CONNECTACK, "Connect Ack" },
118 { 0, NULL }
122 * counts length of the variable length encoded field
124 * @param tvb the buffer to the data
125 * @param offset the offset of data in the buffer
126 * @return int returns number of bytes used
129 static int
130 count_vle_bytes(tvbuff_t *tvb, int offset)
132 int byte_count = 1;
134 if(tvb_get_uint8(tvb, offset) & 0x80) /* If the first bit of the first byte is 1 */
135 byte_count = 2; /* There's at least 2 bytes of content length */
136 if(tvb_get_uint8(tvb, offset+1) & 0x80) /* If the next one is also 1 */
137 byte_count = 4;
139 return byte_count;
143 * dissect_packetid is a utility function which calculates
144 * the packets Packet ID from the data. Packet ID is a field
145 * located in the datagram header.
147 * @see dissect_reliable_message_index_base()
148 * @see dissect_reliable_message_number()
149 * @see dissect_content_length()
150 * @see dissect_messageid()
151 * @see dissect_payload()
152 * @param buffer the buffer to the data
153 * @param offset the offset where to start reading the data
154 * @param tree the parent tree where the dissected data is going to be inserted
155 * @return int returns the new offset
158 static uint32_t
159 dissect_packetid(tvbuff_t *buffer, int offset, proto_tree *tree)
161 uint32_t packetid;
163 packetid = tvb_get_uint8(buffer, offset+2) << 14;
164 packetid += tvb_get_uint8(buffer, offset+1) << 6;
165 packetid += tvb_get_uint8(buffer, offset) & 63;
167 proto_tree_add_uint(tree, hf_knet_packetid, buffer, 0, 3, packetid);
168 return packetid;
172 * dissect_reliable_message_index_base is a utility function
173 * which calculates the packets RMIB if and only if the reliable
174 * flag is set to 1.
176 * @see dissect_packetid()
177 * @see dissect_content_length()
178 * @see dissect_reliable_message_number()
179 * @see dissect_messageid()
180 * @see dissect_payload()
181 * @param buffer the buffer to the data
182 * @param offset the offset where to start reading the data
183 * @param tree the parent tree where the dissected data is going to be inserted
184 * @return int returns the new offset
187 static int
188 dissect_reliable_message_index_base(tvbuff_t *buffer, int offset, proto_tree *tree)
190 int byte_count = 2;
192 if(tvb_get_uint8(buffer, offset+1) & 0x80)
193 byte_count = 4;
195 proto_tree_add_item(tree, hf_knet_rmib, buffer, offset, byte_count, ENC_LITTLE_ENDIAN);
197 return byte_count;
201 * dissect_content_length_vle is a utility function which
202 * calculates how long is the payload section of the message
203 * in bytes which is VLE encoded.
205 * @see dissect_packetid()
206 * @see dissect_reliable_message_index_base()
207 * @see dissect_reliable_message_number()
208 * @see dissect_messageid()
209 * @see dissect_payload()
210 * @param buffer the buffer to the data
211 * @param offset the offset where to start reading the data
212 * @param tree the parent tree where the dissected data is going to be inserted
213 * @return int returns the content length of the packet
216 static int
217 dissect_content_length_vle(tvbuff_t *buffer, int *offset, proto_tree *tree)
219 int byte_count;
220 uint32_t length;
222 length = 0;
223 byte_count = count_vle_bytes(buffer, *offset);
225 switch(byte_count) /*We must calculate length by hand because we use the length later */
227 case 4:
228 length = tvb_get_uint8(buffer, (*offset) + 3) << 23;
229 length += (tvb_get_uint8(buffer, (*offset) + 2) << 15);
230 /* FALLTHRU */
231 case 2:
232 length += (tvb_get_uint8(buffer, (*offset) + 1) << 7);
233 /* FALLTHRU */
234 case 1:
235 length += (tvb_get_uint8(buffer, (*offset)) & 0x7F);
236 break;
237 default:
238 REPORT_DISSECTOR_BUG("Error in Content Length calculation");
239 break;
242 proto_tree_add_uint(tree, hf_knet_content_length_vle, buffer, (*offset), byte_count, length);
243 (*offset) += byte_count;
245 return length;
249 * dissect_content_length is a utility function which
250 * calculates how long is the payload section of the message
251 * in bytes. Used only by the UDP dissector.
253 * @see dissect_packetid()
254 * @see dissect_reliable_message_index_base()
255 * @see dissect_reliable_message_number()
256 * @see dissect_messageid()
257 * @see dissect_payload()
258 * @param buffer the buffer to the data
259 * @param offset the offset where to start reading the data
260 * @param tree the parent tree where the dissected data is going to be inserted
261 * @return int returns the content length of the packet
264 static int
265 dissect_content_length(tvbuff_t *buffer, int offset, proto_tree *tree)
267 proto_item *msgflags_ti;
268 proto_tree *msgflags_tree;
269 uint32_t length;
271 length = tvb_get_bits8(buffer, offset * 8 + 12, 4) << 8;
272 length += tvb_get_bits8(buffer, offset * 8, 8);
274 if(tree != NULL)
276 msgflags_ti = proto_tree_add_item(tree, hf_knet_msg_flags, buffer, offset + 1, 1, ENC_NA);
277 msgflags_tree = proto_item_add_subtree(msgflags_ti, ett_knet_message_flags);
279 proto_tree_add_item(msgflags_tree, hf_knet_msg_fs, buffer, offset+1, 1, ENC_NA); /* Fragment start flag */
280 proto_tree_add_item(msgflags_tree, hf_knet_msg_ff, buffer, offset+1, 1, ENC_NA); /* Fragment flag */
281 proto_tree_add_item(msgflags_tree, hf_knet_msg_inorder, buffer, offset+1, 1, ENC_NA); /* Inorder flag */
282 proto_tree_add_item(msgflags_tree, hf_knet_msg_reliable, buffer, offset+1, 1, ENC_NA); /* Reliable flag */
284 proto_tree_add_uint(tree, hf_knet_content_length, buffer, offset, 2, length);
287 return length;
291 * dissect_reliable_message_number is a utility function which
292 * calculates the RMN if and only if the reliable flag in the
293 * message block is set to 1.
295 * @see dissect_packetid()
296 * @see dissect_reliable_message_index_base()
297 * @see dissect_content_length()
298 * @see dissect_messageid()
299 * @see dissect_payload()
300 * @param buffer the buffer to the data
301 * @param offset the offset where to start reading the data
302 * @param tree the parent tree where the dissected data is going to be inserted
303 * @return int returns the new offset
306 static int
307 dissect_reliable_message_number(tvbuff_t *buffer, int offset, proto_tree *tree)
309 int byte_count = 1;
311 if(tvb_get_uint8(buffer, offset) & 0x80)
312 byte_count = 2;
314 proto_tree_add_item(tree, hf_knet_msg_reliable_message_number, buffer, offset, byte_count, ENC_LITTLE_ENDIAN);
316 return byte_count;
320 * dissect_messageid is a utility function which
321 * calculates the ID of the message.
323 * @see dissect_packetid()
324 * @see dissect_reliable_message_index_base()
325 * @see dissect_content_length()
326 * @see dissect_reliable_message_number()
327 * @see dissect_payload()
328 * @param buffer the buffer to the data
329 * @param offset the offset where to start reading the data
330 * @param tree the parent tree where the dissected data is going to be inserted
331 * @return int returns the messageid
334 static int
335 dissect_messageid(tvbuff_t *buffer, int *offset, proto_tree *tree, packet_info *pinfo, bool separator)
337 int messageid_length;
338 uint8_t messageid;
340 messageid = tvb_get_uint8(buffer, (*offset));
342 switch(messageid)
344 case DISCONNECT:
345 case DISCONNECTACK:
346 case CONNECTSYN:
347 case CONNECTSYNACK:
348 case CONNECTACK:
349 messageid_length = 4;
350 break;
351 default:
352 messageid_length = 1;
353 break;
356 proto_tree_add_uint_format_value(tree, hf_knet_messageid, buffer, *offset, messageid_length, messageid,
357 "%s (%d)", val_to_str_const(messageid, packettypenames, "AppData or Malformed Message ID"), messageid);
359 if (separator)
361 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s (%d)", val_to_str_const(messageid, packettypenames, "AppData"), messageid);
363 else
365 col_append_fstr(pinfo->cinfo, COL_INFO, "%s (%d)", val_to_str_const(messageid, packettypenames, "AppData"), messageid);
368 *offset += messageid_length;
370 return messageid;
374 * dissect_payload is a utility function which
375 * calculates the actual payload of the message.
377 * @see dissect_packetid()
378 * @see dissect_reliable_message_index_base()
379 * @see dissect_content_length()
380 * @see dissect_reliable_message_number()
381 * @see dissect_messageid()
382 * @param buffer the buffer to the data
383 * @param offset the offset where to start reading the data
384 * @param messageid the messageid of the received message
385 * @param tree the parent tree where the dissected data is going to be inserted
386 * @param content_length the content length of the payload
387 * @return int returns 0 at the moment
390 static int
391 dissect_payload(tvbuff_t *buffer, int offset, int messageid, proto_tree *tree, int content_length)
393 proto_item *payload_ti;
394 proto_tree *payload_tree;
396 payload_ti = proto_tree_add_item(tree, hf_knet_payload_tree, buffer, offset, content_length - 1, ENC_NA);
397 payload_tree = proto_item_add_subtree(payload_ti, ett_knet_payload);
399 switch(messageid)
401 case PINGREQUEST:
402 case PINGREPLY:
403 proto_tree_add_item(payload_tree, hf_knet_pingid, buffer, offset, 1, ENC_LITTLE_ENDIAN);
404 break;
405 case FLOWCONTROLREQUEST:
406 proto_tree_add_item(payload_tree, hf_knet_flowctrlreq, buffer, offset, 3, ENC_LITTLE_ENDIAN);
407 break;
408 case PACKETACK:
409 proto_tree_add_item(payload_tree, hf_knet_packetack, buffer, offset, 3, ENC_LITTLE_ENDIAN);
410 offset += 3;
411 proto_tree_add_item(payload_tree, hf_knet_seqnumber, buffer, offset, 4, ENC_LITTLE_ENDIAN);
412 break;
413 case DISCONNECT: /*No payload*/
414 case DISCONNECTACK: /*No payload*/
415 proto_tree_add_bytes_format(payload_tree, hf_knet_payload, buffer, offset, 0, NULL, "No Payload");
416 break;
417 case CONNECTSYN: /*TODO: Not yet implemented, implement when available*/
418 case CONNECTSYNACK: /*TODO: Not yet implemented, implement when available*/
419 case CONNECTACK: /*TODO: Not yet implemented, implement when available*/
420 proto_tree_add_item(payload_tree, hf_knet_payload, buffer, offset, content_length-1, ENC_NA);
421 break;
422 default: /* Application Specific Message */
423 proto_tree_add_item(payload_tree, hf_knet_payload, buffer, offset, content_length-1, ENC_NA);
424 break;
427 return 0;
431 * dissect_knet_message is the subdissector which is called
432 * by dissect_knet when the dissector has dissected the
433 * datagram header. This subdissector dissects all of the
434 * messages which are encapsulated in the kNet datagram.
436 * @see dissect_knet()
437 * @param tvb the buffer to the data
438 * @param pinfo the packet info structure
439 * @param tree the parent tree where the dissected data is going to be inserted
442 static int
443 dissect_knet_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int messageindex)
445 int content_length, total_length, messageid;
446 int start_offset = offset;
448 proto_item *msgblock_ti;
449 proto_tree *msgblock_tree;
451 msgblock_ti = proto_tree_add_item(tree, hf_knet_message_tree, tvb, offset, -1, ENC_NA);
452 msgblock_tree = proto_item_add_subtree(msgblock_ti, ett_knet_message);
454 content_length = dissect_content_length(tvb, offset, msgblock_tree); /* Calculates the Content Length of this packet. */
456 if(tvb_get_uint8(tvb, offset+1) & UDP_MSG_BLOCK_RELIABLE_FLAG) /* If the reliable flag is 1 then calculate RMN */
457 offset += dissect_reliable_message_number(tvb, offset+2, msgblock_tree);
459 offset += 2; /* Move the offset the amount of contentlength and flags fields */
461 total_length = (offset-start_offset)+content_length;
462 proto_item_set_len(msgblock_ti, total_length);
464 messageid = dissect_messageid(tvb, &offset, msgblock_tree, pinfo, messageindex != 0);
466 dissect_payload(tvb, offset, messageid, msgblock_tree, content_length);
468 return total_length;
472 * dissect_knet is the dissector which is called
473 * by Wireshark when kNet packets are captured. Here
474 * is dissected the SCTP and TCP packets in its own
475 * section and UDP packets in its own, because UDP
476 * packets differ quite a lot from SCTP and TCP.
477 * SCTP and TCP in the other hand has quite the same
478 * structure.
480 * @param tvb the buffer to the data
481 * @param pinfo the packet info structure
482 * @param tree the parent tree where the dissected data is going to be inserted
485 static void
486 dissect_knet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int current_protocol)
488 proto_item *knet_ti, *message_ti;
489 proto_tree *knet_tree, *message_tree;
491 int offset = 0, content_length, messageid;
493 /* Attach kNet main tree to Wireshark tree */
494 knet_ti = proto_tree_add_item(tree, proto_knet, tvb, 0, -1, ENC_NA);
495 knet_tree = proto_item_add_subtree(knet_ti, ett_knet_main);
497 /* Attach message tree to kNet tree */
498 message_ti = proto_tree_add_item(knet_tree, hf_knet_message_tree, tvb, offset, -1, ENC_NA);
499 message_tree = proto_item_add_subtree(message_ti, ett_knet_message);
501 content_length = dissect_content_length_vle(tvb, &offset, message_tree); /* Calculate length and add it to the tree-view */
502 proto_item_set_len(message_ti, (current_protocol == KNET_SCTP_PACKET ? content_length + 1 : content_length + 2));
504 messageid = dissect_messageid(tvb, &offset, message_tree, pinfo, true); /* Calculate messageid and add it to the tree-view */
506 dissect_payload(tvb, offset, messageid, message_tree, content_length); /* Calculate payload and add it to the tree-view */
508 col_set_fence(pinfo->cinfo, COL_INFO);
512 * Callback function that returns the pdu length.
513 * Used by TCP dissector.
515 * @param pinfo the info about the packet
516 * @param tvb the data buffer
517 * @param offset the offset to the tvb buffer
518 * @return unsigned returns pdu length
521 static unsigned
522 get_knet_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
524 return count_vle_bytes(tvb, offset) + dissect_content_length_vle(tvb, &offset, NULL);
528 * dissect_knet_tcp is the dissector which is called
529 * by Wireshark when kNet TCP packets are captured.
531 * @param tvb the buffer to the data
532 * @param pinfo the packet info structure
533 * @param tree the parent tree where the dissected data is going to be inserted
536 static int
537 dissect_knet_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
539 dissect_knet(tvb, pinfo, tree, KNET_TCP_PACKET);
540 return tvb_captured_length(tvb);
543 static int
544 dissect_knet_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
546 //Sanity check the length field
547 if (tvb_reported_length(tvb) < 2)
548 return 0;
550 int offset = 0;
551 if (dissect_content_length_vle(tvb, &offset, NULL) == 0)
552 return 0;
554 col_clear(pinfo->cinfo, COL_INFO);
555 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KNET");
557 tcp_dissect_pdus(tvb, pinfo, tree, true, 2, get_knet_pdu_len, dissect_knet_tcp_pdu, data);
558 return tvb_captured_length(tvb);
562 * dissect_knet_sctp is the dissector which is called
563 * by Wireshark when kNet STCP packets are captured.
565 * @param tvb the buffer to the data
566 * @param pinfo the packet info structure
567 * @param tree the parent tree where the dissected data is going to be inserted
570 static int
571 dissect_knet_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
573 col_clear(pinfo->cinfo, COL_INFO);
574 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KNET");
576 dissect_knet(tvb, pinfo, tree, KNET_SCTP_PACKET);
577 return tvb_captured_length(tvb);
581 * dissect_knet_udp is the dissector which is called
582 * by Wireshark when kNet UDP packets are captured.
584 * @param tvb the buffer to the data
585 * @param pinfo the packet info structure
586 * @param tree the parent tree where the dissected data is going to be inserted
589 static int
590 dissect_knet_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
592 /* Common subtrees */
593 proto_item *knet_ti;
594 proto_tree *knet_tree;
596 /* Subtrees used in kNet UDP dissector */
597 proto_item *datagram_ti, *udpflags_ti;
598 proto_tree *datagram_tree, /* Tree containing all header related info */
599 *udpflags_tree; /* Tree containing UDP Datagram Flags */
601 int offset = 0;
602 uint32_t packetid; /* Contains info about PacketID */
603 int messageindex = 0; /*!< Index of the kNet message inside a datagram */
605 col_clear(pinfo->cinfo, COL_INFO);
606 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KNET");
608 /*kNet UDP Tree*/
609 knet_ti = proto_tree_add_item(tree, proto_knet, tvb, 0, -1, ENC_NA); /* Attach kNet tree to wireshark main tree */
610 knet_tree = proto_item_add_subtree(knet_ti, ett_knet_main);
612 /*Datagram Header Tree*/
613 datagram_ti = proto_tree_add_item(knet_ti, hf_knet_datagram_tree, tvb, 0, 3, ENC_NA); /* Attach Header tree to wireshark main tree */
614 datagram_tree = proto_item_add_subtree(datagram_ti, ett_knet_datagram);
616 packetid = dissect_packetid(tvb, 0, datagram_tree); /* Lets calculate our packetid! */
617 col_add_fstr(pinfo->cinfo, COL_INFO, "Packet ID %d: ", packetid);
619 /*UDPFlags Tree*/
620 udpflags_ti = proto_tree_add_item(datagram_ti, hf_knet_flags, tvb, 0, 1, ENC_NA); /* Attach UDP Flags tree to kNet tree */
621 udpflags_tree = proto_item_add_subtree(udpflags_ti, ett_knet_flags);
623 proto_tree_add_item(udpflags_tree, hf_knet_inorder, tvb, 0, 1, ENC_NA); /* Add inorder flag to UDP Flags tree */
624 proto_tree_add_item(udpflags_tree, hf_knet_reliable, tvb, 0, 1, ENC_NA); /* Add reliable flag to UDP Flags tree */
626 offset += 3;
628 if(tvb_get_uint8(tvb, 0) & UDP_DATAGRAM_RELIABLE_FLAG)
629 offset += dissect_reliable_message_index_base(tvb, 3, datagram_tree); /* Calculate RMIB */
631 while ((tvb_reported_length_remaining(tvb, offset) > 2) && /* If there's at least 2 bytes available in the buffer */
632 (dissect_content_length(tvb, offset, NULL) > 0)) /* Empty data Abort */
634 offset += dissect_knet_message(tvb, pinfo, knet_tree, offset, messageindex); /* Call the message subdissector */
635 messageindex++;
638 return tvb_captured_length(tvb);
641 * proto_register_knet registers our kNet protocol,
642 * headerfield- and subtree-array to Wireshark.
645 void
646 proto_register_knet(void)
648 /* module_t *knet_module; */
650 static hf_register_info hf_knet[] =
652 /* TCP & SCTP Header */
653 {&hf_knet_content_length_vle,
654 {"Content Length", "knet.length",
655 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
656 {&hf_knet_message_tree,
657 {"Message Block", "knet.msg",
658 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
660 /* UDP Header */
661 {&hf_knet_datagram_tree,
662 {"Datagram Header", "knet.datagram",
663 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
664 {&hf_knet_flags,
665 {"Flags", "knet.datagram.flags",
666 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
667 {&hf_knet_inorder,
668 {"Inorder Flag", "knet.datagram.inorder",
669 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
670 {&hf_knet_reliable,
671 {"Reliable Flag", "knet.datagram.reliable",
672 FT_BOOLEAN, 8, NULL, UDP_DATAGRAM_RELIABLE_FLAG, NULL, HFILL}},
673 {&hf_knet_packetid,
674 {"Packet ID", "knet.datagram.packetid",
675 FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}},
676 {&hf_knet_rmib,
677 {"Reliable Message Index Base", "knet.datagram.rmib",
678 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
679 {&hf_knet_msg_flags,
680 {"Flags", "knet.msg.flags",
681 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
682 {&hf_knet_msg_fs,
683 {"Fragment Start", "knet.msg.flags.fs",
684 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
685 {&hf_knet_msg_ff,
686 {"Fragment Flag", "knet.msg.flags.ff",
687 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
688 {&hf_knet_msg_inorder,
689 {"Inorder Flag", "knet.msg.flags.inorder",
690 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
691 {&hf_knet_msg_reliable,
692 {"Reliable Flag", "knet.msg.flags.reliable",
693 FT_BOOLEAN, 8, NULL, UDP_MSG_BLOCK_RELIABLE_FLAG, NULL, HFILL}},
694 {&hf_knet_content_length,
695 {"Content Length", "knet.length",
696 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
697 {&hf_knet_msg_reliable_message_number,
698 {"Reliable Message Number", "knet.msg.reliable_number",
699 FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}},
701 /* Payload */
702 {&hf_knet_payload_tree,
703 {"Payload", "knet.payload.tree",
704 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
705 {&hf_knet_payload,
706 {"Payload", "knet.payload.data",
707 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
708 {&hf_knet_messageid,
709 {"Message ID", "knet.payload.messageid",
710 FT_UINT32, BASE_DEC, VALS(packettypenames), 0x0, NULL, HFILL}},
711 {&hf_knet_pingid,
712 {"Ping ID", "knet.payload.pingid",
713 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
714 {&hf_knet_flowctrlreq,
715 {"Flowcontrol Request", "knet.payload.flowctrlreq",
716 FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}},
717 {&hf_knet_packetack,
718 {"Packet Ack", "knet.payload.packetack",
719 FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}},
720 {&hf_knet_seqnumber,
721 {"Sequence Number", "knet.payload.seqnumber",
722 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}
725 static int *ett_knet[] =
727 &ett_knet_main,
728 &ett_knet_datagram,
729 &ett_knet_flags,
730 &ett_knet_message,
731 &ett_knet_message_flags,
732 &ett_knet_payload
735 /* Register protocols */
736 proto_knet = proto_register_protocol ("kNet Protocol", "KNET", "knet");
738 /* Register header field & subtree arrays */
739 proto_register_field_array(proto_knet, hf_knet, array_length(hf_knet));
740 proto_register_subtree_array(ett_knet, array_length(ett_knet));
742 knet_handle_sctp = register_dissector("knetsctp", dissect_knet_sctp, proto_knet);
743 knet_handle_tcp = register_dissector("knettcp", dissect_knet_tcp, proto_knet);
744 knet_handle_udp = register_dissector("knetudp", dissect_knet_udp, proto_knet);
746 /* Prefs module added by Decode As */
747 /* knet_module = prefs_register_protocol(proto_knet, NULL); */
752 * proto_reg_handoff_knet registers our kNet dissectors to Wireshark
755 void
756 proto_reg_handoff_knet(void)
758 dissector_add_uint_with_preference("tcp.port", PORT, knet_handle_tcp);
759 dissector_add_uint_with_preference("udp.port", PORT, knet_handle_udp);
760 dissector_add_uint_with_preference("sctp.port", PORT, knet_handle_sctp);
763 * Editor modelines - https://www.wireshark.org/tools/modelines.html
765 * Local variables:
766 * c-basic-offset: 4
767 * tab-width: 8
768 * indent-tabs-mode: nil
769 * End:
771 * ex: set shiftwidth=4 tabstop=8 expandtab:
772 * :indentSize=4:tabSize=8:noTabs=true: