2 * Reliable Multicast Transport (RMT)
3 * FEC Building Block dissector
4 * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
6 * Forward Error Correction (ALC):
7 * -------------------------------
9 * The goal of the FEC building block is to describe functionality
10 * directly related to FEC codes that is common to all reliable content
11 * delivery IP multicast protocols, and to leave out any additional
12 * functionality that is specific to particular protocols.
15 * RFC 3452, Forward Error Correction Building Block
16 * RFC 3695, Compact Forward Error Correction (FEC) Schemes
17 * Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Schemes draft-peltotalo-rmt-bb-fec-supp-xor-pcm-rs-00
18 * IANA RMT FEC parameters (http://www.iana.org/assignments/rmt-fec-parameters)
22 * Wireshark - Network traffic analyzer
23 * By Gerald Combs <gerald@wireshark.org>
24 * Copyright 1998 Gerald Combs
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version 2
29 * of the License, or (at your option) any later version.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
49 #include <epan/packet.h>
50 #include <epan/prefs.h>
52 #include "packet-rmt-fec.h"
55 const value_string string_fec_encoding_id[] =
57 { 0, "Compact No-Code" },
58 { 2, "Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Codes" },
59 { 128, "Small Block, Large Block and Expandable FEC Codes" },
60 { 129, "Small Block Systematic FEC Codes" },
61 { 130, "Compact FEC Codes" },
62 { 132, "Simple XOR, Reed-Solomon, and Parity Check Matrix-based FEC Codes" },
66 /* FEC exported functions */
67 /* ====================== */
72 void fec_info_column(struct _fec *fec, packet_info *pinfo)
75 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", fec->sbn);
78 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", fec->esi);
84 /* Decode an EXT_FTI extension and fill FEC array */
85 void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
87 proto_item* ti = NULL;
91 ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length,
92 "EXT_FTI, FEC Object Transmission Information (%u)", e->het);
94 if (f.fec->encoding_id_present)
96 ext_tree = proto_item_add_subtree(ti, ett);
97 rmt_ext_decode_default_header(e, tvb, ext_tree);
99 /* Decode 48-bit length field */
100 f.fec->transfer_length = tvb_get_ntoh64(tvb, e->offset) & G_GINT64_CONSTANT(0xFFFFFFFFFFFFU);
102 if (f.fec->encoding_id >= 128)
104 /* Decode FEC Instance ID */
105 f.fec->instance_id_present = TRUE;
106 f.fec->instance_id = (guint8) tvb_get_ntohs(tvb, e->offset+8);
110 proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length);
112 switch (f.fec->encoding_id)
118 f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
119 f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
123 proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
124 proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
129 f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
130 f.fec->max_source_block_length = tvb_get_ntohs(tvb, e->offset+12);
131 f.fec->max_number_encoding_symbols = tvb_get_ntohs(tvb, e->offset+14);
135 proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
136 proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 2, f.fec->max_source_block_length);
137 proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+14, 2, f.fec->max_number_encoding_symbols);
142 f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
143 f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
144 f.fec->max_number_encoding_symbols = tvb_get_ntohl(tvb, e->offset+16);
148 proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
149 proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
150 proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+16, 4, f.fec->max_number_encoding_symbols);
157 rmt_ext_decode_default_subtree(e, tvb, ti, ett);
160 /* Dissect a FEC header:
161 * fec - ptr to the logical FEC packet representation to fill
162 * hf - ptr to header fields array
163 * ett - ptr to ett array
164 * prefs - ptr to FEC prefs array
166 * pinfo - packet info
167 * tree - tree where to add FEC header subtree
168 * offset - ptr to offset to use and update
170 void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
173 proto_tree *fec_tree;
174 guint offset_save = *offset;
176 /* Create the FEC subtree */
179 ti = proto_tree_add_item(tree, f.hf->header, tvb, *offset, -1, FALSE);
180 fec_tree = proto_item_add_subtree(ti, f.ett->main);
187 /* FEC Encoding ID and FEC Instance ID processing */
188 if (f.fec->encoding_id_present)
192 proto_tree_add_uint(fec_tree, f.hf->encoding_id, tvb, *offset, 0, f.fec->encoding_id);
194 if (f.fec->encoding_id >= 128 && f.fec->instance_id_present)
195 proto_tree_add_uint(fec_tree, f.hf->instance_id, tvb, *offset, 0, f.fec->instance_id);
198 switch (f.fec->encoding_id)
202 f.fec->sbn = tvb_get_ntohs(tvb, *offset);
203 f.fec->esi = tvb_get_ntohs(tvb, *offset+2);
207 proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 2, f.fec->sbn);
208 proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+2, 2, f.fec->esi);
211 f.fec->sbn_present = TRUE;
212 f.fec->esi_present = TRUE;
219 f.fec->sbn = tvb_get_ntohl(tvb, *offset);
220 f.fec->esi = tvb_get_ntohl(tvb, *offset+4);
224 proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
225 proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+4, 4, f.fec->esi);
228 f.fec->sbn_present = TRUE;
229 f.fec->esi_present = TRUE;
234 f.fec->sbn = tvb_get_ntohl(tvb, *offset);
235 f.fec->sbl = tvb_get_ntohs(tvb, *offset+4);
236 f.fec->esi = tvb_get_ntohs(tvb, *offset+6);
240 proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
241 proto_tree_add_uint(fec_tree, f.hf->sbl, tvb, *offset+4, 2, f.fec->sbl);
242 proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+6, 2, f.fec->esi);
245 f.fec->sbn_present = TRUE;
246 f.fec->sbl_present = TRUE;
247 f.fec->esi_present = TRUE;
253 proto_item_set_len(ti, *offset - offset_save);
256 void fec_dissector_free(struct _fec *fec _U_)
264 /* Set/Reset preferences to default values */
265 void fec_prefs_set_default(struct _fec_prefs *fec_prefs _U_)
270 /* Register preferences */
271 void fec_prefs_register(struct _fec_prefs *fec_prefs _U_, module_t *module _U_)