2 * Routines for opening Apple's (Bluetooth) PacketLogger file format captures
3 * Copyright 2008-2009, Stephen Fisher (see AUTHORS file)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Based on commview.c, Linux's BlueZ-Gnome Analyzer program and hexdumps of
12 * the output files from Apple's PacketLogger tool.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 #include "file_wrappers.h"
42 #include "packetlogger.h"
44 typedef struct packetlogger_header
{
47 } packetlogger_header_t
;
49 static gboolean
packetlogger_read(wtap
*wth
, int *err
, gchar
**err_info
,
51 static gboolean
packetlogger_seek_read(wtap
*wth
, gint64 seek_off
,
52 struct wtap_pkthdr
*phdr
,
53 Buffer
*buf
, int length
, int *err
,
55 static gboolean
packetlogger_read_header(packetlogger_header_t
*pl_hdr
,
56 FILE_T fh
, int *err
, gchar
**err_info
);
57 static gboolean
packetlogger_read_packet(FILE_T fh
, struct wtap_pkthdr
*phdr
,
58 Buffer
*buf
, int *err
,
61 int packetlogger_open(wtap
*wth
, int *err
, gchar
**err_info
)
63 packetlogger_header_t pl_hdr
;
66 if(!packetlogger_read_header(&pl_hdr
, wth
->fh
, err
, err_info
)) {
67 if (*err
!= 0 && *err
!= WTAP_ERR_SHORT_READ
)
72 if (file_read(&type
, 1, wth
->fh
) <= 0) {
73 *err
= file_error(wth
->fh
, err_info
);
74 if (*err
!= 0 && *err
!= WTAP_ERR_SHORT_READ
)
79 /* Verify this file belongs to us */
80 if (!((8 <= pl_hdr
.len
) && (pl_hdr
.len
< 65536) &&
81 (type
< 0x04 || type
== 0xFB || type
== 0xFC || type
== 0xFE || type
== 0xFF)))
84 /* No file header. Reset the fh to 0 so we can read the first packet */
85 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1)
88 /* Set up the pointers to the handlers for this file type */
89 wth
->subtype_read
= packetlogger_read
;
90 wth
->subtype_seek_read
= packetlogger_seek_read
;
92 wth
->file_type_subtype
= WTAP_FILE_TYPE_SUBTYPE_PACKETLOGGER
;
93 wth
->file_encap
= WTAP_ENCAP_PACKETLOGGER
;
94 wth
->tsprecision
= WTAP_FILE_TSPREC_USEC
;
96 return 1; /* Our kind of file */
100 packetlogger_read(wtap
*wth
, int *err
, gchar
**err_info
, gint64
*data_offset
)
102 *data_offset
= file_tell(wth
->fh
);
104 return packetlogger_read_packet(wth
->fh
, &wth
->phdr
,
105 wth
->frame_buffer
, err
, err_info
);
109 packetlogger_seek_read(wtap
*wth
, gint64 seek_off
, struct wtap_pkthdr
*phdr
,
110 Buffer
*buf
, int length _U_
, int *err
, gchar
**err_info
)
112 if(file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
115 if(!packetlogger_read_packet(wth
->random_fh
, phdr
, buf
, err
, err_info
)) {
117 *err
= WTAP_ERR_SHORT_READ
;
125 packetlogger_read_header(packetlogger_header_t
*pl_hdr
, FILE_T fh
, int *err
,
128 wtap_file_read_expected_bytes(&pl_hdr
->len
, 4, fh
, err
, err_info
);
129 wtap_file_read_expected_bytes(&pl_hdr
->ts
, 8, fh
, err
, err_info
);
131 /* Convert multi-byte values from big endian to host endian */
132 pl_hdr
->len
= GUINT32_FROM_BE(pl_hdr
->len
);
133 pl_hdr
->ts
= GUINT64_FROM_BE(pl_hdr
->ts
);
139 packetlogger_read_packet(FILE_T fh
, struct wtap_pkthdr
*phdr
, Buffer
*buf
,
140 int *err
, gchar
**err_info
)
142 packetlogger_header_t pl_hdr
;
144 if(!packetlogger_read_header(&pl_hdr
, fh
, err
, err_info
))
147 if (pl_hdr
.len
< 8) {
148 *err
= WTAP_ERR_BAD_FILE
;
149 *err_info
= g_strdup_printf("packetlogger: record length %u is too small", pl_hdr
.len
);
152 if (pl_hdr
.len
- 8 > WTAP_MAX_PACKET_SIZE
) {
154 * Probably a corrupt capture file; don't blow up trying
155 * to allocate space for an immensely-large packet.
157 *err
= WTAP_ERR_BAD_FILE
;
158 *err_info
= g_strdup_printf("packetlogger: File has %u-byte packet, bigger than maximum of %u",
159 pl_hdr
.len
- 8, WTAP_MAX_PACKET_SIZE
);
163 phdr
->presence_flags
= WTAP_HAS_TS
;
165 phdr
->len
= pl_hdr
.len
- 8;
166 phdr
->caplen
= pl_hdr
.len
- 8;
168 phdr
->ts
.secs
= (time_t) (pl_hdr
.ts
>> 32);
169 phdr
->ts
.nsecs
= (int)((pl_hdr
.ts
& 0xFFFFFFFF) * 1000);
171 return wtap_read_packet_bytes(fh
, buf
, phdr
->caplen
, err
, err_info
);