1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
/* packet-uhd.c
* Routines for UHD captures
*
* (C) 2013 by Klyuchnikov Ivan <kluchnikovi@gmail.com>, Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/*
* Original dissector can be found here
* https://github.com/chemeris/uhd_dissector
*/
#include "config.h"
#include <epan/packet.h>
void proto_register_uhd(void);
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
#define USRP2_CTRL_ID_HUH_WHAT 0x20 /* ' ' */
#define UMTRX_CTRL_ID_REQUEST 0x75 /* 'u' */
#define UMTRX_CTRL_ID_RESPONSE 0x55 /* 'U' */
#define USRP2_CTRL_ID_WAZZUP_BRO 0x61 /* 'a' */
#define USRP2_CTRL_ID_WAZZUP_DUDE 0x41 /* 'A' */
#define USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO 0x73 /* 's' */
#define USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE 0x53 /* 'S' */
#define USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO 0x69 /* 'i' */
#define USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE 0x49 /* 'I' */
#define USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO 0x68 /* 'h' */
#define USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE 0x48 /* 'H' */
#define USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO 0x72 /* 'r' */
#define USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE 0x52 /* 'R' */
#define USRP2_CTRL_ID_HOLLER_AT_ME_BRO 0x6c /* 'l' */
#define USRP2_CTRL_ID_HOLLER_BACK_DUDE 0x4c /* 'L' */
#define USRP2_CTRL_ID_PEACE_OUT 0x7e /* '~' */
#define USRP2_REG_ACTION_FPGA_PEEK32 1
#define USRP2_REG_ACTION_FPGA_PEEK16 2
#define USRP2_REG_ACTION_FPGA_POKE32 3
#define USRP2_REG_ACTION_FPGA_POKE16 4
#define USRP2_REG_ACTION_FW_PEEK32 5
#define USRP2_REG_ACTION_FW_POKE32 6
#define UHD_UDP_PORT 49152
/* This is the header as it is used by uhd-generating software.
* It is not used by the wireshark dissector and provided for reference only.
typedef struct{
uint32_t proto_ver;
uint32_t id;
uint32_t seq;
union{
uint32_t ip_addr;
struct {
uint32_t dev;
uint32_t data;
uint8_t miso_edge;
uint8_t mosi_edge;
uint8_t num_bits;
uint8_t readback;
} spi_args;
struct {
uint8_t addr;
uint8_t bytes;
uint8_t data[20];
} i2c_args;
struct {
uint32_t addr;
uint32_t data;
uint8_t action;
} reg_args;
struct {
uint32_t len;
} echo_args;
} data;
} usrp2_ctrl_data_t;
*/
static int proto_uhd = -1;
static int hf_uhd_version = -1;
static int hf_uhd_id = -1;
static int hf_uhd_seq = -1;
static int hf_uhd_ip_addr = -1;
static int hf_uhd_i2c_addr = -1;
static int hf_uhd_i2c_bytes = -1;
static int hf_uhd_i2c_data = -1;
static int hf_uhd_spi_dev = -1;
static int hf_uhd_spi_data = -1;
static int hf_uhd_spi_miso_edge = -1;
static int hf_uhd_spi_mosi_edge = -1;
static int hf_uhd_spi_num_bits = -1;
static int hf_uhd_spi_readback = -1;
static int hf_uhd_reg_addr = -1;
static int hf_uhd_reg_data = -1;
static int hf_uhd_reg_action = -1;
static int hf_uhd_echo_len = -1;
static gint ett_uhd = -1;
static const value_string uhd_ids[] = {
{ USRP2_CTRL_ID_HUH_WHAT, "HUH WHAT" },
{ UMTRX_CTRL_ID_REQUEST, "UMTRX REQUEST" },
{ UMTRX_CTRL_ID_RESPONSE, "UMTRX RESPONSE" },
{ USRP2_CTRL_ID_WAZZUP_BRO, "WAZZUP BRO" },
{ USRP2_CTRL_ID_WAZZUP_DUDE, "WAZZUP DUDE" },
{ USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO, "TRANSACT ME SOME SPI BRO" },
{ USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE, "OMG TRANSACTED SPI DUDE" },
{ USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO, "DO AN I2C READ FOR ME BRO" },
{ USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE, "HERES THE I2C DATA DUDE" },
{ USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO, "WRITE THESE I2C VALUES BRO" },
{ USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE, "COOL IM DONE I2C WRITE DUDE" },
{ USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO, "GET THIS REGISTER FOR ME BRO" },
{ USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE, "OMG GOT REGISTER SO BAD DUDE" },
{ USRP2_CTRL_ID_HOLLER_AT_ME_BRO, "HOLLER AT ME BRO" },
{ USRP2_CTRL_ID_HOLLER_BACK_DUDE, "HOLLER BACK DUDE" },
{ USRP2_CTRL_ID_PEACE_OUT, "PEACE OUT" },
{ 0, NULL }
};
static const value_string uhd_reg_actions[] = {
{ USRP2_REG_ACTION_FPGA_PEEK32, "FPGA PEEK32" },
{ USRP2_REG_ACTION_FPGA_PEEK16, "FPGA PEEK16" },
{ USRP2_REG_ACTION_FPGA_POKE32, "FPGA POKE32" },
{ USRP2_REG_ACTION_FPGA_POKE16, "FPGA POKE16" },
{ USRP2_REG_ACTION_FW_PEEK32, "FW PEEK32" },
{ USRP2_REG_ACTION_FW_POKE32, "FW POKE32" },
{ 0, NULL }
};
void proto_reg_handoff_uhd(void);
static dissector_handle_t uhd_handle;
/* dissect a UHD header and hand payload off to respective dissector */
static int
dissect_uhd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
int ind;
proto_item *ti;
proto_tree *uhd_tree;
guint32 id;
guint8 i2c_bytes;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "UHD");
col_clear(pinfo->cinfo, COL_INFO);
id = tvb_get_ntohl(tvb, 4);
col_add_str(pinfo->cinfo, COL_INFO, val_to_str(id, uhd_ids, "Unknown UHD message type '%c'"));
if (tree == NULL)
return tvb_captured_length(tvb);
ti = proto_tree_add_protocol_format(tree, proto_uhd, tvb, 0, 34, "UHD id = %c ", id);
uhd_tree = proto_item_add_subtree(ti, ett_uhd);
proto_tree_add_item(uhd_tree, hf_uhd_version, tvb, 0, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_id, tvb, 4, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_seq, tvb, 8, 4, ENC_BIG_ENDIAN);
switch (id) {
case UMTRX_CTRL_ID_REQUEST:
case UMTRX_CTRL_ID_RESPONSE:
case USRP2_CTRL_ID_WAZZUP_BRO:
case USRP2_CTRL_ID_WAZZUP_DUDE:
proto_tree_add_item(uhd_tree, hf_uhd_ip_addr, tvb, 12, 4, ENC_BIG_ENDIAN);
break;
case USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO:
case USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE:
proto_tree_add_item(uhd_tree, hf_uhd_spi_dev, tvb, 12, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_spi_data, tvb, 16, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_spi_miso_edge, tvb, 20, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_spi_mosi_edge, tvb, 21, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_spi_num_bits, tvb, 22, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_spi_readback, tvb, 23, 1, ENC_BIG_ENDIAN);
break;
case USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO:
case USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE:
case USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO:
case USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE:
proto_tree_add_item(uhd_tree, hf_uhd_i2c_addr, tvb, 12, 1, ENC_BIG_ENDIAN);
i2c_bytes = tvb_get_guint8(tvb, 13);
proto_tree_add_item(uhd_tree, hf_uhd_i2c_bytes, tvb, 13, 1, ENC_BIG_ENDIAN);
for (ind = 0; ind < i2c_bytes; ind++) {
proto_tree_add_item(uhd_tree, hf_uhd_i2c_data, tvb, 14 + ind, 1, ENC_BIG_ENDIAN);
}
break;
case USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO:
case USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE:
proto_tree_add_item(uhd_tree, hf_uhd_reg_addr, tvb, 12, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_reg_data, tvb, 16, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(uhd_tree, hf_uhd_reg_action, tvb, 20, 1, ENC_BIG_ENDIAN);
break;
case USRP2_CTRL_ID_HOLLER_AT_ME_BRO:
case USRP2_CTRL_ID_HOLLER_BACK_DUDE:
case USRP2_CTRL_ID_HUH_WHAT:
case USRP2_CTRL_ID_PEACE_OUT:
proto_tree_add_item(uhd_tree, hf_uhd_echo_len, tvb, 12, 4, ENC_BIG_ENDIAN);
break;
}
return tvb_captured_length(tvb);
}
void
proto_register_uhd(void)
{
static hf_register_info hf[] = {
{ &hf_uhd_version, { "VERSION", "uhd.version",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
{ &hf_uhd_id, { "ID", "uhd.id",
FT_UINT32, BASE_HEX, VALS(uhd_ids), 0, NULL, HFILL } },
{ &hf_uhd_seq, { "SEQ", "uhd.seq",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
{ &hf_uhd_ip_addr, { "IP ADDR", "uhd.ip_addr",
FT_IPv4, BASE_NONE, NULL, 0x0,"", HFILL } },
{ &hf_uhd_i2c_addr, { "I2C ADDR", "uhd.i2c_addr",
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_i2c_bytes, { "I2C BYTES", "uhd.i2c_bytes",
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
{ &hf_uhd_i2c_data, { "I2C DATA", "uhd.i2c_data",
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_dev, { "SPI DEV", "uhd.spi_dev",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_data, { "SPI DATA", "uhd.spi_data",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_miso_edge, { "SPI MISO EDGE", "uhd.spi_miso_edge",
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_mosi_edge, { "SPI MOSI EDGE", "uhd.spi_mosi_edge",
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_num_bits, { "SPI NUM BITS", "uhd.spi_num_bits",
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
{ &hf_uhd_spi_readback, { "SPI READBACK", "uhd.spi_readback",
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_reg_addr, { "REG ADDR", "uhd.reg_addr",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_reg_data, { "REG DATA", "uhd.reg_data",
FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
{ &hf_uhd_reg_action, { "REG ACTION", "uhd.reg_action",
FT_UINT8, BASE_HEX, VALS(uhd_reg_actions), 0, NULL, HFILL } },
{ &hf_uhd_echo_len, { "ECHO LEN", "uhd.echo_len",
FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
};
static gint *ett[] = {
&ett_uhd
};
proto_uhd = proto_register_protocol("UHD", "UHD", "uhd");
proto_register_field_array(proto_uhd, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
uhd_handle = register_dissector("uhd", dissect_uhd, proto_uhd);
}
void
proto_reg_handoff_uhd(void)
{
dissector_add_for_decode_as_with_preference("udp.port", uhd_handle);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/
|