Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gdb.c
blob95d9519f07a8f07a69ff1c99b159e919f4b291e1
1 /* packet-gdb.c
2 * Routines for dissection of GDB's Remote Serial Protocol
4 * Copyright 2014, Martin Kaiser <martin@kaiser.cx>
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
14 * The GDB Remote Serial Protocol is used between an instance of the
15 * GNU Debugger and a remote target such as an embedded system.
16 * It can be run over TCP/IP or a serial line, we support only TCP/IP.
18 * The protocol specification is in Annex E of the GDB user manual
19 * http://www.gnu.org/software/gdb/documentation/
23 #include "config.h"
25 #include <epan/packet.h>
26 #include <epan/tvbparse.h>
28 enum {
29 GDB_TOK_ACK,
30 GDB_TOK_START,
31 GDB_TOK_PAYLOAD,
32 GDB_TOK_END,
33 GDB_TOK_CHKSUM
36 static const value_string gdb_ack[] = {
37 { '+', "Transmission successful" },
38 { '-', "Transmission failed" },
39 { 0, NULL }
43 void proto_register_gdb(void);
44 void proto_reg_handoff_gdb(void);
46 static dissector_handle_t gdb_handle;
48 static int proto_gdb;
50 static int ett_gdb;
52 static int hf_gdb_ack;
53 static int hf_gdb_start;
54 static int hf_gdb_payload;
55 static int hf_gdb_end;
56 static int hf_gdb_chksum;
58 static tvbparse_wanted_t *want;
60 static void
61 dissect_gdb_token(void *tvbparse_data, const void *wanted_data, tvbparse_elem_t *tok)
63 proto_tree *tree;
64 unsigned token;
66 if (!tok) /* XXX - is this check necessary? */
67 return;
69 tree = (proto_tree *)tvbparse_data;
70 token = GPOINTER_TO_UINT(wanted_data);
72 /* XXX - check that tok->len is what we expect? */
73 switch (token) {
74 case GDB_TOK_ACK:
75 proto_tree_add_item(tree, hf_gdb_ack,
76 tok->tvb, tok->offset, tok->len, ENC_ASCII|ENC_NA);
77 break;
78 case GDB_TOK_START:
79 proto_tree_add_item(tree, hf_gdb_start,
80 tok->tvb, tok->offset, tok->len, ENC_ASCII);
81 break;
82 case GDB_TOK_PAYLOAD:
83 proto_tree_add_item(tree, hf_gdb_payload,
84 tok->tvb, tok->offset, tok->len, ENC_NA);
85 break;
86 case GDB_TOK_END:
87 proto_tree_add_item(tree, hf_gdb_end,
88 tok->tvb, tok->offset, tok->len, ENC_ASCII);
89 break;
90 case GDB_TOK_CHKSUM:
91 proto_tree_add_item(tree, hf_gdb_chksum,
92 tok->tvb, tok->offset, tok->len, ENC_ASCII);
93 break;
94 default:
95 break;
99 static void init_gdb_parser(void) {
100 tvbparse_wanted_t *want_ack;
101 tvbparse_wanted_t *want_start;
102 tvbparse_wanted_t *want_payload;
103 tvbparse_wanted_t *want_end;
104 tvbparse_wanted_t *want_chksum;
106 want_ack = tvbparse_chars(-1, 1, 1, "+-",
107 GUINT_TO_POINTER(GDB_TOK_ACK), NULL, dissect_gdb_token);
108 want_start = tvbparse_chars(-1, 1, 1, "$",
109 GUINT_TO_POINTER(GDB_TOK_START), NULL, dissect_gdb_token);
110 want_payload = tvbparse_not_chars(-1, 1, 0, "$#",
111 GUINT_TO_POINTER(GDB_TOK_PAYLOAD), NULL, dissect_gdb_token);
112 want_end = tvbparse_chars(-1, 1, 1, "#",
113 GUINT_TO_POINTER(GDB_TOK_END), NULL, dissect_gdb_token);
114 want_chksum = tvbparse_chars(-1, 2, 2, "0123456789abcdefABCDEF",
115 GUINT_TO_POINTER(GDB_TOK_CHKSUM), NULL, dissect_gdb_token);
117 want = tvbparse_set_seq(-1, NULL, NULL, NULL,
118 tvbparse_some(-1, 0, 1, NULL, NULL, NULL, want_ack),
119 want_start, want_payload, want_end, want_chksum, NULL);
123 static void
124 dissect_gdb_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
126 proto_item *ti;
127 proto_tree *gdb_tree;
128 tvbparse_t *tt;
130 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GDB");
131 col_clear(pinfo->cinfo, COL_INFO);
133 ti = proto_tree_add_protocol_format(tree, proto_gdb,
134 tvb, 0, tvb_reported_length(tvb), "GDB Remote Serial Protocol");
135 gdb_tree = proto_item_add_subtree(ti, ett_gdb);
137 /* XXX support multiple sub-trees */
138 tt = tvbparse_init(pinfo->pool, tvb, 0, -1, (void *)gdb_tree, NULL);
140 while(tvbparse_get(tt, want)) {
146 static int
147 dissect_gdb_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
149 int offset=0, offset_start;
150 int pos;
151 unsigned packet_len;
152 tvbuff_t *packet_tvb;
154 while (tvb_captured_length_remaining(tvb, offset) > 0) {
155 packet_tvb = NULL;
156 offset_start = offset;
157 pos = tvb_find_uint8(tvb, offset, -1, '#');
158 if (pos != -1) {
159 offset += pos;
160 offset++; /* skip the hash sign */
161 /* to have a complete packet, we need another two bytes
162 for the checksum */
163 if (tvb_bytes_exist(tvb, offset, 2)) {
164 offset += 2;
165 packet_len = offset-offset_start;
166 packet_tvb = tvb_new_subset_length(tvb, offset_start,
167 packet_len);
171 if (packet_tvb)
172 dissect_gdb_packet(tvb, pinfo, tree);
173 else {
174 pinfo->desegment_offset = offset;
175 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
176 return tvb_captured_length(tvb);
179 return tvb_captured_length(tvb);
183 void
184 proto_register_gdb(void)
186 static hf_register_info hf[] = {
187 { &hf_gdb_ack,
188 { "Acknowledge", "gdb.ack", FT_CHAR, BASE_HEX,
189 VALS(gdb_ack), 0, NULL, HFILL } },
190 { &hf_gdb_start,
191 { "Start character", "gdb.start", FT_STRING, BASE_NONE,
192 NULL, 0, NULL, HFILL } },
193 { &hf_gdb_payload,
194 { "Payload", "gdb.payload", FT_BYTES, BASE_NONE,
195 NULL, 0, NULL, HFILL } },
196 { &hf_gdb_end,
197 { "Terminating character", "gdb.end", FT_STRING, BASE_NONE,
198 NULL, 0, NULL, HFILL } },
199 { &hf_gdb_chksum,
200 { "Checksum", "gdb.chksum", FT_STRING, BASE_NONE,
201 NULL, 0, NULL, HFILL } }
204 static int *ett[] = {
205 &ett_gdb
209 proto_gdb = proto_register_protocol("GDB Remote Serial Protocol", "GDB remote", "gdb");
210 gdb_handle = register_dissector("gdb", dissect_gdb_tcp, proto_gdb);
212 proto_register_field_array(proto_gdb, hf, array_length(hf));
213 proto_register_subtree_array(ett, array_length(ett));
215 init_gdb_parser();
219 void
220 proto_reg_handoff_gdb(void)
222 dissector_add_for_decode_as_with_preference("tcp.port", gdb_handle);
226 * Editor modelines - https://www.wireshark.org/tools/modelines.html
228 * Local variables:
229 * c-basic-offset: 4
230 * tab-width: 8
231 * indent-tabs-mode: nil
232 * End:
234 * vi: set shiftwidth=4 tabstop=8 expandtab:
235 * :indentSize=4:tabSize=8:noTabs=true: