summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/asn1/t38/t38.cnf
blob: 7b8fad229a60e3451eb78141729b94b1906dc132 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# t38.cnf
# T.38 conformation file
# 2007  Tomas Kukosa

#.EXPORTS ONLY_VALS WS_DLL
Type-of-msg/t30-indicator
Type-of-msg/t30-data
#.END

#.TYPE_RENAME
Type-of-msg/t30-indicator  T30_indicator
Type-of-msg/t30-data       T30_data
#.END

#.PDU
IFPPacket
UDPTLPacket
#.END

#.FN_PARS Type-of-msg  VAL_PTR=&Type_of_msg_value
#.FN_FTR Type-of-msg
  /* info for tap */
  if (primary_part)
    t38_info->type_msg = Type_of_msg_value;
#.END

#.FN_PARS Type-of-msg/t30-indicator  VAL_PTR=&T30ind_value
#.FN_FTR Type-of-msg/t30-indicator
    if (primary_part){
        col_append_fstr(actx->pinfo->cinfo, COL_INFO, " t30ind: %s",
         val_to_str(T30ind_value,t38_T30_indicator_vals,"<unknown>"));
    }

    /* info for tap */
    if (primary_part)
        t38_info->t30ind_value = T30ind_value;
#.END

#.FN_PARS Type-of-msg/t30-data  VAL_PTR=&Data_value
#.FN_FTR Type-of-msg/t30-data
    if (primary_part){
        col_append_fstr(actx->pinfo->cinfo, COL_INFO, " data:%s:",
         val_to_str(Data_value,t38_T30_data_vals,"<unknown>"));
    }


    /* info for tap */
    if (primary_part)
        t38_info->data_value = Data_value;
#.END

#.FN_FTR Data-Field/_item
    if (primary_part) Data_Field_item_num++;
#.END

