summaryrefslogtreecommitdiff
path: root/asn1/t38/t38.cnf
blob: d5df9e8b6aef1d705a091367430fc511fcce908e (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
# t38.cnf
# T.38 conformation file
# 2007  Tomas Kukosa

# $Id$

#.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_NEW
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>"));
    }

    /* We only reassmeble packets in the Primary part and in the first two Items.                       */
    /* There maybe be t38 packets with more than two Items, but reassemble those packets is not easy    */
    /* using the current ressaemble functions.                                                          */
    /* TODO: reassemble all the Items in one frame */
    if (primary_part && (Data_Field_item_num<2)) {
        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_data *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) {
                frag_msg = fragment_add_seq(tvb, offset, actx->pinfo,
                    p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
                    data_fragment_table, /* list of message fragments */
                    seq_number + Data_Field_item_num - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter,  /* fragment sequence number */
                    /*0,*/
                    0, /* fragment length */
                    FALSE); /* More fragments */
                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(actx->pinfo,
                            p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
                            data_fragment_table /* list of message fragments */
                        );
                    } else {
                        col_append_str(actx->pinfo->cinfo, COL_INFO, " (t4-data Reassembled: No packet lost)");

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


                    if (p_t38_packet_conv_info->packet_lost) {
                        g_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 {
                        g_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;
                    actx->pinfo->private_data = t38_info;

                    if (new_tvb) call_dissector((t30_hdlc_handle) ? t30_hdlc_handle : data_handle, new_tvb, actx->pinfo, tree);
                }
            } else {
                if(tree){
                    proto_tree_add_text(tree, 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;
        }
        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_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(value_tvb,0,value_len));
        }
        else {
            col_append_fstr(actx->pinfo->cinfo, COL_INFO, "[%s...]",
               tvb_bytes_to_str(value_tvb,0,7));
        }
    }

    /* We only reassmeble packets in the Primary part and in the first two Items.                       */
    /* There maybe be t38 packets with more than two Items, but reassemble those packets is not easy    */
    /* using the current ressaemble functions.                                                          */
    /* TODO: reassemble all the Items in one frame */
    if (primary_part && (Data_Field_item_num<2)) {
        fragment_data *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_ID == 0)) {
                /* we use the first fragment's frame_number as fragment ID because the protocol doesn't provide it */
                    p_t38_conv_info->reass_ID = actx->pinfo->fd->num;
                    p_t38_conv_info->reass_start_seqnum = seq_number;
                    p_t38_conv_info->time_first_t4_data = nstime_to_sec(&actx->pinfo->fd->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->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){
	           p_t38_packet_conv_info->additional_hdlc_data_field_counter ++;
                   if(p_t38_conv){
                     p_t38_conv_info->additional_hdlc_data_field_counter =  p_t38_packet_conv_info->additional_hdlc_data_field_counter;
                   }
	    }
            frag_msg = fragment_add_seq(value_tvb, 0, actx->pinfo,
                p_t38_packet_conv_info->reass_ID, /* ID for fragments belonging together */
                data_fragment_table, /* list of message fragments */
                seq_number - (guint32)p_t38_packet_conv_info->reass_start_seqnum + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter, /* fragment sequence number */
                value_len, /* fragment length */
                TRUE); /* More fragments */
            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)",
                                                                     seq_number + (guint32)p_t38_packet_conv_info->additional_hdlc_data_field_counter
                                                                       - (guint32)p_t38_packet_conv_info->reass_start_seqnum);
                } 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 */
    if (p_t38_packet_conv && (!actx->pinfo->flags.in_error_pkt) && ((gint32) seq_number != p_t38_packet_conv_info->last_seqnum))
        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