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