HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / dissectors / packet-netrom.c
1 /* packet-netrom.c
2  *
3  * Routines for Amateur Packet Radio protocol dissection
4  * NET/ROM inter-node frames.
5  * Copyright 2005,2006,2007,2008,2009,2010,2012 R.W. Stearn <richard@rns-stearn.demon.co.uk>
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 /*
15  * Information on the protocol drawn from:
16  *
17  * Protocol specification is at:
18  *
19  *    ftp://ftp.ucsd.edu/hamradio/packet/tcpip/docs/netrom.ps.gz
20  *
21  * (yes, it's PostScript, and, yes, it's an FTP URL).
22  *
23  * Inspiration on how to build the dissector drawn from
24  *   packet-sdlc.c
25  *   packet-x25.c
26  *   packet-lapb.c
27  *   paket-gprs-llc.c
28  *   xdlc.c
29  * with the base file built from README.developers.
30  */
31
32 #include "config.h"
33
34 #include <epan/packet.h>
35 #include <epan/to_str.h>
36 #include <epan/capture_dissectors.h>
37 #include <epan/ax25_pids.h>
38
39 void proto_register_netrom(void);
40 void proto_reg_handoff_netrom(void);
41
42 #define STRLEN 80
43
44 #define NETROM_MIN_SIZE            7    /* minimum payload for a routing packet */
45 #define NETROM_HEADER_SIZE        20    /* minimum payload for a normal packet */
46
47 #define NETROM_PROTOEXT         0x00
48 #define NETROM_CONNREQ          0x01
49 #define NETROM_CONNACK          0x02
50 #define NETROM_DISCREQ          0x03
51 #define NETROM_DISCACK          0x04
52 #define NETROM_INFO             0x05
53 #define NETROM_INFOACK          0x06
54
55 #define NETROM_MORE_FLAG        0x20
56 #define NETROM_NAK_FLAG         0x40
57 #define NETROM_CHOKE_FLAG       0x80
58
59 #define NETROM_PROTO_IP         0x0C
60
61 /* Dissector handles */
62 static dissector_handle_t ip_handle;
63
64 /* Initialize the protocol and registered fields */
65 static int proto_netrom                 = -1;
66 static int hf_netrom_src                = -1;
67 static int hf_netrom_dst                = -1;
68 static int hf_netrom_ttl                = -1;
69 static int hf_netrom_my_cct_index       = -1;
70 static int hf_netrom_my_cct_id          = -1;
71 static int hf_netrom_your_cct_index     = -1;
72 static int hf_netrom_your_cct_id        = -1;
73 static int hf_netrom_n_r                = -1;
74 static int hf_netrom_n_s                = -1;
75 static int hf_netrom_type               = -1;
76 static int hf_netrom_op                 = -1;
77 static int hf_netrom_more               = -1;
78 static int hf_netrom_nak                = -1;
79 static int hf_netrom_choke              = -1;
80
81 static int hf_netrom_user               = -1;
82 static int hf_netrom_node               = -1;
83 static int hf_netrom_pwindow            = -1;
84 static int hf_netrom_awindow            = -1;
85
86 static int hf_netrom_mnemonic           = -1;
87
88 /*
89  * Structure containing pointers to hf_ values for various subfields of
90  * the type field.
91  */
92 typedef struct {
93         int     *hf_tf_op;
94         int     *hf_tf_more;
95         int     *hf_tf_nak;
96         int     *hf_tf_choke;
97 } netrom_tf_items;
98
99 static const netrom_tf_items netrom_type_items = {
100         &hf_netrom_op,
101         &hf_netrom_more,
102         &hf_netrom_nak,
103         &hf_netrom_choke
104 };
105
106
107 const value_string op_code_vals_abbrev[] = {
108         { NETROM_PROTOEXT       , "PROTOEXT"},
109         { NETROM_CONNREQ        , "CONNREQ"},
110         { NETROM_CONNACK        , "CONNACK"},
111         { NETROM_DISCREQ        , "DISCREQ"},
112         { NETROM_DISCACK        , "DISCACK"},
113         { NETROM_INFO           , "INFO"},
114         { NETROM_INFOACK        , "INFOACK"},
115         { 0                     , NULL}
116 };
117
118 const value_string op_code_vals_text[] = {
119         { NETROM_PROTOEXT       , "Protocol extension"},
120         { NETROM_CONNREQ        , "Connect request"},
121         { NETROM_CONNACK        , "Connect acknowledge"},
122         { NETROM_DISCREQ        , "Disconnect request"},
123         { NETROM_DISCACK        , "Disconnect acknowledge"},
124         { NETROM_INFO           , "Information"},
125         { NETROM_INFOACK        , "Information acknowledge"},
126         { 0                     , NULL}
127 };
128
129 /* Initialize the subtree pointers */
130 static gint ett_netrom      = -1;
131 static gint ett_netrom_type = -1;
132
133 static void
134 dissect_netrom_type(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
135                         int hf_netrom_type_param, gint ett_netrom_type_param, const netrom_tf_items *type_items )
136 {
137         proto_tree *tc;
138         proto_tree *type_tree;
139         char       *info_buffer;
140         guint8      type;
141         guint8      op_code;
142
143         type    =  tvb_get_guint8( tvb, offset );
144         op_code = type &0x0f;
145
146         info_buffer = wmem_strdup_printf( wmem_packet_scope(), "%s%s%s%s (0x%02x)",
147                                         val_to_str_const( op_code, op_code_vals_text, "Unknown" ),
148                                         ( type & NETROM_MORE_FLAG  ) ? ", More"  : "",
149                                         ( type & NETROM_NAK_FLAG   ) ? ", NAK"   : "",
150                                         ( type & NETROM_CHOKE_FLAG ) ? ", Choke" : "",
151                                         type );
152         col_add_str( pinfo->cinfo, COL_INFO, info_buffer );
153
154         if ( tree )
155                 {
156                 tc = proto_tree_add_uint_format( tree,
157                                                 hf_netrom_type_param,
158                                                 tvb,
159                                                 offset,
160                                                 1,
161                                                 type,
162                                                 "Type field: %s",
163                                                 info_buffer
164                                                 );
165                 type_tree = proto_item_add_subtree( tc, ett_netrom_type_param );
166
167                 proto_tree_add_item( type_tree, *type_items->hf_tf_op, tvb, offset, 1, ENC_BIG_ENDIAN );
168                 proto_tree_add_item( type_tree, *type_items->hf_tf_choke, tvb, offset, 1, ENC_BIG_ENDIAN );
169                 proto_tree_add_item( type_tree, *type_items->hf_tf_nak, tvb, offset, 1, ENC_BIG_ENDIAN );
170                 proto_tree_add_item( type_tree, *type_items->hf_tf_more, tvb, offset, 1, ENC_BIG_ENDIAN );
171                 }
172 }
173
174 static void
175 dissect_netrom_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
176 {
177         proto_item   *ti;
178         proto_tree   *netrom_tree;
179         int           offset;
180 #if 0
181         guint8        src_ssid;
182         guint8        dst_ssid;
183 #endif
184         guint8        op_code;
185         guint8        cct_index;
186         guint8        cct_id;
187         tvbuff_t     *next_tvb;
188
189         col_set_str( pinfo->cinfo, COL_PROTOCOL, "NET/ROM" );
190         col_clear( pinfo->cinfo, COL_INFO );
191
192         offset = 0;
193
194         /* source */
195         set_address_tvb(&pinfo->dl_src, AT_AX25, AX25_ADDR_LEN, tvb, offset);
196         set_address_tvb(&pinfo->src,    AT_AX25, AX25_ADDR_LEN, tvb, offset);
197         /* src_ssid = tvb_get_guint8(tvb, offset+6); */
198         offset += AX25_ADDR_LEN; /* step over src addr */
199
200         /* destination */
201         set_address_tvb(&pinfo->dl_dst, AT_AX25, AX25_ADDR_LEN, tvb, offset);
202         set_address_tvb(&pinfo->dst,    AT_AX25, AX25_ADDR_LEN, tvb, offset);
203         /* dst_ssid = tvb_get_guint8(tvb, offset+6); */
204         offset += AX25_ADDR_LEN; /* step over dst addr */
205
206         offset += 1; /* step over ttl */
207         cct_index =  tvb_get_guint8( tvb, offset );
208         offset += 1; /* step over cct index*/
209         cct_id =  tvb_get_guint8( tvb, offset );
210         offset += 1; /* step over cct id */
211         offset += 1; /* step over n_s */
212         offset += 1; /* step over n_r */
213
214         /* frame type */
215         op_code =  tvb_get_guint8( tvb, offset ) & 0x0f;
216         /*offset += 1;*/ /* step over op_code */
217
218         col_add_fstr( pinfo->cinfo, COL_INFO, "%s", val_to_str_const( op_code, op_code_vals_text, "Unknown" ));
219
220         /* if ( tree ) */
221                 {
222                 /* create display subtree for the protocol */
223
224                 ti = proto_tree_add_protocol_format( tree, proto_netrom, tvb, 0, NETROM_HEADER_SIZE,
225                         "NET/ROM, Src: %s, Dst: %s",
226                         address_to_str(wmem_packet_scope(), &pinfo->src),
227                         address_to_str(wmem_packet_scope(), &pinfo->dst));
228
229                 netrom_tree = proto_item_add_subtree( ti, ett_netrom );
230
231                 offset = 0;
232
233                 /* source */
234                 proto_tree_add_item( netrom_tree, hf_netrom_src, tvb, offset, AX25_ADDR_LEN, ENC_NA );
235                 offset += AX25_ADDR_LEN;
236
237                 /* destination */
238                 proto_tree_add_item( netrom_tree, hf_netrom_dst, tvb, offset, AX25_ADDR_LEN, ENC_NA );
239                 offset += AX25_ADDR_LEN;
240
241                 /* ttl */
242                 proto_tree_add_item( netrom_tree, hf_netrom_ttl, tvb, offset, 1, ENC_BIG_ENDIAN );
243                 offset += 1;
244
245                 switch ( op_code )
246                         {
247                         case NETROM_PROTOEXT    :
248                                                 /* cct index */
249                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
250                                                 offset += 1;
251
252                                                 /* cct id */
253                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
254                                                 offset += 1;
255
256                                                 /* unused */
257                                                 offset += 1;
258
259                                                 /* unused */
260                                                 offset += 1;
261                                                 break;
262                         case NETROM_CONNREQ     :
263                                                 /* cct index */
264                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
265                                                 offset += 1;
266
267                                                 /* cct id */
268                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
269                                                 offset += 1;
270
271                                                 /* unused */
272                                                 offset += 1;
273
274                                                 /* unused */
275                                                 offset += 1;
276
277                                                 break;
278                         case NETROM_CONNACK     :
279                                                 /* your cct index */
280                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
281                                                 offset += 1;
282
283                                                 /* your cct id */
284                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
285                                                 offset += 1;
286
287                                                 /* my cct index */
288                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
289                                                 offset += 1;
290
291                                                 /* my cct id */
292                                                 proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
293                                                 offset += 1;
294
295                                                 break;
296                         case NETROM_DISCREQ     :
297                                                 /* your cct index */
298                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
299                                                 offset += 1;
300
301                                                 /* your cct id */
302                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
303                                                 offset += 1;
304
305                                                 /* unused */
306                                                 offset += 1;
307
308                                                 /* unused */
309                                                 offset += 1;
310
311                                                 break;
312                         case NETROM_DISCACK     :
313                                                 /* your cct index */
314                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
315                                                 offset += 1;
316
317                                                 /* your cct id */
318                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
319                                                 offset += 1;
320
321                                                 /* unused */
322                                                 offset += 1;
323
324                                                 /* unused */
325                                                 offset += 1;
326
327                                                 break;
328                         case NETROM_INFO        :
329                                                 /* your cct index */
330                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
331                                                 offset += 1;
332
333                                                 /* your cct id */
334                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
335                                                 offset += 1;
336
337                                                 /* n_s */
338                                                 proto_tree_add_item( netrom_tree, hf_netrom_n_s, tvb, offset, 1, ENC_BIG_ENDIAN );
339                                                 offset += 1;
340
341                                                 /* n_r */
342                                                 proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN );
343                                                 offset += 1;
344
345                                                 break;
346                         case NETROM_INFOACK     :
347                                                 /* your cct index */
348                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
349                                                 offset += 1;
350
351                                                 /* your cct id */
352                                                 proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
353                                                 offset += 1;
354
355                                                 /* unused */
356                                                 offset += 1;
357
358                                                 /* n_r */
359                                                 proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN );
360                                                 offset += 1;
361
362                                                 break;
363                         default                 :
364                                                 offset += 1;
365                                                 offset += 1;
366                                                 offset += 1;
367                                                 offset += 1;
368
369                                                 break;
370                         }
371
372                 /* type */
373                 dissect_netrom_type(    tvb,
374                                         offset,
375                                         pinfo,
376                                         netrom_tree,
377                                         hf_netrom_type,
378                                         ett_netrom_type,
379                                         &netrom_type_items
380                                         );
381                 offset += 1;
382
383                 switch ( op_code )
384                         {
385                         case NETROM_PROTOEXT    :
386                                                 break;
387                         case NETROM_CONNREQ     :
388                                                 /* proposed window size */
389                                                 proto_tree_add_item( netrom_tree, hf_netrom_pwindow, tvb, offset, 1, ENC_BIG_ENDIAN );
390                                                 offset += 1;
391
392                                                 proto_tree_add_item( netrom_tree, hf_netrom_user, tvb, offset, AX25_ADDR_LEN, ENC_NA );
393                                                 offset += AX25_ADDR_LEN;
394
395                                                 proto_tree_add_item( netrom_tree, hf_netrom_node, tvb, offset, AX25_ADDR_LEN, ENC_NA );
396                                                 offset += AX25_ADDR_LEN;
397
398                                                 break;
399                         case NETROM_CONNACK     :
400                                                 /* accepted window size */
401                                                 proto_tree_add_item( netrom_tree, hf_netrom_awindow, tvb, offset, 1, ENC_BIG_ENDIAN );
402                                                 offset += 1;
403
404                                                 break;
405                         case NETROM_DISCREQ     :
406                                                 break;
407                         case NETROM_DISCACK     :
408                                                 break;
409                         case NETROM_INFO        :
410                                                 break;
411                         case NETROM_INFOACK     :
412                                                 break;
413                         default                 :
414                                                 break;
415                         }
416                 }
417
418         /* Call sub-dissectors here */
419
420         next_tvb = tvb_new_subset_remaining(tvb, offset);
421
422         switch ( op_code )
423                 {
424                 case NETROM_PROTOEXT    :
425                                         if ( cct_index == NETROM_PROTO_IP && cct_id == NETROM_PROTO_IP )
426                                                 call_dissector( ip_handle , next_tvb, pinfo, tree );
427                                         else
428                                                 call_data_dissector(next_tvb, pinfo, tree );
429
430                                         break;
431                 case NETROM_INFO        :
432                 default                 :
433                                         call_data_dissector(next_tvb, pinfo, tree );
434                                         break;
435                 }
436 }
437
438 static void
439 dissect_netrom_routing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
440 {
441         tvbuff_t *next_tvb;
442         const guint8* mnemonic;
443         gint mnemonic_len;
444
445         col_set_str( pinfo->cinfo, COL_PROTOCOL, "NET/ROM");
446         col_set_str( pinfo->cinfo, COL_INFO, "routing table frame");
447
448         if (tree)
449         {
450                 proto_item *ti;
451                 proto_tree *netrom_tree;
452                 ti = proto_tree_add_item( tree, proto_netrom, tvb, 0, -1, ENC_NA);
453                 netrom_tree = proto_item_add_subtree( ti, ett_netrom );
454
455                 proto_tree_add_item_ret_string_and_length(netrom_tree, hf_netrom_mnemonic, tvb, 1, 6, ENC_ASCII|ENC_NA,
456                                                                                                         wmem_packet_scope(), &mnemonic, &mnemonic_len);
457                 proto_item_append_text(ti, ", routing table frame, Node: %.6s", mnemonic);
458         }
459
460         next_tvb = tvb_new_subset_remaining(tvb, 7);
461
462         call_data_dissector(next_tvb, pinfo, tree );
463 }
464
465 /* Code to actually dissect the packets */
466 static int
467 dissect_netrom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
468 {
469         if ( tvb_get_guint8( tvb, 0 ) == 0xff )
470                 dissect_netrom_routing( tvb, pinfo, tree );
471         else
472                 dissect_netrom_proto( tvb, pinfo, tree );
473
474         return tvb_captured_length(tvb);
475 }
476
477 static gboolean
478 capture_netrom( const guchar *pd _U_, int offset, int len, capture_packet_info_t *cpinfo _U_, const union wtap_pseudo_header *pseudo_header _U_)
479 {
480         if ( ! BYTES_ARE_IN_FRAME( offset, len, NETROM_MIN_SIZE ) )
481                 return FALSE;
482
483         /* XXX - check for IP-over-NetROM here! */
484         return FALSE;
485 }
486
487 void
488 proto_register_netrom(void)
489 {
490         /* Setup list of header fields */
491         static hf_register_info hf[] = {
492                 { &hf_netrom_src,
493                         { "Source",                     "netrom.src",
494                         FT_AX25, BASE_NONE, NULL, 0x0,
495                         "Source callsign", HFILL }
496                 },
497                 { &hf_netrom_dst,
498                         { "Destination",                "netrom.dst",
499                         FT_AX25, BASE_NONE, NULL, 0x0,
500                         "Destination callsign", HFILL }
501                 },
502                 { &hf_netrom_ttl,
503                         { "TTL",                        "netrom.ttl",
504                         FT_UINT8, BASE_HEX, NULL, 0x0,
505                         NULL, HFILL }
506                 },
507                 { &hf_netrom_my_cct_index,
508                         { "My circuit index",           "netrom.my.cct.index",
509                         FT_UINT8, BASE_HEX, NULL, 0x0,
510                         NULL, HFILL }
511                 },
512                 { &hf_netrom_my_cct_id,
513                         { "My circuit ID",              "netrom.my.cct.id",
514                         FT_UINT8, BASE_HEX, NULL, 0x0,
515                         NULL, HFILL }
516                 },
517                 { &hf_netrom_your_cct_index,
518                         { "Your circuit index",         "netrom.your.cct.index",
519                         FT_UINT8, BASE_HEX, NULL, 0x0,
520                         NULL, HFILL }
521                 },
522                 { &hf_netrom_your_cct_id,
523                         { "Your circuit ID",            "netrom.your.cct.id",
524                         FT_UINT8, BASE_HEX, NULL, 0x0,
525                         NULL, HFILL }
526                 },
527                 { &hf_netrom_n_r,
528                         { "N(r)",                       "netrom.n_r",
529                         FT_UINT8, BASE_DEC, NULL, 0x0,
530                         NULL, HFILL }
531                 },
532                 { &hf_netrom_n_s,
533                         { "N(s)",                       "netrom.n_s",
534                         FT_UINT8, BASE_DEC, NULL, 0x0,
535                         NULL, HFILL }
536                 },
537                 { &hf_netrom_type,
538                         { "Type",                       "netrom.type",
539                         FT_UINT8, BASE_HEX, NULL, 0x0,
540                         "Packet type field", HFILL }
541                 },
542                 { &hf_netrom_op,
543                         { "OP code",                    "netrom.op",
544                         FT_UINT8, BASE_HEX, VALS( op_code_vals_abbrev ), 0x0f,
545                         "Protocol operation code", HFILL }
546                 },
547                 { &hf_netrom_more,
548                         { "More",                       "netrom.flag.more",
549                         FT_BOOLEAN, 8, TFS(&tfs_set_notset), NETROM_MORE_FLAG,
550                         "More flag", HFILL }
551                 },
552                 { &hf_netrom_nak,
553                         { "NAK",                        "netrom.flag.nak",
554                         FT_BOOLEAN, 8, TFS(&tfs_set_notset), NETROM_NAK_FLAG,
555                         "NAK flag", HFILL }
556                 },
557                 { &hf_netrom_choke,
558                         { "Choke",                      "netrom.flag.choke",
559                         FT_BOOLEAN, 8, TFS(&tfs_set_notset), NETROM_CHOKE_FLAG,
560                         "Choke flag", HFILL }
561                 },
562                 { &hf_netrom_user,
563                         { "User",                       "netrom.user",
564                         FT_AX25, BASE_NONE, NULL, 0x0,
565                         "User callsign", HFILL }
566                 },
567                 { &hf_netrom_node,
568                         { "Node",                       "netrom.node",
569                         FT_AX25, BASE_NONE, NULL, 0x0,
570                         "Node callsign", HFILL }
571                 },
572                 { &hf_netrom_pwindow,
573                         { "Window",                     "netrom.pwindow",
574                         FT_UINT8, BASE_DEC, NULL, 0x0,
575                         "Proposed window", HFILL }
576                 },
577                 { &hf_netrom_awindow,
578                         { "Window",                     "netrom.awindow",
579                         FT_UINT8, BASE_DEC, NULL, 0x0,
580                         "Accepted window", HFILL }
581                 },
582                 { &hf_netrom_mnemonic,
583                         { "Node name",                  "netrom.name",
584                         FT_STRING, BASE_NONE, NULL, 0x0,
585                         NULL, HFILL }
586                 },
587         };
588
589         /* Setup protocol subtree array */
590         static gint *ett[] = {
591                 &ett_netrom,
592                 &ett_netrom_type,
593         };
594
595         /* Register the protocol name and description */
596         proto_netrom = proto_register_protocol( "Amateur Radio NET/ROM", "NET/ROM", "netrom" );
597
598         /* Required function calls to register the header fields and subtrees used */
599         proto_register_field_array( proto_netrom, hf, array_length(hf ) );
600         proto_register_subtree_array( ett, array_length( ett ) );
601 }
602
603 void
604 proto_reg_handoff_netrom(void)
605 {
606         capture_dissector_handle_t netrom_cap_handle;
607
608         dissector_add_uint( "ax25.pid", AX25_P_NETROM, create_dissector_handle( dissect_netrom, proto_netrom ) );
609         netrom_cap_handle = create_capture_dissector_handle(capture_netrom, proto_netrom);
610         capture_dissector_add_uint("ax25.pid", AX25_P_NETROM, netrom_cap_handle);
611
612         ip_handle   = find_dissector_add_dependency( "ip", proto_netrom );
613 }
614
615 /*
616  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
617  *
618  * Local variables:
619  * c-basic-offset: 8
620  * tab-width: 8
621  * indent-tabs-mode: t
622  * End:
623  *
624  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
625  * :indentSize=8:tabSize=8:noTabs=false:
626  */