3 * Routines for GMR-1 LAPSat dissection in wireshark.
5 * Link Access Procedures (LAP) for the Satellite Channel (LAPSat).
6 * LAPSat is the protocol for signalling transfer between an Access
7 * Terminal (MES) and a Gateway Station (GS) in the GeoMobile (GMR-1) network.
9 * Copyright (c) 2011 Sylvain Munaut <tnt@246tNt.com>
10 * Inspired on LAPDm code by Duncan Salerno <duncan.salerno@googlemail.com>
13 * [1] ETSI TS 101 376-4-6 V1.2.1 - GMR-1 04.006
17 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39 #include <epan/packet.h>
40 #include <epan/reassemble.h>
41 #include <epan/wmem/wmem.h>
44 static int proto_lapsat
= -1;
46 static reassembly_table lapsat_reassembly_table
;
48 static dissector_table_t lapsat_sapi_dissector_table
;
50 static dissector_handle_t data_handle
;
52 static gint ett_lapsat
= -1;
53 static gint ett_lapsat_address
= -1;
54 static gint ett_lapsat_control
= -1;
55 static gint ett_lapsat_fragment
= -1;
56 static gint ett_lapsat_fragments
= -1;
58 static int hf_lapsat_addr
= -1;
59 static int hf_lapsat_addr_sst
= -1;
60 static int hf_lapsat_addr_cr
= -1;
61 static int hf_lapsat_addr_sapi
= -1;
62 static int hf_lapsat_addr_si
= -1;
63 static int hf_lapsat_addr_lpd
= -1;
64 static int hf_lapsat_addr_lfi
= -1;
66 static int hf_lapsat_ctl
= -1;
67 static int hf_lapsat_ctl_ftype_i
= -1;
68 static int hf_lapsat_ctl_ftype_s_u
= -1;
69 static int hf_lapsat_ctl_s_ftype
= -1;
70 static int hf_lapsat_ctl_u_modifier_cmd
= -1;
71 static int hf_lapsat_ctl_u_modifier_resp
= -1;
72 static int hf_lapsat_ctl_n_r
= -1;
73 static int hf_lapsat_ctl_n_s
= -1;
74 static int hf_lapsat_ctl_p
= -1;
75 static int hf_lapsat_ctl_f
= -1;
76 static int hf_lapsat_ctl_mii
= -1;
78 static int hf_lapsat_payload_last_nibble
= -1;
80 static int hf_lapsat_len
= -1;
82 static int hf_lapsat_fragments
= -1;
83 static int hf_lapsat_fragment
= -1;
84 static int hf_lapsat_fragment_overlap
= -1;
85 static int hf_lapsat_fragment_overlap_conflicts
= -1;
86 static int hf_lapsat_fragment_multiple_tails
= -1;
87 static int hf_lapsat_fragment_too_long_fragment
= -1;
88 static int hf_lapsat_fragment_error
= -1;
89 static int hf_lapsat_fragment_count
= -1;
90 static int hf_lapsat_reassembled_in
= -1;
91 static int hf_lapsat_reassembled_length
= -1;
94 #define LAPSAT_HEADER_LEN 3
96 #define LAPSAT_SAPI_RR_CC_MM 0
97 #define LAPSAT_SAPI_SMS 3
104 #define LAPSAT_SST 0x01 /* SACCH status bit */
105 #define LAPSAT_CR 0x02 /* Command/Response bit */
106 #define LAPSAT_SAPI_MSK 0x0c /* Service Access Point Identifier */
107 #define LAPSAT_SAPI_SHIFT 2
108 #define LAPSAT_SI 0x10 /* Segment Indicator */
109 #define LAPSAT_LPD_MSK 0x60 /* DL for LAPSat or SMS-CB */
110 #define LAPSAT_LPD_SHIFT 6
111 #define LAPSAT_LFI 0x80 /* Length Field Indicator */
113 static const value_string lapsat_addr_sst_vals
[] = {
114 { 0, "FACCH and all other messages" },
115 { 1, "SACCH message" },
119 static const value_string lapsat_addr_sapi_vals
[] = {
120 { LAPSAT_SAPI_RR_CC_MM
, "RR/MM/CC" },
121 { LAPSAT_SAPI_SMS
, "SMS/SS" },
125 static const value_string lapsat_addr_lpd_vals
[] = {
126 { 0, "Normal GMR-1" },
127 { 1, "Cell broadcast service" },
131 static const value_string lapsat_addr_si_vals
[] = {
132 { 0, "Complete/Last Segment of L3 message" },
133 { 1, "Segment only" },
137 static const value_string lapsat_addr_lfi_vals
[] = {
138 { 0, "Length Field not present (all data valid)" },
139 { 1, "Length Field present" },
148 #define LAPSAT_CTL_TYPE_S 0x001
149 #define LAPSAT_CTL_TYPE_U 0x003
150 #define LAPSAT_CTL_TYPE_S_U_MSK 0x003
152 #define LAPSAT_CTL_TYPE_I 0x000
153 #define LAPSAT_CTL_TYPE_I_MSK 0x001
155 static const value_string lapsat_ctl_ftype_vals
[] = {
156 { LAPSAT_CTL_TYPE_I
, "Information frame" },
157 { LAPSAT_CTL_TYPE_S
, "Supervisory frame" },
158 { LAPSAT_CTL_TYPE_U
, "Unnumbered frame" },
164 * S-format frame types
167 #define LAPSAT_CTL_S_FTYPE_MSK 0x00c
169 #define LAPSAT_RR 0x000
170 #define LAPSAT_GREJ 0x008
172 static const value_string lapsat_ctl_s_ftype_vals
[] = {
173 { LAPSAT_RR
>> 2, "Receiver ready" },
174 { LAPSAT_GREJ
>> 2, "Group reject" },
183 #define LAPSAT_CTL_U_MODIFIER_MSK 0x18c
185 #define LAPSAT_SABM 0x08c
186 #define LAPSAT_DM 0x00c
187 #define LAPSAT_DISC 0x100
188 #define LAPSAT_UA 0x180
189 #define LAPSAT_UI 0x000
191 static const value_string lapsat_ctl_u_modifier_vals_cmd
[] = {
192 { LAPSAT_SABM
>> 2, "Set Asynchronous Balanced Mode" },
193 { LAPSAT_DISC
>> 2, "Disconnect" },
194 { LAPSAT_UI
>> 2, "Unnumbered Information" },
198 static const value_string lapsat_ctl_u_modifier_vals_resp
[] = {
199 { LAPSAT_DM
>> 2, "Disconnected mode" },
200 { LAPSAT_UA
>> 2, "Unnumbered Acknowledge" },
209 #define LAPSAT_CTL_P_F 0x040
210 #define LAPSAT_CTL_MII 0x200
211 #define LAPSAT_CTL_N_R_MSK 0xf80
212 #define LAPSAT_CTL_N_R_SHIFT 7
213 #define LAPSAT_CTL_N_S_MSK 0x03e
214 #define LAPSAT_CTL_N_S_SHIFT 1
221 static const value_string true_false_vals
[] = {
228 static const fragment_items lapsat_frag_items
= {
229 /* Fragment subtrees */
230 &ett_lapsat_fragment
,
231 &ett_lapsat_fragments
,
232 /* Fragment fields */
233 &hf_lapsat_fragments
,
235 &hf_lapsat_fragment_overlap
,
236 &hf_lapsat_fragment_overlap_conflicts
,
237 &hf_lapsat_fragment_multiple_tails
,
238 &hf_lapsat_fragment_too_long_fragment
,
239 &hf_lapsat_fragment_error
,
240 &hf_lapsat_fragment_count
,
241 /* Reassembled in field */
242 &hf_lapsat_reassembled_in
,
243 /* Reassembled length field */
244 &hf_lapsat_reassembled_length
,
245 /* Reassembled data field */
252 lapsat_defragment_init(void)
254 reassembly_table_init(&lapsat_reassembly_table
,
255 &addresses_reassembly_table_functions
);
260 * Main dissection functions
264 dissect_control(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int is_response
)
266 proto_tree
*ctl_tree
;
268 guint16 ctl
, poll_final
;
269 const char *frame_type
;
272 info
= (char *)wmem_alloc(wmem_packet_scope(), 80);
274 /* Grab complete control field */
275 ctl
= tvb_get_ntohs(tvb
, 1) >> 4;
277 poll_final
= ctl
& LAPSAT_CTL_P_F
;
279 /* Generate small 'descriptive' text */
280 switch (ctl
& LAPSAT_CTL_TYPE_S_U_MSK
) {
281 case LAPSAT_CTL_TYPE_S
:
285 switch (ctl
& LAPSAT_CTL_S_FTYPE_MSK
) {
293 frame_type
= "Unknown";
297 g_snprintf(info
, 80, "S%s, func=%s, N(R)=%u",
298 poll_final
? (is_response
? " F" : " P") : "",
300 (ctl
& LAPSAT_CTL_N_R_MSK
) >> LAPSAT_CTL_N_R_SHIFT
);
304 case LAPSAT_CTL_TYPE_U
:
308 switch (ctl
& LAPSAT_CTL_U_MODIFIER_MSK
) {
310 frame_type
= (ctl
& LAPSAT_CTL_MII
) ?
311 "SABM, MII=1" : "SABM, MII=0";
326 frame_type
= "Unknown";
330 g_snprintf(info
, 80, "U%s, func=%s",
331 poll_final
? (is_response
? " F" : " P") : "",
340 g_snprintf(info
, 80, "I%s, N(R)=%u, N(S)=%u",
341 poll_final
? " P" : "",
342 (ctl
& LAPSAT_CTL_N_R_MSK
) >> LAPSAT_CTL_N_R_SHIFT
,
343 (ctl
& LAPSAT_CTL_N_S_MSK
) >> LAPSAT_CTL_N_S_SHIFT
);
349 col_add_str(pinfo
->cinfo
, COL_INFO
, info
);
351 /* Create item & subtree */
352 ctl_ti
= proto_tree_add_uint_format_value(
354 tvb
, 1, 2, (guint32
)ctl
,
355 "%s (0x%03x)", info
, ctl
358 ctl_tree
= proto_item_add_subtree(ctl_ti
, ett_lapsat_control
);
361 switch (ctl
& LAPSAT_CTL_TYPE_S_U_MSK
) {
362 case LAPSAT_CTL_TYPE_S
:
367 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_ftype_s_u
,
368 tvb
, 1, 2, ENC_BIG_ENDIAN
);
370 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_s_ftype
,
371 tvb
, 1, 2, ENC_BIG_ENDIAN
);
373 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_n_r
,
374 tvb
, 1, 2, ENC_BIG_ENDIAN
);
377 proto_tree_add_item(ctl_tree
,
378 is_response
? hf_lapsat_ctl_f
: hf_lapsat_ctl_p
,
379 tvb
, 1, 2, ENC_BIG_ENDIAN
);
383 case LAPSAT_CTL_TYPE_U
:
388 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_ftype_s_u
,
389 tvb
, 1, 2, ENC_BIG_ENDIAN
);
391 proto_tree_add_item(ctl_tree
,
392 is_response
? hf_lapsat_ctl_u_modifier_resp
:
393 hf_lapsat_ctl_u_modifier_cmd
,
394 tvb
, 1, 2, ENC_BIG_ENDIAN
);
397 proto_tree_add_item(ctl_tree
,
398 is_response
? hf_lapsat_ctl_f
: hf_lapsat_ctl_p
,
399 tvb
, 1, 2, ENC_BIG_ENDIAN
);
401 if (((ctl
& LAPSAT_CTL_U_MODIFIER_MSK
) == LAPSAT_SABM
) &&
402 (ctl
& LAPSAT_CTL_MII
))
403 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_mii
,
404 tvb
, 1, 2, ENC_BIG_ENDIAN
);
413 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_ftype_i
,
414 tvb
, 1, 2, ENC_BIG_ENDIAN
);
416 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_n_r
,
417 tvb
, 1, 2, ENC_BIG_ENDIAN
);
419 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_n_s
,
420 tvb
, 1, 2, ENC_BIG_ENDIAN
);
423 proto_tree_add_item(ctl_tree
, hf_lapsat_ctl_p
,
424 tvb
, 1, 2, ENC_BIG_ENDIAN
);
433 dissect_lapsat(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
435 proto_tree
*lapsat_tree
, *addr_tree
;
436 proto_item
*lapsat_ti
, *addr_ti
;
438 guint8 addr
, sapi
, cr
;
440 unsigned int hlen
, is_response
= 0, plen
;
442 /* Check that there's enough data */
443 if (tvb_length(tvb
) < LAPSAT_HEADER_LEN
)
446 /* Set protocol column */
447 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "LAPSat");
449 /* Grab a couple of fields */
450 addr
= tvb_get_guint8(tvb
, 0);
452 sapi
= (addr
& LAPSAT_SAPI_MSK
) >> LAPSAT_SAPI_SHIFT
;
454 cr
= addr
& LAPSAT_CR
;
455 if (pinfo
->p2p_dir
== P2P_DIR_RECV
) {
456 is_response
= cr
? FALSE
: TRUE
;
458 else if (pinfo
->p2p_dir
== P2P_DIR_SENT
) {
459 is_response
= cr
? TRUE
: FALSE
;
462 hlen
= LAPSAT_HEADER_LEN
;
464 if (addr
& LAPSAT_LFI
)
467 /* FIXME if "S func=GREJ", extend */
469 /* Create LAPSat tree */
470 lapsat_ti
= proto_tree_add_item(tree
, proto_lapsat
, tvb
, 0, hlen
, ENC_BIG_ENDIAN
);
471 lapsat_tree
= proto_item_add_subtree(lapsat_ti
, ett_lapsat
);
473 /* Dissect address field */
474 addr_ti
= proto_tree_add_item(lapsat_tree
, hf_lapsat_addr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
475 addr_tree
= proto_item_add_subtree(addr_ti
, ett_lapsat_address
);
477 proto_tree_add_item(addr_tree
, hf_lapsat_addr_sst
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
478 proto_tree_add_item(addr_tree
, hf_lapsat_addr_cr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
479 proto_tree_add_item(addr_tree
, hf_lapsat_addr_sapi
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
480 proto_tree_add_item(addr_tree
, hf_lapsat_addr_si
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
481 proto_tree_add_item(addr_tree
, hf_lapsat_addr_lpd
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
482 proto_tree_add_item(addr_tree
, hf_lapsat_addr_lfi
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
484 /* Dissect control field */
485 control
= dissect_control(tvb
, pinfo
, lapsat_tree
, is_response
);
487 /* Last payload nibble */
488 proto_tree_add_item(lapsat_tree
, hf_lapsat_payload_last_nibble
, tvb
, 2, 1, ENC_BIG_ENDIAN
);
490 /* Optional length field */
491 if (addr
& LAPSAT_LFI
)
492 proto_tree_add_item(lapsat_tree
, hf_lapsat_len
, tvb
, 3, 1, ENC_BIG_ENDIAN
);
494 /* If frame is "S func=GREJ", then add Na(R) & Nb(R) */
497 /* Get the payload */
498 plen
= (addr
& LAPSAT_LFI
) ?
499 tvb_get_guint8(tvb
, 3) : tvb_length(tvb
) - hlen
;
502 return; /* No point in doing more if there is no payload */
504 DISSECTOR_ASSERT((plen
+ hlen
) <= tvb_length(tvb
));
506 if ((plen
+ hlen
) == tvb_length(tvb
)) {
507 /* Need to integrate the last nibble */
508 guint8
*data
= (guint8
*)tvb_memdup(NULL
, tvb
, hlen
, plen
);
509 data
[plen
-1] |= tvb_get_guint8(tvb
, 2) << 4;
510 payload
= tvb_new_child_real_data(tvb
, data
, plen
, plen
);
511 tvb_set_free_cb(payload
, g_free
);
513 /* Last nibble doesn't need merging */
514 payload
= tvb_new_subset(tvb
, hlen
, plen
, -1);
517 add_new_data_source(pinfo
, payload
, "LAPSat Payload");
519 /* Handle fragments */
520 if ((control
& LAPSAT_CTL_TYPE_I_MSK
) == LAPSAT_CTL_TYPE_I
) {
522 * Potentially fragmented I frames
524 fragment_head
*fd_m
= NULL
;
525 tvbuff_t
*reassembled
= NULL
;
527 gboolean save_fragmented
= pinfo
->fragmented
;
529 /* Is this a fragment ? */
530 pinfo
->fragmented
= !!(addr
& LAPSAT_SI
);
532 /* Rely on caller to provide a way to group fragments */
533 fragment_id
= (pinfo
->circuit_id
<< 3) | (sapi
<< 1) | pinfo
->p2p_dir
;
535 /* Fragment reconstruction helpers */
536 fd_m
= fragment_add_seq_next(
537 &lapsat_reassembly_table
,
540 fragment_id
, /* To group fragments */
543 !!(addr
& LAPSAT_SI
) /* More fragment ? */
546 reassembled
= process_reassembled_data(
548 "Reassembled LAPSat", fd_m
, &lapsat_frag_items
,
552 /* Reassembled into this packet ? */
553 if (fd_m
&& pinfo
->fd
->num
== fd_m
->reassembled_in
) {
554 /* Yes, so handoff to upper layers */
555 if (!dissector_try_uint(lapsat_sapi_dissector_table
, sapi
,
556 reassembled
, pinfo
, tree
))
557 call_dissector(data_handle
, reassembled
, pinfo
, tree
);
559 /* No, just add infos */
560 col_append_str(pinfo
->cinfo
, COL_INFO
, " (Fragment)");
561 proto_tree_add_text(lapsat_tree
, payload
, 0, -1, "Fragment Data");
564 /* Now reset fragmentation information in pinfo */
565 pinfo
->fragmented
= save_fragmented
;
570 if (!dissector_try_uint(lapsat_sapi_dissector_table
, sapi
, payload
, pinfo
, tree
))
571 call_dissector(data_handle
, payload
, pinfo
, tree
);
576 proto_register_lapsat(void)
578 static hf_register_info hf
[] = {
581 { "Address Field", "lapsat.address",
582 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
585 { &hf_lapsat_addr_sst
,
586 { "SST", "lapsat.address.sst",
587 FT_UINT8
, BASE_DEC
, VALS(lapsat_addr_sst_vals
), LAPSAT_SST
,
588 "SACCH status bit", HFILL
},
590 { &hf_lapsat_addr_cr
,
591 { "C/R", "lapsat.address.cr",
592 FT_UINT8
, BASE_DEC
, NULL
, LAPSAT_CR
,
593 "Command/response bit", HFILL
},
595 { &hf_lapsat_addr_sapi
,
596 { "SAPI", "lapsat.address.sapi",
597 FT_UINT8
, BASE_DEC
, VALS(lapsat_addr_sapi_vals
), LAPSAT_SAPI_MSK
,
598 "Service access point identifier", HFILL
},
600 { &hf_lapsat_addr_si
,
601 { "SI", "lapsat.address.si",
602 FT_UINT8
, BASE_DEC
, VALS(lapsat_addr_si_vals
), LAPSAT_SI
,
603 "Segment Indicator", HFILL
},
605 { &hf_lapsat_addr_lpd
,
606 { "LPD", "lapsat.address.lpd",
607 FT_UINT8
, BASE_DEC
, VALS(lapsat_addr_lpd_vals
), LAPSAT_LPD_MSK
,
608 "Link Protocol Discriminator", HFILL
},
610 { &hf_lapsat_addr_lfi
,
611 { "LFI", "lapsat.address.lfi",
612 FT_UINT8
, BASE_DEC
, VALS(lapsat_addr_lfi_vals
), LAPSAT_LFI
,
613 "Length Field Indicator", HFILL
},
618 { "Control Field", "lapsat.control_field",
619 FT_UINT16
, BASE_HEX
, NULL
, 0x00,
622 { &hf_lapsat_ctl_ftype_i
,
623 { "Frame type", "lapsat.control.ftype",
624 FT_UINT16
, BASE_DEC
, VALS(lapsat_ctl_ftype_vals
), LAPSAT_CTL_TYPE_I_MSK
<< 4,
627 { &hf_lapsat_ctl_ftype_s_u
,
628 { "Frame type", "lapsat.control.ftype",
629 FT_UINT16
, BASE_DEC
, VALS(lapsat_ctl_ftype_vals
), LAPSAT_CTL_TYPE_S_U_MSK
<< 4,
632 { &hf_lapsat_ctl_s_ftype
,
633 { "Supervisory frame type", "lapsat.control.s_ftype",
634 FT_UINT16
, BASE_DEC
, VALS(lapsat_ctl_s_ftype_vals
), LAPSAT_CTL_S_FTYPE_MSK
<< 4,
637 { &hf_lapsat_ctl_u_modifier_cmd
,
638 { "Command", "lapsat.control.u_modifier_cmd",
639 FT_UINT16
, BASE_HEX
, VALS(lapsat_ctl_u_modifier_vals_cmd
),
640 LAPSAT_CTL_U_MODIFIER_MSK
<< 4,
643 { &hf_lapsat_ctl_u_modifier_resp
,
644 { "Response", "lapsat.control.u_modifier_resp",
645 FT_UINT16
, BASE_HEX
, VALS(lapsat_ctl_u_modifier_vals_resp
),
646 LAPSAT_CTL_U_MODIFIER_MSK
<< 4,
649 { &hf_lapsat_ctl_n_r
,
650 { "N(R)", "lapsat.control.n_r",
651 FT_UINT16
, BASE_DEC
, NULL
, LAPSAT_CTL_N_R_MSK
<< 4,
654 { &hf_lapsat_ctl_n_s
,
655 { "N(S)", "lapsat.control.n_s",
656 FT_UINT16
, BASE_DEC
, NULL
, LAPSAT_CTL_N_S_MSK
<< 4,
660 { "Poll", "lapsat.control.p",
661 FT_UINT16
, BASE_DEC
, VALS(true_false_vals
), LAPSAT_CTL_P_F
<< 4,
665 { "Final", "lapsat.control.f",
666 FT_UINT16
, BASE_DEC
, VALS(true_false_vals
), LAPSAT_CTL_P_F
<< 4,
669 { &hf_lapsat_ctl_mii
,
670 { "MII", "lapsat.control.mii",
671 FT_UINT16
, BASE_DEC
, VALS(true_false_vals
), LAPSAT_CTL_MII
<< 4,
672 "Mobile Identity Indicator", HFILL
}
675 /* Payload last nibble */
676 { &hf_lapsat_payload_last_nibble
,
677 { "Payload last nibble", "lapsat.payload.last_nibble",
678 FT_UINT8
, BASE_HEX
, NULL
, 0x0f,
684 { "Length Field", "lapsat.length",
685 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
689 /* Fragment reassembly */
690 { &hf_lapsat_fragments
,
691 { "Message fragments", "lapsat.fragments",
692 FT_NONE
, BASE_NONE
, NULL
, 0x00,
693 "LAPSat Message fragments", HFILL
}
695 { &hf_lapsat_fragment
,
696 { "Message fragment", "lapsat.fragment",
697 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
698 "LAPSat Message fragment", HFILL
}
700 { &hf_lapsat_fragment_overlap
,
701 { "Message fragment overlap", "lapsat.fragment.overlap",
702 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
703 "LAPSat Message fragment overlaps with other fragment(s)", HFILL
}
705 { &hf_lapsat_fragment_overlap_conflicts
,
706 { "Message fragment overlapping with conflicting data",
707 "lapsat.fragment.overlap.conflicts",
708 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
709 "LAPSat Message fragment overlaps with conflicting data", HFILL
}
711 { &hf_lapsat_fragment_multiple_tails
,
712 { "Message has multiple tail fragments", "lapsat.fragment.multiple_tails",
713 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
714 "LAPSat Message fragment has multiple tail fragments", HFILL
}
716 { &hf_lapsat_fragment_too_long_fragment
,
717 { "Message fragment too long", "lapsat.fragment.too_long_fragment",
718 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
719 "LAPSat Message fragment data goes beyond the packet end", HFILL
}
721 { &hf_lapsat_fragment_error
,
722 { "Message defragmentation error", "lapsat.fragment.error",
723 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
724 "LAPSat Message defragmentation error due to illegal fragments", HFILL
}
726 { &hf_lapsat_fragment_count
,
727 { "Message fragment count", "lapsat.fragment.count",
728 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
731 { &hf_lapsat_reassembled_in
,
732 { "Reassembled in", "lapsat.reassembled.in",
733 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
734 "LAPSat Message has been reassembled in this packet.", HFILL
}
736 { &hf_lapsat_reassembled_length
,
737 { "Reassembled LAPSat length", "lapsat.reassembled.length",
738 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
739 "The total length of the reassembled payload", HFILL
}
743 static gint
*ett
[] = {
747 &ett_lapsat_fragment
,
748 &ett_lapsat_fragments
,
751 proto_lapsat
= proto_register_protocol("Link Access Procedure, Satellite channel (LAPSat)", "LAPSat", "lapsat");
753 proto_register_field_array (proto_lapsat
, hf
, array_length(hf
));
754 proto_register_subtree_array(ett
, array_length(ett
));
756 register_dissector("lapsat", dissect_lapsat
, proto_lapsat
);
758 lapsat_sapi_dissector_table
= register_dissector_table("lapsat.sapi", "LAPSat SAPI", FT_UINT8
, BASE_DEC
);
760 register_init_routine (lapsat_defragment_init
);
764 proto_reg_handoff_lapsat(void)
766 data_handle
= find_dissector("data");