Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-smpte-2110-20.c
blob0f16e92a86106238ba42f5f61c8e16336d303c01
1 /* packet-smpte-2110-20.c
2 * SMPTE ST2110-20
4 * Copyright 2023, Sergey V. Lobanov <sergey@lobanov.in>
6 * References:
7 * SMPTE ST 2110-20:2022, Uncompressed Active Video
8 * RFC4175, RTP Payload Format for Uncompressed Video
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include "config.h"
19 #include <epan/packet.h>
20 #include <epan/prefs.h>
21 #include <epan/proto.h>
22 #include <epan/proto_data.h>
24 #include "packet-rtp.h"
26 void proto_reg_handoff_st2110_20(void);
27 void proto_register_st2110_20(void);
29 static dissector_handle_t st2110_20_handle;
31 /* Initialize the protocol and registered fields */
32 static int proto_st2110_20;
33 static int proto_rtp;
35 static int hf_st2110_ext_seqno;
36 static int hf_st2110_seqno;
37 static int hf_st2110_rtp_time;
38 static int hf_st2110_srd_index;
39 static int hf_st2110_srd_length;
40 static int hf_st2110_field_ident;
41 static int hf_st2110_row_num;
42 static int hf_st2110_continuation;
43 static int hf_st2110_srd_offset;
44 static int hf_st2110_srd_data;
45 static int hf_st2110_srd_rows;
47 /* Initialize the subtree pointers */
48 static int ett_st2110_20;
49 static int ett_st2110_20_srd_row;
52 static int
53 dissect_st2110_20(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data _U_)
55 proto_item *item;
56 proto_tree *st2110_20_tree;
58 int offset = 0;
60 struct _rtp_packet_info *rtp_pkt_info = (struct _rtp_packet_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rtp, RTP_CONVERSATION_PROTO_DATA);
62 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ST2110-20");
64 item = proto_tree_add_item(tree, proto_st2110_20, tvb, 0, -1, ENC_NA);
65 st2110_20_tree = proto_item_add_subtree(item, ett_st2110_20);
67 /* Extract original RTP sequence number from low bits */
68 uint32_t rtp_seqno = (rtp_pkt_info != NULL) ? (rtp_pkt_info->extended_seqno & 0xFFFF) : 0;
69 /* ST2110-20 extended sequence number field */
70 uint32_t ext_seqno = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
71 /* Sequence number (RTP seqno is low bits, ST2110-20 ext seqno is high bits) */
72 uint32_t seqno = (ext_seqno << 16) + rtp_seqno;
74 /* Extract original RTP timestamp */
75 uint32_t rtp_time = (rtp_pkt_info != NULL) ? (uint32_t)(rtp_pkt_info->extended_timestamp & 0xFFFFFFFF) : 0;
77 proto_tree_add_item(st2110_20_tree, hf_st2110_ext_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
78 PROTO_ITEM_SET_GENERATED(
79 proto_tree_add_uint(st2110_20_tree, hf_st2110_seqno, tvb, offset, 2, seqno)
81 PROTO_ITEM_SET_GENERATED(
82 proto_tree_add_uint(st2110_20_tree, hf_st2110_rtp_time, NULL, 0, 0, rtp_time)
84 offset += 2; /* st2110-20 ext seqno */
86 /* According to ST2110-20:2022 6.2.1, max three SRD headers might be in a packet */
87 uint16_t srd_lengths[3] = {0, 0, 0}; /* store for second pass */
88 proto_tree* srd_header_trees[3] = {NULL, NULL, NULL}; /* store for second pass */
89 uint8_t srd_rows = 0; /* rows count */
90 uint16_t first_row; /* first row number */
91 for (uint8_t srd_idx = 0; srd_idx < 3 ; srd_idx++) {
92 proto_tree *srd_header_tree = proto_tree_add_subtree_format(st2110_20_tree, tvb, offset, 6,
93 ett_st2110_20_srd_row, &item, "Sample Row Data %u", srd_idx);
94 srd_header_trees[srd_idx] = srd_header_tree;
95 PROTO_ITEM_SET_GENERATED(
96 proto_tree_add_uint(srd_header_tree, hf_st2110_srd_index, NULL, 0, 0, srd_idx)
99 srd_lengths[srd_idx] = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
100 proto_tree_add_item(srd_header_tree, hf_st2110_srd_length, tvb, offset, 2, ENC_BIG_ENDIAN);
101 offset += 2;
103 first_row = (srd_idx == 0) ? (tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN) & 0x7FFF) : first_row;
104 proto_tree_add_item(srd_header_tree, hf_st2110_field_ident, tvb, offset, 2, ENC_BIG_ENDIAN);
105 proto_tree_add_item(srd_header_tree, hf_st2110_row_num, tvb, offset, 2, ENC_BIG_ENDIAN);
106 offset += 2;
108 uint16_t cont_bit = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN) >> 15;
109 proto_tree_add_item(srd_header_tree, hf_st2110_continuation, tvb, offset, 2, ENC_BIG_ENDIAN);
110 proto_tree_add_item(srd_header_tree, hf_st2110_srd_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
111 offset += 2;
113 srd_rows++;
115 if (cont_bit != 1) /* if continuation is not set, then no more headers*/
116 break;
119 PROTO_ITEM_SET_GENERATED(
120 proto_tree_add_uint(st2110_20_tree, hf_st2110_srd_rows, NULL, 0, 0, srd_rows)
123 /* Second pass, get SRD data and add it to the same trees created for SRD headers */
124 for (uint8_t srd_idx = 0; srd_idx < srd_rows ; srd_idx++) {
125 uint16_t srd_length = srd_lengths[srd_idx];
127 proto_tree_add_item(srd_header_trees[srd_idx], hf_st2110_srd_data, tvb, offset, srd_length, ENC_NA);
128 offset += srd_length;
131 col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=%u, Time=%u, FirstRow=%u, Rows=%u", seqno, rtp_time, first_row, srd_rows);
133 return offset;
136 void
137 proto_register_st2110_20(void)
139 module_t *st2110_20_module;
141 static hf_register_info hf[] = {
142 { &hf_st2110_ext_seqno,
143 { "Extended Sequence Number", "st2110_20.ext_seq",
144 FT_UINT16, BASE_DEC, NULL, 0x0,
145 NULL, HFILL }
147 { &hf_st2110_seqno,
148 { "Sequence Number", "st2110_20.seq",
149 FT_UINT16, BASE_DEC, NULL, 0x0,
150 NULL, HFILL }
152 { &hf_st2110_rtp_time,
153 { "RTP Timestamp", "st2110_20.rtp_timestamp",
154 FT_UINT32, BASE_DEC, NULL, 0x0,
155 NULL, HFILL }
157 { &hf_st2110_srd_index,
158 { "SRD Header Index", "st2110_20.srd_index",
159 FT_UINT8, BASE_DEC, NULL, 0x0,
160 NULL, HFILL }
162 { &hf_st2110_srd_length,
163 { "SRD Length", "st2110_20.srd_length",
164 FT_UINT16, BASE_DEC, NULL, 0x0,
165 NULL, HFILL }
167 { &hf_st2110_field_ident,
168 { "Field Identification Bit", "st2110_20.srd_field_ident",
169 FT_UINT16, BASE_DEC, NULL, 0x8000,
170 NULL, HFILL }
172 { &hf_st2110_row_num,
173 { "SRD Row Number", "st2110_20.srd_row_num",
174 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
175 NULL, HFILL }
177 { &hf_st2110_continuation,
178 { "SRD Continuation Bit", "st2110_20.srd_cont_bit",
179 FT_UINT16, BASE_DEC, NULL, 0x8000,
180 NULL, HFILL }
182 { &hf_st2110_srd_offset,
183 { "SRD Offset", "st2110_20.srd_offset",
184 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
185 NULL, HFILL }
187 { &hf_st2110_srd_data,
188 { "SRD Data", "st2110_20.srd_data",
189 FT_NONE, BASE_NONE, NULL, 0x0,
190 NULL, HFILL }
192 { &hf_st2110_srd_rows,
193 { "SRD Rows", "st2110_20.srd_rows",
194 FT_UINT8, BASE_DEC, NULL, 0x0,
195 NULL, HFILL }
199 static int *ett[] =
201 &ett_st2110_20,
202 &ett_st2110_20_srd_row
205 proto_st2110_20 = proto_register_protocol("SMPTE ST2110-20 (Uncompressed Active Video)", "ST2110-20", "st2110_20");
207 proto_register_field_array(proto_st2110_20, hf, array_length(hf));
208 proto_register_subtree_array(ett, array_length(ett));
210 st2110_20_module = prefs_register_protocol(proto_st2110_20, NULL);
212 prefs_register_obsolete_preference(st2110_20_module, "dynamic.payload.type");
213 st2110_20_handle = register_dissector("st2110_20", dissect_st2110_20, proto_st2110_20);
216 void
217 proto_reg_handoff_st2110_20(void)
219 dissector_add_string("rtp_dyn_payload_type" , "ST2110-20", st2110_20_handle);
220 dissector_add_uint_range_with_preference("rtp.pt", "", st2110_20_handle);
221 proto_rtp = proto_get_id_by_filter_name("rtp");
225 * Editor modelines - https://www.wireshark.org/tools/modelines.html
227 * Local variables:
228 * c-basic-offset: 4
229 * tab-width: 8
230 * indent-tabs-mode: nil
231 * End:
233 * vi: set shiftwidth=4 tabstop=8 expandtab:
234 * :indentSize=4:tabSize=8:noTabs=true: