Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-hipercontracer.c
blob97614c74d0e8a051a3ba95c78263195bb02e4528
1 /* packet-hipercontracer.c
2 * Routines for the HiPerConTracer protocol
3 * https://www.uni-due.de/~be0001/hipercontracer/
5 * Copyright 2021 by Thomas Dreibholz <dreibh [AT] simula.no>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from README.developer
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/ipproto.h>
20 #include <epan/sctpppids.h>
21 #include <epan/stat_tap_ui.h>
24 void proto_register_hipercontracer(void);
25 void proto_reg_handoff_hipercontracer(void);
27 /* Initialize the protocol and registered fields */
28 static int proto_hipercontracer;
30 /* Initialize the subtree pointers */
31 static int ett_hipercontracer;
33 static int hf_magic_number;
34 static int hf_send_ttl;
35 static int hf_round;
36 static int hf_checksum_tweak;
37 static int hf_seq_number;
38 static int hf_send_timestamp;
40 /* Setup list of header fields */
41 static hf_register_info hf[] = {
42 { &hf_magic_number, { "Magic Number", "hipercontracer.magic_number", FT_UINT32, BASE_HEX, NULL, 0x0, "An identifier chosen by the sender upon startup", HFILL } },
43 { &hf_send_ttl, { "Send TTL", "hipercontracer.send_ttl", FT_UINT8, BASE_DEC, NULL, 0x0, "The IP TTL/IPv6 Hop Count used by the sender", HFILL } },
44 { &hf_round, { "Round", "hipercontracer.round", FT_UINT8, BASE_DEC, NULL, 0x0, "The round number the packet belongs to", HFILL } },
45 { &hf_checksum_tweak, { "Checksum Tweak", "hipercontracer.checksum_tweak", FT_UINT16, BASE_HEX, NULL, 0x0, "A 16-bit value to ensure a given checksum for the ICMP/ICMPv6 message", HFILL } },
46 { &hf_seq_number, { "Sequence Number", "hipercontracer.seq_number", FT_UINT16, BASE_DEC, NULL, 0x0, "A 16-bit sequence number", HFILL } },
47 { &hf_send_timestamp, { "Send Time Stamp", "hipercontracer.send_timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, "The send time stamp (microseconds since September 29, 1976, 00:00:00)", HFILL } }
51 static int
52 heur_dissect_hipercontracer(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
54 proto_item* hipercontracer_item;
55 proto_tree* hipercontracer_tree;
56 uint64_t timestamp;
57 nstime_t t;
59 // Check length
60 const unsigned length = tvb_captured_length(message_tvb);
61 if (length < 16)
62 return false;
64 const uint32_t magic = tvb_get_ntohl(message_tvb, 0);
66 // Send TTL cannot be < 1
67 const uint8_t sendTTL = tvb_get_uint8(message_tvb, 4);
68 if (sendTTL < 1)
69 return false;
71 const uint8_t round = tvb_get_uint8(message_tvb, 5);
73 const uint16_t checksumTweak = tvb_get_ntohs(message_tvb, 6);
75 uint64_t sendTimeStamp = tvb_get_ntoh64(message_tvb, 8);
78 * Don't dissect a SASL ldap message, which starts with the
79 * first 12 bytes like this:
81 * Length: 00000091 (very, very unlikely larger than 24bits).
82 * Magic: 0504 (KRB_TOKEN_CFX_WRAP)
83 * Flags: 04 (0x01, 0x02, 0x04 are defined)
84 * Filler: ff
85 * EC: 000c
86 * RRC: 0000 or 000c
88 if ((magic & 0xff000000) == 0 &&
89 (magic & 0x00ffffff) != 0 &&
90 sendTTL == 0x05 &&
91 round == 0x04 &&
92 (checksumTweak & 0xf8ff) == 0x00ff &&
93 (sendTimeStamp & UINT64_C(0xff00ff0000000000)) == 0)
94 return false;
96 // Check for plausible send time stamp:
97 // * After: 01.01.2016 00:00:00.000000
98 // * Before: 31.12.2099 23:59.59.999999
99 // Time stamp is microseconds since 29.09.1976 00:00:00.000000.
100 sendTimeStamp += UINT64_C(212803200000000);
101 if ( (sendTimeStamp < UINT64_C(1451602800000000)) ||
102 (sendTimeStamp > UINT64_C(4102441199999999)) )
103 return false;
105 col_append_sep_fstr(pinfo->cinfo, COL_PROTOCOL, NULL, "HiPerConTracer");
107 // Create the HiPerConTracer protocol tree
108 hipercontracer_item = proto_tree_add_item(tree, proto_hipercontracer, message_tvb, 0, -1, ENC_NA);
109 hipercontracer_tree = proto_item_add_subtree(hipercontracer_item, ett_hipercontracer);
111 // Dissect the message
112 proto_tree_add_item(hipercontracer_tree, hf_magic_number, message_tvb, 0, 4, ENC_BIG_ENDIAN);
113 proto_tree_add_item(hipercontracer_tree, hf_send_ttl, message_tvb, 4, 1, ENC_BIG_ENDIAN);
114 proto_tree_add_item(hipercontracer_tree, hf_round, message_tvb, 5, 1, ENC_BIG_ENDIAN);
115 if (pinfo->ptype == PT_NONE) {
116 // ICMP or ICMPv6 do not have ports -> Checksum Tweak field
117 proto_tree_add_item(hipercontracer_tree, hf_checksum_tweak, message_tvb, 6, 2, ENC_BIG_ENDIAN);
119 else {
120 // Otherwise, there are ports -> Sequence Number field
121 proto_tree_add_item(hipercontracer_tree, hf_seq_number, message_tvb, 6, 2, ENC_BIG_ENDIAN);
124 // Time stamp is microseconds since 29.09.1976 00:00:00.000000.
125 timestamp = tvb_get_ntoh64(message_tvb, 8) + UINT64_C(212803200000000);
126 t.secs = (time_t)(timestamp / 1000000);
127 t.nsecs = (int)((timestamp - 1000000 * t.secs) * 1000);
128 proto_tree_add_time(hipercontracer_tree, hf_send_timestamp, message_tvb, 8, 8, &t);
130 col_append_fstr(pinfo->cinfo, COL_INFO, " (SendTTL=%u, Round=%u)",
131 (unsigned int)tvb_get_uint8(message_tvb, 4),
132 (unsigned int)tvb_get_uint8(message_tvb, 5));
134 return tvb_reported_length(message_tvb);
137 static bool
138 heur_dissect_hipercontracer_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
140 return heur_dissect_hipercontracer(tvb, pinfo, tree, data) > 0;
143 /* Register the protocol with Wireshark */
144 void
145 proto_register_hipercontracer(void)
147 /* Setup protocol subtree array */
148 static int *ett[] = {
149 &ett_hipercontracer
152 /* Register the protocol name and description */
153 proto_hipercontracer = proto_register_protocol("HiPerConTracer Trace Service", "HiPerConTracer", "hipercontracer");
155 /* Required function calls to register the header fields and subtrees used */
156 proto_register_field_array(proto_hipercontracer, hf, array_length(hf));
157 proto_register_subtree_array(ett, array_length(ett));
159 register_dissector("hipercontracer", heur_dissect_hipercontracer, proto_hipercontracer);
162 void
163 proto_reg_handoff_hipercontracer(void)
165 /* Heuristic dissector for ICMP/ICMPv6 */
166 heur_dissector_add("icmp", heur_dissect_hipercontracer_heur, "HiPerConTracer over ICMP", "hipercontracer_icmp", proto_hipercontracer, HEURISTIC_ENABLE);
167 heur_dissector_add("icmpv6", heur_dissect_hipercontracer_heur, "HiPerConTracer over ICMPv6", "hipercontracer_icmpv6", proto_hipercontracer, HEURISTIC_ENABLE);
168 heur_dissector_add("udp", heur_dissect_hipercontracer_heur, "HiPerConTracer over UDP", "hipercontracer_udp", proto_hipercontracer, HEURISTIC_ENABLE);
169 heur_dissector_add("tcp", heur_dissect_hipercontracer_heur, "HiPerConTracer over TCP", "hipercontracer_tcp", proto_hipercontracer, HEURISTIC_ENABLE);
173 * Editor modelines
175 * Local Variables:
176 * c-basic-offset: 2
177 * tab-width: 8
178 * indent-tabs-mode: nil
179 * End:
181 * ex: set shiftwidth=2 tabstop=8 expandtab:
182 * :indentSize=2:tabSize=8:noTabs=true: