/src/wireshark/epan/dissectors/packet-rudp.c
Line | Count | Source |
1 | | /* packet-rudp.c |
2 | | * Routines for Reliable UDP Protocol. |
3 | | * Copyright 2004, Duncan Sargeant <dunc-ethereal@rcpt.to> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * Copied from packet-data.c, README.developer, and various other files. |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | |
13 | | |
14 | | * Reliable UDP is a lightweight protocol for providing TCP-like flow |
15 | | * control over UDP. Cisco published an PFC a long time ago, and |
16 | | * their actual implementation is slightly different, having no |
17 | | * checksum field. |
18 | | * |
19 | | * I've cheated here - RUDP could be used for anything, but I've only |
20 | | * seen it used to switched telephony calls, so we just call the Cisco SM |
21 | | * dissector from here. |
22 | | * |
23 | | * Here are some links: |
24 | | * |
25 | | * http://www.watersprings.org/pub/id/draft-ietf-sigtran-reliable-udp-00.txt |
26 | | * http://www.javvin.com/protocolRUDP.html |
27 | | * http://www.cisco.com/univercd/cc/td/doc/product/access/sc/rel7/omts/omts_apb.htm#30052 |
28 | | |
29 | | */ |
30 | | |
31 | | #include "config.h" |
32 | | |
33 | | #include <epan/packet.h> |
34 | | |
35 | | |
36 | | void proto_register_rudp(void); |
37 | | |
38 | | void proto_reg_handoff_rudp(void); |
39 | | |
40 | | static dissector_handle_t rudp_handle; |
41 | | |
42 | | static int proto_rudp; |
43 | | |
44 | | static int hf_rudp_flags; |
45 | | static int hf_rudp_flags_syn; |
46 | | static int hf_rudp_flags_ack; |
47 | | static int hf_rudp_flags_eak; |
48 | | static int hf_rudp_flags_rst; |
49 | | static int hf_rudp_flags_nul; |
50 | | static int hf_rudp_flags_chk; |
51 | | static int hf_rudp_flags_tcs; |
52 | | static int hf_rudp_flags_0; |
53 | | static int hf_rudp_hlen; |
54 | | static int hf_rudp_seq; |
55 | | static int hf_rudp_ack; |
56 | | static int hf_rudp_cksum; |
57 | | |
58 | | static int ett_rudp; |
59 | | static int ett_rudp_flags; |
60 | | |
61 | | static dissector_handle_t sm_handle; |
62 | | |
63 | | static int |
64 | | dissect_rudp(tvbuff_t *tvb, packet_info *pinfo _U_ , proto_tree *tree, void* data _U_) |
65 | 0 | { |
66 | 0 | tvbuff_t * next_tvb; |
67 | 0 | proto_tree *rudp_tree; |
68 | 0 | proto_item *ti; |
69 | 0 | uint8_t hlen; |
70 | 0 | static int * const flags[] = { |
71 | 0 | &hf_rudp_flags_syn, |
72 | 0 | &hf_rudp_flags_ack, |
73 | 0 | &hf_rudp_flags_eak, |
74 | 0 | &hf_rudp_flags_rst, |
75 | 0 | &hf_rudp_flags_nul, |
76 | 0 | &hf_rudp_flags_chk, |
77 | 0 | &hf_rudp_flags_tcs, |
78 | 0 | &hf_rudp_flags_0, |
79 | 0 | NULL |
80 | 0 | }; |
81 | |
|
82 | 0 | hlen = tvb_get_uint8(tvb, 1); |
83 | |
|
84 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "RUDP"); |
85 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
86 | |
|
87 | 0 | ti = proto_tree_add_item(tree, proto_rudp, tvb, 0, hlen, ENC_NA); |
88 | 0 | rudp_tree = proto_item_add_subtree(ti, ett_rudp); |
89 | |
|
90 | 0 | proto_tree_add_bitmask(rudp_tree, tvb, 0, hf_rudp_flags, ett_rudp_flags, flags, ENC_BIG_ENDIAN); |
91 | |
|
92 | 0 | proto_tree_add_item(rudp_tree, hf_rudp_hlen, tvb, 1, 1, ENC_BIG_ENDIAN); |
93 | 0 | proto_tree_add_item(rudp_tree, hf_rudp_seq, tvb, 2, 1, ENC_BIG_ENDIAN); |
94 | 0 | proto_tree_add_item(rudp_tree, hf_rudp_ack, tvb, 3, 1, ENC_BIG_ENDIAN); |
95 | | |
96 | | /* If the header is more than 4 bytes the next 2 bytes are the checksum */ |
97 | 0 | if (hlen > 4) { |
98 | 0 | proto_tree_add_checksum(rudp_tree, tvb, 4, hf_rudp_cksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
99 | 0 | } |
100 | | |
101 | | /* If we have even more bytes their meaning is unknown - we have seen this |
102 | | * in live captures */ |
103 | 0 | if (hlen > 6) { |
104 | 0 | next_tvb = tvb_new_subset_length(tvb, 6, hlen-6); |
105 | 0 | call_data_dissector(next_tvb, pinfo, rudp_tree); |
106 | 0 | } |
107 | |
|
108 | 0 | next_tvb = tvb_new_subset_remaining(tvb, hlen); |
109 | 0 | if (tvb_captured_length(next_tvb) && sm_handle) |
110 | 0 | call_dissector(sm_handle, next_tvb, pinfo, tree); |
111 | |
|
112 | 0 | return tvb_captured_length(tvb); |
113 | 0 | } |
114 | | |
115 | | void |
116 | | proto_register_rudp(void) |
117 | 16 | { |
118 | | |
119 | 16 | static hf_register_info hf[] = { |
120 | 16 | { &hf_rudp_flags, |
121 | 16 | { "RUDP Header flags", "rudp.flags", |
122 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
123 | 16 | NULL, HFILL } |
124 | 16 | }, |
125 | 16 | { &hf_rudp_flags_syn, |
126 | 16 | { "Syn", "rudp.flags.syn", |
127 | 16 | FT_BOOLEAN, 8, NULL, 0x80, |
128 | 16 | NULL, HFILL } |
129 | 16 | }, |
130 | 16 | { &hf_rudp_flags_ack, |
131 | 16 | { "Ack", "rudp.flags.ack", |
132 | 16 | FT_BOOLEAN, 8, NULL, 0x40, |
133 | 16 | NULL, HFILL } |
134 | 16 | }, |
135 | 16 | { &hf_rudp_flags_eak, |
136 | 16 | { "Eak", "rudp.flags.eak", |
137 | 16 | FT_BOOLEAN, 8, NULL, 0x20, |
138 | 16 | "Extended Ack", HFILL } |
139 | 16 | }, |
140 | 16 | { &hf_rudp_flags_rst, |
141 | 16 | { "RST", "rudp.flags.rst", |
142 | 16 | FT_BOOLEAN, 8, NULL, 0x10, |
143 | 16 | "Reset flag", HFILL } |
144 | 16 | }, |
145 | 16 | { &hf_rudp_flags_nul, |
146 | 16 | { "NULL", "rudp.flags.nul", |
147 | 16 | FT_BOOLEAN, 8, NULL, 0x08, |
148 | 16 | "Null flag", HFILL } |
149 | 16 | }, |
150 | 16 | { &hf_rudp_flags_chk, |
151 | 16 | { "CHK", "rudp.flags.chk", |
152 | 16 | FT_BOOLEAN, 8, NULL, 0x04, |
153 | 16 | "Checksum is on header or body", HFILL } |
154 | 16 | }, |
155 | 16 | { &hf_rudp_flags_tcs, |
156 | 16 | { "TCS", "rudp.flags.tcs", |
157 | 16 | FT_BOOLEAN, 8, NULL, 0x02, |
158 | 16 | "Transfer Connection System", HFILL } |
159 | 16 | }, |
160 | 16 | { &hf_rudp_flags_0, |
161 | 16 | { "0", "rudp.flags.0", |
162 | 16 | FT_BOOLEAN, 8, NULL, 0x01, |
163 | 16 | NULL, HFILL } |
164 | 16 | }, |
165 | 16 | { &hf_rudp_hlen, |
166 | 16 | { "Header Length", "rudp.hlen", |
167 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
168 | 16 | NULL, HFILL } |
169 | 16 | }, |
170 | 16 | { &hf_rudp_seq, |
171 | 16 | { "Seq", "rudp.seq", |
172 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
173 | 16 | "Sequence Number", HFILL } |
174 | 16 | }, |
175 | 16 | { &hf_rudp_ack, |
176 | 16 | { "Ack", "rudp.ack", |
177 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
178 | 16 | "Acknowledgement Number", HFILL } |
179 | 16 | }, |
180 | 16 | { &hf_rudp_cksum, |
181 | 16 | { "Checksum", "rudp.cksum", |
182 | 16 | FT_UINT16, BASE_HEX, NULL, 0x0, |
183 | 16 | NULL, HFILL } |
184 | 16 | }, |
185 | 16 | }; |
186 | | |
187 | | |
188 | | /* Setup protocol subtree array */ |
189 | 16 | static int *ett[] = { |
190 | 16 | &ett_rudp, |
191 | 16 | &ett_rudp_flags, |
192 | 16 | }; |
193 | | |
194 | | |
195 | 16 | proto_rudp = proto_register_protocol ("Reliable UDP", "RUDP", "rudp"); |
196 | | |
197 | 16 | proto_register_field_array(proto_rudp, hf, array_length(hf)); |
198 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
199 | | |
200 | 16 | rudp_handle = register_dissector("rudp", dissect_rudp, proto_rudp); |
201 | 16 | } |
202 | | |
203 | | void |
204 | 16 | proto_reg_handoff_rudp(void) { |
205 | | |
206 | | /* Disable rudp by default. The previously hardcoded value of |
207 | | * 7000 (used by Cisco) collides with afs and as the draft states: |
208 | | * "RUDP doesn't place any restrictions on which UDP port numbers are used. |
209 | | * Valid port numbers are ports not defined in RFC 1700." |
210 | | */ |
211 | | /* FIXME: The proper solution would be to convert this dissector into |
212 | | * heuristic dissector, but it isn't complete anyway. |
213 | | */ |
214 | | |
215 | 16 | dissector_add_for_decode_as_with_preference("udp.port", rudp_handle); |
216 | 16 | sm_handle = find_dissector_add_dependency("sm", proto_rudp); |
217 | 16 | } |
218 | | |
219 | | /* |
220 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
221 | | * |
222 | | * Local variables: |
223 | | * c-basic-offset: 8 |
224 | | * tab-width: 8 |
225 | | * indent-tabs-mode: t |
226 | | * End: |
227 | | * |
228 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
229 | | * :indentSize=8:tabSize=8:noTabs=false: |
230 | | */ |