2 * Routines for UHD captures
4 * (C) 2013 by Klyuchnikov Ivan <kluchnikovi@gmail.com>, Dario Lombardo <lomato@gmail.com>
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 * Original dissector can be found here
15 * https://github.com/chemeris/uhd_dissector
21 #include <epan/packet.h>
23 void proto_register_uhd(void);
25 /* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
27 #define USRP2_CTRL_ID_HUH_WHAT 0x20 /* ' ' */
28 #define UMTRX_CTRL_ID_REQUEST 0x75 /* 'u' */
29 #define UMTRX_CTRL_ID_RESPONSE 0x55 /* 'U' */
30 #define USRP2_CTRL_ID_WAZZUP_BRO 0x61 /* 'a' */
31 #define USRP2_CTRL_ID_WAZZUP_DUDE 0x41 /* 'A' */
32 #define USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO 0x73 /* 's' */
33 #define USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE 0x53 /* 'S' */
34 #define USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO 0x69 /* 'i' */
35 #define USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE 0x49 /* 'I' */
36 #define USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO 0x68 /* 'h' */
37 #define USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE 0x48 /* 'H' */
38 #define USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO 0x72 /* 'r' */
39 #define USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE 0x52 /* 'R' */
40 #define USRP2_CTRL_ID_HOLLER_AT_ME_BRO 0x6c /* 'l' */
41 #define USRP2_CTRL_ID_HOLLER_BACK_DUDE 0x4c /* 'L' */
42 #define USRP2_CTRL_ID_PEACE_OUT 0x7e /* '~' */
44 #define USRP2_REG_ACTION_FPGA_PEEK32 1
45 #define USRP2_REG_ACTION_FPGA_PEEK16 2
46 #define USRP2_REG_ACTION_FPGA_POKE32 3
47 #define USRP2_REG_ACTION_FPGA_POKE16 4
48 #define USRP2_REG_ACTION_FW_PEEK32 5
49 #define USRP2_REG_ACTION_FW_POKE32 6
51 #define UHD_UDP_PORT 49152
53 /* This is the header as it is used by uhd-generating software.
54 * It is not used by the wireshark dissector and provided for reference only.
88 static int hf_uhd_version
;
90 static int hf_uhd_seq
;
91 static int hf_uhd_ip_addr
;
92 static int hf_uhd_i2c_addr
;
93 static int hf_uhd_i2c_bytes
;
94 static int hf_uhd_i2c_data
;
95 static int hf_uhd_spi_dev
;
96 static int hf_uhd_spi_data
;
97 static int hf_uhd_spi_miso_edge
;
98 static int hf_uhd_spi_mosi_edge
;
99 static int hf_uhd_spi_num_bits
;
100 static int hf_uhd_spi_readback
;
101 static int hf_uhd_reg_addr
;
102 static int hf_uhd_reg_data
;
103 static int hf_uhd_reg_action
;
104 static int hf_uhd_echo_len
;
110 static const value_string uhd_ids
[] = {
111 { USRP2_CTRL_ID_HUH_WHAT
, "HUH WHAT" },
112 { UMTRX_CTRL_ID_REQUEST
, "UMTRX REQUEST" },
113 { UMTRX_CTRL_ID_RESPONSE
, "UMTRX RESPONSE" },
114 { USRP2_CTRL_ID_WAZZUP_BRO
, "WAZZUP BRO" },
115 { USRP2_CTRL_ID_WAZZUP_DUDE
, "WAZZUP DUDE" },
116 { USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO
, "TRANSACT ME SOME SPI BRO" },
117 { USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE
, "OMG TRANSACTED SPI DUDE" },
118 { USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO
, "DO AN I2C READ FOR ME BRO" },
119 { USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE
, "HERES THE I2C DATA DUDE" },
120 { USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO
, "WRITE THESE I2C VALUES BRO" },
121 { USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE
, "COOL IM DONE I2C WRITE DUDE" },
122 { USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO
, "GET THIS REGISTER FOR ME BRO" },
123 { USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE
, "OMG GOT REGISTER SO BAD DUDE" },
124 { USRP2_CTRL_ID_HOLLER_AT_ME_BRO
, "HOLLER AT ME BRO" },
125 { USRP2_CTRL_ID_HOLLER_BACK_DUDE
, "HOLLER BACK DUDE" },
126 { USRP2_CTRL_ID_PEACE_OUT
, "PEACE OUT" },
130 static const value_string uhd_reg_actions
[] = {
131 { USRP2_REG_ACTION_FPGA_PEEK32
, "FPGA PEEK32" },
132 { USRP2_REG_ACTION_FPGA_PEEK16
, "FPGA PEEK16" },
133 { USRP2_REG_ACTION_FPGA_POKE32
, "FPGA POKE32" },
134 { USRP2_REG_ACTION_FPGA_POKE16
, "FPGA POKE16" },
135 { USRP2_REG_ACTION_FW_PEEK32
, "FW PEEK32" },
136 { USRP2_REG_ACTION_FW_POKE32
, "FW POKE32" },
140 void proto_reg_handoff_uhd(void);
142 static dissector_handle_t uhd_handle
;
144 /* dissect a UHD header and hand payload off to respective dissector */
146 dissect_uhd(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
150 proto_tree
*uhd_tree
;
154 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "UHD");
155 col_clear(pinfo
->cinfo
, COL_INFO
);
157 id
= tvb_get_ntohl(tvb
, 4);
159 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(id
, uhd_ids
, "Unknown UHD message type '%c'"));
162 return tvb_captured_length(tvb
);
164 ti
= proto_tree_add_protocol_format(tree
, proto_uhd
, tvb
, 0, 34, "UHD id = %c ", id
);
165 uhd_tree
= proto_item_add_subtree(ti
, ett_uhd
);
167 proto_tree_add_item(uhd_tree
, hf_uhd_version
, tvb
, 0, 4, ENC_BIG_ENDIAN
);
168 proto_tree_add_item(uhd_tree
, hf_uhd_id
, tvb
, 4, 4, ENC_BIG_ENDIAN
);
169 proto_tree_add_item(uhd_tree
, hf_uhd_seq
, tvb
, 8, 4, ENC_BIG_ENDIAN
);
172 case UMTRX_CTRL_ID_REQUEST
:
173 case UMTRX_CTRL_ID_RESPONSE
:
174 case USRP2_CTRL_ID_WAZZUP_BRO
:
175 case USRP2_CTRL_ID_WAZZUP_DUDE
:
176 proto_tree_add_item(uhd_tree
, hf_uhd_ip_addr
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
178 case USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO
:
179 case USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE
:
180 proto_tree_add_item(uhd_tree
, hf_uhd_spi_dev
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
181 proto_tree_add_item(uhd_tree
, hf_uhd_spi_data
, tvb
, 16, 4, ENC_BIG_ENDIAN
);
182 proto_tree_add_item(uhd_tree
, hf_uhd_spi_miso_edge
, tvb
, 20, 1, ENC_BIG_ENDIAN
);
183 proto_tree_add_item(uhd_tree
, hf_uhd_spi_mosi_edge
, tvb
, 21, 1, ENC_BIG_ENDIAN
);
184 proto_tree_add_item(uhd_tree
, hf_uhd_spi_num_bits
, tvb
, 22, 1, ENC_BIG_ENDIAN
);
185 proto_tree_add_item(uhd_tree
, hf_uhd_spi_readback
, tvb
, 23, 1, ENC_BIG_ENDIAN
);
187 case USRP2_CTRL_ID_DO_AN_I2C_READ_FOR_ME_BRO
:
188 case USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE
:
189 case USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO
:
190 case USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE
:
191 proto_tree_add_item(uhd_tree
, hf_uhd_i2c_addr
, tvb
, 12, 1, ENC_BIG_ENDIAN
);
192 i2c_bytes
= tvb_get_uint8(tvb
, 13);
193 proto_tree_add_item(uhd_tree
, hf_uhd_i2c_bytes
, tvb
, 13, 1, ENC_BIG_ENDIAN
);
194 for (ind
= 0; ind
< i2c_bytes
; ind
++) {
195 proto_tree_add_item(uhd_tree
, hf_uhd_i2c_data
, tvb
, 14 + ind
, 1, ENC_BIG_ENDIAN
);
198 case USRP2_CTRL_ID_GET_THIS_REGISTER_FOR_ME_BRO
:
199 case USRP2_CTRL_ID_OMG_GOT_REGISTER_SO_BAD_DUDE
:
200 proto_tree_add_item(uhd_tree
, hf_uhd_reg_addr
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
201 proto_tree_add_item(uhd_tree
, hf_uhd_reg_data
, tvb
, 16, 4, ENC_BIG_ENDIAN
);
202 proto_tree_add_item(uhd_tree
, hf_uhd_reg_action
, tvb
, 20, 1, ENC_BIG_ENDIAN
);
204 case USRP2_CTRL_ID_HOLLER_AT_ME_BRO
:
205 case USRP2_CTRL_ID_HOLLER_BACK_DUDE
:
206 case USRP2_CTRL_ID_HUH_WHAT
:
207 case USRP2_CTRL_ID_PEACE_OUT
:
208 proto_tree_add_item(uhd_tree
, hf_uhd_echo_len
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
211 return tvb_captured_length(tvb
);
215 proto_register_uhd(void)
217 static hf_register_info hf
[] = {
218 { &hf_uhd_version
, { "VERSION", "uhd.version",
219 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
220 { &hf_uhd_id
, { "ID", "uhd.id",
221 FT_UINT32
, BASE_HEX
, VALS(uhd_ids
), 0, NULL
, HFILL
} },
222 { &hf_uhd_seq
, { "SEQ", "uhd.seq",
223 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
224 { &hf_uhd_ip_addr
, { "IP ADDR", "uhd.ip_addr",
225 FT_IPv4
, BASE_NONE
, NULL
, 0x0,"", HFILL
} },
226 { &hf_uhd_i2c_addr
, { "I2C ADDR", "uhd.i2c_addr",
227 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
228 { &hf_uhd_i2c_bytes
, { "I2C BYTES", "uhd.i2c_bytes",
229 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
230 { &hf_uhd_i2c_data
, { "I2C DATA", "uhd.i2c_data",
231 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
232 { &hf_uhd_spi_dev
, { "SPI DEV", "uhd.spi_dev",
233 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
234 { &hf_uhd_spi_data
, { "SPI DATA", "uhd.spi_data",
235 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
236 { &hf_uhd_spi_miso_edge
, { "SPI MISO EDGE", "uhd.spi_miso_edge",
237 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
238 { &hf_uhd_spi_mosi_edge
, { "SPI MOSI EDGE", "uhd.spi_mosi_edge",
239 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
240 { &hf_uhd_spi_num_bits
, { "SPI NUM BITS", "uhd.spi_num_bits",
241 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
242 { &hf_uhd_spi_readback
, { "SPI READBACK", "uhd.spi_readback",
243 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
244 { &hf_uhd_reg_addr
, { "REG ADDR", "uhd.reg_addr",
245 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
246 { &hf_uhd_reg_data
, { "REG DATA", "uhd.reg_data",
247 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
248 { &hf_uhd_reg_action
, { "REG ACTION", "uhd.reg_action",
249 FT_UINT8
, BASE_HEX
, VALS(uhd_reg_actions
), 0, NULL
, HFILL
} },
250 { &hf_uhd_echo_len
, { "ECHO LEN", "uhd.echo_len",
251 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
254 static int *ett
[] = {
258 proto_uhd
= proto_register_protocol("UHD", "UHD", "uhd");
259 proto_register_field_array(proto_uhd
, hf
, array_length(hf
));
260 proto_register_subtree_array(ett
, array_length(ett
));
261 uhd_handle
= register_dissector("uhd", dissect_uhd
, proto_uhd
);
265 proto_reg_handoff_uhd(void)
267 dissector_add_for_decode_as_with_preference("udp.port", uhd_handle
);
271 * Editor modelines - https://www.wireshark.org/tools/modelines.html
276 * indent-tabs-mode: t
279 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
280 * :indentSize=8:tabSize=8:noTabs=false: