Coverage Report

Created: 2026-05-14 06:28

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
1.26M
{
32
1.26M
  const proto_data_t *ap = (const proto_data_t *)a;
33
1.26M
  const proto_data_t *bp = (const proto_data_t *)b;
34
35
1.26M
  if (ap -> proto > bp -> proto) {
36
295k
    return 1;
37
969k
  } else if (ap -> proto == bp -> proto) {
38
827k
    if (ap->key > bp->key){
39
252k
      return 1;
40
575k
    } else if (ap -> key == bp -> key) {
41
563k
      return 0;
42
563k
    }
43
11.4k
    return -1;
44
827k
  } else {
45
141k
    return -1;
46
141k
  }
47
1.26M
}
48
49
void
50
p_add_proto_data(wmem_allocator_t *tmp_scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
51
547k
{
52
547k
  proto_data_t     *p1;
53
547k
  GSList          **proto_list;
54
547k
  wmem_allocator_t *scope;
55
56
547k
  if (tmp_scope == pinfo->pool) {
57
416k
    scope = tmp_scope;
58
416k
    proto_list = &pinfo->proto_data;
59
416k
  } else if (tmp_scope == wmem_file_scope()) {
60
131k
    scope = wmem_file_scope();
61
131k
    proto_list = &pinfo->fd->pfd;
62
131k
  } else {
63
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
64
0
  }
65
66
547k
  p1 = wmem_new(scope, proto_data_t);
67
68
547k
  p1->proto = proto;
69
547k
  p1->key = key;
70
547k
  p1->proto_data = proto_data;
71
72
  /* Add it to the GSLIST */
73
547k
  *proto_list = g_slist_prepend(*proto_list, p1);
74
547k
}
75
76
void
77
p_set_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key, void *proto_data)
78
81.8k
{
79
81.8k
  proto_data_t  temp;
80
81.8k
  GSList       *item;
81
82
81.8k
  temp.proto = proto;
83
81.8k
  temp.key = key;
84
81.8k
  temp.proto_data = NULL;
85
86
81.8k
  if (scope == pinfo->pool) {
87
81.7k
    item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
88
81.7k
  } else if (scope == wmem_file_scope()) {
89
9
    item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
90
9
  } else {
91
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
92
0
  }
93
94
81.8k
  if (item) {
95
78.7k
    proto_data_t *pd = (proto_data_t *)item->data;
96
78.7k
    pd->proto_data = proto_data;
97
78.7k
    return;
98
78.7k
  }
99
100
3.06k
  p_add_proto_data(scope, pinfo, proto, key, proto_data);
101
3.06k
}
102
103
void *
104
p_get_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
105
847k
{
106
847k
  proto_data_t  temp, *p1;
107
847k
  GSList       *item;
108
109
847k
  temp.proto = proto;
110
847k
  temp.key = key;
111
847k
  temp.proto_data = NULL;
112
113
847k
  if (scope == pinfo->pool) {
114
299k
    item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
115
547k
  } else if (scope == wmem_file_scope()) {
116
547k
    item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
117
547k
  } else {
118
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
119
0
  }
120
121
847k
  if (item) {
122
484k
    p1 = (proto_data_t *)item->data;
123
484k
    return p1->proto_data;
124
484k
  }
125
126
362k
  return NULL;
127
847k
}
128
129
void
130
p_remove_proto_data(wmem_allocator_t *scope, struct _packet_info* pinfo, int proto, uint32_t key)
131
1.43k
{
132
1.43k
  proto_data_t  temp;
133
1.43k
  GSList       *item;
134
1.43k
  GSList      **proto_list;
135
136
1.43k
  temp.proto = proto;
137
1.43k
  temp.key = key;
138
1.43k
  temp.proto_data = NULL;
139
140
1.43k
  if (scope == pinfo->pool) {
141
610
    item = g_slist_find_custom(pinfo->proto_data, &temp, p_compare);
142
610
    proto_list = &pinfo->proto_data;
143
821
  } else if (scope == wmem_file_scope()) {
144
821
    item = g_slist_find_custom(pinfo->fd->pfd, &temp, p_compare);
145
821
    proto_list = &pinfo->fd->pfd;
146
821
  } else {
147
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
148
0
  }
149
150
1.43k
  if (item) {
151
596
    *proto_list = g_slist_remove(*proto_list, item->data);
152
596
  }
153
1.43k
}
154
155
char *
156
0
p_get_proto_name_and_key(wmem_allocator_t *scope, struct _packet_info* pinfo, unsigned pfd_index){
157
0
  proto_data_t  *temp;
158
159
0
  if (scope == pinfo->pool) {
160
0
    temp = (proto_data_t *)g_slist_nth_data(pinfo->proto_data, pfd_index);
161
0
  } else if (scope == wmem_file_scope()) {
162
0
    temp = (proto_data_t *)g_slist_nth_data(pinfo->fd->pfd, pfd_index);
163
0
  } else {
164
0
    DISSECTOR_ASSERT(!"invalid wmem scope");
165
0
  }
166
167
0
  return wmem_strdup_printf(pinfo->pool, "[%s, key %u]",proto_get_protocol_name(temp->proto), temp->key);
168
0
}
169
170
80.3k
#define PROTO_DEPTH_KEY 0x3c233fb5 // printf "0x%02x%02x\n" ${RANDOM} ${RANDOM}
171
172
80.3k
void p_set_proto_depth(struct _packet_info *pinfo, int proto, unsigned depth) {
173
80.3k
  p_set_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY, GUINT_TO_POINTER(depth));
174
80.3k
}
175
176
46.0k
unsigned p_get_proto_depth(struct _packet_info *pinfo, int proto) {
177
  return GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto, PROTO_DEPTH_KEY));
178
46.0k
}
179
180
/*
181
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
182
 *
183
 * Local variables:
184
 * c-basic-offset: 2
185
 * tab-width: 8
186
 * indent-tabs-mode: nil
187
 * End:
188
 *
189
 * vi: set shiftwidth=2 tabstop=8 expandtab:
190
 * :indentSize=2:tabSize=8:noTabs=true:
191
 */