Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/wiretap/hcidump.c
Line
Count
Source
1
/* hcidump.c
2
 *
3
 * Copyright (c) 2003 by Marcel Holtmann <marcel@holtmann.org>
4
 *
5
 * SPDX-License-Identifier: GPL-2.0-or-later
6
 */
7
8
#include "config.h"
9
#include "hcidump.h"
10
11
#include "wtap_module.h"
12
#include "file_wrappers.h"
13
14
static int hcidump_file_type_subtype = -1;
15
16
void register_hcidump(void);
17
18
struct dump_hdr {
19
  uint16_t len;
20
  uint8_t  in;
21
  uint8_t  pad;
22
  uint32_t ts_sec;
23
  uint32_t ts_usec;
24
};
25
26
0
#define DUMP_HDR_SIZE (sizeof(struct dump_hdr))
27
28
static bool hcidump_read_packet(wtap *wth, FILE_T fh, wtap_rec *rec,
29
    int *err, char **err_info)
30
0
{
31
0
  struct dump_hdr dh;
32
0
  unsigned packet_size;
33
34
0
  if (!wtap_read_bytes_or_eof(fh, &dh, DUMP_HDR_SIZE, err, err_info))
35
0
    return false;
36
37
0
  packet_size = GUINT16_FROM_LE(dh.len);
38
0
  if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
39
    /*
40
     * Probably a corrupt capture file; don't blow up trying
41
     * to allocate space for an immensely-large packet.
42
     */
43
0
    *err = WTAP_ERR_BAD_FILE;
44
0
    *err_info = ws_strdup_printf("hcidump: File has %u-byte packet, bigger than maximum of %u",
45
0
      packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
46
0
    return false;
47
0
  }
48
49
0
  wtap_setup_packet_rec(rec, wth->file_encap);
50
0
  rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
51
0
  rec->presence_flags = WTAP_HAS_TS;
52
0
  rec->ts.secs = GUINT32_FROM_LE(dh.ts_sec);
53
0
  rec->ts.nsecs = GUINT32_FROM_LE(dh.ts_usec) * 1000;
54
0
  rec->rec_header.packet_header.caplen = packet_size;
55
0
  rec->rec_header.packet_header.len = packet_size;
56
57
0
  rec->rec_header.packet_header.pseudo_header.p2p.sent = (dh.in ? false : true);
58
59
0
  return wtap_read_bytes_buffer(fh, &rec->data, packet_size, err, err_info);
60
0
}
61
62
static bool hcidump_read(wtap *wth, wtap_rec *rec,
63
    int *err, char **err_info, int64_t *data_offset)
64
0
{
65
0
  *data_offset = file_tell(wth->fh);
66
67
0
  return hcidump_read_packet(wth, wth->fh, rec, err, err_info);
68
0
}
69
70
static bool hcidump_seek_read(wtap *wth, int64_t seek_off,
71
    wtap_rec *rec, int *err, char **err_info)
72
0
{
73
0
  if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
74
0
    return false;
75
76
0
  return hcidump_read_packet(wth, wth->random_fh, rec, err, err_info);
77
0
}
78
79
wtap_open_return_val hcidump_open(wtap *wth, int *err, char **err_info)
80
0
{
81
0
  struct dump_hdr dh;
82
0
  uint8_t type;
83
84
0
  if (!wtap_read_bytes(wth->fh, &dh, DUMP_HDR_SIZE, err, err_info)) {
85
0
    if (*err != WTAP_ERR_SHORT_READ)
86
0
      return WTAP_OPEN_ERROR;
87
0
    return WTAP_OPEN_NOT_MINE;
88
0
  }
89
90
0
  if ((dh.in != 0 && dh.in != 1) || dh.pad != 0
91
0
      || GUINT16_FROM_LE(dh.len) < 1)
92
0
    return WTAP_OPEN_NOT_MINE;
93
94
0
  if (!wtap_read_bytes(wth->fh, &type, 1, err, err_info)) {
95
0
    if (*err != WTAP_ERR_SHORT_READ)
96
0
      return WTAP_OPEN_ERROR;
97
0
    return WTAP_OPEN_NOT_MINE;
98
0
  }
99
100
0
  if (type < 1 || type > 4)
101
0
    return WTAP_OPEN_NOT_MINE;
102
103
0
  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
104
0
    return WTAP_OPEN_ERROR;
105
106
0
  wth->file_type_subtype = hcidump_file_type_subtype;
107
0
  wth->file_encap = WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR;
108
0
  wth->snapshot_length = 0;
109
110
0
  wth->subtype_read = hcidump_read;
111
0
  wth->subtype_seek_read = hcidump_seek_read;
112
0
  wth->file_tsprec = WTAP_TSPREC_USEC;
113
114
  /*
115
   * Add an IDB; we don't know how many interfaces were
116
   * involved, so we just say one interface, about which
117
   * we only know the link-layer type, snapshot length,
118
   * and time stamp resolution.
119
   */
120
0
  wtap_add_generated_idb(wth);
121
122
0
  return WTAP_OPEN_MINE;
123
0
}
124
125
static const struct supported_block_type hcidummp_blocks_supported[] = {
126
  /*
127
   * We support packet blocks, with no comments or other options.
128
   */
129
  { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
130
};
131
132
static const struct file_type_subtype_info hcidump_info = {
133
  "Bluetooth HCI dump", "hcidump", NULL, NULL,
134
  false, BLOCKS_SUPPORTED(hcidummp_blocks_supported),
135
  NULL, NULL, NULL
136
};
137
138
void register_hcidump(void)
139
16
{
140
16
  hcidump_file_type_subtype = wtap_register_file_type_subtype(&hcidump_info);
141
142
  /*
143
   * Register name for backwards compatibility with the
144
   * wtap_filetypes table in Lua.
145
   */
146
16
  wtap_register_backwards_compatibility_lua_name("HCIDUMP",
147
16
      hcidump_file_type_subtype);
148
16
}
149
150
/*
151
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
152
 *
153
 * Local variables:
154
 * c-basic-offset: 8
155
 * tab-width: 8
156
 * indent-tabs-mode: t
157
 * End:
158
 *
159
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
160
 * :indentSize=8:tabSize=8:noTabs=false:
161
 */