Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-dsr.c
Line
Count
Source
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
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/addr_resolv.h>
18
#include <epan/iana-info.h>
19
20
/* Please refer to rfc4728 for DSR protocol specifications */
21
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);
27
28
static dissector_handle_t dsr_handle;
29
30
static dissector_table_t ip_dissector_table;
31
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;
82
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;
97
98
/* hoplist trees */
99
static int ett_dsr_rreq_hoplist;
100
static int ett_dsr_rrep_hoplist;
101
static int ett_dsr_srcrt_hoplist;
102
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
207
#define DSR_MIN_LENGTH 4
107
108
/* DSR option types */
109
276
#define DSR_OPT_TYPE_RREQ 1
110
230
#define DSR_OPT_TYPE_RREP 2
111
155
#define DSR_OPT_TYPE_RERR 3
112
26
#define DSR_OPT_TYPE_ACKREQ 160
113
30
#define DSR_OPT_TYPE_ACK 32
114
37
#define DSR_OPT_TYPE_SRCRT 96
115
15.2k
#define DSR_OPT_TYPE_PAD1 224
116
6.35k
#define DSR_OPT_TYPE_PADN 0
117
/* DSR Flow State extension types */
118
17
#define DSR_FS_OPT_TYPE_TIMEOUT 128
119
15
#define DSR_FS_OPT_TYPE_DESTFLOWID 129
120
/* Route error types */
121
2
#define DSR_RERR_TYPE_UNREACHABLE 1
122
1
#define DSR_RERR_TYPE_FLOWSTATENOTSUPPORTED 2
123
82
#define DSR_RERR_TYPE_OPTIONNOTSUPPORTED 3
124
1
#define DSR_RERR_TYPE_UNKNOWNFLOW 129
125
4
#define DSR_RERR_TYPE_DEFAULTFLOWUNKNOWN 130
126
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}
138
};
139
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}
148
};
149
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_)
154
207
{
155
    /* Set up structures needed to add the protocol subtree and manage it */
156
207
    proto_item *ti_main, *ti, *ti_hoplist;
157
207
    proto_tree *dsr_tree, *opt_tree, *options_tree, *opt_hoplist_tree;
158
    /* Other misc. local variables. */
159
207
    unsigned offset = 0;           /* Global offset in DSR packet */
160
207
    unsigned offset_in_option = 0; /* Per-option offset */
161
207
    unsigned nexthdr, opt_tot_len, opt_len, opt_type, opt_id, opt_err_type, flowstate_hdr;
162
207
    unsigned i;
163
164
207
    tvbuff_t *next_tvb;
165
166
    /* Check that the packet is long enough for it to belong to us. */
167
207
    if (tvb_reported_length(tvb) < DSR_MIN_LENGTH)
168
4
        return 0;
169
170
    /* Set the Protocol column to the constant string of dsr */
171
203
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DSR");
172
203
    col_set_str(pinfo->cinfo, COL_INFO, "Options : ");
173
174
    /* create display subtree for the protocol */
175
203
    ti_main = proto_tree_add_item(tree, proto_dsr, tvb, 0, -1, ENC_NA);
176
203
    dsr_tree = proto_item_add_subtree(ti_main, ett_dsr);
177
178
203
    proto_tree_add_item_ret_uint(dsr_tree, hf_dsr_nexthdr, tvb, offset, 1, ENC_BIG_ENDIAN, &nexthdr); /* Next header */
179
203
    offset += 1;
180
181
203
    proto_tree_add_item(dsr_tree, hf_dsr_flowstate, tvb, offset, 1, ENC_BIG_ENDIAN); /* Flowstate */
182
203
    flowstate_hdr = tvb_get_bits8(tvb, offset*8, 1);
183
184
    /*DSR normal header*/
185
203
    if (!flowstate_hdr) {
186
175
        proto_tree_add_item(dsr_tree, hf_dsr_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); /* Reserved */
187
175
        offset += 1;
188
189
175
        proto_tree_add_item(dsr_tree, hf_dsr_length, tvb, offset, 2, ENC_BIG_ENDIAN);  /* Dsr opt tot length */
190
175
        opt_tot_len = tvb_get_ntohs(tvb, offset);
191
175
        proto_item_set_len(ti_main, opt_tot_len+4);
192
175
        offset += 2;
193
194
175
        options_tree = proto_tree_add_subtree(dsr_tree, tvb, offset, opt_tot_len, ett_dsr_options, NULL, "Options"); /* DSR options */
195
196
        /* DSR options dissection */
197
5.22k
        while (offset - 4 < opt_tot_len) {
198
5.17k
                opt_type = tvb_get_uint8(tvb, offset);
199
5.17k
                offset_in_option = offset;
200
5.17k
                opt_len = 0;
201
5.17k
                switch(opt_type) {
202
276
                        case DSR_OPT_TYPE_RREQ:
203
276
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rreq_opt, &ti, "Route request"); /* Opt subtree */
204
276
                                col_append_str(pinfo->cinfo, COL_INFO, "Route request");
205
206
276
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
207
276
                                offset_in_option += 1;
208
209
276
                                proto_tree_add_item_ret_uint(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN, &opt_len); /* Opt len */
210
276
                                proto_item_set_len(ti, opt_len+2);
211
276
                                offset_in_option += 1;
212
213
276
                                proto_tree_add_item_ret_uint(opt_tree, hf_dsr_opt_rreq_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN, &opt_id); /* Opt rreq id */
214
276
                                col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
215
276
                                offset_in_option += 2;
216
217
276
                                proto_tree_add_item(opt_tree, hf_dsr_opt_rreq_targetaddress, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt rreq target address */
218
276
                                offset_in_option += 4;
219
220
276
                                if(opt_len > 6) {
221
69
                                        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 */
222
69
                                        proto_item_append_text(ti_hoplist, " :");
223
882
                                        for(i=0;i<(opt_len-4)/4;i++) {
224
813
                                                proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_rreq_address, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt rreq address */
225
813
                                                proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
226
813
                                                offset_in_option += 4;
227
813
                                        }
228
69
                                }
229
276
                                break;
230
230
                        case DSR_OPT_TYPE_RREP:
231
230
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rrep_opt, &ti, "Route reply"); /* Opt subtree */
232
230
                                col_append_str(pinfo->cinfo, COL_INFO, "Route reply");
233
234
230
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
235
230
                                offset_in_option += 1;
236
237
230
                                proto_tree_add_item_ret_uint(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN, &opt_len); /* Opt len */
238
230
                                proto_item_set_len(ti, opt_len+2);
239
230
                                offset_in_option += 1;
240
241
230
                                proto_tree_add_item(opt_tree, hf_dsr_opt_rrep_lasthopex, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt rrep reserved */
242
230
                                proto_tree_add_item(opt_tree, hf_dsr_opt_rrep_reserved, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt rrep reserved */
243
230
                                offset_in_option += 1;
244
245
230
                                if(opt_len > 2) {
246
57
                                        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 */
247
57
                                        proto_item_append_text(ti_hoplist, " :");
248
597
                                        for(i=0;i<(opt_len-1)/4;i++) {
249
540
                                                proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_rrep_address, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /*Opt rrep address */
250
540
                                                proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
251
540
                                                offset_in_option += 4;
252
540
                                        }
253
57
                                }
254
230
                                break;
255
155
                        case DSR_OPT_TYPE_RERR:
256
155
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_rerr_opt, &ti, "Route error"); /* Opt subtree */
257
155
                                col_append_str(pinfo->cinfo, COL_INFO, "Route error");
258
259
155
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
260
155
                                offset_in_option += 1;
261
262
155
                                proto_tree_add_item_ret_uint(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN, &opt_len); /* Opt len */
263
155
                                proto_item_set_len(ti, opt_len+2);
264
155
                                offset_in_option += 1;
265
266
155
                                proto_tree_add_item_ret_uint(opt_tree, hf_dsr_opt_err_type, tvb, offset_in_option, 1, ENC_BIG_ENDIAN, &opt_err_type); /* Opt err type */
267
155
                                offset_in_option += 1;
268
269
155
                                proto_tree_add_bits_item(opt_tree, hf_dsr_opt_err_reserved, tvb, offset_in_option*8, 4, ENC_BIG_ENDIAN); /*Opt err reserved */
270
155
                                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 */
271
155
                                offset_in_option += 1;
272
273
155
                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_src, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /*Opt err source address */
274
155
                                offset_in_option += 4;
275
276
155
                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_dest, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt err dest address */
277
155
                                offset_in_option += 4;
278
279
155
                                switch(opt_err_type) {
280
2
                                        case DSR_RERR_TYPE_UNREACHABLE:
281
2
                                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_unreach_addr, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt err unreachable node address */
282
                                                /*offset_in_option += 4;*/
283
2
                                                break;
284
1
                                        case DSR_RERR_TYPE_FLOWSTATENOTSUPPORTED:
285
1
                                                break;
286
82
                                        case DSR_RERR_TYPE_OPTIONNOTSUPPORTED:
287
82
                                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_unsupportedoption, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt err unsupported opt */
288
                                                /*offset_in_option += 1;*/
289
82
                                                break;
290
1
                                        case DSR_RERR_TYPE_UNKNOWNFLOW:
291
1
                                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_unknownflow_dest, tvb, offset_in_option, 4, ENC_BIG_ENDIAN);/* Opt err unknown flow original ip destination address */
292
1
                                                offset_in_option += 4;
293
294
1
                                                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 */
295
                                                /*offset_in_option += 1;*/
296
1
                                                break;
297
4
                                        case DSR_RERR_TYPE_DEFAULTFLOWUNKNOWN:
298
4
                                                proto_tree_add_item(opt_tree, hf_dsr_opt_err_defaultflowunknown_dest, tvb, offset_in_option, 4, ENC_BIG_ENDIAN);/* opt err default flow unknown original ip destination address */
299
                                                /*offset_in_option += 4;*/
300
4
                                                break;
301
155
                                }
302
152
                                break;
303
152
                        case DSR_OPT_TYPE_ACKREQ:
304
26
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_ackreq_opt, &ti, "Acknowledgement request"); /* Opt subtree */
305
26
                                col_append_str(pinfo->cinfo, COL_INFO, "Ack request");
306
307
26
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
308
26
                                offset_in_option += 1;
309
310
26
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
311
26
                                opt_len = tvb_get_uint8(tvb, offset_in_option);
312
26
                                proto_item_set_len(ti, opt_len+2);
313
26
                                offset_in_option += 1;
314
315
26
                                proto_tree_add_item(opt_tree, hf_dsr_opt_ack_req_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Opt ack req id */
316
26
                                opt_id = tvb_get_ntohs(tvb, offset_in_option);
317
26
                                col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
318
26
                                offset_in_option += 2;
319
320
26
                                if(opt_len >= 6) {
321
15
                                        proto_tree_add_item(opt_tree, hf_dsr_opt_ack_req_address, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt ack req id */
322
                                        /*offset_in_option += 4;*/
323
15
                                }
324
26
                                break;
325
30
                        case DSR_OPT_TYPE_ACK:
326
30
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_ack_opt, &ti, "Acknowledgement"); /* Opt subtree */
327
30
                                col_append_str(pinfo->cinfo, COL_INFO, "Ack");
328
329
30
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
330
30
                                offset_in_option += 1;
331
332
30
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt len */
333
30
                                opt_len = tvb_get_uint8(tvb, offset_in_option);
334
30
                                proto_item_set_len(ti, opt_len+2);
335
30
                                offset_in_option += 1;
336
337
338
30
                                proto_tree_add_item(opt_tree, hf_dsr_opt_ack_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Opt ack id */
339
30
                                opt_id = tvb_get_ntohs(tvb, offset_in_option);
340
30
                                col_append_fstr(pinfo->cinfo, COL_INFO, " (id=0x%x)", opt_id);
341
30
                                offset_in_option += 2;
342
343
30
                                proto_tree_add_item(opt_tree, hf_dsr_opt_ack_src, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt ack source address */
344
30
                                offset_in_option += 4;
345
346
30
                                proto_tree_add_item(opt_tree, hf_dsr_opt_ack_dest, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Opt ack dest address */
347
                                /*offset_in_option += 4;*/
348
30
                                break;
349
37
                        case DSR_OPT_TYPE_SRCRT:
350
37
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_srcrt_opt, &ti, "Source route"); /* Opt subtree */
351
37
                                col_append_str(pinfo->cinfo, COL_INFO, "Source route");
352
353
37
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
354
37
                                offset_in_option += 1;
355
356
37
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option,  1, ENC_BIG_ENDIAN); /* Opt len */
357
37
                                opt_len = tvb_get_uint8(tvb, offset_in_option );
358
37
                                proto_item_set_len(ti, opt_len+2);
359
37
                                offset_in_option += 1;
360
361
37
                                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 */
362
37
                                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 */
363
37
                                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 */
364
37
                                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 */
365
37
                                offset_in_option += 1;
366
37
                                proto_tree_add_item(opt_tree, hf_dsr_opt_srcrt_segsleft, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt srcrt segs left */
367
37
                                offset_in_option  += 1;
368
369
37
                                if(opt_len > 2) {
370
25
                                        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 */
371
372
25
                                        proto_item_append_text(ti_hoplist, " :");
373
341
                                        for(i=0;i<(opt_len-2)/4;i++) {
374
316
                                                proto_tree_add_item(opt_hoplist_tree, hf_dsr_opt_srcrt_address, tvb, offset_in_option , 4, ENC_BIG_ENDIAN); /* Opt srcrt addresses */
375
316
                                                proto_item_append_text(ti_hoplist, " %s", tvb_ip_to_str(pinfo->pool, tvb, offset_in_option));
376
316
                                                offset_in_option  += 4;
377
316
                                        }
378
25
                                }
379
37
                                break;
380
1.40k
                        case DSR_OPT_TYPE_PADN:
381
1.40k
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_padn_opt, &ti, "PadN"); /* Opt subtree */
382
383
1.40k
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt type */
384
1.40k
                                offset_in_option  += 1;
385
386
1.40k
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt len */
387
1.40k
                                opt_len = tvb_get_uint8(tvb, offset_in_option );
388
1.40k
                                proto_item_set_len(ti, opt_len+2);
389
                                /*offset_in_option += 1;
390
                                offset_in_option += opt_len;*/
391
1.40k
                                break;
392
79
                        case DSR_OPT_TYPE_PAD1:
393
79
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_pad1_opt, &ti, "Pad1"); /* Opt subtree */
394
395
79
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option , 1, ENC_BIG_ENDIAN); /* Opt type */
396
                                /*offset_in_option += 1;*/
397
79
                                break;
398
399
17
                        case DSR_FS_OPT_TYPE_TIMEOUT :
400
17
                                opt_tree = proto_tree_add_subtree(options_tree, tvb, offset_in_option, 1, ett_dsr_fs_timeout_opt, &ti, "Timeout"); /* Opt subtree */
401
17
                                col_append_str(pinfo->cinfo, COL_INFO, "Timeout");
402
403
17
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
404
17
                                offset_in_option += 1;
405
406
17
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option,  1, ENC_BIG_ENDIAN); /* Opt len */
407
17
                                opt_len = tvb_get_uint8(tvb, offset_in_option );
408
17
                                proto_item_set_len(ti, opt_len+2);
409
17
                                offset_in_option += 1;
410
411
17
                                proto_tree_add_item(opt_tree, hf_dsr_fs_opt_timeout_timeout, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Timeout */
412
                                /*offset_in_option += 2;*/
413
17
                                break;
414
15
                        case DSR_FS_OPT_TYPE_DESTFLOWID:
415
15
                                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 */
416
15
                                col_append_str(pinfo->cinfo, COL_INFO, "Dest&FlowId");
417
418
15
                                proto_tree_add_item(opt_tree, hf_dsr_opttype, tvb, offset_in_option, 1, ENC_BIG_ENDIAN); /* Opt type */
419
15
                                offset_in_option += 1;
420
421
15
                                proto_tree_add_item(opt_tree, hf_dsr_optlen, tvb, offset_in_option,  1, ENC_BIG_ENDIAN); /* Opt len */
422
15
                                opt_len = tvb_get_uint8(tvb, offset_in_option );
423
15
                                proto_item_set_len(ti, opt_len+2);
424
15
                                offset_in_option += 1;
425
426
15
                                proto_tree_add_item(opt_tree, hf_dsr_fs_opt_destflowid_id, tvb, offset_in_option, 2, ENC_BIG_ENDIAN); /* Flow ID */
427
15
                                offset_in_option += 2;
428
429
15
                                proto_tree_add_item(opt_tree, hf_dsr_fs_opt_destflowid_dest, tvb, offset_in_option, 4, ENC_BIG_ENDIAN); /* Original IP Dest Address */
430
                                /*offset_in_option += 4;*/
431
15
                                break;
432
5.17k
                }
433
5.04k
                if (opt_type != DSR_OPT_TYPE_PAD1)
434
4.96k
                        offset += 2+opt_len;
435
79
                else
436
79
                        offset += 1;
437
5.04k
                if(offset-4 < opt_tot_len && opt_type != DSR_OPT_TYPE_PAD1 && opt_type != DSR_OPT_TYPE_PADN) {
438
3.55k
                        col_append_str(pinfo->cinfo, COL_INFO, ", ");
439
3.55k
                }
440
5.04k
        }
