Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/proto_data.c
Line
Count
Source
1
/* proto_data.c
2
 * Protocol-specific data
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
15
#include <epan/wmem_scopes.h>
16
#include <epan/packet_info.h>
17
#include <epan/proto_data.h>
18
#include <epan/proto.h>
19
20
/* Protocol-specific data attached to a frame_data structure - protocol
21
   index, key for multiple items with the same protocol index,
22
   and opaque pointer. */
23
typedef struct _proto_data {
24
  int   proto;
25
  uint32_t key;
26
  void *proto_data;
27
} proto_data_t;
28
29
static int
30
p_compare(const void *a, const void *b)
31
2.43M
{
32
2.43M
  const proto_data_t *ap = (const proto_data_t *)a;
33
2.43M
  const proto_data_t *bp = (const proto_data_t *)b;
34
35
2.43M
  if (ap -> proto > bp -> proto) {
36
650k
    return 1;
37
1.78M
  } else if (ap -> proto == bp -> proto) {
38
1.49M
    if (ap->key > bp->key){
39
362k
      return 1;
40
1.12M
    } else if (ap -> key == bp -> key) {
41
1.02M
      return 0;
42
1.02M
    }
43
106k
    return -1;
44
1.49M
  } else {
45
296k
    return -1;
46
296k
  }
47
2.43M
}
48
49
void
50
p_add_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
51
1.04M
{
52
1.04M
  proto_data_t     *p1;
53
1.04M
  wmem_list_t     **proto_list;
54
55
1.04M
  if (scope == pinfo->pool) {
56
834k
    proto_list = &pinfo->proto_data;
57
834k
  } else if (scope == wmem_file_scope()) {
58
214k
    proto_list = &pinfo->fd->pfd;
59
214k
  } else {
60
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
61
0
  }
62
63
1.04M
  if (*proto_list == NULL) {
64
289k
    *proto_list = wmem_list_new(scope);
65
289k
  }
66
67
1.04M
  p1 = wmem_new(scope, proto_data_t);
68
69
1.04M
  p1->proto = proto;
70
1.04M
  p1->key = key;
71
1.04M
  p1->proto_data = proto_data;
72
73
  /* Add it to the list */
74
1.04M
  wmem_list_prepend(*proto_list, p1);
75
1.04M
}
76
77
void
78
p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
79
187k
{
80
  /* Probably more dissectors should use this instead of p_add_proto_data. */
81
187k
  proto_data_t  temp;
82
187k
  wmem_list_t  *proto_list;
83
187k
  wmem_list_frame_t *item;
84
85
187k
  temp.proto = proto;
86
187k
  temp.key = key;
87
187k
  temp.proto_data = NULL;
88
89
187k
  if (scope == pinfo->pool) {
90
187k
    proto_list = pinfo->proto_data;
91
187k
  } else if (scope == wmem_file_scope()) {
92
17
    proto_list = pinfo->fd->pfd;
93
17
  } else {
94
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
95
0
  }
96
97
187k
  if (proto_list) {
98
167k
    item = wmem_list_find_custom(proto_list, &temp, p_compare);
99
167k
    if (item) {
100
158k
      proto_data_t *pd = (proto_data_t*)wmem_list_frame_data(item);
101
158k
      pd->proto_data = proto_data;
102
158k
      return;
103
158k
    }
104
167k
  }
105
106
28.8k
  p_add_proto_data(scope, pinfo, proto, key, proto_data);
107
28.8k
}
108
109
void *
110
p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
111
1.51M
{
112
1.51M
  proto_data_t  temp, *p1;
113
1.51M
  wmem_list_t  *proto_list;
114
1.51M
  wmem_list_frame_t *item;
115
116
1.51M
  temp.proto = proto;
117
1.51M
  temp.key = key;
118
1.51M
  temp.proto_data = NULL;
119
120
1.51M
  if (scope == pinfo->pool) {
121
670k
    proto_list = pinfo->proto_data;
122
848k
  } else if (scope == wmem_file_scope()) {
123
848k
    proto_list = pinfo->fd->pfd;
124
848k
  } else {
125
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
126
0
  }
127
128
1.51M
  if (!proto_list)
129
398k
    return NULL;
130
131
1.12M
  item = wmem_list_find_custom(proto_list, &temp, p_compare);
132
133
1.12M
  if (item) {
134
862k
    p1 = wmem_list_frame_data(item);
135
862k
    return p1->proto_data;
136
862k
  }
137
138
257k
  return NULL;
139
1.12M
}
140
141
void
142
p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
143
2.07k
{
144
2.07k
  proto_data_t  temp;
145
2.07k
  wmem_list_t  *proto_list;
146
2.07k
  wmem_list_frame_t *item;
147
148
2.07k
  temp.proto = proto;
149
2.07k
  temp.key = key;
150
2.07k
  temp.proto_data = NULL;
151
152
2.07k
  if (scope == pinfo->pool) {
153
1.11k
    proto_list = pinfo->proto_data;
154
1.11k
  } else if (scope == wmem_file_scope()) {
155
959
    proto_list = pinfo->fd->pfd;
156
959
  } else {
157
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
158
0
  }
159
160
2.07k
  if (!proto_list)
161
0
    return;
162
163
2.07k
  item = wmem_list_find_custom(proto_list, &temp, p_compare);
164
2.07k
  if (item) {
165
678
    wmem_list_remove_frame(proto_list, item);
166
678
  }
167
2.07k
}
168
169
GPtrArray *
170
0
p_get_proto_names_and_keys(wmem_allocator_t *scope, struct _packet_info* pinfo) {
171
0
  wmem_list_t  *proto_list;
172
0
  proto_data_t *temp;
173
0
  GPtrArray *ret;
174
175
0
  if (scope == pinfo->pool) {
176
0
    proto_list = pinfo->proto_data;
177
0
  } else if (scope == wmem_file_scope()) {
178
0
    proto_list = pinfo->fd->pfd;
179
0
  } else {
180
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
181
0
  }
182
183
0
  if (!proto_list)
184
0
    return NULL;
185
186
0
  ret = g_ptr_array_new();
187
188
0
  for (wmem_list_frame_t *frame = wmem_list_head(proto_list);
189
0
      frame; frame = wmem_list_frame_next(frame)) {
190
191
0
    temp = wmem_list_frame_data(frame);
192
0
    g_ptr_array_add(ret, wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key));
193
0
  }
194
0
  return ret;
195
0
}
196
197
184k
#define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM}
198
199
184k
void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) {
200
184k
  p_set_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth));
201
184k
}
202
203
113k
unsigned p_get_proto_depth(struct _packet_info *pinfo, int proto) {
204
  return GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY));
205
113k
}
206
207
/*
208
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
209
 *
210
 * Local variables:
211
 * c-basic-offset: 2
212
 * tab-width: 8
213
 * indent-tabs-mode: nil
214
 * End:
215
 *
216
 * vi: set shiftwidth=2 tabstop=8 expandtab:
217
 * :indentSize=2:tabSize=8:noTabs=true:
218
 */