From robionekenobi via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9375 :
[metze/wireshark/wip.git] / epan / exported_pdu.c
1 /* 
2  * exported_pdu.c
3  * exported_pdu helper functions
4  * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #include "config.h"
28 #include <glib.h>
29
30 #include <epan/packet.h>
31 #include <epan/exported_pdu.h>
32 #include <epan/dissectors/packet-mtp3.h>
33 #include <epan/dissectors/packet-dvbci.h>
34
35 /**
36  * Allocates and fills the exp_pdu_data_t struct according to the wanted_exp_tags
37  * bit_fileld, if proto_name is != NULL, wtap_encap must be -1 or vice-versa
38  */
39 exp_pdu_data_t *
40 load_export_pdu_tags(packet_info *pinfo, const char* proto_name, int wtap_encap _U_, guint32 tags_bit_field)
41 {
42         exp_pdu_data_t *exp_pdu_data;
43         int tag_buf_size = 0;
44         int str_len = 0;
45         int tag_str_len = 0;
46         int i = 0, j;
47         gboolean port_type_defined = FALSE;
48
49         exp_pdu_data = (exp_pdu_data_t *)g_malloc(sizeof(exp_pdu_data_t));
50
51         /* If we have a protocol name, calculate the buffer size needed including padding and tag + length */
52         if(proto_name){
53                 str_len = (int)strlen(proto_name);
54
55                 /* Ensure that tag length is a multiple of 4 bytes */
56                 tag_str_len = (str_len + 3) & 0xfffffffc;
57                 /* Add Tag + length */
58                 tag_buf_size = tag_str_len + 4;
59         }
60
61         if((tags_bit_field & EXP_PDU_TAG_IP_SRC_BIT) == EXP_PDU_TAG_IP_SRC_BIT){
62                 if(pinfo->net_src.type == AT_IPv4){
63                         tag_buf_size += 4 + EXP_PDU_TAG_IPV4_SRC_LEN;
64                 }else if(pinfo->net_src.type == AT_IPv6){
65                         tag_buf_size += 4 + EXP_PDU_TAG_IPV6_SRC_LEN;
66                 }
67         }
68
69         if((tags_bit_field & EXP_PDU_TAG_IP_DST_BIT) == EXP_PDU_TAG_IP_DST_BIT){
70                 if(pinfo->net_dst.type == AT_IPv4){
71                         tag_buf_size += 4 + EXP_PDU_TAG_IPV4_DST_LEN;
72                 }else if(pinfo->net_dst.type == AT_IPv6){
73                         tag_buf_size += 4 + EXP_PDU_TAG_IPV6_DST_LEN;
74                 }
75         }
76
77         if((tags_bit_field & EXP_PDU_TAG_SRC_PORT_BIT) == EXP_PDU_TAG_SRC_PORT_BIT){
78                 if (!port_type_defined) {
79                         tag_buf_size= tag_buf_size + EXP_PDU_TAG_PORT_TYPE_LEN + 4;
80                         port_type_defined = TRUE;
81                 }
82                 tag_buf_size= tag_buf_size + EXP_PDU_TAG_SRC_PORT_LEN + 4;
83         }
84
85         if((tags_bit_field & EXP_PDU_TAG_DST_PORT_BIT) == EXP_PDU_TAG_DST_PORT_BIT){
86                 if (!port_type_defined) {
87                         tag_buf_size= tag_buf_size + EXP_PDU_TAG_PORT_TYPE_LEN + 4;
88                 }
89                 tag_buf_size= tag_buf_size + EXP_PDU_TAG_DST_PORT_LEN + 4;
90         }
91
92         if((tags_bit_field & EXP_PDU_TAG_SCTP_PPID_BIT) == EXP_PDU_TAG_SCTP_PPID_BIT){
93                 for(j = 0; j < MAX_NUMBER_OF_PPIDS; j++) {
94                         if (pinfo->ppids[j] != LAST_PPID) {
95                                 tag_buf_size= tag_buf_size + EXP_PDU_TAG_SCTP_PPID_LEN + 4;
96                         } else {
97                                 break;
98                         }
99                 }
100         }
101
102         if((tags_bit_field & EXP_PDU_TAG_SS7_OPC_BIT) == EXP_PDU_TAG_SS7_OPC_BIT){
103                 if(pinfo->src.type == AT_SS7PC){
104                         tag_buf_size += 4 + EXP_PDU_TAG_SS7_OPC_LEN;
105                 }
106         }
107
108         if((tags_bit_field & EXP_PDU_TAG_SS7_DPC_BIT) == EXP_PDU_TAG_SS7_DPC_BIT){
109                 if(pinfo->dst.type == AT_SS7PC){
110                         tag_buf_size += 4 + EXP_PDU_TAG_SS7_DPC_LEN;
111                 }
112         }
113
114         if((tags_bit_field & EXP_PDU_TAG_ORIG_FNO_BIT) == EXP_PDU_TAG_ORIG_FNO_BIT){
115                 tag_buf_size= tag_buf_size + EXP_PDU_TAG_ORIG_FNO_LEN + 4;
116         }
117
118         if((tags_bit_field & EXP_PDU_TAG_DVBCI_EVT_BIT) == EXP_PDU_TAG_DVBCI_EVT_BIT){
119                 tag_buf_size= tag_buf_size + EXP_PDU_TAG_DVBCI_EVT_LEN + 4;
120         }
121
122         /* Add end of options length */
123         tag_buf_size+=4;
124
125         exp_pdu_data->tlv_buffer = (guint8 *)g_malloc0(tag_buf_size);
126         exp_pdu_data->tlv_buffer_len = tag_buf_size;
127         port_type_defined = FALSE;
128
129         if(proto_name){
130                 exp_pdu_data->tlv_buffer[i] = 0;
131                 i++;
132                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_PROTO_NAME;
133                 i++;
134                 exp_pdu_data->tlv_buffer[i] = 0;
135                 i++;
136                 exp_pdu_data->tlv_buffer[i] = tag_str_len; /* tag length */
137                 i++;
138                 memcpy(exp_pdu_data->tlv_buffer+i, proto_name, str_len);
139                 i = i + tag_str_len;
140
141         }
142
143         if((tags_bit_field & EXP_PDU_TAG_IP_SRC_BIT) == EXP_PDU_TAG_IP_SRC_BIT){
144                 if(pinfo->net_src.type == AT_IPv4){
145                         exp_pdu_data->tlv_buffer[i] = 0;
146                         i++;
147                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV4_SRC;
148                         i++;
149                         exp_pdu_data->tlv_buffer[i] = 0;
150                         i++;
151                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV4_SRC_LEN; /* tag length */
152                         i++;
153                         memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_src.data, EXP_PDU_TAG_IPV4_SRC_LEN);
154                         i += EXP_PDU_TAG_IPV4_SRC_LEN;
155                 }else if(pinfo->net_src.type == AT_IPv6){
156                         exp_pdu_data->tlv_buffer[i] = 0;
157                         i++;
158                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV6_SRC;
159                         i++;
160                         exp_pdu_data->tlv_buffer[i] = 0;
161                         i++;
162                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV6_SRC_LEN; /* tag length */
163                         i++;
164                         memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_src.data, EXP_PDU_TAG_IPV6_SRC_LEN);
165                         i += EXP_PDU_TAG_IPV6_SRC_LEN;
166                 }
167         }
168
169         if((tags_bit_field & EXP_PDU_TAG_IP_DST_BIT) == EXP_PDU_TAG_IP_DST_BIT){
170                 if(pinfo->net_dst.type == AT_IPv4){
171                         exp_pdu_data->tlv_buffer[i] = 0;
172                         i++;
173                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV4_DST;
174                         i++;
175                         exp_pdu_data->tlv_buffer[i] = 0;
176                         i++;
177                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV4_DST_LEN; /* tag length */
178                         i++;
179                         memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_dst.data, EXP_PDU_TAG_IPV4_DST_LEN);
180                         i += EXP_PDU_TAG_IPV4_DST_LEN;
181                 }else if(pinfo->net_dst.type == AT_IPv6){
182                         exp_pdu_data->tlv_buffer[i] = 0;
183                         i++;
184                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV6_DST;
185                         i++;
186                         exp_pdu_data->tlv_buffer[i] = 0;
187                         i++;
188                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_IPV6_DST_LEN; /* tag length */
189                         i++;
190                         memcpy(exp_pdu_data->tlv_buffer+i, pinfo->net_dst.data, EXP_PDU_TAG_IPV6_DST_LEN);
191                         i += EXP_PDU_TAG_IPV6_DST_LEN;
192                 }
193         }
194
195         if((tags_bit_field & EXP_PDU_TAG_SRC_PORT_BIT) == EXP_PDU_TAG_SRC_PORT_BIT){
196                 if (!port_type_defined) {
197                         exp_pdu_data->tlv_buffer[i] = 0;
198                         i++;
199                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_PORT_TYPE;
200                         i++;
201                         exp_pdu_data->tlv_buffer[i] = 0;
202                         i++;
203                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_PORT_TYPE_LEN; /* tag length */
204                         i++;
205                         exp_pdu_data->tlv_buffer[i]   = (pinfo->ptype & 0xff000000) >> 24;
206                         exp_pdu_data->tlv_buffer[i+1] = (pinfo->ptype & 0x00ff0000) >> 16;
207                         exp_pdu_data->tlv_buffer[i+2] = (pinfo->ptype & 0x0000ff00) >> 8;
208                         exp_pdu_data->tlv_buffer[i+3] = (pinfo->ptype & 0x000000ff);
209                         i = i +EXP_PDU_TAG_PORT_TYPE_LEN;
210                         port_type_defined = TRUE;
211                 }
212                 exp_pdu_data->tlv_buffer[i] = 0;
213                 i++;
214                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SRC_PORT;
215                 i++;
216                 exp_pdu_data->tlv_buffer[i] = 0;
217                 i++;
218                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SRC_PORT_LEN; /* tag length */
219                 i++;
220                 exp_pdu_data->tlv_buffer[i]   = (pinfo->srcport & 0xff000000) >> 24;
221                 exp_pdu_data->tlv_buffer[i+1] = (pinfo->srcport & 0x00ff0000) >> 16;
222                 exp_pdu_data->tlv_buffer[i+2] = (pinfo->srcport & 0x0000ff00) >> 8;
223                 exp_pdu_data->tlv_buffer[i+3] = (pinfo->srcport & 0x000000ff);
224                 i = i +EXP_PDU_TAG_SRC_PORT_LEN;
225         }
226
227         if((tags_bit_field & EXP_PDU_TAG_DST_PORT_BIT) == EXP_PDU_TAG_DST_PORT_BIT){
228                 if (!port_type_defined) {
229                         exp_pdu_data->tlv_buffer[i] = 0;
230                         i++;
231                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_PORT_TYPE;
232                         i++;
233                         exp_pdu_data->tlv_buffer[i] = 0;
234                         i++;
235                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_PORT_TYPE_LEN; /* tag length */
236                         i++;
237                         exp_pdu_data->tlv_buffer[i]   = (pinfo->ptype & 0xff000000) >> 24;
238                         exp_pdu_data->tlv_buffer[i+1] = (pinfo->ptype & 0x00ff0000) >> 16;
239                         exp_pdu_data->tlv_buffer[i+2] = (pinfo->ptype & 0x0000ff00) >> 8;
240                         exp_pdu_data->tlv_buffer[i+3] = (pinfo->ptype & 0x000000ff);
241                         i = i +EXP_PDU_TAG_PORT_TYPE_LEN;
242                 }
243                 exp_pdu_data->tlv_buffer[i] = 0;
244                 i++;
245                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_DST_PORT;
246                 i++;
247                 exp_pdu_data->tlv_buffer[i] = 0;
248                 i++;
249                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_DST_PORT_LEN; /* tag length */
250                 i++;
251                 exp_pdu_data->tlv_buffer[i]   = (pinfo->destport & 0xff000000) >> 24;
252                 exp_pdu_data->tlv_buffer[i+1] = (pinfo->destport & 0x00ff0000) >> 16;
253                 exp_pdu_data->tlv_buffer[i+2] = (pinfo->destport & 0x0000ff00) >> 8;
254                 exp_pdu_data->tlv_buffer[i+3] = (pinfo->destport & 0x000000ff);
255                 i = i +EXP_PDU_TAG_DST_PORT_LEN;
256         }
257
258         if((tags_bit_field & EXP_PDU_TAG_SCTP_PPID_BIT) == EXP_PDU_TAG_SCTP_PPID_BIT){
259                 for(j = 0; j < MAX_NUMBER_OF_PPIDS; j++) {
260                         if (pinfo->ppids[j] != LAST_PPID) {
261                                 exp_pdu_data->tlv_buffer[i] = 0;
262                                 i++;
263                                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SCTP_PPID;
264                                 i++;
265                                 exp_pdu_data->tlv_buffer[i] = 0;
266                                 i++;
267                                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SCTP_PPID_LEN; /* tag length */
268                                 i++;
269                                 exp_pdu_data->tlv_buffer[i]   = (pinfo->ppids[j] & 0xff000000) >> 24;
270                                 exp_pdu_data->tlv_buffer[i+1] = (pinfo->ppids[j] & 0x00ff0000) >> 16;
271                                 exp_pdu_data->tlv_buffer[i+2] = (pinfo->ppids[j] & 0x0000ff00) >> 8;
272                                 exp_pdu_data->tlv_buffer[i+3] = (pinfo->ppids[j] & 0x000000ff);
273                                 i = i +EXP_PDU_TAG_SCTP_PPID_LEN;
274                         } else {
275                                 break;
276                         }
277                 }
278         }
279
280         if((tags_bit_field & EXP_PDU_TAG_SS7_OPC_BIT) == EXP_PDU_TAG_SS7_OPC_BIT){
281                 if(pinfo->src.type == AT_SS7PC){
282                         mtp3_addr_pc_t *mtp3_addr = (mtp3_addr_pc_t *)(pinfo->src.data);
283                         exp_pdu_data->tlv_buffer[i] = 0;
284                         i++;
285                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SS7_OPC;
286                         i++;
287                         exp_pdu_data->tlv_buffer[i] = 0;
288                         i++;
289                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SS7_OPC_LEN; /* tag length */
290                         i++;
291                         exp_pdu_data->tlv_buffer[i]   = (mtp3_addr->pc & 0xff000000) >> 24;
292                         exp_pdu_data->tlv_buffer[i+1] = (mtp3_addr->pc & 0x00ff0000) >> 16;
293                         exp_pdu_data->tlv_buffer[i+2] = (mtp3_addr->pc & 0x0000ff00) >> 8;
294                         exp_pdu_data->tlv_buffer[i+3] = (mtp3_addr->pc & 0x000000ff);
295                         exp_pdu_data->tlv_buffer[i+4] = (mtp3_addr->type & 0xff00) >> 8;
296                         exp_pdu_data->tlv_buffer[i+5] = (mtp3_addr->type & 0x00ff);
297                         exp_pdu_data->tlv_buffer[i+6] =  mtp3_addr->ni;
298                         i += EXP_PDU_TAG_SS7_OPC_LEN;
299                 }
300         }
301
302         if((tags_bit_field & EXP_PDU_TAG_SS7_DPC_BIT) == EXP_PDU_TAG_SS7_DPC_BIT){
303                 if(pinfo->dst.type == AT_SS7PC){
304                         mtp3_addr_pc_t *mtp3_addr = (mtp3_addr_pc_t *)(pinfo->dst.data);
305                         exp_pdu_data->tlv_buffer[i] = 0;
306                         i++;
307                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SS7_DPC;
308                         i++;
309                         exp_pdu_data->tlv_buffer[i] = 0;
310                         i++;
311                         exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_SS7_DPC_LEN; /* tag length */
312                         i++;
313                         exp_pdu_data->tlv_buffer[i]   = (mtp3_addr->pc & 0xff000000) >> 24;
314                         exp_pdu_data->tlv_buffer[i+1] = (mtp3_addr->pc & 0x00ff0000) >> 16;
315                         exp_pdu_data->tlv_buffer[i+2] = (mtp3_addr->pc & 0x0000ff00) >> 8;
316                         exp_pdu_data->tlv_buffer[i+3] = (mtp3_addr->pc & 0x000000ff);
317                         exp_pdu_data->tlv_buffer[i+4] = (mtp3_addr->type & 0xff00) >> 8;
318                         exp_pdu_data->tlv_buffer[i+5] = (mtp3_addr->type & 0x00ff);
319                         exp_pdu_data->tlv_buffer[i+6] =  mtp3_addr->ni;
320                         i += EXP_PDU_TAG_SS7_DPC_LEN;
321                 }
322         }
323
324         if((tags_bit_field & EXP_PDU_TAG_ORIG_FNO_BIT) == EXP_PDU_TAG_ORIG_FNO_BIT){
325                 exp_pdu_data->tlv_buffer[i] = 0;
326                 i++;
327                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_ORIG_FNO;
328                 i++;
329                 exp_pdu_data->tlv_buffer[i] = 0;
330                 i++;
331                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_ORIG_FNO_LEN; /* tag length */
332                 i++;
333                 exp_pdu_data->tlv_buffer[i]   = (pinfo->fd->num & 0xff000000) >> 24;
334                 exp_pdu_data->tlv_buffer[i+1] = (pinfo->fd->num & 0x00ff0000) >> 16;
335                 exp_pdu_data->tlv_buffer[i+2] = (pinfo->fd->num & 0x0000ff00) >> 8;
336                 exp_pdu_data->tlv_buffer[i+3] = (pinfo->fd->num & 0x000000ff);
337                 /*i = i +EXP_PDU_TAG_ORIG_FNO_LEN;*/
338         }
339
340         if((tags_bit_field & EXP_PDU_TAG_DVBCI_EVT_BIT) == EXP_PDU_TAG_DVBCI_EVT_BIT){
341                 exp_pdu_data->tlv_buffer[i] = 0;
342                 i++;
343                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_DVBCI_EVT;
344                 i++;
345                 exp_pdu_data->tlv_buffer[i] = 0;
346                 i++;
347                 exp_pdu_data->tlv_buffer[i] = EXP_PDU_TAG_DVBCI_EVT_LEN;
348                 i++;
349         exp_pdu_data->tlv_buffer[i] = dvbci_get_evt_from_addrs(pinfo);
350         }
351
352         return exp_pdu_data;
353 }