Get rid of TestBigEndian and AC_C_BIGENDIAN.
[metze/wireshark/wip.git] / epan / capture_dissectors.c
1 /* capture_dissectors.c
2  * Routines for handling capture dissectors
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "config.h"
12
13 #include <glib.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include "packet.h"
17
18 #include "capture_dissectors.h"
19
20 struct capture_dissector_table {
21     GHashTable *hash_table;
22     const char *ui_name;
23 };
24
25 struct capture_dissector_handle
26 {
27     const char *name;
28     capture_dissector_t dissector;
29     protocol_t* protocol;
30 };
31
32 typedef struct capture_dissector_count
33 {
34     guint32 count;
35 } capture_dissector_count_t;
36
37 static GHashTable *registered_dissectors = NULL;
38
39 static GHashTable *capture_dissector_tables = NULL;
40
41 static void
42 destroy_capture_dissector_table(void *data)
43 {
44     struct capture_dissector_table *table = (struct capture_dissector_table *)data;
45
46     g_hash_table_destroy(table->hash_table);
47     g_free(data);
48 }
49
50 void capture_dissector_init(void)
51 {
52     registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
53     capture_dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, destroy_capture_dissector_table);
54 }
55
56 void capture_dissector_cleanup(void)
57 {
58     g_hash_table_destroy(capture_dissector_tables);
59     g_hash_table_destroy(registered_dissectors);
60 }
61
62 void register_capture_dissector_table(const char *name, const char *ui_name)
63 {
64     struct capture_dissector_table*     sub_dissectors;
65
66     /* Make sure the registration is unique */
67     if(g_hash_table_lookup( capture_dissector_tables, name )) {
68         g_error("The capture dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
69     }
70
71     sub_dissectors = g_new(struct capture_dissector_table, 1);
72
73     sub_dissectors->hash_table = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, NULL );
74     sub_dissectors->ui_name = ui_name;
75     g_hash_table_insert( capture_dissector_tables, (gpointer)name, (gpointer) sub_dissectors );
76
77 }
78
79 static capture_dissector_handle_t
80 new_capture_dissector_handle(capture_dissector_t dissector, int proto, const char *name)
81 {
82     struct capture_dissector_handle* handle;
83
84     handle                = wmem_new(wmem_epan_scope(), struct capture_dissector_handle);
85     handle->name          = name;
86     handle->dissector     = dissector;
87     handle->protocol      = find_protocol_by_id(proto);
88     return handle;
89 }
90
91 capture_dissector_handle_t
92 create_capture_dissector_handle(capture_dissector_t dissector, const int proto)
93 {
94     return new_capture_dissector_handle(dissector, proto, NULL);
95 }
96
97 capture_dissector_handle_t find_capture_dissector(const char *name)
98 {
99     return (capture_dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
100 }
101
102 capture_dissector_handle_t register_capture_dissector(const char *name, capture_dissector_t dissector, int proto)
103 {
104     capture_dissector_handle_t handle;
105
106     /* Make sure the registration is unique */
107     g_assert(g_hash_table_lookup(registered_dissectors, name) == NULL);
108
109     handle = new_capture_dissector_handle(dissector, proto, name);
110     g_hash_table_insert(registered_dissectors, (gpointer)name, handle);
111     return handle;
112 }
113
114 void capture_dissector_add_uint(const char *name, const guint32 pattern, capture_dissector_handle_t handle)
115 {
116     struct capture_dissector_table*     sub_dissectors;
117
118     if (handle == NULL)
119         return;
120
121     /* Make sure table exists */
122     sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name );
123     if (sub_dissectors == NULL) {
124             fprintf(stderr, "OOPS: Subdissector \"%s\" not found in capture_dissector_tables\n", name);
125             if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
126                     abort();
127             return;
128     }
129     g_assert(sub_dissectors != NULL);
130
131     /* Make sure the registration is unique */
132     g_assert(g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)) == NULL);
133
134     g_hash_table_insert(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern), (gpointer) handle);
135 }
136
137 gboolean try_capture_dissector(const char* name, const guint32 pattern, const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
138 {
139     struct capture_dissector_table*     sub_dissectors;
140     capture_dissector_handle_t handle;
141
142     sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name );
143     if (sub_dissectors == NULL)
144     {
145         /* XXX - ASSERT? */
146         return FALSE;
147     }
148
149     handle = (capture_dissector_handle_t)g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern));
150     if (handle == NULL)
151         return FALSE;
152
153     return handle->dissector(pd, offset, len, cpinfo, pseudo_header);
154 }
155
156 gboolean call_capture_dissector(capture_dissector_handle_t handle, const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header)
157 {
158     if (handle == NULL)
159         return FALSE;
160     return handle->dissector(pd, offset, len, cpinfo, pseudo_header);
161 }
162
163 guint32 capture_dissector_get_count(packet_counts* counts, const int proto)
164 {
165     capture_dissector_count_t* hash_count = (capture_dissector_count_t*)g_hash_table_lookup(counts->counts_hash, GUINT_TO_POINTER(proto));
166     if (hash_count == NULL)
167         return 0;
168
169     return hash_count->count;
170 }
171
172 void capture_dissector_increment_count(capture_packet_info_t *cpinfo, const int proto)
173 {
174     /* See if we already have a counter for the protocol */
175     capture_dissector_count_t* hash_count = (capture_dissector_count_t*)g_hash_table_lookup(cpinfo->counts, GUINT_TO_POINTER(proto));
176     if (hash_count == NULL)
177     {
178         hash_count = g_new0(capture_dissector_count_t, 1);
179         g_hash_table_insert(cpinfo->counts, GUINT_TO_POINTER(proto), (gpointer)hash_count);
180     }
181
182     hash_count->count++;
183 }
184
185 /*
186  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
187  *
188  * Local variables:
189  * c-basic-offset: 4
190  * tab-width: 8
191  * indent-tabs-mode: nil
192  * End:
193  *
194  * vi: set shiftwidth=4 tabstop=8 expandtab:
195  * :indentSize=4:tabSize=8:noTabs=true:
196  */