441
175
    } else { /* DSR Flow state header */
442
28
        proto_tree_add_item(dsr_tree, hf_dsr_fs_hopcount, tvb, offset, 1, ENC_BIG_ENDIAN); /* Hop count */
443
28
        offset += 1;
444
445
28
        proto_tree_add_item(dsr_tree, hf_dsr_fs_id, tvb, offset, 1, ENC_BIG_ENDIAN); /* Flow identifier */
446
28
        offset += 2;
447
28
    }
448
449
    /* Call other dissectors if needed */
450
75
    next_tvb = tvb_new_subset_remaining(tvb, offset);
451
75
    if (!dissector_try_uint(ip_dissector_table, nexthdr, next_tvb, pinfo, tree)) {
452
7
        call_data_dissector(next_tvb, pinfo, tree);
453
7
    }
454
455
75
    return offset+4;
456
203
}
457
458
/* Register DSR with Wireshark.*/
459
void
460
proto_register_dsr(void)
461
15
{
462
    /* Setup list of header fields */
463
15
    static hf_register_info hf[] = {
464
15
        { &hf_dsr_nexthdr,
465
15
            { "Next header", "dsr.nexthdr",
466
15
               FT_UINT8, BASE_HEX | BASE_EXT_STRING,
467
15
               &ipproto_val_ext, 0x0,
468
15
               "Next header protocol type", HFILL }
469
15
        },
470
15
        { &hf_dsr_flowstate,
471
15
            { "Flow state", "dsr.flowstate",
472
15
               FT_BOOLEAN, 8,
473
15
               NULL, 0x80,
474
15
               NULL, HFILL }
475
15
        },
476
        /* DSR normal header */
477
15
        { &hf_dsr_reserved,
478
15
            { "Reserved", "dsr.reserved",
479
15
               FT_UINT8, BASE_HEX,
480
15
               NULL, 0x7F,
481
15
               NULL, HFILL }
482
15
        },
483
15
        { &hf_dsr_length,
484
15
            { "Length", "dsr.len",
485
15
               FT_UINT16, BASE_DEC,
486
15
               NULL, 0x0,
487
15
              "Payload length", HFILL }
488
15
        },
489
15
        { &hf_dsr_opttype,
490
15
            { "Type", "dsr.option.type",
491
15
               FT_UINT8, BASE_DEC,
492
15
               VALS(dsropttypenames), 0x0,
493
15
               NULL, HFILL }
494
15
        },
495
15
        { &hf_dsr_optlen,
496
15
            { "Length", "dsr.option.len",
497
15
               FT_UINT8, BASE_DEC,
498
15
               NULL, 0x0,
499
15
               "Option length", HFILL }
500
15
        },
501
        /* RREQ fields */
502
15
        { &hf_dsr_opt_rreq_id,
503
15
            { "Id", "dsr.option.rreq.id",
504
15
               FT_UINT16, BASE_HEX_DEC,
505
15
               NULL, 0x0,
506
15
               NULL, HFILL }
507
15
        },
508
15
        { &hf_dsr_opt_rreq_targetaddress,
509
15
            { "Target address", "dsr.option.rreq.targetaddress",
510
15
               FT_IPv4, BASE_NONE,
511
15
               NULL, 0x0,
512
15
               "Target IP address", HFILL }
513
15
        },
514
15
        { &hf_dsr_opt_rreq_address,
515
15
            { "Hop", "dsr.option.rreq.address",
516
15
               FT_IPv4, BASE_NONE,
517
15
               NULL, 0x0,
518
15
               NULL, HFILL }
519
15
        },
520
        /* RREP fields */
521
15
        { &hf_dsr_opt_rrep_lasthopex,
522
15
            { "Last hop external", "dsr.option.rrep.lasthopex",
523
15
               FT_BOOLEAN, 8,
524
15
               NULL, 0x80,
525
15
               NULL, HFILL }
526
15
        },
527
15
        { &hf_dsr_opt_rrep_reserved,
528
15
            { "Reserved", "dsr.option.rrep.reserved",
529
15
               FT_UINT8, BASE_HEX,
530
15
               NULL, 0x7F,
531
15
               NULL, HFILL }
532
15
        },
533
15
        { &hf_dsr_opt_rrep_address,
534
15
            { "Hop", "dsr.option.rrep.address",
535
15
               FT_IPv4, BASE_NONE,
536
15
               NULL, 0x0,
537
15
               NULL, HFILL }
538
15
        },
539
        /* RERR fields */
540
15
        { &hf_dsr_opt_err_type,
541
15
            { "Type", "dsr.option.err.type",
542
15
               FT_UINT8, BASE_DEC,
543
15
               VALS(dsrrerrtypenames), 0x0,
544
15
               NULL, HFILL }
545
15
        },
546
15
        { &hf_dsr_opt_err_reserved,
547
15
            {  "Reserved", "dsr.option.err.reserved",
548
15
               FT_UINT8, BASE_HEX,
549
15
               NULL, 0x00,
550
15
               NULL, HFILL }
551
15
        },
552
15
        { &hf_dsr_opt_err_salvage,
553
15
            {  "Salvage", "dsr.option.err.salvage",
554
15
               FT_UINT8, BASE_HEX,
555
556
15
               NULL, 0x00,
557
15
               NULL, HFILL }
558
15
        },
559
15
        { &hf_dsr_opt_err_src,
560
15
            {  "Source address", "dsr.option.err.src",
561
15
               FT_IPv4, BASE_NONE,
562
15
               NULL, 0x00,
563
15
               "Source IP address", HFILL }
564
15
        },
565
15
        { &hf_dsr_opt_err_dest,
566
15
            {  "Destination address", "dsr.option.err.dest",
567
15
               FT_IPv4, BASE_NONE,
568
15
               NULL, 0x00,
569
15
               "Destination IP address", HFILL }
570
15
        },
571
15
        { &hf_dsr_opt_err_unreach_addr,
572
15
            {  "Unreachable node address", "dsr.option.err.unreachablenode",
573
15
               FT_IPv4, BASE_NONE,
574
15
               NULL, 0x00,
575
15
               "Unreachable node IP address", HFILL }
576
15
        },
577
15
        { &hf_dsr_opt_err_unsupportedoption,
578
15
            {  "Unsupported option", "dsr.option.err.unsupportedoption",
579
15
               FT_UINT8, BASE_HEX,
580
15
               NULL, 0x00,
581
15
               NULL, HFILL }
582
15
        },
583
        /* ACKREQ fields */
584
15
        { &hf_dsr_opt_ack_req_id,
585
15
            { "Id", "dsr.option.ackreq.id",
586
15
               FT_UINT16, BASE_HEX_DEC,
587
15
               NULL, 0x0,
588
15
               NULL, HFILL }
589
15
        },
590
15
        { &hf_dsr_opt_ack_req_address,
591
15
            { "Source address", "dsr.option.ackreq.address",
592
15
               FT_IPv4, BASE_NONE,
593
15
               NULL, 0x0,
594
15
               "Source IP address", HFILL }
595
15
        },
596
        /* ACK fields */
597
15
        { &hf_dsr_opt_ack_id,
598
15
            { "Id", "dsr.option.ack.id",
599
15
               FT_UINT16, BASE_HEX_DEC,
600
15
               NULL, 0x0,
601
15
               NULL, HFILL }
602
15
        },
603
15
        { &hf_dsr_opt_ack_src,
604
15
            { "Source IP", "dsr.option.ack.source",
605
15
               FT_IPv4, BASE_NONE,
606
15
               NULL, 0x0,
607
15
               "Source IP address", HFILL }
608
15
        },
609
15
        { &hf_dsr_opt_ack_dest,
610
15
            { "Destination IP", "dsr.option.ack.dest",
611
15
               FT_IPv4, BASE_NONE,
612
15
               NULL, 0x0,
613
15
               "Destination IP address", HFILL }
614
15
        },
615
        /* SRCRT fields */
616
15
        { &hf_dsr_opt_srcrt_firsthopext,
617
15
            { "First hop external", "dsr.option.srcrt.firsthopext",
618
15
               FT_BOOLEAN, BASE_NONE,
619
15
               NULL, 0x0,
620
15
               NULL, HFILL }
621
15
        },
622
15
        { &hf_dsr_opt_srcrt_lasthopext,
623
15
            { "Last hop external", "dsr.option.srcrt.lasthopext",
624
15
               FT_BOOLEAN, BASE_NONE,
625
15
               NULL, 0x0,
626
15
               NULL, HFILL }
627
15
        },
628
15
        { &hf_dsr_opt_srcrt_reserved,
629
15
            { "Reserved", "dsr.option.srcrt.reserved",
630
15
               FT_UINT8, BASE_HEX,
631
15
               NULL, 0x0,
632
15
               NULL, HFILL }
633
15
        },
634
15
        { &hf_dsr_opt_srcrt_salvage,
635
15
            { "Salvage", "dsr.option.srcrt.salvage",
636
15
               FT_UINT8, BASE_HEX,
637
15
               NULL, 0x0,
638
15
               NULL, HFILL }
639
15
        },
640
15
        { &hf_dsr_opt_srcrt_segsleft,
641
15
            { "Segments left", "dsr.option.srcrt.segsleft",
642
15
               FT_UINT8, BASE_DEC,
643
15
               NULL, 0x3F,
644
15
               NULL, HFILL }
645
15
        },
646
15
        { &hf_dsr_opt_srcrt_address,
647
15
            { "Hop", "dsr.option.ack.address",
648
15
               FT_IPv4, BASE_NONE,
649
15
               NULL, 0x0,
650
15
               "Hop IP address", HFILL }
651
15
        },
652
        /* DSR flow state */
653
15
        { &hf_dsr_fs_hopcount,
654
15
            { "Hop count", "dsr.fs.hopcount",
655
15
               FT_UINT8, BASE_DEC,
656
15
               NULL, 0x7F,
657
15
               NULL, HFILL }
658
15
        },
659
15
        { &hf_dsr_fs_id,
660
15
            { "Flow id", "dsr.fs.id",
661
15
               FT_UINT16, BASE_HEX_DEC,
662
15
               NULL, 0x00,
663
15
               NULL, HFILL }
664
15
        },
665
15
        { &hf_dsr_fs_opt_timeout_timeout,
666
15
            { "Timeout", "dsr.option.timeout.timeout",
667
15
               FT_UINT16, BASE_DEC,
668
15
               NULL, 0x0,
669
15
               NULL, HFILL }
670
15
        },
671
15
        { &hf_dsr_fs_opt_destflowid_id,
672
15
            { "Flow id", "dsr.option.destflowid.id",
673
15
               FT_UINT16, BASE_HEX_DEC,
674
15
               NULL, 0x0,
675
15
               "New flow identifier", HFILL }
676
15
        },
677
15
        { &hf_dsr_fs_opt_destflowid_dest,
678
15
            { "Destination IP", "dsr.option.destflowid.dest",
679
15
               FT_IPv4, BASE_NONE,
680
15
               NULL, 0x0,
681
15
               "New IP destination address", HFILL }
682
15
        },
683
15
        { &hf_dsr_opt_err_unknownflow_dest,
684
15
            {  "Original IP destination", "dsr.option.err.unknownflow.dest",
685
15
               FT_IPv4, BASE_NONE,
686
15
               NULL, 0x00,
687
15
               "Original IP destination address", HFILL }
688
15
        },
689
15
        { &hf_dsr_opt_err_unknownflow_id,
690
15
            {  "Flow id", "dsr.option.err.unknownflow.id",
691
15
               FT_UINT16, BASE_HEX_DEC,
692
15
               NULL, 0x00,
693
15
               NULL, HFILL }
694
15
        },
695
15
        { &hf_dsr_opt_err_defaultflowunknown_dest,
696
15
            {  "Original IP destination", "dsr.option.err.defaultflowunknown.dest",
697
15
               FT_IPv4, BASE_NONE,
698
15
               NULL, 0x00,
699
15
               NULL, HFILL }
700
15
        },
701
15
    };
702
703
    /* Setup protocol subtree array */
704
15
    static int *ett[] = {
705
15
        &ett_dsr,
706
15
        &ett_dsr_options,
707
15
        &ett_dsr_rreq_opt,
708
15
        &ett_dsr_rrep_opt,
709
15
        &ett_dsr_rerr_opt,
710
15
        &ett_dsr_ackreq_opt,
711
15
        &ett_dsr_ack_opt,
712
15
        &ett_dsr_srcrt_opt,
713
15
        &ett_dsr_padn_opt,
714
15
        &ett_dsr_pad1_opt,
715
15
        &ett_dsr_fs_timeout_opt,
716
15
        &ett_dsr_fs_destflowid_opt,
717
15
        &ett_dsr_rreq_hoplist,
718
15
        &ett_dsr_rrep_hoplist,
719
15
        &ett_dsr_srcrt_hoplist
720
15
    };
721
722
    /* Register the protocol name and description */
723
15
    proto_dsr = proto_register_protocol("Dynamic Source Routing", "DSR", "dsr");
724
15
    dsr_handle = register_dissector("dsr", dissect_dsr, proto_dsr);
725
726
    /* Required function calls to register the header fields and subtrees */
727
15
    proto_register_field_array(proto_dsr, hf, array_length(hf));
728
15
    proto_register_subtree_array(ett, array_length(ett));
729
730
15
}
731
732
void
733
proto_reg_handoff_dsr(void)
734
15
{
735
15
    ip_dissector_table = find_dissector_table("ip.proto");
736
15
    dissector_add_uint("ip.proto", IP_PROTO_DSR, dsr_handle);
737
15
}
738
/*
739
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
740
 *
741
 * Local variables:
742
 * c-basic-offset: 4
743
 * tab-width: 8
744
 * indent-tabs-mode: nil
745
 * End:
746
 *
747
 * vim: set shiftwidth=4 tabstop=8 expandtab:
748
 * :indentSize=4:tabSize=8:noTabs=true:
749
 */