/src/wireshark/epan/capture_dissectors.c
Line | Count | Source |
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 | 0 | #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN |
13 | | |
14 | | #include <glib.h> |
15 | | #include <stdio.h> |
16 | | #include <stdlib.h> |
17 | | #include <epan/packet.h> |
18 | | |
19 | | #include "capture_dissectors.h" |
20 | | #include <wsutil/ws_assert.h> |
21 | | |
22 | | #include <wsutil/wslog.h> |
23 | | |
24 | | struct capture_dissector_table { |
25 | | GHashTable *hash_table; |
26 | | const char *ui_name; |
27 | | }; |
28 | | |
29 | | struct capture_dissector_handle |
30 | | { |
31 | | const char *name; |
32 | | capture_dissector_t dissector; |
33 | | protocol_t* protocol; |
34 | | }; |
35 | | |
36 | | typedef struct capture_dissector_count |
37 | | { |
38 | | uint64_t count; |
39 | | } capture_dissector_count_t; |
40 | | |
41 | | static GHashTable *registered_dissectors; |
42 | | |
43 | | static GHashTable *capture_dissector_tables; |
44 | | |
45 | | static void |
46 | | destroy_capture_dissector_table(void *data) |
47 | 0 | { |
48 | 0 | struct capture_dissector_table *table = (struct capture_dissector_table *)data; |
49 | |
|
50 | 0 | g_hash_table_destroy(table->hash_table); |
51 | 0 | g_free(data); |
52 | 0 | } |
53 | | |
54 | | void capture_dissector_init(void) |
55 | 16 | { |
56 | 16 | registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); |
57 | 16 | capture_dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, destroy_capture_dissector_table); |
58 | 16 | } |
59 | | |
60 | | void capture_dissector_cleanup(void) |
61 | 0 | { |
62 | 0 | g_hash_table_destroy(capture_dissector_tables); |
63 | 0 | g_hash_table_destroy(registered_dissectors); |
64 | 0 | } |
65 | | |
66 | | void register_capture_dissector_table(const char *name, const char *ui_name) |
67 | 256 | { |
68 | 256 | struct capture_dissector_table* sub_dissectors; |
69 | | |
70 | | /* Make sure the registration is unique */ |
71 | 256 | if(g_hash_table_lookup( capture_dissector_tables, name )) { |
72 | 0 | ws_error("The capture dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name); |
73 | 0 | } |
74 | | |
75 | 256 | sub_dissectors = g_new(struct capture_dissector_table, 1); |
76 | | |
77 | 256 | sub_dissectors->hash_table = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, NULL ); |
78 | 256 | sub_dissectors->ui_name = ui_name; |
79 | 256 | g_hash_table_insert( capture_dissector_tables, (void *)name, (void *) sub_dissectors ); |
80 | | |
81 | 256 | } |
82 | | |
83 | | static capture_dissector_handle_t |
84 | | new_capture_dissector_handle(capture_dissector_t dissector, int proto, const char *name) |
85 | 928 | { |
86 | 928 | struct capture_dissector_handle* handle; |
87 | | |
88 | 928 | handle = wmem_new(wmem_epan_scope(), struct capture_dissector_handle); |
89 | 928 | handle->name = name; |
90 | 928 | handle->dissector = dissector; |
91 | 928 | handle->protocol = find_protocol_by_id(proto); |
92 | 928 | return handle; |
93 | 928 | } |
94 | | |
95 | | capture_dissector_handle_t |
96 | | create_capture_dissector_handle(capture_dissector_t dissector, const int proto) |
97 | 368 | { |
98 | 368 | return new_capture_dissector_handle(dissector, proto, NULL); |
99 | 368 | } |
100 | | |
101 | | capture_dissector_handle_t find_capture_dissector(const char *name) |
102 | 672 | { |
103 | 672 | return (capture_dissector_handle_t)g_hash_table_lookup(registered_dissectors, name); |
104 | 672 | } |
105 | | |
106 | | capture_dissector_handle_t register_capture_dissector(const char *name, capture_dissector_t dissector, int proto) |
107 | 560 | { |
108 | 560 | capture_dissector_handle_t handle; |
109 | | |
110 | | /* Make sure the registration is unique */ |
111 | 560 | ws_assert(g_hash_table_lookup(registered_dissectors, name) == NULL); |
112 | | |
113 | 560 | handle = new_capture_dissector_handle(dissector, proto, name); |
114 | 560 | g_hash_table_insert(registered_dissectors, (void *)name, handle); |
115 | 560 | return handle; |
116 | 560 | } |
117 | | |
118 | | void capture_dissector_add_uint(const char *name, const uint32_t pattern, capture_dissector_handle_t handle) |
119 | 1.48k | { |
120 | 1.48k | struct capture_dissector_table* sub_dissectors; |
121 | | |
122 | 1.48k | if (handle == NULL) |
123 | 0 | return; |
124 | | |
125 | | /* Make sure table exists */ |
126 | 1.48k | sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name ); |
127 | 1.48k | if (sub_dissectors == NULL) { |
128 | 0 | ws_dissector_oops("Subdissector \"%s\" not found in capture_dissector_tables\n", name); |
129 | 0 | return; |
130 | 0 | } |
131 | | |
132 | | /* Make sure the registration is unique */ |
133 | 1.48k | ws_assert(g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)) == NULL); |
134 | | |
135 | 1.48k | g_hash_table_insert(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern), (void *) handle); |
136 | 1.48k | } |
137 | | |
138 | | bool try_capture_dissector(const char* name, const uint32_t pattern, const uint8_t *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) |
139 | 0 | { |
140 | 0 | struct capture_dissector_table* sub_dissectors; |
141 | 0 | capture_dissector_handle_t handle; |
142 | |
|
143 | 0 | sub_dissectors = (struct capture_dissector_table*)g_hash_table_lookup( capture_dissector_tables, name ); |
144 | 0 | if (sub_dissectors == NULL) |
145 | 0 | { |
146 | | /* XXX - ASSERT? */ |
147 | 0 | return false; |
148 | 0 | } |
149 | | |
150 | 0 | handle = (capture_dissector_handle_t)g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern)); |
151 | 0 | if (handle == NULL) |
152 | 0 | return false; |
153 | | |
154 | 0 | return handle->dissector(pd, offset, len, cpinfo, pseudo_header); |
155 | 0 | } |
156 | | |
157 | | bool call_capture_dissector(capture_dissector_handle_t handle, const uint8_t *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) |
158 | 0 | { |
159 | 0 | if (handle == NULL) |
160 | 0 | return false; |
161 | 0 | return handle->dissector(pd, offset, len, cpinfo, pseudo_header); |
162 | 0 | } |
163 | | |
164 | | uint64_t capture_dissector_get_count(packet_counts* counts, const int proto) |
165 | 0 | { |
166 | 0 | capture_dissector_count_t* hash_count = (capture_dissector_count_t*)g_hash_table_lookup(counts->counts_hash, GINT_TO_POINTER(proto)); |
167 | 0 | if (hash_count == NULL) |
168 | 0 | return 0; |
169 | | |
170 | 0 | return hash_count->count; |
171 | 0 | } |
172 | | |
173 | | void capture_dissector_increment_count(capture_packet_info_t *cpinfo, const int proto) |
174 | 0 | { |
175 | | /* See if we already have a counter for the protocol */ |
176 | 0 | capture_dissector_count_t* hash_count = (capture_dissector_count_t*)g_hash_table_lookup(cpinfo->counts, GINT_TO_POINTER(proto)); |
177 | 0 | if (hash_count == NULL) |
178 | 0 | { |
179 | 0 | hash_count = g_new0(capture_dissector_count_t, 1); |
180 | 0 | g_hash_table_insert(cpinfo->counts, GINT_TO_POINTER(proto), (void *)hash_count); |
181 | 0 | } |
182 | |
|
183 | 0 | hash_count->count++; |
184 | 0 | } |
185 | | |
186 | | /* |
187 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
188 | | * |
189 | | * Local variables: |
190 | | * c-basic-offset: 4 |
191 | | * tab-width: 8 |
192 | | * indent-tabs-mode: nil |
193 | | * End: |
194 | | * |
195 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
196 | | * :indentSize=4:tabSize=8:noTabs=true: |
197 | | */ |