#.FN_PARS Data-Field/_item/field-type
EXT=(use_pre_corrigendum_asn1_specification)?FALSE:TRUE
EXT_NUM=(use_pre_corrigendum_asn1_specification)?0:4
VAL_PTR=&Data_Field_field_type_value
#.FN_FTR Data-Field/_item/field-type
    if (primary_part){
        col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s",
         val_to_str(Data_Field_field_type_value,t38_T_field_type_vals,"<unknown>"));
    }

    if (primary_part) {
        if (Data_Field_field_type_value == 2 || Data_Field_field_type_value == 4 || Data_Field_field_type_value == 7) {/* hdlc-fcs-OK or hdlc-fcs-OK-sig-end or t4-non-ecm-sig-end*/
            fragment_head *frag_msg = NULL;
            tvbuff_t* new_tvb = NULL;
            gboolean save_fragmented = actx->pinfo->fragmented;

            actx->pinfo->fragmented = TRUE;

            /* if reass_start_seqnum=-1 it means we have received the end of the fragmente, without received any fragment data */
            if (p_t38_packet_conv_info->reass_start_seqnum != -1) {
                guint32 frag_seq_num;
                if (seq_number == (guint32)p_t38_packet_conv_info->reass_start_seqnum) {
                    frag_seq_num = (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter + Data_Field_item_num - p_t38_packet_conv_info->reass_start_data_field;
                } else {
                    frag_seq_num = seq_number - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter + Data_Field_item_num;
                }
                frag_msg = fragment_add_seq(&data_reassembly_table, /* reassembly table */
                    tvb, offset, actx->pinfo,
                    p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
                    NULL,
                    frag_seq_num,  /* fragment sequence number */
                    /*0,*/
                    0, /* fragment length */
                    FALSE, /* More fragments */
                    0);
                if ( Data_Field_field_type_value == 7 ) {
                    /* if there was packet lost or other errors during the defrag then frag_msg is NULL. This could also means
                     * there are out of order packets (e.g, got the tail frame t4-non-ecm-sig-end before the last fragment),
                     * but we will assume there was packet lost instead, which is more usual. So, we are going to reassemble the packet
                     * and get some stat, like packet lost and burst number of packet lost
                    */
                    if (!frag_msg) {
                        force_reassemble_seq(&data_reassembly_table, /* reassembly table */
                            actx->pinfo,
                            p_t38_packet_conv_info->reass_ID /* ID for fragments belonging together */
                        );
                    } else {
                        col_append_str(actx->pinfo->cinfo, COL_INFO, " (t4-data Reassembled: No packet lost)");

                        snprintf(t38_info->desc_comment, MAX_T38_DESC, "No packet lost");
                    }


                    if (p_t38_packet_conv_info->packet_lost) {
                        snprintf(t38_info->desc_comment, MAX_T38_DESC, " Pack lost: %d, Pack burst lost: %d", p_t38_packet_conv_info->packet_lost, p_t38_packet_conv_info->burst_lost);
                    } else {
                        snprintf(t38_info->desc_comment, MAX_T38_DESC, "No packet lost");
                    }

                    process_reassembled_data(tvb, offset, actx->pinfo,
                                "Reassembled T38", frag_msg, &data_frag_items, NULL, tree);

                    /* Now reset fragmentation information in pinfo */
                    actx->pinfo->fragmented = save_fragmented;

                    t38_info->time_first_t4_data = p_t38_packet_conv_info->time_first_t4_data;
                    t38_info->frame_num_first_t4_data = p_t38_packet_conv_info->reass_ID; /* The reass_ID is the Frame number of the first t4 fragment */

                } else {
                    new_tvb = process_reassembled_data(tvb, offset, actx->pinfo,
                                "Reassembled T38", frag_msg, &data_frag_items, NULL, tree);

                    /* Now reset fragmentation information in pinfo */
                    actx->pinfo->fragmented = save_fragmented;

                    if (new_tvb) call_dissector_with_data((t30_hdlc_handle) ? t30_hdlc_handle : data_handle, new_tvb, actx->pinfo, tree, t38_info);
                }
            } else {
                /* If this is the same sequence number as the previous packet
                 * (i.e., a retransmission), we don't expect to have any
                 * fragment data (we reassembled it in the previous packet).
                 */
                if (p_t38_packet_conv && ((gint32) seq_number != p_t38_packet_conv_info->last_seqnum)) {
                    proto_tree_add_expert_format(tree, actx->pinfo, &ei_t38_malformed, tvb, offset, tvb_reported_length_remaining(tvb, offset),
                            "[RECEIVED END OF FRAGMENT W/OUT ANY FRAGMENT DATA]");
                    col_append_str(actx->pinfo->cinfo, COL_INFO, " [Malformed?]");
                }
                actx->pinfo->fragmented = save_fragmented;
            }
        }

        /* reset the reassemble ID and the start seq number if it is not HDLC data */
        if ( p_t38_conv && ( ((Data_Field_field_type_value >0) && (Data_Field_field_type_value <6)) || (Data_Field_field_type_value == 7) ) ){
            p_t38_conv_info->reass_ID = 0;
            p_t38_conv_info->reass_start_seqnum = -1;
            p_t38_conv_info->additional_hdlc_data_field_counter = 0;
            p_t38_conv_info->seqnum_prev_data_field = -1;

            if (p_t38_packet_conv_info->next == NULL) {
                p_t38_packet_conv_info->next = wmem_new(wmem_file_scope(), t38_conv_info);
                p_t38_packet_conv_info = p_t38_packet_conv_info->next;
                memcpy(p_t38_packet_conv_info, p_t38_conv_info, sizeof(t38_conv_info));
            }

        }
        t38_info->Data_Field_field_type_value = Data_Field_field_type_value;
    }
#.END

#.FN_BODY Data-Field/_item/field-data  VAL_PTR=&value_tvb
    tvbuff_t *value_tvb = NULL;
    guint32 value_len;

%(DEFAULT_BODY)s
    value_len = tvb_reported_length(value_tvb);

#.FN_FTR Data-Field/_item/field-data
    if (primary_part){
        if(value_len < 8){
            col_append_fstr(actx->pinfo->cinfo, COL_INFO, "[%s]",
               tvb_bytes_to_str(actx->pinfo->pool, value_tvb,0,value_len));
        }
        else {
            col_append_fstr(actx->pinfo->cinfo, COL_INFO, "[%s...]",
               tvb_bytes_to_str(actx->pinfo->pool, value_tvb,0,7));
        }
    }

    if (primary_part) {
        fragment_head *frag_msg = NULL;

        /* HDLC Data or t4-non-ecm-data */
        if (Data_Field_field_type_value == 0 || Data_Field_field_type_value == 6) { /* 0=HDLC Data or 6=t4-non-ecm-data*/
            gboolean save_fragmented = actx->pinfo->fragmented;

            actx->pinfo->fragmented = TRUE;

            /* if we have not reassembled this packet and it is the first fragment, reset the reassemble ID and the start seq number*/
            if (p_t38_packet_conv && p_t38_conv && (p_t38_packet_conv_info->reass_start_seqnum == -1)) {
                /* we use the first fragment's frame_number as fragment ID because the protocol doesn't provide it */
                /* XXX: We'd be better off assigning our own IDs using a one-up
                 * counter, if it's possible for more than one reassembly to
                 * begin in the same frame.
                 */
                    p_t38_conv_info->reass_ID = actx->pinfo->num;
                    p_t38_conv_info->reass_start_seqnum = seq_number;
                    p_t38_conv_info->time_first_t4_data = nstime_to_sec(&actx->pinfo->rel_ts);
                    p_t38_conv_info->additional_hdlc_data_field_counter = 0;
                    p_t38_packet_conv_info->reass_ID = p_t38_conv_info->reass_ID;
                    p_t38_packet_conv_info->reass_start_seqnum = p_t38_conv_info->reass_start_seqnum;
                    p_t38_packet_conv_info->reass_start_data_field = Data_Field_item_num;
                    p_t38_packet_conv_info->seqnum_prev_data_field = p_t38_conv_info->seqnum_prev_data_field;
                    p_t38_packet_conv_info->additional_hdlc_data_field_counter = p_t38_conv_info->additional_hdlc_data_field_counter;
                    p_t38_packet_conv_info->time_first_t4_data = p_t38_conv_info->time_first_t4_data;
            }
            if (seq_number == (guint32)p_t38_packet_conv_info->seqnum_prev_data_field){
                   if(p_t38_conv){
                     p_t38_conv_info->additional_hdlc_data_field_counter++;
                   }
	    }
            guint32 frag_seq_num;
            if (seq_number == (guint32)p_t38_packet_conv_info->reass_start_seqnum) {
                frag_seq_num = (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter + Data_Field_item_num - (guint32)p_t38_packet_conv_info->reass_start_data_field;
            } else {
                frag_seq_num = seq_number - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter + Data_Field_item_num;
            }
            frag_msg = fragment_add_seq(&data_reassembly_table,
                value_tvb, 0,
                actx->pinfo,
                p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
                NULL,
                frag_seq_num, /* fragment sequence number */
                value_len, /* fragment length */
                TRUE, /* More fragments */
                0);
            p_t38_packet_conv_info->seqnum_prev_data_field = (gint32)seq_number;
            process_reassembled_data(tvb, offset, actx->pinfo,
                        "Reassembled T38", frag_msg, &data_frag_items, NULL, tree);

            if (!frag_msg) { /* Not last packet of reassembled */
                if (Data_Field_field_type_value == 0) {
                    col_append_fstr(actx->pinfo->cinfo, COL_INFO," (HDLC fragment %u)", frag_seq_num);
                } else {
                    col_append_fstr(actx->pinfo->cinfo, COL_INFO," (t4-data fragment %u)", seq_number - (guint32)p_t38_packet_conv_info->reass_start_seqnum);
                }
            }

            /* Now reset fragmentation information in pinfo */
            actx->pinfo->fragmented = save_fragmented;
        }
    }
#.END


#.FN_HDR UDPTLPacket
    /* Initialize to something else than data type */
    Data_Field_field_type_value = 1;
#.END

#.FN_PARS UDPTLPacket/seq-number  VAL_PTR=&seq_number
#.FN_FTR UDPTLPacket/seq-number
    /* info for tap */
    if (primary_part)
        t38_info->seq_num = seq_number;

    col_append_fstr(actx->pinfo->cinfo, COL_INFO, "Seq=%05u ",seq_number);
#.END

#.FN_HDR UDPTLPacket/primary-ifp-packet
    primary_part = TRUE;
#.FN_FTR UDPTLPacket/primary-ifp-packet
    /* if is a valid t38 packet, add to tap */
    /* Note that t4-non-ecm-sig-end without first_t4_data is not valid */
    if (p_t38_packet_conv && (!actx->pinfo->flags.in_error_pkt) && ((gint32) seq_number != p_t38_packet_conv_info->last_seqnum) &&
        !(t38_info->type_msg == 1 && t38_info->Data_Field_field_type_value == 7 && t38_info->frame_num_first_t4_data == 0))
        tap_queue_packet(t38_tap, actx->pinfo, t38_info);

    if (p_t38_conv) p_t38_conv_info->last_seqnum = (gint32) seq_number;
#.END

#.FN_HDR UDPTLPacket/error-recovery
    primary_part = FALSE;
#.FN_FTR UDPTLPacket/error-recovery
    primary_part = TRUE;
#.END