2 * Routines for LBT-RU Packet dissection
4 * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/prefs.h>
16 #include <epan/expert.h>
18 #include <epan/conversation.h>
19 #include <epan/to_str.h>
21 #include "packet-lbm.h"
22 #include "packet-lbtru.h"
24 void proto_register_lbtru(void);
25 void proto_reg_handoff_lbtru(void);
28 static int proto_lbtru
;
30 /* Dissector handle */
31 static dissector_handle_t lbtru_dissector_handle
;
34 static int lbtru_tap_handle
= -1;
36 /*----------------------------------------------------------------------------*/
37 /* LBT-RU transport management. */
38 /*----------------------------------------------------------------------------*/
40 static const address lbtru_null_address
= ADDRESS_INIT_NONE
;
42 static lbtru_transport_t
* lbtru_transport_find(const address
* source_address
, uint16_t source_port
, uint32_t session_id
, uint32_t frame
)
44 lbtru_transport_t
* entry
= NULL
;
45 wmem_tree_t
* session_tree
= NULL
;
46 conversation_t
* conv
= NULL
;
48 conv
= find_conversation(frame
, source_address
, &lbtru_null_address
, CONVERSATION_UDP
, source_port
, 0, 0);
53 if (conv
->setup_frame
== 0)
55 conv
->setup_frame
= frame
;
57 if (frame
> conv
->last_frame
)
59 conv
->last_frame
= frame
;
62 session_tree
= (wmem_tree_t
*) conversation_get_proto_data(conv
, proto_lbtru
);
63 if (session_tree
!= NULL
)
65 entry
= (lbtru_transport_t
*) wmem_tree_lookup32(session_tree
, session_id
);
71 lbtru_transport_t
* lbtru_transport_add(const address
* source_address
, uint16_t source_port
, uint32_t session_id
, uint32_t frame
)
73 lbtru_transport_t
* entry
= NULL
;
74 wmem_tree_t
* session_tree
= NULL
;
75 conversation_t
* conv
= NULL
;
77 conv
= find_conversation(frame
, source_address
, &lbtru_null_address
, CONVERSATION_UDP
, source_port
, 0, 0);
80 conv
= conversation_new(frame
, source_address
, &lbtru_null_address
, CONVERSATION_UDP
, source_port
, 0, 0);
84 if (conv
->setup_frame
== 0)
86 conv
->setup_frame
= frame
;
88 if (frame
> conv
->last_frame
)
90 conv
->last_frame
= frame
;
93 session_tree
= (wmem_tree_t
*) conversation_get_proto_data(conv
, proto_lbtru
);
94 if (session_tree
== NULL
)
96 session_tree
= wmem_tree_new(wmem_file_scope());
97 conversation_add_proto_data(conv
, proto_lbtru
, (void *)session_tree
);
99 entry
= (lbtru_transport_t
*) wmem_tree_lookup32(session_tree
, session_id
);
104 entry
= wmem_new(wmem_file_scope(), lbtru_transport_t
);
105 copy_address_wmem(wmem_file_scope(), &(entry
->source_address
), source_address
);
106 entry
->source_port
= source_port
;
107 entry
->session_id
= session_id
;
108 entry
->channel
= lbm_channel_assign(LBM_CHANNEL_TRANSPORT_LBTRU
);
109 entry
->next_client_id
= 1;
110 entry
->client_list
= wmem_list_new(wmem_file_scope());
111 wmem_tree_insert32(session_tree
, session_id
, (void *) entry
);
115 static lbtru_client_transport_t
* lbtru_client_transport_find(lbtru_transport_t
* transport
, const address
* receiver_address
, uint16_t receiver_port
, uint32_t frame
)
117 lbtru_client_transport_t
* entry
= NULL
;
118 conversation_t
* client_conv
= NULL
;
120 if (transport
== NULL
)
124 client_conv
= find_conversation(frame
, &(transport
->source_address
), receiver_address
, CONVERSATION_UDP
, transport
->source_port
, receiver_port
, 0);
125 if (client_conv
!= NULL
)
127 wmem_tree_t
* session_tree
= NULL
;
129 session_tree
= (wmem_tree_t
*) conversation_get_proto_data(client_conv
, proto_lbtru
);
130 if (session_tree
!= NULL
)
132 entry
= (lbtru_client_transport_t
*) wmem_tree_lookup32(session_tree
, transport
->session_id
);
138 static lbtru_client_transport_t
* lbtru_client_transport_add(lbtru_transport_t
* transport
, const address
* receiver_address
, uint16_t receiver_port
, uint32_t frame
)
140 lbtru_client_transport_t
* entry
= NULL
;
141 conversation_t
* client_conv
= NULL
;
142 wmem_tree_t
* session_tree
= NULL
;
144 if (transport
== NULL
)
148 entry
= lbtru_client_transport_find(transport
, receiver_address
, receiver_port
, frame
);
153 entry
= wmem_new0(wmem_file_scope(), lbtru_client_transport_t
);
154 copy_address_wmem(wmem_file_scope(), &(entry
->receiver_address
), receiver_address
);
155 entry
->receiver_port
= receiver_port
;
156 entry
->transport
= transport
;
157 entry
->id
= transport
->next_client_id
++;
158 entry
->frame
= wmem_tree_new(wmem_file_scope());
159 entry
->last_frame
= NULL
;
160 entry
->last_data_frame
= NULL
;
161 entry
->last_sm_frame
= NULL
;
162 entry
->last_nak_frame
= NULL
;
163 entry
->last_ncf_frame
= NULL
;
164 entry
->last_ack_frame
= NULL
;
165 entry
->last_creq_frame
= NULL
;
166 entry
->last_rst_frame
= NULL
;
167 entry
->data_sqn
= wmem_tree_new(wmem_file_scope());
168 entry
->sm_sqn
= wmem_tree_new(wmem_file_scope());
169 entry
->data_high_sqn
= 0;
170 entry
->sm_high_sqn
= 0;
172 /* See if a conversation for this address/port pair exists. */
173 client_conv
= find_conversation(frame
, &(transport
->source_address
), receiver_address
, CONVERSATION_UDP
, transport
->source_port
, receiver_port
, 0);
174 if (client_conv
== NULL
)
176 client_conv
= conversation_new(frame
, &(transport
->source_address
), receiver_address
, CONVERSATION_UDP
, transport
->source_port
, receiver_port
, 0);
177 session_tree
= wmem_tree_new(wmem_file_scope());
178 conversation_add_proto_data(client_conv
, proto_lbtru
, (void *) session_tree
);
182 session_tree
= (wmem_tree_t
*) conversation_get_proto_data(client_conv
, proto_lbtru
);
183 if (session_tree
== NULL
)
185 session_tree
= wmem_tree_new(wmem_file_scope());
186 conversation_add_proto_data(client_conv
, proto_lbtru
, (void *) session_tree
);
189 wmem_tree_insert32(session_tree
, transport
->session_id
, (void *) entry
);
191 /* Add this client to the transport. */
192 wmem_list_append(transport
->client_list
, (void *) entry
);
196 static lbm_transport_sqn_t
* lbtru_client_transport_sqn_find(lbtru_client_transport_t
* client
, uint8_t type
, uint32_t sqn
)
198 lbm_transport_sqn_t
* sqn_entry
= NULL
;
202 case LBTRU_PACKET_TYPE_DATA
:
203 sqn_entry
= (lbm_transport_sqn_t
*) wmem_tree_lookup32(client
->data_sqn
, sqn
);
205 case LBTRU_PACKET_TYPE_SM
:
206 sqn_entry
= (lbm_transport_sqn_t
*) wmem_tree_lookup32(client
->sm_sqn
, sqn
);
208 case LBTRU_PACKET_TYPE_NAK
:
209 case LBTRU_PACKET_TYPE_NCF
:
210 case LBTRU_PACKET_TYPE_ACK
:
211 case LBTRU_PACKET_TYPE_CREQ
:
212 case LBTRU_PACKET_TYPE_RST
:
220 static lbm_transport_sqn_t
* lbtru_client_transport_sqn_add(lbtru_client_transport_t
* client
, lbm_transport_frame_t
* frame
)
222 wmem_tree_t
* sqn_list
= NULL
;
223 lbm_transport_sqn_t
* sqn_entry
= NULL
;
227 case LBTRU_PACKET_TYPE_DATA
:
228 sqn_list
= client
->data_sqn
;
230 case LBTRU_PACKET_TYPE_SM
:
231 sqn_list
= client
->sm_sqn
;
233 case LBTRU_PACKET_TYPE_NAK
:
234 case LBTRU_PACKET_TYPE_NCF
:
235 case LBTRU_PACKET_TYPE_ACK
:
236 case LBTRU_PACKET_TYPE_CREQ
:
237 case LBTRU_PACKET_TYPE_RST
:
243 sqn_entry
= lbm_transport_sqn_add(sqn_list
, frame
);
247 static lbm_transport_frame_t
* lbtru_client_transport_frame_find(lbtru_client_transport_t
* client
, uint32_t frame
)
249 return ((lbm_transport_frame_t
*) wmem_tree_lookup32(client
->frame
, frame
));
252 static lbm_transport_frame_t
* lbtru_client_transport_frame_add(lbtru_client_transport_t
* client
, uint8_t type
, uint32_t frame
, uint32_t sqn
, bool retransmission
)
254 lbm_transport_sqn_t
* dup_sqn_entry
= NULL
;
255 lbm_transport_frame_t
* frame_entry
= NULL
;
257 /* Locate the frame. */
258 frame_entry
= lbtru_client_transport_frame_find(client
, frame
);
259 if (frame_entry
!= NULL
)
261 return (frame_entry
);
263 frame_entry
= lbm_transport_frame_add(client
->frame
, type
, frame
, sqn
, retransmission
);
264 if (client
->last_frame
!= NULL
)
266 frame_entry
->previous_frame
= client
->last_frame
->frame
;
267 client
->last_frame
->next_frame
= frame
;
269 client
->last_frame
= frame_entry
;
272 case LBTRU_PACKET_TYPE_DATA
:
273 if (client
->last_data_frame
!= NULL
)
275 frame_entry
->previous_type_frame
= client
->last_data_frame
->frame
;
276 client
->last_data_frame
->next_type_frame
= frame
;
277 /* Ideally, this frame's sqn is 1 more than the highest data sqn seen */
278 if (frame_entry
->sqn
<= client
->data_high_sqn
)
280 dup_sqn_entry
= lbtru_client_transport_sqn_find(client
, type
, frame_entry
->sqn
);
281 if (!frame_entry
->retransmission
)
284 if (dup_sqn_entry
!= NULL
)
286 frame_entry
->duplicate
= true;
288 if (frame_entry
->sqn
!= client
->data_high_sqn
)
290 frame_entry
->ooo_gap
= client
->data_high_sqn
- frame_entry
->sqn
;
296 if (!frame_entry
->retransmission
)
298 if (frame_entry
->sqn
!= (client
->data_high_sqn
+ 1))
301 frame_entry
->sqn_gap
= frame_entry
->sqn
- (client
->last_data_frame
->sqn
+ 1);
306 if ((frame_entry
->sqn
> client
->data_high_sqn
) && !frame_entry
->retransmission
)
308 client
->data_high_sqn
= frame_entry
->sqn
;
310 client
->last_data_frame
= frame_entry
;
312 case LBTRU_PACKET_TYPE_SM
:
313 if (client
->last_sm_frame
!= NULL
)
315 frame_entry
->previous_type_frame
= client
->last_sm_frame
->frame
;
316 client
->last_sm_frame
->next_type_frame
= frame
;
317 /* Ideally, this frame's sqn is 1 more than the highest SM sqn seen */
318 if (frame_entry
->sqn
<= client
->sm_high_sqn
)
321 dup_sqn_entry
= lbtru_client_transport_sqn_find(client
, type
, frame_entry
->sqn
);
322 if (dup_sqn_entry
!= NULL
)
324 frame_entry
->duplicate
= true;
326 if (frame_entry
->sqn
!= client
->sm_high_sqn
)
328 frame_entry
->ooo_gap
= client
->sm_high_sqn
- frame_entry
->sqn
;
333 if (frame_entry
->sqn
!= (client
->sm_high_sqn
+ 1))
336 frame_entry
->sqn_gap
= frame_entry
->sqn
- (client
->sm_high_sqn
+ 1);
340 if (frame_entry
->sqn
> client
->sm_high_sqn
)
342 client
->sm_high_sqn
= frame_entry
->sqn
;
344 client
->last_sm_frame
= frame_entry
;
346 case LBTRU_PACKET_TYPE_NAK
:
347 if (client
->last_nak_frame
!= NULL
)
349 frame_entry
->previous_type_frame
= client
->last_nak_frame
->frame
;
350 client
->last_nak_frame
->next_type_frame
= frame
;
352 client
->last_nak_frame
= frame_entry
;
354 case LBTRU_PACKET_TYPE_NCF
:
355 if (client
->last_ncf_frame
!= NULL
)
357 frame_entry
->previous_type_frame
= client
->last_ncf_frame
->frame
;
358 client
->last_ncf_frame
->next_type_frame
= frame
;
360 client
->last_ncf_frame
= frame_entry
;
362 case LBTRU_PACKET_TYPE_ACK
:
363 if (client
->last_ack_frame
!= NULL
)
365 frame_entry
->previous_type_frame
= client
->last_ack_frame
->frame
;
366 client
->last_ack_frame
->next_type_frame
= frame
;
368 client
->last_ack_frame
= frame_entry
;
370 case LBTRU_PACKET_TYPE_CREQ
:
371 if (client
->last_creq_frame
!= NULL
)
373 frame_entry
->previous_type_frame
= client
->last_creq_frame
->frame
;
374 client
->last_creq_frame
->next_type_frame
= frame
;
376 client
->last_creq_frame
= frame_entry
;
378 case LBTRU_PACKET_TYPE_RST
:
379 if (client
->last_rst_frame
!= NULL
)
381 frame_entry
->previous_type_frame
= client
->last_rst_frame
->frame
;
382 client
->last_rst_frame
->next_type_frame
= frame
;
384 client
->last_rst_frame
= frame_entry
;
389 (void)lbtru_client_transport_sqn_add(client
, frame_entry
);
390 return (frame_entry
);
393 static char * lbtru_transport_source_string_format(wmem_allocator_t
*scope
, const address
* source_address
, uint16_t source_port
, uint32_t session_id
)
395 char * bufptr
= NULL
;
399 bufptr
= wmem_strdup_printf(scope
, "LBT-RU:%s:%" PRIu16
, address_to_str(scope
, source_address
), source_port
);
403 bufptr
= wmem_strdup_printf(scope
, "LBT-RU:%s:%" PRIu16
":%08x", address_to_str(scope
, source_address
), source_port
, session_id
);
408 char * lbtru_transport_source_string(const address
* source_address
, uint16_t source_port
, uint32_t session_id
)
410 /* Returns a file-scoped string. */
411 return lbtru_transport_source_string_format(wmem_file_scope(), source_address
, source_port
, session_id
);
414 static char * lbtru_transport_source_string_transport(wmem_allocator_t
*scope
, lbtru_transport_t
* transport
)
416 return lbtru_transport_source_string_format(scope
, &(transport
->source_address
), transport
->source_port
, transport
->session_id
);
419 /*----------------------------------------------------------------------------*/
420 /* Packet layouts. */
421 /*----------------------------------------------------------------------------*/
423 /* LBT-RU main header */
426 lbm_uint8_t ver_type
;
427 lbm_uint8_t next_hdr
;
428 lbm_uint16_t flags_or_res
;
430 #define O_LBTRU_HDR_T_VER_TYPE OFFSETOF(lbtru_hdr_t, ver_type)
431 #define L_LBTRU_HDR_T_VER_TYPE SIZEOF(lbtru_hdr_t, ver_type)
432 #define O_LBTRU_HDR_T_NEXT_HDR OFFSETOF(lbtru_hdr_t, next_hdr)
433 #define L_LBTRU_HDR_T_NEXT_HDR SIZEOF(lbtru_hdr_t, next_hdr)
434 #define O_LBTRU_HDR_T_FLAGS_OR_RES OFFSETOF(lbtru_hdr_t, flags_or_res)
435 #define L_LBTRU_HDR_T_FLAGS_OR_RES SIZEOF(lbtru_hdr_t, flags_or_res)
436 #define L_LBTRU_HDR_T (int) sizeof(lbtru_hdr_t)
438 #define LBTRU_VERSION 0x00
439 #define LBTRU_HDR_VER(x) (x >> 4)
440 #define LBTRU_HDR_TYPE(x) (x & 0x0F)
441 #define LBTRU_HDR_VER_VER_MASK 0xF0
442 #define LBTRU_HDR_VER_TYPE_MASK 0x0F
444 #define LBTRU_RETRANSMISSION_FLAG 0x4000
446 /* LBT-RU data header */
450 lbm_uint32_t trail_sqn
;
452 #define O_LBTRU_DATA_HDR_T_SQN OFFSETOF(lbtru_data_hdr_t, sqn)
453 #define L_LBTRU_DATA_HDR_T_SQN SIZEOF(lbtru_data_hdr_t, sqn)
454 #define O_LBTRU_DATA_HDR_T_TRAIL_SQN OFFSETOF(lbtru_data_hdr_t, trail_sqn)
455 #define L_LBTRU_DATA_HDR_T_TRAIL_SQN SIZEOF(lbtru_data_hdr_t, trail_sqn)
456 #define L_LBTRU_DATA_HDR_T (int) (sizeof(lbtru_data_hdr_t))
458 /* LBT-RU Session Message header */
462 lbm_uint32_t lead_sqn
;
463 lbm_uint32_t trail_sqn
;
465 #define O_LBTRU_SM_HDR_T_SM_SQN OFFSETOF(lbtru_sm_hdr_t, sm_sqn)
466 #define L_LBTRU_SM_HDR_T_SM_SQN SIZEOF(lbtru_sm_hdr_t, sm_sqn)
467 #define O_LBTRU_SM_HDR_T_LEAD_SQN OFFSETOF(lbtru_sm_hdr_t, lead_sqn)
468 #define L_LBTRU_SM_HDR_T_LEAD_SQN SIZEOF(lbtru_sm_hdr_t, lead_sqn)
469 #define O_LBTRU_SM_HDR_T_TRAIL_SQN OFFSETOF(lbtru_sm_hdr_t, trail_sqn)
470 #define L_LBTRU_SM_HDR_T_TRAIL_SQN SIZEOF(lbtru_sm_hdr_t, trail_sqn)
471 #define L_LBTRU_SM_HDR_T (int) (sizeof(lbtru_sm_hdr_t))
473 #define LBTRU_SM_SYN_FLAG 0x8000
475 /* LBT-RU NAK header */
478 lbm_uint16_t num_naks
;
481 #define O_LBTRU_NAK_HDR_T_NUM_NAKS OFFSETOF(lbtru_nak_hdr_t, num_naks)
482 #define L_LBTRU_NAK_HDR_T_NUM_NAKS SIZEOF(lbtru_nak_hdr_t, num_naks)
483 #define O_LBTRU_NAK_HDR_T_FORMAT OFFSETOF(lbtru_nak_hdr_t, format)
484 #define L_LBTRU_NAK_HDR_T_FORMAT SIZEOF(lbtru_nak_hdr_t, format)
485 #define L_LBTRU_NAK_HDR_T (int) (sizeof(lbtru_nak_hdr_t))
487 #define LBTRU_NAK_SELECTIVE_FORMAT 0x0
488 #define LBTRU_NAK_HDR_FORMAT_MASK 0x000F
489 #define LBTRU_NAK_HDR_FORMAT(x) (x & 0xF)
491 /* LBT-RU NAK Confirmation header */
494 lbm_uint32_t trail_sqn
;
495 lbm_uint16_t num_ncfs
;
496 lbm_uint8_t reserved
;
497 lbm_uint8_t reason_format
;
499 #define O_LBTRU_NCF_HDR_T_TRAIL_SQN OFFSETOF(lbtru_ncf_hdr_t, trail_sqn)
500 #define L_LBTRU_NCF_HDR_T_TRAIL_SQN SIZEOF(lbtru_ncf_hdr_t, trail_sqn)
501 #define O_LBTRU_NCF_HDR_T_NUM_NCFS OFFSETOF(lbtru_ncf_hdr_t, num_ncfs)
502 #define L_LBTRU_NCF_HDR_T_NUM_NCFS SIZEOF(lbtru_ncf_hdr_t, num_ncfs)
503 #define O_LBTRU_NCF_HDR_T_RESERVED OFFSETOF(lbtru_ncf_hdr_t, reserved)
504 #define L_LBTRU_NCF_HDR_T_RESERVED SIZEOF(lbtru_ncf_hdr_t, reserved)
505 #define O_LBTRU_NCF_HDR_T_REASON_FORMAT OFFSETOF(lbtru_ncf_hdr_t, reason_format)
506 #define L_LBTRU_NCF_HDR_T_REASON_FORMAT SIZEOF(lbtru_ncf_hdr_t, reason_format)
507 #define L_LBTRU_NCF_HDR_T (int) (sizeof(lbtru_ncf_hdr_t))
509 #define LBTRU_NCF_SELECTIVE_FORMAT 0x0
510 #define LBTRU_NCF_HDR_REASON(x) ((x & 0xF0) >> 4)
511 #define LBTRU_NCF_HDR_FORMAT(x) (x & 0xF)
512 #define LBTRU_NCF_HDR_REASON_MASK 0xF0
513 #define LBTRU_NCF_HDR_FORMAT_MASK 0x0F
515 /* LBT-RU ACK header */
518 lbm_uint32_t ack_sqn
;
520 #define O_LBTRU_ACK_HDR_T_ACK_SQN OFFSETOF(lbtru_ack_hdr_t, ack_sqn)
521 #define L_LBTRU_ACK_HDR_T_ACK_SQN SIZEOF(lbtru_ack_hdr_t, ack_sqn)
522 #define L_LBTRU_ACK_HDR_T (int) (sizeof(lbtru_ack_hdr_t))
524 /* LBT-RU basic option header */
527 lbm_uint8_t next_hdr
;
531 #define O_LBTRU_BASIC_OPT_T_NEXT_HDR OFFSETOF(lbtru_basic_opt_t, next_hdr)
532 #define L_LBTRU_BASIC_OPT_T_NEXT_HDR SIZEOF(lbtru_basic_opt_t, next_hdr)
533 #define O_LBTRU_BASIC_OPT_T_HDR_LEN OFFSETOF(lbtru_basic_opt_t, hdr_len)
534 #define L_LBTRU_BASIC_OPT_T_HDR_LEN SIZEOF(lbtru_basic_opt_t, hdr_len)
535 #define O_LBTRU_BASIC_OPT_T_RES OFFSETOF(lbtru_basic_opt_t, res)
536 #define L_LBTRU_BASIC_OPT_T_RES SIZEOF(lbtru_basic_opt_t, res)
537 #define L_LBTRU_BASIC_OPT_T (int) (sizeof(lbtru_basic_opt_t))
539 /* LBT-RU Session ID option header */
542 lbm_uint32_t session_id
;
544 #define O_LBTRU_SID_OPT_T_SESSION_ID OFFSETOF(lbtru_sid_opt_t, session_id)
545 #define L_LBTRU_SID_OPT_T_SESSION_ID SIZEOF(lbtru_sid_opt_t, session_id)
546 #define L_LBTRU_SID_OPT_T (int) (sizeof(lbtru_sid_opt_t))
548 /* LBT-RU Client ID option header */
551 lbm_uint32_t client_sid
;
553 #define O_LBTRU_CID_OPT_T_CLIENT_SID OFFSETOF(lbtru_cid_opt_t, client_sid)
554 #define L_LBTRU_CID_OPT_T_CLIENT_SID SIZEOF(lbtru_cid_opt_t, client_sid)
555 #define L_LBTRU_CID_OPT_T (int) (sizeof(lbtru_cid_opt_t))
557 #define LBTRU_OPT_IGNORE 0x8000
559 #define LBTRU_NHDR_DATA 0x00
560 #define LBTRU_NHDR_SID 0x01
561 #define LBTRU_NHDR_CID 0x02
563 /*----------------------------------------------------------------------------*/
564 /* Value translation tables. */
565 /*----------------------------------------------------------------------------*/
567 static const value_string lbtru_packet_type
[] =
569 { LBTRU_PACKET_TYPE_DATA
, "DATA" },
570 { LBTRU_PACKET_TYPE_SM
, "SM" },
571 { LBTRU_PACKET_TYPE_NAK
, "NAK" },
572 { LBTRU_PACKET_TYPE_NCF
, "NCF" },
573 { LBTRU_PACKET_TYPE_ACK
, "ACK" },
574 { LBTRU_PACKET_TYPE_CREQ
, "CREQ" },
575 { LBTRU_PACKET_TYPE_RST
, "RST" },
579 static const value_string lbtru_nak_format
[] =
581 { LBTRU_NAK_SELECTIVE_FORMAT
, "Selective" },
585 static const value_string lbtru_ncf_format
[] =
587 { LBTRU_NCF_SELECTIVE_FORMAT
, "Selective" },
591 static const value_string lbtru_ncf_reason
[] =
593 { LBTRU_NCF_REASON_NO_RETRY
, "Do not retry" },
594 { LBTRU_NCF_REASON_IGNORED
, "NAK Ignored" },
595 { LBTRU_NCF_REASON_RX_DELAY
, "Retransmit Delay" },
596 { LBTRU_NCF_REASON_SHED
, "NAK Shed" },
600 static const value_string lbtru_creq_request
[] =
602 { LBTRU_CREQ_REQUEST_SYN
, "SYN" },
606 static const value_string lbtru_rst_reason
[] =
608 { LBTRU_RST_REASON_DEFAULT
, "Default" },
612 static const value_string lbtru_next_header
[] =
614 { LBTRU_NHDR_DATA
, "DATA" },
615 { LBTRU_NHDR_SID
, "SID" },
616 { LBTRU_NHDR_CID
, "CID" },
620 /*----------------------------------------------------------------------------*/
622 /*----------------------------------------------------------------------------*/
624 /* Preferences default values. */
625 #define LBTRU_DEFAULT_SOURCE_PORT_LOW 14380
626 #define LBTRU_DEFAULT_SOURCE_PORT_HIGH 14389
627 #define LBTRU_DEFAULT_RECEIVER_PORT_LOW 14360
628 #define LBTRU_DEFAULT_RECEIVER_PORT_HIGH 14379
630 /* Global preferences variables (altered by the preferences dialog). */
631 static uint32_t global_lbtru_source_port_low
= LBTRU_DEFAULT_SOURCE_PORT_LOW
;
632 static uint32_t global_lbtru_source_port_high
= LBTRU_DEFAULT_SOURCE_PORT_HIGH
;
633 static uint32_t global_lbtru_receiver_port_low
= LBTRU_DEFAULT_RECEIVER_PORT_LOW
;
634 static uint32_t global_lbtru_receiver_port_high
= LBTRU_DEFAULT_RECEIVER_PORT_HIGH
;
635 static bool global_lbtru_expert_separate_naks
;
636 static bool global_lbtru_expert_separate_ncfs
;
637 static bool global_lbtru_use_tag
;
638 static bool global_lbtru_sequence_analysis
;
640 /* Local preferences variables (used by the dissector). */
641 static uint32_t lbtru_source_port_low
= LBTRU_DEFAULT_SOURCE_PORT_LOW
;
642 static uint32_t lbtru_source_port_high
= LBTRU_DEFAULT_SOURCE_PORT_HIGH
;
643 static uint32_t lbtru_receiver_port_low
= LBTRU_DEFAULT_RECEIVER_PORT_LOW
;
644 static uint32_t lbtru_receiver_port_high
= LBTRU_DEFAULT_RECEIVER_PORT_HIGH
;
645 static bool lbtru_expert_separate_naks
;
646 static bool lbtru_expert_separate_ncfs
;
647 static bool lbtru_use_tag
;
648 static bool lbtru_sequence_analysis
;
650 /*----------------------------------------------------------------------------*/
651 /* Tag management. */
652 /*----------------------------------------------------------------------------*/
656 uint32_t source_port_low
;
657 uint32_t source_port_high
;
658 uint32_t receiver_port_low
;
659 uint32_t receiver_port_high
;
662 static lbtru_tag_entry_t
* lbtru_tag_entry
;
663 static unsigned lbtru_tag_count
;
665 UAT_CSTRING_CB_DEF(lbtru_tag
, name
, lbtru_tag_entry_t
)
666 UAT_DEC_CB_DEF(lbtru_tag
, source_port_low
, lbtru_tag_entry_t
)
667 UAT_DEC_CB_DEF(lbtru_tag
, source_port_high
, lbtru_tag_entry_t
)
668 UAT_DEC_CB_DEF(lbtru_tag
, receiver_port_low
, lbtru_tag_entry_t
)
669 UAT_DEC_CB_DEF(lbtru_tag
, receiver_port_high
, lbtru_tag_entry_t
)
670 static uat_field_t lbtru_tag_array
[] =
672 UAT_FLD_CSTRING(lbtru_tag
, name
, "Tag name", "Tag name"),
673 UAT_FLD_DEC(lbtru_tag
, source_port_low
, "Source port low", "Source port low"),
674 UAT_FLD_DEC(lbtru_tag
, source_port_high
, "Source port high", "Source port high"),
675 UAT_FLD_DEC(lbtru_tag
, receiver_port_low
, "Receiver port low", "Receiver port low"),
676 UAT_FLD_DEC(lbtru_tag
, receiver_port_high
, "Receiver port high", "Receiver port high"),
680 /*----------------------------------------------------------------------------*/
681 /* UAT callback functions. */
682 /*----------------------------------------------------------------------------*/
683 static bool lbtru_tag_update_cb(void * record
, char * * error_string
)
685 lbtru_tag_entry_t
* tag
= (lbtru_tag_entry_t
*)record
;
687 if (tag
->name
== NULL
)
689 *error_string
= g_strdup("Tag name can't be empty");
694 g_strstrip(tag
->name
);
695 if (tag
->name
[0] == 0)
697 *error_string
= g_strdup("Tag name can't be empty");
704 static void * lbtru_tag_copy_cb(void * destination
, const void * source
, size_t length _U_
)
706 const lbtru_tag_entry_t
* src
= (const lbtru_tag_entry_t
*)source
;
707 lbtru_tag_entry_t
* dest
= (lbtru_tag_entry_t
*)destination
;
709 dest
->name
= g_strdup(src
->name
);
710 dest
->source_port_low
= src
->source_port_low
;
711 dest
->source_port_high
= src
->source_port_high
;
712 dest
->receiver_port_low
= src
->receiver_port_low
;
713 dest
->receiver_port_high
= src
->receiver_port_high
;
717 static void lbtru_tag_free_cb(void * record
)
719 lbtru_tag_entry_t
* tag
= (lbtru_tag_entry_t
*)record
;
721 if (tag
->name
!= NULL
)
728 static char * lbtru_tag_find(packet_info
* pinfo
)
731 lbtru_tag_entry_t
* tag
= NULL
;
738 for (idx
= 0; idx
< lbtru_tag_count
; ++idx
)
740 tag
= &(lbtru_tag_entry
[idx
]);
741 if (((pinfo
->destport
>= tag
->source_port_low
)
742 && (pinfo
->destport
<= tag
->source_port_high
)
743 && (pinfo
->srcport
>= tag
->receiver_port_low
)
744 && (pinfo
->srcport
<= tag
->receiver_port_high
))
745 || ((pinfo
->destport
>= tag
->receiver_port_low
)
746 && (pinfo
->destport
<= tag
->receiver_port_high
)
747 && (pinfo
->srcport
>= tag
->source_port_low
)
748 && (pinfo
->srcport
<= tag
->source_port_high
)))
757 /*----------------------------------------------------------------------------*/
758 /* Handles of all types. */
759 /*----------------------------------------------------------------------------*/
761 /* Dissector tree handles */
762 static int ett_lbtru
;
763 static int ett_lbtru_channel
;
764 static int ett_lbtru_hdr
;
765 static int ett_lbtru_hdr_flags
;
766 static int ett_lbtru_data
;
767 static int ett_lbtru_sm
;
768 static int ett_lbtru_nak
;
769 static int ett_lbtru_nak_list
;
770 static int ett_lbtru_ncf
;
771 static int ett_lbtru_ncf_list
;
772 static int ett_lbtru_ack
;
773 static int ett_lbtru_opt
;
774 static int ett_lbtru_opt_sid_flags
;
775 static int ett_lbtru_opt_cid_flags
;
776 static int ett_lbtru_transport
;
777 static int ett_lbtru_transport_sqn
;
779 /* Dissector field handles */
780 static int hf_lbtru_channel
;
781 static int hf_lbtru_channel_id
;
782 static int hf_lbtru_channel_client
;
783 static int hf_lbtru_tag
;
784 static int hf_lbtru_hdr
;
785 static int hf_lbtru_hdr_ver
;
786 static int hf_lbtru_hdr_type
;
787 static int hf_lbtru_hdr_next_hdr
;
788 static int hf_lbtru_hdr_res
;
789 static int hf_lbtru_hdr_flags
;
790 static int hf_lbtru_hdr_flags_syn
;
791 static int hf_lbtru_hdr_flags_rx
;
792 static int hf_lbtru_hdr_request
;
793 static int hf_lbtru_hdr_reason
;
794 static int hf_lbtru_data
;
795 static int hf_lbtru_data_sqn
;
796 static int hf_lbtru_data_trail_sqn
;
797 static int hf_lbtru_sm
;
798 static int hf_lbtru_sm_sqn
;
799 static int hf_lbtru_sm_lead_sqn
;
800 static int hf_lbtru_sm_trail_sqn
;
801 static int hf_lbtru_nak
;
802 static int hf_lbtru_nak_num
;
803 static int hf_lbtru_nak_format
;
804 static int hf_lbtru_nak_list
;
805 static int hf_lbtru_nak_list_nak
;
806 static int hf_lbtru_ncf
;
807 static int hf_lbtru_ncf_trail_sqn
;
808 static int hf_lbtru_ncf_num
;
809 static int hf_lbtru_ncf_reserved
;
810 static int hf_lbtru_ncf_reason
;
811 static int hf_lbtru_ncf_format
;
812 static int hf_lbtru_ncf_list
;
813 static int hf_lbtru_ncf_list_ncf
;
814 static int hf_lbtru_ack
;
815 static int hf_lbtru_ack_sqn
;
816 static int hf_lbtru_opt_sid
;
817 static int hf_lbtru_opt_sid_next_hdr
;
818 static int hf_lbtru_opt_sid_hdr_len
;
819 static int hf_lbtru_opt_sid_flags
;
820 static int hf_lbtru_opt_sid_flags_ignore
;
821 static int hf_lbtru_opt_sid_session_id
;
822 static int hf_lbtru_opt_cid
;
823 static int hf_lbtru_opt_cid_next_hdr
;
824 static int hf_lbtru_opt_cid_hdr_len
;
825 static int hf_lbtru_opt_cid_flags
;
826 static int hf_lbtru_opt_cid_flags_ignore
;
827 static int hf_lbtru_opt_cid_client_id
;
828 static int hf_lbtru_opt_unknown
;
829 static int hf_lbtru_opt_unknown_next_hdr
;
830 static int hf_lbtru_opt_unknown_hdr_len
;
831 static int hf_lbtru_analysis
;
832 static int hf_lbtru_analysis_prev_frame
;
833 static int hf_lbtru_analysis_prev_data_frame
;
834 static int hf_lbtru_analysis_prev_sm_frame
;
835 static int hf_lbtru_analysis_prev_nak_frame
;
836 static int hf_lbtru_analysis_prev_ncf_frame
;
837 static int hf_lbtru_analysis_prev_ack_frame
;
838 static int hf_lbtru_analysis_prev_creq_frame
;
839 static int hf_lbtru_analysis_prev_rst_frame
;
840 static int hf_lbtru_analysis_next_frame
;
841 static int hf_lbtru_analysis_next_data_frame
;
842 static int hf_lbtru_analysis_next_sm_frame
;
843 static int hf_lbtru_analysis_next_nak_frame
;
844 static int hf_lbtru_analysis_next_ncf_frame
;
845 static int hf_lbtru_analysis_next_ack_frame
;
846 static int hf_lbtru_analysis_next_creq_frame
;
847 static int hf_lbtru_analysis_next_rst_frame
;
848 static int hf_lbtru_analysis_sqn
;
849 static int hf_lbtru_analysis_sqn_frame
;
850 static int hf_lbtru_analysis_data_retransmission
;
851 static int hf_lbtru_analysis_data_sqn_gap
;
852 static int hf_lbtru_analysis_data_ooo_gap
;
853 static int hf_lbtru_analysis_data_duplicate
;
854 static int hf_lbtru_analysis_sm_sqn_gap
;
855 static int hf_lbtru_analysis_sm_ooo_gap
;
856 static int hf_lbtru_analysis_sm_duplicate
;
858 /* Expert info handles */
859 static expert_field ei_lbtru_analysis_unknown_type
;
860 static expert_field ei_lbtru_analysis_unknown_header
;
861 static expert_field ei_lbtru_analysis_zero_length_header
;
862 static expert_field ei_lbtru_analysis_ack
;
863 static expert_field ei_lbtru_analysis_ncf
;
864 static expert_field ei_lbtru_analysis_ncf_ncf
;
865 static expert_field ei_lbtru_analysis_nak
;
866 static expert_field ei_lbtru_analysis_nak_nak
;
867 static expert_field ei_lbtru_analysis_sm
;
868 static expert_field ei_lbtru_analysis_sm_syn
;
869 static expert_field ei_lbtru_analysis_creq
;
870 static expert_field ei_lbtru_analysis_rst
;
871 static expert_field ei_lbtru_analysis_data_rx
;
872 static expert_field ei_lbtru_analysis_data_gap
;
873 static expert_field ei_lbtru_analysis_data_ooo
;
874 static expert_field ei_lbtru_analysis_data_dup
;
875 static expert_field ei_lbtru_analysis_sm_gap
;
876 static expert_field ei_lbtru_analysis_sm_ooo
;
877 static expert_field ei_lbtru_analysis_sm_dup
;
879 /*----------------------------------------------------------------------------*/
880 /* LBT-RU data payload dissection functions. */
881 /*----------------------------------------------------------------------------*/
882 static int dissect_lbtru_data_contents(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, const char * tag_name
, uint64_t channel
)
886 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
887 return (lbmc_dissect_lbmc_packet(next_tvb
, 0, pinfo
, tree
, tag_name
, channel
));
890 /*----------------------------------------------------------------------------*/
891 /* LBT-RU ACK packet dissection functions. */
892 /*----------------------------------------------------------------------------*/
893 static int dissect_lbtru_ack(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, lbm_lbtru_tap_info_t
* tap_info
)
895 proto_tree
* ack_tree
= NULL
;
896 proto_item
* ack_item
= NULL
;
897 proto_item
* ack
= NULL
;
899 ack_item
= proto_tree_add_item(tree
, hf_lbtru_ack
, tvb
, offset
, L_LBTRU_ACK_HDR_T
, ENC_NA
);
900 ack_tree
= proto_item_add_subtree(ack_item
, ett_lbtru_ack
);
901 ack
= proto_tree_add_item(ack_tree
, hf_lbtru_ack_sqn
, tvb
, offset
+ O_LBTRU_ACK_HDR_T_ACK_SQN
, L_LBTRU_ACK_HDR_T_ACK_SQN
, ENC_BIG_ENDIAN
);
902 expert_add_info(pinfo
, ack
, &ei_lbtru_analysis_ack
);
903 tap_info
->sqn
= tvb_get_ntohl(tvb
, offset
+ O_LBTRU_ACK_HDR_T_ACK_SQN
);
904 return (L_LBTRU_ACK_HDR_T
);
907 /*----------------------------------------------------------------------------*/
908 /* LBT-RU NAK confirmation packet dissection functions. */
909 /*----------------------------------------------------------------------------*/
910 static int dissect_lbtru_ncf_list(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, int ncf_count
, int reason
, lbm_lbtru_tap_info_t
* tap_info
)
912 proto_tree
* ncf_tree
= NULL
;
913 proto_item
* ncf_item
= NULL
;
918 ncf_item
= proto_tree_add_item(tree
, hf_lbtru_ncf_list
, tvb
, offset
, -1, ENC_NA
);
919 ncf_tree
= proto_item_add_subtree(ncf_item
, ett_lbtru_ncf_list
);
921 for (idx
= 0; idx
< ncf_count
; idx
++)
923 proto_item
* sep_ncf_item
= NULL
;
925 ncf
= tvb_get_ntohl(tvb
, offset
+ len
);
926 sep_ncf_item
= proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_list_ncf
, tvb
, offset
+ len
, sizeof(lbm_uint32_t
), ENC_BIG_ENDIAN
);
927 if (lbtru_expert_separate_ncfs
)
929 expert_add_info_format(pinfo
, sep_ncf_item
, &ei_lbtru_analysis_ncf_ncf
, "NCF 0x%08x %s", ncf
, val_to_str(reason
, lbtru_ncf_reason
, "Unknown (0x%02x)"));
931 tap_info
->sqns
[idx
] = ncf
;
932 len
+= (int)sizeof(lbm_uint32_t
);
934 proto_item_set_len(ncf_item
, len
);
938 static int dissect_lbtru_ncf(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, lbm_lbtru_tap_info_t
* tap_info
)
941 uint8_t reason_format
;
942 proto_tree
* ncf_tree
= NULL
;
943 proto_item
* ncf_item
= NULL
;
944 uint16_t num_ncfs
= 0;
946 ncf_item
= proto_tree_add_item(tree
, hf_lbtru_ncf
, tvb
, offset
, -1, ENC_NA
);
947 ncf_tree
= proto_item_add_subtree(ncf_item
, ett_lbtru_ncf
);
948 reason_format
= tvb_get_uint8(tvb
, offset
+ O_LBTRU_NCF_HDR_T_REASON_FORMAT
);
949 num_ncfs
= tvb_get_ntohs(tvb
, offset
+ O_LBTRU_NCF_HDR_T_NUM_NCFS
);
950 proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_trail_sqn
, tvb
, offset
+ O_LBTRU_NCF_HDR_T_TRAIL_SQN
, L_LBTRU_NCF_HDR_T_TRAIL_SQN
, ENC_BIG_ENDIAN
);
951 proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_num
, tvb
, offset
+ O_LBTRU_NCF_HDR_T_NUM_NCFS
, L_LBTRU_NCF_HDR_T_NUM_NCFS
, ENC_BIG_ENDIAN
);
952 proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_reserved
, tvb
, offset
+ O_LBTRU_NCF_HDR_T_RESERVED
, L_LBTRU_NCF_HDR_T_RESERVED
, ENC_BIG_ENDIAN
);
953 proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_reason
, tvb
, offset
+ O_LBTRU_NCF_HDR_T_REASON_FORMAT
, L_LBTRU_NCF_HDR_T_REASON_FORMAT
, ENC_BIG_ENDIAN
);
954 proto_tree_add_item(ncf_tree
, hf_lbtru_ncf_format
, tvb
, offset
+ O_LBTRU_NCF_HDR_T_REASON_FORMAT
, L_LBTRU_NCF_HDR_T_REASON_FORMAT
, ENC_BIG_ENDIAN
);
955 len_dissected
= L_LBTRU_NCF_HDR_T
;
956 if (!lbtru_expert_separate_ncfs
)
958 expert_add_info_format(pinfo
, ncf_item
, &ei_lbtru_analysis_ncf
, "NCF %s", val_to_str(LBTRU_NCF_HDR_REASON(reason_format
), lbtru_ncf_reason
, "Unknown (0x%02x)"));
960 tap_info
->ncf_reason
= LBTRU_NCF_HDR_REASON(reason_format
);
961 tap_info
->num_sqns
= num_ncfs
;
962 tap_info
->sqns
= wmem_alloc_array(pinfo
->pool
, uint32_t, num_ncfs
);
963 len_dissected
+= dissect_lbtru_ncf_list(tvb
, offset
+ L_LBTRU_NCF_HDR_T
, pinfo
, ncf_tree
, num_ncfs
, LBTRU_NCF_HDR_REASON(reason_format
), tap_info
);
964 proto_item_set_len(ncf_item
, len_dissected
);
965 return (len_dissected
);
968 /*----------------------------------------------------------------------------*/
969 /* LBT-RU NAK packet dissection functions. */
970 /*----------------------------------------------------------------------------*/
971 static int dissect_lbtru_nak_list(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, int nak_count
, lbm_lbtru_tap_info_t
* tap_info
)
973 proto_tree
* nak_tree
= NULL
;
974 proto_item
* nak_item
= NULL
;
978 nak_item
= proto_tree_add_item(tree
, hf_lbtru_nak_list
, tvb
, offset
, -1, ENC_NA
);
979 nak_tree
= proto_item_add_subtree(nak_item
, ett_lbtru_nak_list
);
981 for (idx
= 0; idx
< nak_count
; idx
++)
983 proto_item
* sep_nak_item
= NULL
;
986 nak
= tvb_get_ntohl(tvb
, offset
+ len
);
987 sep_nak_item
= proto_tree_add_item(nak_tree
, hf_lbtru_nak_list_nak
, tvb
, offset
+ len
, sizeof(lbm_uint32_t
), ENC_BIG_ENDIAN
);
988 if (lbtru_expert_separate_naks
)
990 expert_add_info_format(pinfo
, sep_nak_item
, &ei_lbtru_analysis_nak_nak
, "NAK 0x%08x", nak
);
992 tap_info
->sqns
[idx
] = nak
;
993 len
+= (int)sizeof(lbm_uint32_t
);
995 proto_item_set_len(nak_item
, len
);
999 static int dissect_lbtru_nak(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, lbm_lbtru_tap_info_t
* tap_info
)
1002 proto_tree
* nak_tree
= NULL
;
1003 proto_item
* nak_item
= NULL
;
1004 uint16_t num_naks
= 0;
1006 nak_item
= proto_tree_add_item(tree
, hf_lbtru_nak
, tvb
, offset
, -1, ENC_NA
);
1007 nak_tree
= proto_item_add_subtree(nak_item
, ett_lbtru_nak
);
1008 num_naks
= tvb_get_ntohs(tvb
, offset
+ O_LBTRU_NAK_HDR_T_NUM_NAKS
);
1009 proto_tree_add_item(nak_tree
, hf_lbtru_nak_num
, tvb
, offset
+ O_LBTRU_NAK_HDR_T_NUM_NAKS
, L_LBTRU_NAK_HDR_T_NUM_NAKS
, ENC_BIG_ENDIAN
);
1010 proto_tree_add_item(nak_tree
, hf_lbtru_nak_format
, tvb
, offset
+ O_LBTRU_NAK_HDR_T_FORMAT
, L_LBTRU_NAK_HDR_T_FORMAT
, ENC_BIG_ENDIAN
);
1011 len_dissected
= L_LBTRU_NAK_HDR_T
;
1012 if (!lbtru_expert_separate_naks
)
1014 expert_add_info(pinfo
, nak_item
, &ei_lbtru_analysis_nak
);
1016 tap_info
->num_sqns
= num_naks
;
1017 tap_info
->sqns
= wmem_alloc_array(pinfo
->pool
, uint32_t, num_naks
);
1018 len_dissected
+= dissect_lbtru_nak_list(tvb
, offset
+ L_LBTRU_NAK_HDR_T
, pinfo
, nak_tree
, num_naks
, tap_info
);
1019 proto_item_set_len(nak_item
, len_dissected
);
1020 return (len_dissected
);
1023 /*----------------------------------------------------------------------------*/
1024 /* LBT-RU session message packet dissection function. */
1025 /*----------------------------------------------------------------------------*/
1026 static int dissect_lbtru_sm(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_tree
* tree
, int syn
, lbm_lbtru_tap_info_t
* tap_info
)
1028 proto_tree
* sm_tree
= NULL
;
1029 proto_item
* sm_item
= NULL
;
1030 proto_item
* sm_sqn
= NULL
;
1032 sm_item
= proto_tree_add_item(tree
, hf_lbtru_sm
, tvb
, offset
, L_LBTRU_SM_HDR_T
, ENC_NA
);
1033 sm_tree
= proto_item_add_subtree(sm_item
, ett_lbtru_sm
);
1034 sm_sqn
= proto_tree_add_item(sm_tree
, hf_lbtru_sm_sqn
, tvb
, offset
+ O_LBTRU_SM_HDR_T_SM_SQN
, L_LBTRU_SM_HDR_T_SM_SQN
, ENC_BIG_ENDIAN
);
1035 proto_tree_add_item(sm_tree
, hf_lbtru_sm_lead_sqn
, tvb
, offset
+ O_LBTRU_SM_HDR_T_LEAD_SQN
, L_LBTRU_SM_HDR_T_LEAD_SQN
, ENC_BIG_ENDIAN
);
1036 proto_tree_add_item(sm_tree
, hf_lbtru_sm_trail_sqn
, tvb
, offset
+ O_LBTRU_SM_HDR_T_TRAIL_SQN
, L_LBTRU_SM_HDR_T_TRAIL_SQN
, ENC_BIG_ENDIAN
);
1039 expert_add_info(pinfo
, sm_sqn
, &ei_lbtru_analysis_sm_syn
);
1043 expert_add_info(pinfo
, sm_sqn
, &ei_lbtru_analysis_sm
);
1045 tap_info
->sqn
= tvb_get_ntohl(tvb
, offset
+ O_LBTRU_SM_HDR_T_SM_SQN
);
1046 return (L_LBTRU_SM_HDR_T
);
1049 /*----------------------------------------------------------------------------*/
1050 /* LBT-RU data packet dissection functions. */
1051 /*----------------------------------------------------------------------------*/
1052 static int dissect_lbtru_data(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo _U_
, proto_tree
* tree
, lbm_lbtru_tap_info_t
* tap_info
)
1054 proto_tree
* data_tree
= NULL
;
1055 proto_item
* data_item
= NULL
;
1057 data_item
= proto_tree_add_item(tree
, hf_lbtru_data
, tvb
, offset
, L_LBTRU_DATA_HDR_T
, ENC_NA
);
1058 data_tree
= proto_item_add_subtree(data_item
, ett_lbtru_data
);
1059 proto_tree_add_item(data_tree
, hf_lbtru_data_sqn
, tvb
, offset
+ O_LBTRU_DATA_HDR_T_SQN
, L_LBTRU_DATA_HDR_T_SQN
, ENC_BIG_ENDIAN
);
1060 proto_tree_add_item(data_tree
, hf_lbtru_data_trail_sqn
, tvb
, offset
+ O_LBTRU_DATA_HDR_T_TRAIL_SQN
, L_LBTRU_DATA_HDR_T_TRAIL_SQN
, ENC_BIG_ENDIAN
);
1061 tap_info
->sqn
= tvb_get_ntohl(tvb
, offset
+ O_LBTRU_DATA_HDR_T_SQN
);
1062 return (L_LBTRU_DATA_HDR_T
);
1065 /*----------------------------------------------------------------------------*/
1066 /* LBT-RU packet dissector. */
1067 /*----------------------------------------------------------------------------*/
1072 uint32_t current_frame
;
1073 } lbtru_sqn_frame_list_callback_data_t
;
1075 static bool dissect_lbtru_sqn_frame_list_callback(const void *key _U_
, void * frame
, void * user_data
)
1077 lbtru_sqn_frame_list_callback_data_t
* cb_data
= (lbtru_sqn_frame_list_callback_data_t
*) user_data
;
1078 proto_item
* transport_item
= NULL
;
1079 lbm_transport_sqn_frame_t
* sqn_frame
= (lbm_transport_sqn_frame_t
*) frame
;
1081 if (sqn_frame
->frame
!= cb_data
->current_frame
)
1083 if (sqn_frame
->retransmission
)
1085 transport_item
= proto_tree_add_uint_format_value(cb_data
->tree
, hf_lbtru_analysis_sqn_frame
, cb_data
->tvb
, 0, 0, sqn_frame
->frame
, "%" PRIu32
" (RX)", sqn_frame
->frame
);
1089 transport_item
= proto_tree_add_uint(cb_data
->tree
, hf_lbtru_analysis_sqn_frame
, cb_data
->tvb
, 0, 0, sqn_frame
->frame
);
1091 proto_item_set_generated(transport_item
);
1096 static int dissect_lbtru(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * user_data _U_
)
1098 proto_tree
* lbtru_tree
= NULL
;
1099 proto_item
* lbtru_item
= NULL
;
1100 static int * const flags_data
[] =
1102 &hf_lbtru_hdr_flags_rx
,
1105 static int * const flags_sm
[] =
1107 &hf_lbtru_hdr_flags_syn
,
1111 uint32_t session_id
= 0;
1112 char * tag_name
= NULL
;
1114 int total_dissected_len
= 0;
1115 proto_tree
* header_tree
= NULL
;
1116 proto_item
* header_item
= NULL
;
1117 proto_tree
* transport_tree
= NULL
;
1118 proto_item
* transport_item
= NULL
;
1119 bool from_source
= true;
1120 uint8_t packet_type
= 0;
1121 address source_address
;
1122 address receiver_address
;
1123 uint16_t source_port
= 0;
1124 uint16_t receiver_port
= 0;
1125 lbtru_transport_t
* transport
= NULL
;
1126 lbtru_client_transport_t
* client
= NULL
;
1127 uint64_t channel
= LBM_CHANNEL_NO_CHANNEL
;
1128 proto_tree
* channel_tree
= NULL
;
1129 proto_item
* channel_item
= NULL
;
1130 uint8_t ver_type
= 0;
1131 uint8_t next_hdr
= 0;
1132 uint32_t packet_sqn
= 0;
1133 uint16_t flags_or_res
= 0;
1134 uint16_t num_naks
= 0;
1135 uint16_t num_ncfs
= 0;
1136 bool retransmission
= false;
1137 proto_item
* fld_item
= NULL
;
1138 proto_item
* ei_item
= NULL
;
1139 proto_item
* type_item
= NULL
;
1140 proto_item
* next_hdr_item
= NULL
;
1141 lbm_lbtru_tap_info_t
* tapinfo
= NULL
;
1143 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "LBT-RU");
1146 tag_name
= lbtru_tag_find(pinfo
);
1148 col_clear(pinfo
->cinfo
, COL_INFO
);
1149 if (tag_name
!= NULL
)
1151 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "[Tag: %s]", tag_name
);
1153 col_set_fence(pinfo
->cinfo
, COL_INFO
);
1155 ver_type
= tvb_get_uint8(tvb
, O_LBTRU_HDR_T_VER_TYPE
);
1156 next_hdr
= tvb_get_uint8(tvb
, O_LBTRU_HDR_T_NEXT_HDR
);
1157 flags_or_res
= tvb_get_ntohs(tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
);
1158 packet_type
= LBTRU_HDR_TYPE(ver_type
);
1159 if (tag_name
!= NULL
)
1161 lbtru_item
= proto_tree_add_protocol_format(tree
, proto_lbtru
, tvb
, ofs
, -1, "LBT-RU Protocol (Tag: %s): Version %u, Type %s", tag_name
,
1162 LBTRU_HDR_VER(ver_type
), val_to_str(LBTRU_HDR_TYPE(ver_type
), lbtru_packet_type
, "Unknown (0x%02x)"));
1166 lbtru_item
= proto_tree_add_protocol_format(tree
, proto_lbtru
, tvb
, ofs
, -1, "LBT-RU Protocol: Version %u, Type %s", LBTRU_HDR_VER(ver_type
),
1167 val_to_str(LBTRU_HDR_TYPE(ver_type
), lbtru_packet_type
, "Unknown (0x%02x)"));
1169 lbtru_tree
= proto_item_add_subtree(lbtru_item
, ett_lbtru
);
1170 if (tag_name
!= NULL
)
1172 proto_item
* item
= NULL
;
1173 item
= proto_tree_add_string(lbtru_tree
, hf_lbtru_tag
, tvb
, 0, 0, tag_name
);
1174 proto_item_set_generated(item
);
1176 channel_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_channel
, tvb
, 0, 0, ENC_NA
);
1177 proto_item_set_generated(channel_item
);
1178 channel_tree
= proto_item_add_subtree(channel_item
, ett_lbtru_channel
);
1180 tapinfo
= wmem_new0(pinfo
->pool
, lbm_lbtru_tap_info_t
);
1181 tapinfo
->type
= packet_type
;
1183 header_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_hdr
, tvb
, 0, -1, ENC_NA
);
1184 header_tree
= proto_item_add_subtree(header_item
, ett_lbtru_hdr
);
1185 proto_tree_add_item(header_tree
, hf_lbtru_hdr_ver
, tvb
, O_LBTRU_HDR_T_VER_TYPE
, L_LBTRU_HDR_T_VER_TYPE
, ENC_BIG_ENDIAN
);
1186 type_item
= proto_tree_add_item(header_tree
, hf_lbtru_hdr_type
, tvb
, O_LBTRU_HDR_T_VER_TYPE
, L_LBTRU_HDR_T_VER_TYPE
, ENC_BIG_ENDIAN
);
1187 next_hdr_item
= proto_tree_add_item(header_tree
, hf_lbtru_hdr_next_hdr
, tvb
, O_LBTRU_HDR_T_NEXT_HDR
, L_LBTRU_HDR_T_NEXT_HDR
, ENC_BIG_ENDIAN
);
1188 total_dissected_len
= L_LBTRU_HDR_T_VER_TYPE
+ L_LBTRU_HDR_T_NEXT_HDR
;
1189 ofs
= L_LBTRU_HDR_T_VER_TYPE
+ L_LBTRU_HDR_T_NEXT_HDR
;
1191 switch (packet_type
)
1193 case LBTRU_PACKET_TYPE_DATA
:
1194 packet_sqn
= tvb_get_ntohl(tvb
, L_LBTRU_HDR_T
+ O_LBTRU_DATA_HDR_T_SQN
);
1195 if ((flags_or_res
& LBTRU_RETRANSMISSION_FLAG
) != 0)
1197 retransmission
= true;
1198 tapinfo
->retransmission
= true;
1202 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "DATA(RX) sqn 0x%x", packet_sqn
);
1206 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "DATA sqn 0x%x", packet_sqn
);
1210 case LBTRU_PACKET_TYPE_SM
:
1211 packet_sqn
= tvb_get_ntohl(tvb
, L_LBTRU_HDR_T
+ O_LBTRU_SM_HDR_T_SM_SQN
);
1212 if ((flags_or_res
& LBTRU_SM_SYN_FLAG
) != 0)
1214 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "SM sqn 0x%x SYN", packet_sqn
);
1218 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "SM sqn 0x%x", packet_sqn
);
1222 case LBTRU_PACKET_TYPE_NAK
:
1223 num_naks
= tvb_get_ntohs(tvb
, L_LBTRU_HDR_T
+ O_LBTRU_NAK_HDR_T_NUM_NAKS
);
1224 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "NAK %" PRIu16
" naks", num_naks
);
1225 from_source
= false;
1227 case LBTRU_PACKET_TYPE_NCF
:
1228 num_ncfs
= tvb_get_ntohs(tvb
, L_LBTRU_HDR_T
+ O_LBTRU_NCF_HDR_T_NUM_NCFS
);
1229 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "NCF %" PRIu16
" ncfs", num_ncfs
);
1232 case LBTRU_PACKET_TYPE_ACK
:
1233 packet_sqn
= tvb_get_ntohl(tvb
, L_LBTRU_HDR_T
+ O_LBTRU_ACK_HDR_T_ACK_SQN
);
1234 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "ACK sqn 0x%x", packet_sqn
);
1235 from_source
= false;
1237 case LBTRU_PACKET_TYPE_CREQ
:
1238 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "CREQ %s", val_to_str(flags_or_res
, lbtru_creq_request
, "Unknown (0x%02x)"));
1239 from_source
= false;
1241 case LBTRU_PACKET_TYPE_RST
:
1242 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "RST %s", val_to_str(flags_or_res
, lbtru_rst_reason
, "Unknown (0x%02x)"));
1246 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "Unknown (0x%02x)", LBTRU_HDR_TYPE(ver_type
));
1247 expert_add_info_format(pinfo
, type_item
, &ei_lbtru_analysis_unknown_type
, "Unrecognized type 0x%02x", LBTRU_HDR_TYPE(ver_type
));
1248 return (total_dissected_len
);
1251 /* Handle the flags_or_res field. */
1252 switch (packet_type
)
1254 case LBTRU_PACKET_TYPE_DATA
:
1255 proto_tree_add_bitmask(header_tree
, tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
, hf_lbtru_hdr_flags
, ett_lbtru_hdr_flags
, flags_data
, ENC_BIG_ENDIAN
);
1256 total_dissected_len
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1257 ofs
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1259 case LBTRU_PACKET_TYPE_NAK
:
1260 case LBTRU_PACKET_TYPE_NCF
:
1261 case LBTRU_PACKET_TYPE_ACK
:
1262 proto_tree_add_item(header_tree
, hf_lbtru_hdr_res
, tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
, L_LBTRU_HDR_T_FLAGS_OR_RES
, ENC_BIG_ENDIAN
);
1263 total_dissected_len
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1264 ofs
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1266 case LBTRU_PACKET_TYPE_SM
:
1267 proto_tree_add_bitmask(header_tree
, tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
, hf_lbtru_hdr_flags
, ett_lbtru_hdr_flags
, flags_sm
, ENC_BIG_ENDIAN
);
1268 total_dissected_len
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1269 ofs
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1271 case LBTRU_PACKET_TYPE_CREQ
:
1272 ei_item
= proto_tree_add_item(header_tree
, hf_lbtru_hdr_request
, tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
, L_LBTRU_HDR_T_FLAGS_OR_RES
, ENC_BIG_ENDIAN
);
1273 expert_add_info_format(pinfo
, ei_item
, &ei_lbtru_analysis_creq
, "CREQ %s", val_to_str(flags_or_res
, lbtru_creq_request
, "Unknown (0x%04x)"));
1274 total_dissected_len
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1275 ofs
+= L_LBTRU_HDR_T_FLAGS_OR_RES
;
1277 case LBTRU_PACKET_TYPE_RST
:
1278 ei_item
= proto_tree_add_item(header_tree
, hf_lbtru_hdr_reason
, tvb
, O_LBTRU_HDR_T_FLAGS_OR_RES
, L_LBTRU_HDR_T_FLAGS_OR_RES
, ENC_BIG_ENDIAN
);
1279 expert_add_info_format(pinfo
, ei_item
, &ei_lbtru_analysis_rst
, "RST %s", val_to_str(flags_or_res
, lbtru_rst_reason
, "Unknown (0x%04x)"));
1285 /* Handle the packet-specific data */
1286 switch (packet_type
)
1288 case LBTRU_PACKET_TYPE_DATA
:
1289 dissected_len
= dissect_lbtru_data(tvb
, L_LBTRU_HDR_T
, pinfo
, lbtru_tree
, tapinfo
);
1291 case LBTRU_PACKET_TYPE_SM
:
1292 dissected_len
= dissect_lbtru_sm(tvb
, L_LBTRU_HDR_T
, pinfo
, lbtru_tree
, (flags_or_res
& LBTRU_SM_SYN_FLAG
), tapinfo
);
1294 case LBTRU_PACKET_TYPE_NAK
:
1295 dissected_len
= dissect_lbtru_nak(tvb
, ofs
, pinfo
, lbtru_tree
, tapinfo
);
1297 case LBTRU_PACKET_TYPE_NCF
:
1298 dissected_len
= dissect_lbtru_ncf(tvb
, ofs
, pinfo
, lbtru_tree
, tapinfo
);
1300 case LBTRU_PACKET_TYPE_ACK
:
1301 dissected_len
= dissect_lbtru_ack(tvb
, ofs
, pinfo
, lbtru_tree
, tapinfo
);
1303 case LBTRU_PACKET_TYPE_CREQ
:
1305 tapinfo
->creq_type
= flags_or_res
;
1307 case LBTRU_PACKET_TYPE_RST
:
1309 tapinfo
->rst_type
= flags_or_res
;
1315 total_dissected_len
+= dissected_len
;
1316 ofs
+= dissected_len
;
1317 /* If we're doing sequence analysis, the tree goes here. */
1318 if (lbtru_sequence_analysis
)
1320 transport_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_analysis
, tvb
, 0, 0, ENC_NA
);
1321 proto_item_set_generated(transport_item
);
1322 transport_tree
= proto_item_add_subtree(transport_item
, ett_lbtru_transport
);
1324 while (next_hdr
!= LBTRU_NHDR_DATA
)
1326 proto_item
* hdr_length_item
;
1327 proto_tree
* opt_tree
= NULL
;
1328 static int * const sid_flags
[] =
1330 &hf_lbtru_opt_sid_flags_ignore
,
1333 static int * const cid_flags
[] =
1335 &hf_lbtru_opt_cid_flags_ignore
,
1339 uint8_t cur_next_hdr
;
1341 cur_next_hdr
= tvb_get_uint8(tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_NEXT_HDR
);
1342 hdrlen
= (int)tvb_get_uint8(tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_HDR_LEN
);
1345 case LBTRU_NHDR_SID
:
1346 fld_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_opt_sid
, tvb
, ofs
, L_LBTRU_BASIC_OPT_T
+ L_LBTRU_SID_OPT_T
, ENC_NA
);
1347 opt_tree
= proto_item_add_subtree(fld_item
, ett_lbtru_opt
);
1348 next_hdr_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_sid_next_hdr
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_NEXT_HDR
, L_LBTRU_BASIC_OPT_T_NEXT_HDR
, ENC_BIG_ENDIAN
);
1349 hdr_length_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_sid_hdr_len
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_HDR_LEN
, L_LBTRU_BASIC_OPT_T_HDR_LEN
, ENC_BIG_ENDIAN
);
1352 expert_add_info(pinfo
, hdr_length_item
, &ei_lbtru_analysis_zero_length_header
);
1353 return (total_dissected_len
);
1355 proto_tree_add_bitmask(opt_tree
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_RES
, hf_lbtru_opt_sid_flags
, ett_lbtru_opt_sid_flags
, sid_flags
, ENC_BIG_ENDIAN
);
1356 proto_tree_add_item(opt_tree
, hf_lbtru_opt_sid_session_id
, tvb
, ofs
+ L_LBTRU_BASIC_OPT_T
+ O_LBTRU_SID_OPT_T_SESSION_ID
, L_LBTRU_SID_OPT_T_SESSION_ID
, ENC_BIG_ENDIAN
);
1357 session_id
= tvb_get_ntohl(tvb
, ofs
+ L_LBTRU_BASIC_OPT_T
+ O_LBTRU_SID_OPT_T_SESSION_ID
);
1359 case LBTRU_NHDR_CID
:
1360 fld_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_opt_cid
, tvb
, ofs
, L_LBTRU_BASIC_OPT_T
+ L_LBTRU_CID_OPT_T
, ENC_NA
);
1361 opt_tree
= proto_item_add_subtree(fld_item
, ett_lbtru_opt
);
1362 next_hdr_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_cid_next_hdr
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_NEXT_HDR
, L_LBTRU_BASIC_OPT_T_NEXT_HDR
, ENC_BIG_ENDIAN
);
1363 hdr_length_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_cid_hdr_len
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_HDR_LEN
, L_LBTRU_BASIC_OPT_T_HDR_LEN
, ENC_BIG_ENDIAN
);
1366 expert_add_info(pinfo
, hdr_length_item
, &ei_lbtru_analysis_zero_length_header
);
1367 return (total_dissected_len
);
1369 proto_tree_add_bitmask(opt_tree
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_RES
, hf_lbtru_opt_cid_flags
, ett_lbtru_opt_cid_flags
, cid_flags
, ENC_BIG_ENDIAN
);
1370 proto_tree_add_item(opt_tree
, hf_lbtru_opt_cid_client_id
, tvb
, ofs
+ L_LBTRU_BASIC_OPT_T
+ O_LBTRU_CID_OPT_T_CLIENT_SID
, L_LBTRU_CID_OPT_T_CLIENT_SID
, ENC_BIG_ENDIAN
);
1373 expert_add_info_format(pinfo
, next_hdr_item
, &ei_lbtru_analysis_unknown_header
, "Unrecognized header 0x%02x", next_hdr
);
1374 fld_item
= proto_tree_add_item(lbtru_tree
, hf_lbtru_opt_unknown
, tvb
, ofs
, L_LBTRU_BASIC_OPT_T
+ L_LBTRU_CID_OPT_T
, ENC_NA
);
1375 opt_tree
= proto_item_add_subtree(fld_item
, ett_lbtru_opt
);
1376 next_hdr_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_unknown_next_hdr
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_NEXT_HDR
, L_LBTRU_BASIC_OPT_T_NEXT_HDR
, ENC_BIG_ENDIAN
);
1377 hdr_length_item
= proto_tree_add_item(opt_tree
, hf_lbtru_opt_unknown_hdr_len
, tvb
, ofs
+ O_LBTRU_BASIC_OPT_T_HDR_LEN
, L_LBTRU_BASIC_OPT_T_HDR_LEN
, ENC_BIG_ENDIAN
);
1380 expert_add_info(pinfo
, hdr_length_item
, &ei_lbtru_analysis_zero_length_header
);
1381 return (total_dissected_len
);
1385 next_hdr
= cur_next_hdr
;
1387 total_dissected_len
+= hdrlen
;
1390 /* Find (or create) the transport and client entries */
1393 copy_address_shallow(&source_address
, &(pinfo
->src
));
1394 source_port
= pinfo
->srcport
;
1395 copy_address_shallow(&receiver_address
, &(pinfo
->dst
));
1396 receiver_port
= pinfo
->destport
;
1400 copy_address_shallow(&source_address
, &(pinfo
->dst
));
1401 source_port
= pinfo
->destport
;
1402 copy_address_shallow(&receiver_address
, &(pinfo
->src
));
1403 receiver_port
= pinfo
->srcport
;
1405 if (pinfo
->fd
->visited
== 0)
1407 transport
= lbtru_transport_add(&source_address
, source_port
, session_id
, pinfo
->num
);
1411 transport
= lbtru_transport_find(&source_address
, source_port
, session_id
, pinfo
->num
);
1413 if (transport
!= NULL
)
1415 if (pinfo
->fd
->visited
== 0)
1417 client
= lbtru_client_transport_add(transport
, &receiver_address
, receiver_port
, pinfo
->num
);
1420 if (lbtru_sequence_analysis
)
1422 lbtru_client_transport_frame_add(client
, packet_type
, pinfo
->num
, packet_sqn
, retransmission
);
1428 client
= lbtru_client_transport_find(transport
, &receiver_address
, receiver_port
, pinfo
->num
);
1430 tapinfo
->transport
= lbtru_transport_source_string_transport(pinfo
->pool
, transport
);
1431 channel
= transport
->channel
;
1432 fld_item
= proto_tree_add_uint64(channel_tree
, hf_lbtru_channel_id
, tvb
, 0, 0, channel
);
1433 proto_item_set_generated(fld_item
);
1436 fld_item
= proto_tree_add_uint(channel_tree
, hf_lbtru_channel_client
, tvb
, 0, 0, client
->id
);
1437 proto_item_set_generated(fld_item
);
1440 proto_item_set_len(lbtru_item
, total_dissected_len
);
1441 if ((packet_type
== LBTRU_PACKET_TYPE_DATA
) && (next_hdr
== LBTRU_NHDR_DATA
))
1443 total_dissected_len
+= dissect_lbtru_data_contents(tvb
, ofs
, pinfo
, tree
, tag_name
, channel
);
1445 if (lbtru_sequence_analysis
)
1447 if ((transport
!= NULL
) && (client
!= NULL
))
1449 lbm_transport_frame_t
* frame
= NULL
;
1451 /* Fill in the tree */
1452 frame
= lbtru_client_transport_frame_find(client
, pinfo
->num
);
1455 lbm_transport_sqn_t
* sqn
= NULL
;
1457 if (frame
->previous_frame
!= 0)
1459 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_frame
, tvb
, 0, 0, frame
->previous_frame
);
1460 proto_item_set_generated(transport_item
);
1462 if (frame
->next_frame
!= 0)
1464 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_frame
, tvb
, 0, 0, frame
->next_frame
);
1465 proto_item_set_generated(transport_item
);
1467 switch (packet_type
)
1469 case LBTRU_PACKET_TYPE_DATA
:
1470 if (frame
->previous_type_frame
!= 0)
1472 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_data_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1473 proto_item_set_generated(transport_item
);
1475 if (frame
->next_type_frame
!= 0)
1477 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_data_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1478 proto_item_set_generated(transport_item
);
1480 sqn
= lbtru_client_transport_sqn_find(client
, packet_type
, packet_sqn
);
1483 if (sqn
->frame_count
> 1)
1485 proto_tree
* frame_tree
= NULL
;
1486 proto_item
* frame_tree_item
= NULL
;
1487 lbtru_sqn_frame_list_callback_data_t cb_data
;
1489 frame_tree_item
= proto_tree_add_item(transport_tree
, hf_lbtru_analysis_sqn
, tvb
, 0, 0, ENC_NA
);
1490 proto_item_set_generated(frame_tree_item
);
1491 frame_tree
= proto_item_add_subtree(frame_tree_item
, ett_lbtru_transport_sqn
);
1492 cb_data
.tree
= frame_tree
;
1494 cb_data
.current_frame
= pinfo
->num
;
1495 wmem_tree_foreach(sqn
->frame
, dissect_lbtru_sqn_frame_list_callback
, (void *) &cb_data
);
1498 if (frame
->retransmission
)
1500 transport_item
= proto_tree_add_boolean(transport_tree
, hf_lbtru_analysis_data_retransmission
, tvb
, 0, 0, true);
1501 proto_item_set_generated(transport_item
);
1502 expert_add_info(pinfo
, transport_item
, &ei_lbtru_analysis_data_rx
);
1504 if (frame
->sqn_gap
!= 0)
1506 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_data_sqn_gap
, tvb
, 0, 0, frame
->sqn_gap
);
1507 proto_item_set_generated(transport_item
);
1508 expert_add_info_format(pinfo
, transport_item
, &ei_lbtru_analysis_data_gap
, "Data sequence gap (%" PRIu32
")", frame
->sqn_gap
);
1511 if (frame
->ooo_gap
!= 0)
1513 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_data_ooo_gap
, tvb
, 0, 0, frame
->ooo_gap
);
1514 proto_item_set_generated(transport_item
);
1515 expert_add_info_format(pinfo
, transport_item
, &ei_lbtru_analysis_data_ooo
, "Data sequence out of order gap (%" PRIu32
")", frame
->ooo_gap
);
1517 if (frame
->duplicate
)
1519 transport_item
= proto_tree_add_boolean(transport_tree
, hf_lbtru_analysis_data_duplicate
, tvb
, 0, 0, true);
1520 proto_item_set_generated(transport_item
);
1521 expert_add_info(pinfo
, transport_item
, &ei_lbtru_analysis_data_dup
);
1524 case LBTRU_PACKET_TYPE_SM
:
1525 if (frame
->previous_type_frame
!= 0)
1527 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_sm_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1528 proto_item_set_generated(transport_item
);
1530 if (frame
->next_type_frame
!= 0)
1532 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_sm_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1533 proto_item_set_generated(transport_item
);
1535 sqn
= lbtru_client_transport_sqn_find(client
, packet_type
, packet_sqn
);
1538 if (sqn
->frame_count
> 1)
1540 proto_tree
* frame_tree
= NULL
;
1541 proto_item
* frame_tree_item
= NULL
;
1542 lbtru_sqn_frame_list_callback_data_t cb_data
;
1544 frame_tree_item
= proto_tree_add_item(transport_tree
, hf_lbtru_analysis_sqn
, tvb
, 0, 0, ENC_NA
);
1545 proto_item_set_generated(frame_tree_item
);
1546 frame_tree
= proto_item_add_subtree(frame_tree_item
, ett_lbtru_transport_sqn
);
1547 cb_data
.tree
= frame_tree
;
1549 cb_data
.current_frame
= pinfo
->num
;
1550 wmem_tree_foreach(sqn
->frame
, dissect_lbtru_sqn_frame_list_callback
, (void *) &cb_data
);
1553 if (frame
->sqn_gap
!= 0)
1555 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_sm_sqn_gap
, tvb
, 0, 0, frame
->sqn_gap
);
1556 proto_item_set_generated(transport_item
);
1557 expert_add_info_format(pinfo
, transport_item
, &ei_lbtru_analysis_sm_gap
, "SM sequence gap (%" PRIu32
")", frame
->sqn_gap
);
1560 if (frame
->ooo_gap
!= 0)
1562 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_sm_ooo_gap
, tvb
, 0, 0, frame
->ooo_gap
);
1563 proto_item_set_generated(transport_item
);
1564 expert_add_info_format(pinfo
, transport_item
, &ei_lbtru_analysis_sm_ooo
, "SM sequence out of order gap (%" PRIu32
")", frame
->ooo_gap
);
1566 if (frame
->duplicate
)
1568 transport_item
= proto_tree_add_boolean(transport_tree
, hf_lbtru_analysis_sm_duplicate
, tvb
, 0, 0, true);
1569 proto_item_set_generated(transport_item
);
1570 expert_add_info(pinfo
, transport_item
, &ei_lbtru_analysis_sm_dup
);
1573 case LBTRU_PACKET_TYPE_NAK
:
1574 if (frame
->previous_type_frame
!= 0)
1576 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_nak_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1577 proto_item_set_generated(transport_item
);
1579 if (frame
->next_type_frame
!= 0)
1581 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_nak_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1582 proto_item_set_generated(transport_item
);
1585 case LBTRU_PACKET_TYPE_NCF
:
1586 if (frame
->previous_type_frame
!= 0)
1588 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_ncf_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1589 proto_item_set_generated(transport_item
);
1591 if (frame
->next_type_frame
!= 0)
1593 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_ncf_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1594 proto_item_set_generated(transport_item
);
1597 case LBTRU_PACKET_TYPE_ACK
:
1598 if (frame
->previous_type_frame
!= 0)
1600 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_ack_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1601 proto_item_set_generated(transport_item
);
1603 if (frame
->next_type_frame
!= 0)
1605 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_ack_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1606 proto_item_set_generated(transport_item
);
1609 case LBTRU_PACKET_TYPE_CREQ
:
1610 if (frame
->previous_type_frame
!= 0)
1612 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_creq_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1613 proto_item_set_generated(transport_item
);
1615 if (frame
->next_type_frame
!= 0)
1617 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_creq_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1618 proto_item_set_generated(transport_item
);
1621 case LBTRU_PACKET_TYPE_RST
:
1622 if (frame
->previous_type_frame
!= 0)
1624 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_prev_rst_frame
, tvb
, 0, 0, frame
->previous_type_frame
);
1625 proto_item_set_generated(transport_item
);
1627 if (frame
->next_type_frame
!= 0)
1629 transport_item
= proto_tree_add_uint(transport_tree
, hf_lbtru_analysis_next_rst_frame
, tvb
, 0, 0, frame
->next_type_frame
);
1630 proto_item_set_generated(transport_item
);
1639 if (tapinfo
->transport
!= NULL
)
1641 tap_queue_packet(lbtru_tap_handle
, pinfo
, (void *) tapinfo
);
1643 return (total_dissected_len
);
1646 static bool test_lbtru_packet(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * user_data
)
1648 bool valid_packet
= false;
1650 /* Must be a UDP packet. */
1651 if (pinfo
->ptype
!= PT_UDP
)
1655 /* Destination address must be IPV4 and 4 bytes in length. */
1656 if ((pinfo
->dst
.type
!= AT_IPv4
) || (pinfo
->dst
.len
!= 4))
1663 if (lbtru_tag_find(pinfo
) != NULL
)
1665 valid_packet
= true;
1671 Source port must be in the source port range and destination port must be in the receiver port range,
1674 if (((pinfo
->destport
>= lbtru_source_port_low
)
1675 && (pinfo
->destport
<= lbtru_source_port_high
)
1676 && (pinfo
->srcport
>= lbtru_receiver_port_low
)
1677 && (pinfo
->srcport
<= lbtru_receiver_port_high
))
1678 || ((pinfo
->destport
>= lbtru_receiver_port_low
)
1679 && (pinfo
->destport
<= lbtru_receiver_port_high
)
1680 && (pinfo
->srcport
>= lbtru_source_port_low
)
1681 && (pinfo
->srcport
<= lbtru_source_port_high
)))
1684 valid_packet
= true;
1689 dissect_lbtru(tvb
, pinfo
, tree
, user_data
);
1692 /* Not one of ours. */
1696 /* Register all the bits needed with the filtering engine */
1697 void proto_register_lbtru(void)
1699 static hf_register_info hf
[] =
1701 { &hf_lbtru_channel
,
1702 { "Channel", "lbtru.channel", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1703 { &hf_lbtru_channel_id
,
1704 { "Channel ID", "lbtru.channel.channel", FT_UINT64
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1705 { &hf_lbtru_channel_client
,
1706 { "Channel Client", "lbtru.channel.client", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1708 { "Tag", "lbtru.tag", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1710 { "Header", "lbtru.hdr", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1711 { &hf_lbtru_hdr_ver
,
1712 { "Version", "lbtru.hdr.ver", FT_UINT8
, BASE_DEC
, NULL
, LBTRU_HDR_VER_VER_MASK
, NULL
, HFILL
} },
1713 { &hf_lbtru_hdr_type
,
1714 { "Type", "lbtru.hdr.type", FT_UINT8
, BASE_HEX
, VALS(lbtru_packet_type
), LBTRU_HDR_VER_TYPE_MASK
, NULL
, HFILL
} },
1715 { &hf_lbtru_hdr_next_hdr
,
1716 { "Next Header", "lbtru.hdr.next_hdr", FT_UINT8
, BASE_HEX
, VALS(lbtru_next_header
), 0x0, NULL
, HFILL
} },
1717 { &hf_lbtru_hdr_res
,
1718 { "Reserved", "lbtru.hdr.res", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1719 { &hf_lbtru_hdr_flags
,
1720 { "Flags", "lbtru.hdr.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1721 { &hf_lbtru_hdr_flags_rx
,
1722 { "Retransmission", "lbtru.hdr.flags.rx", FT_BOOLEAN
, L_LBTRU_HDR_T_FLAGS_OR_RES
* 8, TFS(&tfs_set_notset
), LBTRU_RETRANSMISSION_FLAG
, NULL
, HFILL
} },
1723 { &hf_lbtru_hdr_flags_syn
,
1724 { "SYN", "lbtru.hdr.flags.syn", FT_BOOLEAN
, L_LBTRU_HDR_T_FLAGS_OR_RES
* 8, TFS(&tfs_set_notset
), LBTRU_SM_SYN_FLAG
, NULL
, HFILL
} },
1725 { &hf_lbtru_hdr_request
,
1726 { "Request", "lbtru.hdr.request", FT_UINT16
, BASE_HEX
, VALS(lbtru_creq_request
), 0x0, NULL
, HFILL
} },
1727 { &hf_lbtru_hdr_reason
,
1728 { "Reason", "lbtru.hdr.reason", FT_UINT16
, BASE_HEX
, VALS(lbtru_rst_reason
), 0x0, NULL
, HFILL
} },
1730 { "Data Header", "lbtru.data", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1731 { &hf_lbtru_data_sqn
,
1732 { "Sequence Number", "lbtru.data.sqn", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1733 { &hf_lbtru_data_trail_sqn
,
1734 { "Trailing Edge Sequence Number", "lbtru.data.trail", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1736 { "Session Message Header", "lbtru.sm", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1738 { "Sequence Number", "lbtru.sm.sqn", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1739 { &hf_lbtru_sm_lead_sqn
,
1740 { "Leading Edge Sequence Number", "lbtru.sm.lead", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1741 { &hf_lbtru_sm_trail_sqn
,
1742 { "Trailing Edge Sequence Number", "lbtru.sm.trail", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1744 { "NAK Header", "lbtru.nak", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1745 { &hf_lbtru_nak_num
,
1746 { "Number of NAKs", "lbtru.nak.num", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1747 { &hf_lbtru_nak_format
,
1748 { "Format", "lbtru.nak.format", FT_UINT16
, BASE_DEC
, VALS(lbtru_nak_format
), LBTRU_NAK_HDR_FORMAT_MASK
, NULL
, HFILL
} },
1749 { &hf_lbtru_nak_list
,
1750 { "NAK List", "lbtru.nak.list", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1751 { &hf_lbtru_nak_list_nak
,
1752 { "NAK", "lbtru.nak.list.nak", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1754 { "NAK Confirmation Header", "lbtru.ncf", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1755 { &hf_lbtru_ncf_trail_sqn
,
1756 { "Trailing Edge Sequence Number", "lbtru.ncf.trail", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1757 { &hf_lbtru_ncf_num
,
1758 { "Number of Individual NCFs", "lbtru.ncf.num", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1759 { &hf_lbtru_ncf_reserved
,
1760 { "Reserved", "lbtru.ncf.reserved", FT_UINT8
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1761 { &hf_lbtru_ncf_reason
,
1762 { "Reason", "lbtru.ncf.reason", FT_UINT8
, BASE_HEX
, VALS(lbtru_ncf_reason
), LBTRU_NCF_HDR_REASON_MASK
, NULL
, HFILL
} },
1763 { &hf_lbtru_ncf_format
,
1764 { "Format", "lbtru.ncf.format", FT_UINT8
, BASE_HEX
, VALS(lbtru_ncf_format
), LBTRU_NCF_HDR_FORMAT_MASK
, NULL
, HFILL
} },
1765 { &hf_lbtru_ncf_list
,
1766 { "NCF List", "lbtru.ncf.list", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1767 { &hf_lbtru_ncf_list_ncf
,
1768 { "NCF", "lbtru.ncf.list.ncf", FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1770 { "ACK Header", "lbtru.ack", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1771 { &hf_lbtru_ack_sqn
,
1772 { "ACK Sequence Number", "lbtru.ack.sqn", FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1773 { &hf_lbtru_opt_sid
,
1774 { "SID Option", "lbtru.opt_sid", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1775 { &hf_lbtru_opt_sid_next_hdr
,
1776 { "Next Header", "lbtru.opt_sid.next_hdr", FT_UINT8
, BASE_DEC_HEX
, VALS(lbtru_next_header
), 0x0, NULL
, HFILL
} },
1777 { &hf_lbtru_opt_sid_hdr_len
,
1778 { "Header Length", "lbtru.opt_sid.hdr_len", FT_UINT8
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1779 { &hf_lbtru_opt_sid_flags
,
1780 { "Flags", "lbtru.opt_sid.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1781 { &hf_lbtru_opt_sid_flags_ignore
,
1782 { "Ignore", "lbtru.opt_sid.flags.ignore", FT_BOOLEAN
, L_LBTRU_BASIC_OPT_T_RES
* 8, &(tfs_set_notset
), LBTRU_OPT_IGNORE
, NULL
, HFILL
} },
1783 { &hf_lbtru_opt_sid_session_id
,
1784 { "Session ID", "lbtru.opt_sid.session_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1785 { &hf_lbtru_opt_cid
,
1786 { "CID Option", "lbtru.opt_cid", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1787 { &hf_lbtru_opt_cid_next_hdr
,
1788 { "Next Header", "lbtru.opt_cid.next_hdr", FT_UINT8
, BASE_DEC_HEX
, VALS(lbtru_next_header
), 0x0, NULL
, HFILL
} },
1789 { &hf_lbtru_opt_cid_hdr_len
,
1790 { "Header Length", "lbtru.opt_cid.hdr_len", FT_UINT8
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1791 { &hf_lbtru_opt_cid_flags
,
1792 { "Flags", "lbtru.opt_cid.flags", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1793 { &hf_lbtru_opt_cid_flags_ignore
,
1794 { "Ignore", "lbtru.opt_cid.flags.ignore", FT_BOOLEAN
, L_LBTRU_BASIC_OPT_T_RES
* 8, &(tfs_set_notset
), LBTRU_OPT_IGNORE
, NULL
, HFILL
} },
1795 { &hf_lbtru_opt_cid_client_id
,
1796 { "Client ID", "lbtru.opt_cid.client_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1797 { &hf_lbtru_opt_unknown
,
1798 { "Unknown Option", "lbtru.opt_unknown", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1799 { &hf_lbtru_opt_unknown_next_hdr
,
1800 { "Next Header", "lbtru.opt_unknown.next_hdr", FT_UINT8
, BASE_DEC_HEX
, VALS(lbtru_next_header
), 0x0, NULL
, HFILL
} },
1801 { &hf_lbtru_opt_unknown_hdr_len
,
1802 { "Header Length", "lbtru.opt_unknown.hdr_len", FT_UINT8
, BASE_DEC_HEX
, NULL
, 0x0, NULL
, HFILL
} },
1803 { &hf_lbtru_analysis
,
1804 { "Transport Analysis", "lbtru.analysis", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1805 { &hf_lbtru_analysis_prev_frame
,
1806 { "Previous Transport Frame", "lbtru.analysis.prev_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1807 { &hf_lbtru_analysis_prev_data_frame
,
1808 { "Previous Transport DATA Frame", "lbtru.analysis.prev_data_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1809 { &hf_lbtru_analysis_prev_sm_frame
,
1810 { "Previous Transport SM Frame", "lbtru.analysis.prev_sm_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1811 { &hf_lbtru_analysis_prev_nak_frame
,
1812 { "Previous Transport NAK Frame", "lbtru.analysis.prev_nak_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1813 { &hf_lbtru_analysis_prev_ncf_frame
,
1814 { "Previous Transport NCF Frame", "lbtru.analysis.prev_ncf_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1815 { &hf_lbtru_analysis_prev_ack_frame
,
1816 { "Previous Transport ACK Frame", "lbtru.analysis.prev_ack_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1817 { &hf_lbtru_analysis_prev_creq_frame
,
1818 { "Previous Transport CREQ Frame", "lbtru.analysis.prev_creq_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1819 { &hf_lbtru_analysis_prev_rst_frame
,
1820 { "Previous Transport RST Frame", "lbtru.analysis.prev_rst_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1821 { &hf_lbtru_analysis_next_frame
,
1822 { "Next Transport Frame", "lbtru.analysis.next_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1823 { &hf_lbtru_analysis_next_data_frame
,
1824 { "Next Transport DATA Frame", "lbtru.analysis.next_data_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1825 { &hf_lbtru_analysis_next_sm_frame
,
1826 { "Next Transport SM Frame", "lbtru.analysis.next_sm_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1827 { &hf_lbtru_analysis_next_nak_frame
,
1828 { "Next Transport NAK Frame", "lbtru.analysis.next_nak_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1829 { &hf_lbtru_analysis_next_ncf_frame
,
1830 { "Next Transport NCF Frame", "lbtru.analysis.next_ncf_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1831 { &hf_lbtru_analysis_next_ack_frame
,
1832 { "Next Transport ACK Frame", "lbtru.analysis.next_ack_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1833 { &hf_lbtru_analysis_next_creq_frame
,
1834 { "Next Transport CREQ Frame", "lbtru.analysis.next_creq_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1835 { &hf_lbtru_analysis_next_rst_frame
,
1836 { "Next Transport RST Frame", "lbtru.analysis.next_rst_frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1837 { &hf_lbtru_analysis_sqn
,
1838 { "SQN Also in", "lbtru.analysis.sqn", FT_NONE
, BASE_NONE
, NULL
, 0x0, "Sequence number also appears in these frames", HFILL
} },
1839 { &hf_lbtru_analysis_sqn_frame
,
1840 { "Frame", "lbtru.analysis.sqn.frame", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1841 { &hf_lbtru_analysis_data_retransmission
,
1842 { "Frame is a Data Retransmission", "lbtru.analysis.data_retransmission", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1843 { &hf_lbtru_analysis_data_sqn_gap
,
1844 { "Gap in Data Sequence", "lbtru.analysis.data_sqn_gap", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1845 { &hf_lbtru_analysis_data_ooo_gap
,
1846 { "Data Sequence Out of Order Gap", "lbtru.analysis.data_ooo_gap", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1847 { &hf_lbtru_analysis_data_duplicate
,
1848 { "Duplicate Data Frame", "lbtru.analysis.data_duplicate", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1849 { &hf_lbtru_analysis_sm_sqn_gap
,
1850 { "Gap in SM Sequence", "lbtru.analysis.sm_sqn_gap", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1851 { &hf_lbtru_analysis_sm_ooo_gap
,
1852 { "SM Sequence Out of Order Gap", "lbtru.analysis.sm_ooo_gap", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
1853 { &hf_lbtru_analysis_sm_duplicate
,
1854 { "Duplicate SM Frame", "lbtru.analysis.sm_duplicate", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
1856 static int * ett
[] =
1861 &ett_lbtru_hdr_flags
,
1865 &ett_lbtru_nak_list
,
1867 &ett_lbtru_ncf_list
,
1870 &ett_lbtru_opt_sid_flags
,
1871 &ett_lbtru_opt_cid_flags
,
1872 &ett_lbtru_transport
,
1873 &ett_lbtru_transport_sqn
,
1875 static ei_register_info ei
[] =
1877 { &ei_lbtru_analysis_unknown_type
, { "lbtru.analysis.unknown_type", PI_MALFORMED
, PI_ERROR
, "Unrecognized type", EXPFILL
} },
1878 { &ei_lbtru_analysis_unknown_header
, { "lbtru.analysis.unknown_header", PI_MALFORMED
, PI_ERROR
, "Unrecognized header", EXPFILL
} },
1879 { &ei_lbtru_analysis_zero_length_header
, { "lbtru.analysis.zero_length_header", PI_MALFORMED
, PI_ERROR
, "Zero-length header", EXPFILL
} },
1880 { &ei_lbtru_analysis_ack
, { "lbtru.analysis.ack", PI_SEQUENCE
, PI_CHAT
, "ACK", EXPFILL
} },
1881 { &ei_lbtru_analysis_ncf
, { "lbtru.analysis.ncf", PI_SEQUENCE
, PI_NOTE
, "NCF", EXPFILL
} },
1882 { &ei_lbtru_analysis_ncf_ncf
, { "lbtru.analysis.ncf.ncf", PI_SEQUENCE
, PI_NOTE
, "NCF", EXPFILL
} },
1883 { &ei_lbtru_analysis_nak
, { "lbtru.analysis.nak", PI_SEQUENCE
, PI_WARN
, "NAK", EXPFILL
} },
1884 { &ei_lbtru_analysis_nak_nak
, { "lbtru.analysis.nak.nak", PI_SEQUENCE
, PI_WARN
, "NAK", EXPFILL
} },
1885 { &ei_lbtru_analysis_sm
, { "lbtru.analysis.sm", PI_SEQUENCE
, PI_CHAT
, "SM", EXPFILL
} },
1886 { &ei_lbtru_analysis_sm_syn
, { "lbtru.analysis.sm.syn", PI_SEQUENCE
, PI_CHAT
, "SM SYN", EXPFILL
} },
1887 { &ei_lbtru_analysis_creq
, { "lbtru.analysis.creq", PI_SEQUENCE
, PI_CHAT
, "Connection REQuest", EXPFILL
} },
1888 { &ei_lbtru_analysis_rst
, { "lbtru.analysis.rst", PI_SEQUENCE
, PI_CHAT
, "ReSeT", EXPFILL
} },
1889 { &ei_lbtru_analysis_data_rx
, { "lbtru.analysis.data.rx", PI_SEQUENCE
, PI_NOTE
, "Data retransmission", EXPFILL
} },
1890 { &ei_lbtru_analysis_data_gap
, { "lbtru.analysis.data.gap", PI_SEQUENCE
, PI_NOTE
, "Data sequence gap", EXPFILL
} },
1891 { &ei_lbtru_analysis_data_ooo
, { "lbtru.analysis.data.ooo", PI_SEQUENCE
, PI_NOTE
, "Data sequence out of order", EXPFILL
} },
1892 { &ei_lbtru_analysis_data_dup
, { "lbtru.analysis.data.dup", PI_SEQUENCE
, PI_NOTE
, "Duplicate data", EXPFILL
} },
1893 { &ei_lbtru_analysis_sm_gap
, { "lbtru.analysis.sm.gap", PI_SEQUENCE
, PI_NOTE
, "SM sequence gap", EXPFILL
} },
1894 { &ei_lbtru_analysis_sm_ooo
, { "lbtru.analysis.sm.ooo", PI_SEQUENCE
, PI_NOTE
, "SM sequence out of order", EXPFILL
} },
1895 { &ei_lbtru_analysis_sm_dup
, { "lbtru.analysis.sm.dup", PI_SEQUENCE
, PI_NOTE
, "Duplicate SM", EXPFILL
} },
1897 module_t
* lbtru_module
;
1899 expert_module_t
* expert_lbtru
;
1901 proto_lbtru
= proto_register_protocol("LBT Reliable Unicast Protocol",
1904 proto_register_field_array(proto_lbtru
, hf
, array_length(hf
));
1905 proto_register_subtree_array(ett
, array_length(ett
));
1906 expert_lbtru
= expert_register_protocol(proto_lbtru
);
1907 expert_register_field_array(expert_lbtru
, ei
, array_length(ei
));
1909 lbtru_dissector_handle
= register_dissector("lbtru", dissect_lbtru
, proto_lbtru
);
1911 lbtru_tap_handle
= register_tap("lbm_lbtru");
1913 lbtru_module
= prefs_register_protocol_subtree("29West", proto_lbtru
, proto_reg_handoff_lbtru
);
1914 prefs_register_uint_preference(lbtru_module
,
1916 "Source port range low (default " MAKESTRING(LBTRU_DEFAULT_SOURCE_PORT_LOW
)")",
1917 "Set the low end of the LBT-RU source UDP port range (context transport_lbtru_port_low)",
1919 &global_lbtru_source_port_low
);
1921 prefs_register_uint_preference(lbtru_module
,
1923 "Source port range high (default " MAKESTRING(LBTRU_DEFAULT_SOURCE_PORT_HIGH
)")",
1924 "Set the high end of the LBT-RU source UDP port range (context transport_lbtru_port_high)",
1926 &global_lbtru_source_port_high
);
1928 prefs_register_uint_preference(lbtru_module
,
1929 "receiver_port_low",
1930 "Receiver port range low (default " MAKESTRING(LBTRU_DEFAULT_RECEIVER_PORT_LOW
)")",
1931 "Set the low end of the LBT-RU receiver UDP port range (receiver transport_lbtru_port_low)",
1933 &global_lbtru_receiver_port_low
);
1935 prefs_register_uint_preference(lbtru_module
,
1936 "receiver_port_high",
1937 "Receiver port range high (default " MAKESTRING(LBTRU_DEFAULT_RECEIVER_PORT_HIGH
)")",
1938 "Set the high end of the LBT-RU receiver UDP port range (receiver transport_lbtru_port_high)",
1940 &global_lbtru_receiver_port_high
);
1942 lbtru_expert_separate_naks
= global_lbtru_expert_separate_naks
;
1943 prefs_register_bool_preference(lbtru_module
,
1944 "expert_separate_naks",
1945 "Separate NAKs in Expert Info",
1946 "Separate multiple NAKs from a single packet into distinct Expert Info entries",
1947 &global_lbtru_expert_separate_naks
);
1948 lbtru_expert_separate_ncfs
= global_lbtru_expert_separate_ncfs
;
1949 prefs_register_bool_preference(lbtru_module
,
1950 "expert_separate_ncfs",
1951 "Separate NCFs in Expert Info",
1952 "Separate multiple NCFs from a single packet into distinct Expert Info entries",
1953 &global_lbtru_expert_separate_ncfs
);
1955 lbtru_sequence_analysis
= global_lbtru_sequence_analysis
;
1956 prefs_register_bool_preference(lbtru_module
,
1957 "sequence_analysis",
1958 "Perform Sequence Number Analysis",
1959 "Perform analysis on LBT-RU sequence numbers to determine out-of-order, gaps, loss, etc",
1960 &global_lbtru_sequence_analysis
);
1962 prefs_register_bool_preference(lbtru_module
,
1964 "Use LBT-RU tag table",
1965 "Use table of LBT-RU tags to decode the packet instead of above values",
1966 &global_lbtru_use_tag
);
1967 tag_uat
= uat_new("LBT-RU tag definitions",
1968 sizeof(lbtru_tag_entry_t
),
1971 (void * *)&lbtru_tag_entry
,
1973 UAT_AFFECTS_DISSECTION
,
1976 lbtru_tag_update_cb
,
1981 prefs_register_uat_preference(lbtru_module
,
1984 "A table to define LBT-RU tags",
1988 /* The registration hand-off routine */
1989 void proto_reg_handoff_lbtru(void)
1991 static bool already_registered
= false;
1993 if (!already_registered
)
1995 dissector_add_for_decode_as_with_preference("udp.port", lbtru_dissector_handle
);
1996 heur_dissector_add("udp", test_lbtru_packet
, "LBT Reliable Unicast over UDP", "lbtru_udp", proto_lbtru
, HEURISTIC_ENABLE
);
1999 /* Make sure the low source port is <= the high source port. If not, don't change them. */
2000 if (global_lbtru_source_port_low
<= global_lbtru_source_port_high
)
2002 lbtru_source_port_low
= global_lbtru_source_port_low
;
2003 lbtru_source_port_high
= global_lbtru_source_port_high
;
2006 /* Make sure the low receiver port is <= the high receiver port. If not, don't change them. */
2007 if (global_lbtru_receiver_port_low
<= global_lbtru_receiver_port_high
)
2009 lbtru_receiver_port_low
= global_lbtru_receiver_port_low
;
2010 lbtru_receiver_port_high
= global_lbtru_receiver_port_high
;
2013 lbtru_expert_separate_naks
= global_lbtru_expert_separate_naks
;
2014 lbtru_expert_separate_ncfs
= global_lbtru_expert_separate_ncfs
;
2016 lbtru_sequence_analysis
= global_lbtru_sequence_analysis
;
2018 lbtru_use_tag
= global_lbtru_use_tag
;
2020 already_registered
= true;
2024 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2029 * indent-tabs-mode: nil
2032 * vi: set shiftwidth=4 tabstop=8 expandtab:
2033 * :indentSize=4:tabSize=8:noTabs=true: