dcerpc-netlogon: split out find_tmp_netlogon_auth_vars()
[wireshark-sm.git] / wiretap / i4btrace.c
blobc3c79ea8c2c522d22e9e4fdfbd50dc120c4402aa
1 /* i4btrace.c
3 * Wiretap Library
4 * Copyright (c) 1999 by Bert Driehuis <driehuis@playbeing.org>
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
9 #include "config.h"
10 #include "i4btrace.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include "wtap-int.h"
15 #include "file_wrappers.h"
16 #include "i4b_trace.h"
18 typedef struct {
19 bool byte_swapped;
20 } i4btrace_t;
22 static bool i4btrace_read(wtap *wth, wtap_rec *rec, Buffer *buf,
23 int *err, char **err_info, int64_t *offset);
24 static bool i4btrace_seek_read(wtap *wth, int64_t seek_off,
25 wtap_rec *rec, Buffer *buf, int *err, char **err_info);
26 static bool i4b_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec,
27 Buffer *buf, int *err, char **err_info);
29 static int i4btrace_file_type_subtype = -1;
31 void register_i4btrace(void);
34 * Byte-swap the header.
36 #define I4B_BYTESWAP_HEADER(hdr) \
37 { \
38 hdr.length = GUINT32_SWAP_LE_BE(hdr.length); \
39 hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit); \
40 hdr.type = GUINT32_SWAP_LE_BE(hdr.type); \
41 hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir); \
42 hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc); \
43 hdr.count = GUINT32_SWAP_LE_BE(hdr.count); \
44 hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec); \
45 hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec); \
49 * Test some fields in the header to see if they make sense.
51 #define I4B_HDR_IS_OK(hdr) \
52 (!(hdr.length < sizeof(hdr) || \
53 hdr.length > 16384 || \
54 hdr.unit > 4 || \
55 hdr.type > TRC_CH_B2 || \
56 hdr.dir > FROM_NT || \
57 hdr.trunc > 2048 || \
58 hdr.ts_usec >= 1000000))
61 * Number of packets to try reading.
63 #define PACKETS_TO_CHECK 5
65 wtap_open_return_val i4btrace_open(wtap *wth, int *err, char **err_info)
67 i4b_trace_hdr_t hdr;
68 bool byte_swapped = false;
69 i4btrace_t *i4btrace;
71 /* I4B trace files have no magic in the header... Sigh */
72 if (!wtap_read_bytes(wth->fh, &hdr, sizeof(hdr), err, err_info)) {
73 if (*err != WTAP_ERR_SHORT_READ)
74 return WTAP_OPEN_ERROR;
75 return WTAP_OPEN_NOT_MINE;
78 /* Silly heuristic... */
79 if (!I4B_HDR_IS_OK(hdr)) {
81 * OK, try byte-swapping the header fields.
83 I4B_BYTESWAP_HEADER(hdr);
84 if (!I4B_HDR_IS_OK(hdr)) {
86 * It doesn't look valid in either byte order.
88 return WTAP_OPEN_NOT_MINE;
92 * It looks valid byte-swapped, so assume it's a
93 * trace written in the opposite byte order.
95 byte_swapped = true;
99 * Now try to read past the packet bytes; if that fails with
100 * a short read, we don't fail, so that we can report
101 * the file as a truncated I4B file.
103 if (!wtap_read_bytes(wth->fh, NULL, hdr.length - (uint32_t)sizeof(hdr),
104 err, err_info)) {
105 if (*err != WTAP_ERR_SHORT_READ)
106 return WTAP_OPEN_ERROR;
107 } else {
109 * Now try reading a few more packets.
111 for (int i = 1; i < PACKETS_TO_CHECK; i++) {
113 * Read and check the file header; we've already
114 * decided whether this would be a byte-swapped file
115 * or not, so we swap iff we decided it was.
117 if (!wtap_read_bytes_or_eof(wth->fh, &hdr, sizeof(hdr), err,
118 err_info)) {
119 if (*err == 0) {
120 /* EOF; no more packets to try. */
121 break;
123 if (*err != WTAP_ERR_SHORT_READ)
124 return WTAP_OPEN_ERROR;
125 return WTAP_OPEN_NOT_MINE;
128 if (byte_swapped)
129 I4B_BYTESWAP_HEADER(hdr);
130 if (!I4B_HDR_IS_OK(hdr)) {
132 * It doesn't look valid.
134 return WTAP_OPEN_NOT_MINE;
138 * Now try to read past the packet bytes; if that
139 * fails with a short read, we don't fail, so that
140 * we can report the file as a truncated I4B file.
142 if (!wtap_read_bytes(wth->fh, NULL,
143 hdr.length - (uint32_t)sizeof(hdr), err, err_info)) {
144 if (*err != WTAP_ERR_SHORT_READ)
145 return WTAP_OPEN_ERROR;
148 * Probably a truncated file, so just quit.
150 break;
155 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
156 return WTAP_OPEN_ERROR;
158 /* Get capture start time */
160 wth->file_type_subtype = i4btrace_file_type_subtype;
161 i4btrace = g_new(i4btrace_t, 1);
162 wth->priv = (void *)i4btrace;
163 wth->subtype_read = i4btrace_read;
164 wth->subtype_seek_read = i4btrace_seek_read;
165 wth->snapshot_length = 0; /* not known */
167 i4btrace->byte_swapped = byte_swapped;
169 wth->file_encap = WTAP_ENCAP_ISDN;
170 wth->file_tsprec = WTAP_TSPREC_USEC;
173 * Add an IDB; we don't know how many interfaces were
174 * involved, so we just say one interface, about which
175 * we only know the link-layer type, snapshot length,
176 * and time stamp resolution.
178 wtap_add_generated_idb(wth);
180 return WTAP_OPEN_MINE;
183 /* Read the next packet */
184 static bool i4btrace_read(wtap *wth, wtap_rec *rec, Buffer *buf,
185 int *err, char **err_info, int64_t *data_offset)
187 *data_offset = file_tell(wth->fh);
189 return i4b_read_rec(wth, wth->fh, rec, buf, err, err_info);
192 static bool
193 i4btrace_seek_read(wtap *wth, int64_t seek_off, wtap_rec *rec,
194 Buffer *buf, int *err, char **err_info)
196 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
197 return false;
199 if (!i4b_read_rec(wth, wth->random_fh, rec, buf, err, err_info)) {
200 /* Read error or EOF */
201 if (*err == 0) {
202 /* EOF means "short read" in random-access mode */
203 *err = WTAP_ERR_SHORT_READ;
205 return false;
207 return true;
210 static bool
211 i4b_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
212 int *err, char **err_info)
214 i4btrace_t *i4btrace = (i4btrace_t *)wth->priv;
215 i4b_trace_hdr_t hdr;
216 uint32_t length;
218 if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info))
219 return false;
221 if (i4btrace->byte_swapped) {
223 * Byte-swap the header.
225 I4B_BYTESWAP_HEADER(hdr);
228 if (hdr.length < sizeof(hdr)) {
229 *err = WTAP_ERR_BAD_FILE; /* record length < header! */
230 *err_info = ws_strdup_printf("i4btrace: record length %u < header length %lu",
231 hdr.length, (unsigned long)sizeof(hdr));
232 return false;
234 length = hdr.length - (uint32_t)sizeof(hdr);
235 if (length > WTAP_MAX_PACKET_SIZE_STANDARD) {
237 * Probably a corrupt capture file; don't blow up trying
238 * to allocate space for an immensely-large packet.
240 *err = WTAP_ERR_BAD_FILE;
241 *err_info = ws_strdup_printf("i4btrace: File has %u-byte packet, bigger than maximum of %u",
242 length, WTAP_MAX_PACKET_SIZE_STANDARD);
243 return false;
246 rec->rec_type = REC_TYPE_PACKET;
247 rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
248 rec->presence_flags = WTAP_HAS_TS;
250 rec->rec_header.packet_header.len = length;
251 rec->rec_header.packet_header.caplen = length;
253 rec->ts.secs = hdr.ts_sec;
254 rec->ts.nsecs = hdr.ts_usec * 1000;
256 switch (hdr.type) {
258 case TRC_CH_I:
260 * XXX - what is it? It's probably not WTAP_ENCAP_NULL,
261 * as that means it has a 4-byte AF_ type as the
262 * encapsulation header.
264 rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NULL;
265 break;
267 case TRC_CH_D:
269 * D channel, so it's LAPD; set "p2p.sent".
271 rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN;
272 rec->rec_header.packet_header.pseudo_header.isdn.channel = 0;
273 break;
275 case TRC_CH_B1:
277 * B channel 1.
279 rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN;
280 rec->rec_header.packet_header.pseudo_header.isdn.channel = 1;
281 break;
283 case TRC_CH_B2:
285 * B channel 2.
287 rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_ISDN;
288 rec->rec_header.packet_header.pseudo_header.isdn.channel = 2;
289 break;
292 rec->rec_header.packet_header.pseudo_header.isdn.uton = (hdr.dir == FROM_TE);
295 * Read the packet data.
297 return wtap_read_packet_bytes(fh, buf, length, err, err_info);
300 static const struct supported_block_type i4btrace_blocks_supported[] = {
302 * We support packet blocks, with no comments or other options.
304 { WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
307 static const struct file_type_subtype_info i4btrace_info = {
308 "I4B ISDN trace", "i4btrace", NULL, NULL,
309 false, BLOCKS_SUPPORTED(i4btrace_blocks_supported),
310 NULL, NULL, NULL
313 void register_i4btrace(void)
315 i4btrace_file_type_subtype = wtap_register_file_type_subtype(&i4btrace_info);
318 * Register name for backwards compatibility with the
319 * wtap_filetypes table in Lua.
321 wtap_register_backwards_compatibility_lua_name("I4BTRACE",
322 i4btrace_file_type_subtype);
326 * Editor modelines - https://www.wireshark.org/tools/modelines.html
328 * Local variables:
329 * c-basic-offset: 8
330 * tab-width: 8
331 * indent-tabs-mode: t
332 * End:
334 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
335 * :indentSize=8:tabSize=8:noTabs=false: