Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-dsr.c
blob3d51501379415231c73f03bc7559fb6563809527
1 /* packet-dsr.c
2 * Routines for DSR dissection
3 * Copyright 2014, ENAC - Gilles Roudiere <gilles.roudiere@enac.fr or gilles@roudiere.net>
4 * ENAC's URL : http://www.enac.fr/
5 * Mail to : gilles.roudiere@enac.fr or nicolas.larrieu@enac.fr
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/ipproto.h>
18 #include <epan/addr_resolv.h>
20 /* Please refer to rfc4728 for DSR protocol specifications */
22 /* Forward declaration that is needed below if using the
23 * proto_reg_handoff_dsr function as a callback for when protocol
24 * preferences get changed. */
25 void proto_reg_handoff_dsr(void);
26 void proto_register_dsr(void);
28 static dissector_handle_t dsr_handle;
30 static dissector_table_t ip_dissector_table;
32 /* Initialize the protocol and registered fields */
33 static int proto_dsr;
34 /* DSR global fields */
35 static int hf_dsr_nexthdr;
36 static int hf_dsr_flowstate;
37 static int hf_dsr_reserved;
38 static int hf_dsr_length;
39 static int hf_dsr_opttype;
40 static int hf_dsr_optlen;
41 static int hf_dsr_fs_hopcount;
42 static int hf_dsr_fs_id;
43 /* RREQ option fields */
44 static int hf_dsr_opt_rreq_id;
45 static int hf_dsr_opt_rreq_targetaddress;
46 static int hf_dsr_opt_rreq_address;
47 /* RREP option fields */
48 static int hf_dsr_opt_rrep_lasthopex;
49 static int hf_dsr_opt_rrep_reserved;
50 static int hf_dsr_opt_rrep_address;
51 /* RERR option fields */
52 static int hf_dsr_opt_err_type;
53 static int hf_dsr_opt_err_reserved;
54 static int hf_dsr_opt_err_salvage;
55 static int hf_dsr_opt_err_src;
56 static int hf_dsr_opt_err_dest;
57 static int hf_dsr_opt_err_unreach_addr;
58 static int hf_dsr_opt_err_unsupportedoption;
59 static int hf_dsr_opt_err_unknownflow_dest;
60 static int hf_dsr_opt_err_unknownflow_id;
61 static int hf_dsr_opt_err_defaultflowunknown_dest;
62 /* ACK REQuest option fields */
63 static int hf_dsr_opt_ack_req_id;
64 static int hf_dsr_opt_ack_req_address;
65 /* ACK option fields */
66 static int hf_dsr_opt_ack_id;
67 static int hf_dsr_opt_ack_src;
68 static int hf_dsr_opt_ack_dest;
69 /* SRCRT option fields */
70 static int hf_dsr_opt_srcrt_firsthopext;
71 static int hf_dsr_opt_srcrt_lasthopext;
72 static int hf_dsr_opt_srcrt_reserved;
73 static int hf_dsr_opt_srcrt_salvage;
74 static int hf_dsr_opt_srcrt_segsleft;
75 static int hf_dsr_opt_srcrt_address;
76 /* Flow State Extensions */
77 /* Timout option fields */
78 static int hf_dsr_fs_opt_timeout_timeout;
79 /* Flow ID / destination option fields */
80 static int hf_dsr_fs_opt_destflowid_id;
81 static int hf_dsr_fs_opt_destflowid_dest;
83 /* Initialize the subtree pointers */
84 static int ett_dsr;
85 /* DSR options tree */
86 static int ett_dsr_options;
87 static int ett_dsr_rreq_opt;
88 static int ett_dsr_rrep_opt;
89 static int ett_dsr_rerr_opt;
90 static int ett_dsr_ackreq_opt;
91 static int ett_dsr_ack_opt;
92 static int ett_dsr_srcrt_opt;
93 static int ett_dsr_padn_opt;
94 static int ett_dsr_pad1_opt;
95 static int ett_dsr_fs_timeout_opt;
96 static int ett_dsr_fs_destflowid_opt;
98 /* hoplist trees */
99 static int ett_dsr_rreq_hoplist;
100 static int ett_dsr_rrep_hoplist;
101 static int ett_dsr_srcrt_hoplist;
103 /* A sample #define of the minimum length (in bytes) of the protocol data.
104 * If data is received with fewer than this many bytes it is rejected by
105 * the current dissector. */
106 #define DSR_MIN_LENGTH 4
108 /* DSR option types */
109 #define DSR_OPT_TYPE_RREQ 1
110 #define DSR_OPT_TYPE_RREP 2
111 #define DSR_OPT_TYPE_RERR 3
112 #define DSR_OPT_TYPE_ACKREQ 160
113 #define DSR_OPT_TYPE_ACK 32
114 #define DSR_OPT_TYPE_SRCRT 96
115 #define DSR_OPT_TYPE_PAD1 224
116 #define DSR_OPT_TYPE_PADN 0
117 /* DSR Flow State extension types */
118 #define DSR_FS_OPT_TYPE_TIMEOUT 128
119 #define DSR_FS_OPT_TYPE_DESTFLOWID 129
120 /* Route error types */
121 #define DSR_RERR_TYPE_UNREACHABLE 1
122 #define DSR_RERR_TYPE_FLOWSTATENOTSUPPORTED 2
123 #define DSR_RERR_TYPE_OPTIONNOTSUPPORTED 3
124 #define DSR_RERR_TYPE_UNKNOWNFLOW 129
125 #define DSR_RERR_TYPE_DEFAULTFLOWUNKNOWN 130
127 /* DSR option names */
128 static const value_string dsropttypenames[] ={
129 {DSR_OPT_TYPE_RREQ, "Route request"},
130 {DSR_OPT_TYPE_RREP, "Route reply"},
131 {DSR_OPT_TYPE_RERR, "Route error"},
132 {DSR_OPT_TYPE_ACKREQ, "Acknowledgement request"},
133 {DSR_OPT_TYPE_ACK, "Acknowledgement"},
134 {DSR_OPT_TYPE_SRCRT, "Source route"},
135 {DSR_OPT_TYPE_PAD1, "Padding by 1"},
136 {DSR_OPT_TYPE_PADN, "Padding by N"},
137 {0, NULL}
140 /* DSR Route error names */
141 static const value_string dsrrerrtypenames[] ={
142 {DSR_RERR_TYPE_UNREACHABLE, "Unreachable node"},
143 {DSR_RERR_TYPE_FLOWSTATENOTSUPPORTED, "Flow state not supported"},
144 {DSR_RERR_TYPE_OPTIONNOTSUPPORTED, "Option not supported"},
145 {DSR_RERR_TYPE_UNKNOWNFLOW, "Unknown flow"},
146 {DSR_RERR_TYPE_DEFAULTFLOWUNKNOWN, "Default flow unknown"},
147 {0, NULL}
150 /* Code to actually dissect the packets */
151 static int
152 dissect_dsr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
153 void *data _U_)
155 /* Set up structures needed to add the protocol subtree and manage it */
156 proto_item *ti_main, *ti, *ti_hoplist;
157 proto_tree *dsr_tree, *opt_tree, *options_tree, *opt_hoplist_tree;
158 /* Other misc. local variables. */
159 unsigned offset = 0; /* Global offset in DSR packet */
160 unsigned offset_in_option = 0; /* Per-option offset */
161 unsigned nexthdr, opt_tot_len, opt_len, opt_type, opt_id, opt_err_type, flowstate_hdr;
162 unsigned i;
164 tvbuff_t *next_tvb;
166 /* Check that the packet is long enough for it to belong to us. */
167 if (tvb_reported_length(tvb) < DSR_MIN_LENGTH)
168 return 0;
170 /* Set the Protocol column to the constant string of dsr */
171 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DSR");
172 col_set_str(pinfo->cinfo, COL_INFO, "Options : ");
174 /* create display subtree for the protocol */
175 ti_main = proto_tree_add_item(tree, proto_dsr, tvb, 0, -1, ENC_NA);
176 dsr_tree = proto_item_add_subtree(ti_main, ett_dsr);
178 proto_tree_add_item(dsr_tree, hf_dsr_nexthdr, tvb, offset, 1, ENC_BIG_ENDIAN); /* Next header */
179 nexthdr = tvb_get_uint8(tvb, offset);
180 offset += 1;
182 proto_tree_add_item(dsr_tree, hf_dsr_flowstate, tvb, offset, 1, ENC_BIG_ENDIAN); /* Flowstate */
183 flowstate_hdr = tvb_get_bits8(tvb, offset*8, 1);
185 /*DSR normal header*/
186 if (!flowstate_hdr) {
187 proto_tree_add_item(dsr_tree, hf_dsr_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); /* Reserved */
188 offset += 1;
190 proto_tree_add_item(dsr_tree, hf_dsr_length, tvb, offset, 2, ENC_BIG_ENDIAN); /* Dsr opt tot length */
191 opt_tot_len = tvb_get_ntohs(tvb, offset);
192 proto_item_set_len(ti_main, opt_tot_len+4);
193 offset += 2;
195 options_tree = proto_tree_add_subtree(dsr_tree, tvb, offset, opt_tot_len, ett_dsr_options, NULL, "Options"); /* DSR options */
197 /* DSR options dissection */
198 while (offset - 4 < opt_tot_len) {
199 opt_type = tvb_get_uint8(tvb, offset);
200 offset_in_option = offset;
201 opt_len = 0;
202 switch(opt_type) {
203 case DSR_OPT_TYPE_RREQ:
204 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rreq_opt, &ti, "Route request"); /* Opt subtree */
205 col_append_str(pinfo->cinfo, COL_INFO, "Route request");
207 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
208 offset_in_option += 1;
210 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
211 opt_len = tvb_get_uint8(tvb, offset_in_option);
212 proto_item_set_len(ti, opt_len+2);
213 offset_in_option += 1;
215 proto_tree_add_item(opt_tree, hf_dsr_opt_rreq_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Opt rreq id */
216 opt_id = tvb_get_ntohs(tvb, offset_in_option);
217 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
218 offset_in_option += 2;
220 proto_tree_add_item(opt_tree, hf_dsr_opt_rreq_targetaddress, tvb, offset_in_option, 4, ENC_NA); /* Opt rreq target address */
221 offset_in_option += 4;
223 if(opt_len > 6) {
224 opt_hoplist_tree = proto_tree_add_subtree(opt_tree, tvb, offset_in_option, 1, ett_dsr_rreq_hoplist, &ti_hoplist, "Hop list" ); /* Opt hop list */
225 proto_item_append_text(ti_hoplist, " :");
226 for(i=0;i<(opt_len-4)/4;i++) {
227 proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_rreq_address, tvb, offset_in_option, 4, ENC_NA); /* Opt rreq address */
228 proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
229 offset_in_option += 4;
232 break;
233 case DSR_OPT_TYPE_RREP:
234 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rrep_opt, &ti, "Route reply"); /* Opt subtree */
235 col_append_str(pinfo->cinfo, COL_INFO, "Route reply");
237 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
238 offset_in_option += 1;
240 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
241 opt_len = tvb_get_uint8(tvb, offset_in_option);
242 proto_item_set_len(ti, opt_len+2);
243 offset_in_option += 1;
245 proto_tree_add_item(opt_tree, hf_dsr_opt_rrep_lasthopex, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt rrep reserved */
246 proto_tree_add_item(opt_tree, hf_dsr_opt_rrep_reserved, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt rrep reserved */
247 offset_in_option += 1;
249 if(opt_len > 2) {
250 opt_hoplist_tree = proto_tree_add_subtree(opt_tree, tvb, offset_in_option, 1, ett_dsr_rrep_hoplist, &ti_hoplist, "Hop list" ); /* Opt hop list */
251 proto_item_append_text(ti_hoplist, " :");
252 for(i=0;i<(opt_len-1)/4;i++) {
253 proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_rrep_address, tvb, offset_in_option, 4, ENC_NA); /*Opt rrep address */
254 proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
255 offset_in_option += 4;
258 break;
259 case DSR_OPT_TYPE_RERR:
260 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rerr_opt, &ti, "Route error"); /* Opt subtree */
261 col_append_str(pinfo->cinfo, COL_INFO, "Route error");
263 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
264 offset_in_option += 1;
266 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
267 opt_len = tvb_get_uint8(tvb, offset_in_option);
268 proto_item_set_len(ti, opt_len+2);
269 offset_in_option += 1;
271 proto_tree_add_item(opt_tree, hf_dsr_opt_err_type, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt err type */
272 opt_err_type = tvb_get_uint8(tvb, offset_in_option);
273 offset_in_option += 1;
275 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_err_reserved, tvb, offset_in_option*8, 4, ENC_BIG_ENDIAN); /*Opt err reserved */
276 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_err_salvage, tvb, offset_in_option*8+4, 4, ENC_BIG_ENDIAN); /*Opt err salvage */
277 offset_in_option += 1;
279 proto_tree_add_item(opt_tree, hf_dsr_opt_err_src, tvb, offset_in_option, 4, ENC_NA); /*Opt err source address */
280 offset_in_option += 4;
282 proto_tree_add_item(opt_tree, hf_dsr_opt_err_dest, tvb, offset_in_option, 4, ENC_NA); /* Opt err dest address */
283 offset_in_option += 4;
285 switch(opt_err_type) {
286 case DSR_RERR_TYPE_UNREACHABLE:
287 proto_tree_add_item(opt_tree, hf_dsr_opt_err_unreach_addr, tvb, offset_in_option, 4, ENC_NA); /* Opt err unreachable node address */
288 /*offset_in_option += 4;*/
289 break;
290 case DSR_RERR_TYPE_FLOWSTATENOTSUPPORTED:
291 break;
292 case DSR_RERR_TYPE_OPTIONNOTSUPPORTED:
293 proto_tree_add_item(opt_tree, hf_dsr_opt_err_unsupportedoption, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt err unsupported opt */
294 /*offset_in_option += 1;*/
295 break;
296 case DSR_RERR_TYPE_UNKNOWNFLOW:
297 proto_tree_add_item(opt_tree, hf_dsr_opt_err_unknownflow_dest, tvb, offset_in_option, 4, ENC_NA);/* Opt err unknown flow original ip destination address */
298 offset_in_option += 4;
300 proto_tree_add_item(opt_tree, hf_dsr_opt_err_unknownflow_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN);/* Opt err unknown flow id */
301 /*offset_in_option += 1;*/
302 break;
303 case DSR_RERR_TYPE_DEFAULTFLOWUNKNOWN:
304 proto_tree_add_item(opt_tree, hf_dsr_opt_err_defaultflowunknown_dest, tvb, offset_in_option, 4, ENC_NA);/* opt err default flow unknown original ip destination address */
305 /*offset_in_option += 4;*/
306 break;
308 break;
309 case DSR_OPT_TYPE_ACKREQ:
310 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_ackreq_opt, &ti, "Acknowledgement request"); /* Opt subtree */
311 col_append_str(pinfo->cinfo, COL_INFO, "Ack request");
313 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
314 offset_in_option += 1;
316 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
317 opt_len = tvb_get_uint8(tvb, offset_in_option);
318 proto_item_set_len(ti, opt_len+2);
319 offset_in_option += 1;
321 proto_tree_add_item(opt_tree, hf_dsr_opt_ack_req_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Opt ack req id */
322 opt_id = tvb_get_ntohs(tvb, offset_in_option);
323 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
324 offset_in_option += 2;
326 if(opt_len >= 6) {
327 proto_tree_add_item(opt_tree, hf_dsr_opt_ack_req_address, tvb, offset_in_option, 4, ENC_NA); /* Opt ack req id */
328 /*offset_in_option += 4;*/
330 break;
331 case DSR_OPT_TYPE_ACK:
332 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_ack_opt, &ti, "Acknowledgement"); /* Opt subtree */
333 col_append_str(pinfo->cinfo, COL_INFO, "Ack");
335 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
336 offset_in_option += 1;
338 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
339 opt_len = tvb_get_uint8(tvb, offset_in_option);
340 proto_item_set_len(ti, opt_len+2);
341 offset_in_option += 1;
344 proto_tree_add_item(opt_tree, hf_dsr_opt_ack_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Opt ack id */
345 opt_id = tvb_get_ntohs(tvb, offset_in_option);
346 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
347 offset_in_option += 2;
349 proto_tree_add_item(opt_tree, hf_dsr_opt_ack_src, tvb, offset_in_option, 4, ENC_NA); /* Opt ack source address */
350 offset_in_option += 4;
352 proto_tree_add_item(opt_tree, hf_dsr_opt_ack_dest, tvb, offset_in_option, 4, ENC_NA); /* Opt ack dest address */
353 /*offset_in_option += 4;*/
354 break;
355 case DSR_OPT_TYPE_SRCRT:
356 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_srcrt_opt, &ti, "Source route"); /* Opt subtree */
357 col_append_str(pinfo->cinfo, COL_INFO, "Source route");
359 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
360 offset_in_option += 1;
362 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
363 opt_len = tvb_get_uint8(tvb, offset_in_option );
364 proto_item_set_len(ti, opt_len+2);
365 offset_in_option += 1;
367 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_srcrt_firsthopext, tvb, offset_in_option*8, 1, ENC_BIG_ENDIAN); /* Opt srcrt first hop external */
368 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_srcrt_lasthopext, tvb, offset_in_option*8+1, 1, ENC_BIG_ENDIAN); /* Opt srcrt last hop external */
369 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_srcrt_reserved, tvb, offset_in_option*8+2, 4, ENC_BIG_ENDIAN); /* Opt srcrt reserved */
370 proto_tree_add_bits_item(opt_tree, hf_dsr_opt_srcrt_salvage, tvb, offset_in_option*8+6, 4, ENC_BIG_ENDIAN); /* Opt srcrt salvage */
371 offset_in_option += 1;
372 proto_tree_add_item(opt_tree, hf_dsr_opt_srcrt_segsleft, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt srcrt segs left */
373 offset_in_option += 1;
375 if(opt_len > 2) {
376 opt_hoplist_tree = proto_tree_add_subtree(opt_tree, tvb, offset_in_option, 1, ett_dsr_srcrt_hoplist, &ti_hoplist, "Hop list" ); /* Opt hop list */
378 proto_item_append_text(ti_hoplist, " :");
379 for(i=0;i<(opt_len-2)/4;i++) {
380 proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_srcrt_address, tvb, offset_in_option , 4, ENC_NA); /* Opt srcrt addresses */
381 proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
382 offset_in_option += 4;
385 break;
386 case DSR_OPT_TYPE_PADN:
387 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_padn_opt, &ti, "PadN"); /* Opt subtree */
389 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt type */
390 offset_in_option += 1;
392 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt len */
393 opt_len = tvb_get_uint8(tvb, offset_in_option );
394 proto_item_set_len(ti, opt_len+2);
395 /*offset_in_option += 1;
396 offset_in_option += opt_len;*/
397 break;
398 case DSR_OPT_TYPE_PAD1:
399 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_pad1_opt, &ti, "Pad1"); /* Opt subtree */
401 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt type */
402 /*offset_in_option += 1;*/
403 break;
405 case DSR_FS_OPT_TYPE_TIMEOUT :
406 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_fs_timeout_opt, &ti, "Timeout"); /* Opt subtree */
407 col_append_str(pinfo->cinfo, COL_INFO, "Timeout");
409 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
410 offset_in_option += 1;
412 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
413 opt_len = tvb_get_uint8(tvb, offset_in_option );
414 proto_item_set_len(ti, opt_len+2);
415 offset_in_option += 1;
417 proto_tree_add_item(opt_tree, hf_dsr_fs_opt_timeout_timeout, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Timeout */
418 /*offset_in_option += 2;*/
419 break;
420 case DSR_FS_OPT_TYPE_DESTFLOWID:
421 opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_fs_destflowid_opt, &ti, "Destination and flow id"); /* Opt subtree */
422 col_append_str(pinfo->cinfo, COL_INFO, "Dest&FlowId");
424 proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
425 offset_in_option += 1;
427 proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
428 opt_len = tvb_get_uint8(tvb, offset_in_option );
429 proto_item_set_len(ti, opt_len+2);
430 offset_in_option += 1;
432 proto_tree_add_item(opt_tree, hf_dsr_fs_opt_destflowid_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Flow ID */
433 offset_in_option += 2;
435 proto_tree_add_item(opt_tree, hf_dsr_fs_opt_destflowid_dest, tvb, offset_in_option, 4, ENC_NA); /* Original IP Dest Address */
436 /*offset_in_option += 4;*/
437 break;
439 if (opt_type != DSR_OPT_TYPE_PAD1)
440 offset += 2+opt_len;
441 else
442 offset += 1;
443 if(offset-4 < opt_tot_len && opt_type != DSR_OPT_TYPE_PAD1 && opt_type != DSR_OPT_TYPE_PADN) {
444 col_append_str(pinfo->cinfo, COL_INFO, ", ");
447 } else { /* DSR Flow state header */
448 proto_tree_add_item(dsr_tree, hf_dsr_fs_hopcount, tvb, offset, 1, ENC_BIG_ENDIAN); /* Hop count */
449 offset += 1;
451 proto_tree_add_item(dsr_tree, hf_dsr_fs_id, tvb, offset, 1, ENC_BIG_ENDIAN); /* Flow identifier */
452 offset += 2;
455 /* Call other dissectors if needed */
456 next_tvb = tvb_new_subset_remaining(tvb, offset);
457 if (!dissector_try_uint(ip_dissector_table, nexthdr, next_tvb, pinfo, tree)) {
458 call_data_dissector(next_tvb, pinfo, tree);
461 return offset+4;
464 /* Register DSR with Wireshark.*/
465 void
466 proto_register_dsr(void)
468 /* Setup list of header fields */
469 static hf_register_info hf[] = {
470 { &hf_dsr_nexthdr,
471 { "Next header", "dsr.nexthdr",
472 FT_UINT8, BASE_HEX | BASE_EXT_STRING,
473 &ipproto_val_ext, 0x0,
474 "Next header protocol type", HFILL }
476 { &hf_dsr_flowstate,
477 { "Flow state", "dsr.flowstate",
478 FT_BOOLEAN, 8,
479 NULL, 0x80,
480 NULL, HFILL }
482 /* DSR normal header */
483 { &hf_dsr_reserved,
484 { "Reserved", "dsr.reserved",
485 FT_UINT8, BASE_HEX,
486 NULL, 0x7F,
487 NULL, HFILL }
489 { &hf_dsr_length,
490 { "Length", "dsr.len",
491 FT_UINT16, BASE_DEC,
492 NULL, 0x0,
493 "Payload length", HFILL }
495 { &hf_dsr_opttype,
496 { "Type", "dsr.option.type",
497 FT_UINT8, BASE_DEC,
498 VALS(dsropttypenames), 0x0,
499 NULL, HFILL }
501 { &hf_dsr_optlen,
502 { "Length", "dsr.option.len",
503 FT_UINT8, BASE_DEC,
504 NULL, 0x0,
505 "Option length", HFILL }
507 /* RREQ fields */
508 { &hf_dsr_opt_rreq_id,
509 { "Id", "dsr.option.rreq.id",
510 FT_UINT16, BASE_HEX_DEC,
511 NULL, 0x0,
512 NULL, HFILL }
514 { &hf_dsr_opt_rreq_targetaddress,
515 { "Target address", "dsr.option.rreq.targetaddress",
516 FT_IPv4, BASE_NONE,
517 NULL, 0x0,
518 "Target IP address", HFILL }
520 { &hf_dsr_opt_rreq_address,
521 { "Hop", "dsr.option.rreq.address",
522 FT_IPv4, BASE_NONE,
523 NULL, 0x0,
524 NULL, HFILL }
526 /* RREP fields */
527 { &hf_dsr_opt_rrep_lasthopex,
528 { "Last hop external", "dsr.option.rrep.lasthopex",
529 FT_BOOLEAN, 8,
530 NULL, 0x80,
531 NULL, HFILL }
533 { &hf_dsr_opt_rrep_reserved,
534 { "Reserved", "dsr.option.rrep.reserved",
535 FT_UINT8, BASE_HEX,
536 NULL, 0x7F,
537 NULL, HFILL }
539 { &hf_dsr_opt_rrep_address,
540 { "Hop", "dsr.option.rrep.address",
541 FT_IPv4, BASE_NONE,
542 NULL, 0x0,
543 NULL, HFILL }
545 /* RERR fields */
546 { &hf_dsr_opt_err_type,
547 { "Type", "dsr.option.err.type",
548 FT_UINT8, BASE_DEC,
549 VALS(dsrrerrtypenames), 0x0,
550 NULL, HFILL }
552 { &hf_dsr_opt_err_reserved,
553 { "Reserved", "dsr.option.err.reserved",
554 FT_UINT8, BASE_HEX,
555 NULL, 0x00,
556 NULL, HFILL }
558 { &hf_dsr_opt_err_salvage,
559 { "Salvage", "dsr.option.err.salvage",
560 FT_UINT8, BASE_HEX,
562 NULL, 0x00,
563 NULL, HFILL }
565 { &hf_dsr_opt_err_src,
566 { "Source address", "dsr.option.err.src",
567 FT_IPv4, BASE_NONE,
568 NULL, 0x00,
569 "Source IP address", HFILL }
571 { &hf_dsr_opt_err_dest,
572 { "Destination address", "dsr.option.err.dest",
573 FT_IPv4, BASE_NONE,
574 NULL, 0x00,
575 "Destination IP address", HFILL }
577 { &hf_dsr_opt_err_unreach_addr,
578 { "Unreachable node address", "dsr.option.err.unreachablenode",
579 FT_IPv4, BASE_NONE,
580 NULL, 0x00,
581 "Unreachable node IP address", HFILL }
583 { &hf_dsr_opt_err_unsupportedoption,
584 { "Unsupported option", "dsr.option.err.unsupportedoption",
585 FT_UINT8, BASE_HEX,
586 NULL, 0x00,
587 NULL, HFILL }
589 /* ACKREQ fields */
590 { &hf_dsr_opt_ack_req_id,
591 { "Id", "dsr.option.ackreq.id",
592 FT_UINT16, BASE_HEX_DEC,
593 NULL, 0x0,
594 NULL, HFILL }
596 { &hf_dsr_opt_ack_req_address,
597 { "Source address", "dsr.option.ackreq.address",
598 FT_IPv4, BASE_NONE,
599 NULL, 0x0,
600 "Source IP address", HFILL }
602 /* ACK fields */
603 { &hf_dsr_opt_ack_id,
604 { "Id", "dsr.option.ack.id",
605 FT_UINT16, BASE_HEX_DEC,
606 NULL, 0x0,
607 NULL, HFILL }
609 { &hf_dsr_opt_ack_src,
610 { "Source IP", "dsr.option.ack.source",
611 FT_IPv4, BASE_NONE,
612 NULL, 0x0,
613 "Source IP address", HFILL }
615 { &hf_dsr_opt_ack_dest,
616 { "Destination IP", "dsr.option.ack.dest",
617 FT_IPv4, BASE_NONE,
618 NULL, 0x0,
619 "Destination IP address", HFILL }
621 /* SRCRT fields */
622 { &hf_dsr_opt_srcrt_firsthopext,
623 { "First hop external", "dsr.option.srcrt.firsthopext",
624 FT_BOOLEAN, BASE_NONE,
625 NULL, 0x0,
626 NULL, HFILL }
628 { &hf_dsr_opt_srcrt_lasthopext,
629 { "Last hop external", "dsr.option.srcrt.lasthopext",
630 FT_BOOLEAN, BASE_NONE,
631 NULL, 0x0,
632 NULL, HFILL }
634 { &hf_dsr_opt_srcrt_reserved,
635 { "Reserved", "dsr.option.srcrt.reserved",
636 FT_UINT8, BASE_HEX,
637 NULL, 0x0,
638 NULL, HFILL }
640 { &hf_dsr_opt_srcrt_salvage,
641 { "Salvage", "dsr.option.srcrt.salvage",
642 FT_UINT8, BASE_HEX,
643 NULL, 0x0,
644 NULL, HFILL }
646 { &hf_dsr_opt_srcrt_segsleft,
647 { "Segments left", "dsr.option.srcrt.segsleft",
648 FT_UINT8, BASE_DEC,
649 NULL, 0x3F,
650 NULL, HFILL }
652 { &hf_dsr_opt_srcrt_address,
653 { "Hop", "dsr.option.ack.address",
654 FT_IPv4, BASE_NONE,
655 NULL, 0x0,
656 "Hop IP address", HFILL }
658 /* DSR flow state */
659 { &hf_dsr_fs_hopcount,
660 { "Hop count", "dsr.fs.hopcount",
661 FT_UINT8, BASE_DEC,
662 NULL, 0x7F,
663 NULL, HFILL }
665 { &hf_dsr_fs_id,
666 { "Flow id", "dsr.fs.id",
667 FT_UINT16, BASE_HEX_DEC,
668 NULL, 0x00,
669 NULL, HFILL }
671 { &hf_dsr_fs_opt_timeout_timeout,
672 { "Timeout", "dsr.option.timeout.timeout",
673 FT_UINT16, BASE_DEC,
674 NULL, 0x0,
675 NULL, HFILL }
677 { &hf_dsr_fs_opt_destflowid_id,
678 { "Flow id", "dsr.option.destflowid.id",
679 FT_UINT16, BASE_HEX_DEC,
680 NULL, 0x0,
681 "New flow identifier", HFILL }
683 { &hf_dsr_fs_opt_destflowid_dest,
684 { "Destination IP", "dsr.option.destflowid.dest",
685 FT_IPv4, BASE_NONE,
686 NULL, 0x0,
687 "New IP destination address", HFILL }
689 { &hf_dsr_opt_err_unknownflow_dest,
690 { "Original IP destination", "dsr.option.err.unknownflow.dest",
691 FT_IPv4, BASE_NONE,
692 NULL, 0x00,
693 "Original IP destination address", HFILL }
695 { &hf_dsr_opt_err_unknownflow_id,
696 { "Flow id", "dsr.option.err.unknownflow.id",
697 FT_UINT16, BASE_HEX_DEC,
698 NULL, 0x00,
699 NULL, HFILL }
701 { &hf_dsr_opt_err_defaultflowunknown_dest,
702 { "Original IP destination", "dsr.option.err.defaultflowunknown.dest",
703 FT_IPv4, BASE_NONE,
704 NULL, 0x00,
705 NULL, HFILL }
709 /* Setup protocol subtree array */
710 static int *ett[] = {
711 &ett_dsr,
712 &ett_dsr_options,
713 &ett_dsr_rreq_opt,
714 &ett_dsr_rrep_opt,
715 &ett_dsr_rerr_opt,
716 &ett_dsr_ackreq_opt,
717 &ett_dsr_ack_opt,
718 &ett_dsr_srcrt_opt,
719 &ett_dsr_padn_opt,
720 &ett_dsr_pad1_opt,
721 &ett_dsr_fs_timeout_opt,
722 &ett_dsr_fs_destflowid_opt,
723 &ett_dsr_rreq_hoplist,
724 &ett_dsr_rrep_hoplist,
725 &ett_dsr_srcrt_hoplist
728 /* Register the protocol name and description */
729 proto_dsr = proto_register_protocol("Dynamic Source Routing", "DSR", "dsr");
730 dsr_handle = register_dissector("dsr", dissect_dsr, proto_dsr);
732 /* Required function calls to register the header fields and subtrees */
733 proto_register_field_array(proto_dsr, hf, array_length(hf));
734 proto_register_subtree_array(ett, array_length(ett));
738 void
739 proto_reg_handoff_dsr(void)
741 ip_dissector_table = find_dissector_table("ip.proto");
742 dissector_add_uint("ip.proto", IP_PROTO_DSR, dsr_handle);
745 * Editor modelines - https://www.wireshark.org/tools/modelines.html
747 * Local variables:
748 * c-basic-offset: 4
749 * tab-width: 8
750 * indent-tabs-mode: nil
751 * End:
753 * vim: set shiftwidth=4 tabstop=8 expandtab:
754 * :indentSize=4:tabSize=8:noTabs=true: