diff --git a/tools/hcidump.1 b/tools/hcidump.1
index 3f8a01f..d9bd7c2 100644
--- a/tools/hcidump.1
+++ b/tools/hcidump.1
.BR -P ", " "\-\^\-ppp=" "<channel>"
Sets the RFCOMM channel value for the Point-to-Point Protocol.
.TP
+.BR -D ", " "\-\^\-pppdump=" "<file>"
+Extract PPP traffic with pppdump format.
+.TP
.BR -A ", " "\-\^\-audio=" "<file>"
Extract SCO audio data.
.TP
diff --git a/tools/hcidump.c b/tools/hcidump.c
index 362e0e9..f330e28 100644
--- a/tools/hcidump.c
+++ b/tools/hcidump.c
WRITE,
RECEIVE,
SEND,
+ PPPDUMP,
AUDIO
};
static long flags;
static long filter;
static char *dump_file = NULL;
+static char *pppdump_file = NULL;
static char *audio_file = NULL;
static in_addr_t dump_addr = INADDR_LOOPBACK;
static in_port_t dump_port = DEFAULT_PORT;
frm.data_len = len;
frm.dev_id = dev;
frm.in = 0;
- frm.audio_fd = parser.audio_fd;
+ frm.pppdump_fd = parser.pppdump_fd;
+ frm.audio_fd = parser.audio_fd;
cmsg = CMSG_FIRSTHDR(&msg);
while (cmsg) {
struct btsnoop_hdr hdr;
int fd, len, open_flags;
- if (mode == WRITE || mode == AUDIO) {
+ if (mode == WRITE || mode == PPPDUMP || mode == AUDIO) {
if (flags & DUMP_BTSNOOP)
open_flags = O_WRONLY | O_CREAT;
else
" -H, --hcrp=psm PSM for HCRP\n"
" -O, --obex=channel Channel for OBEX\n"
" -P, --ppp=channel Channel for PPP\n"
+ " -D, --pppdump=file Extract PPP traffic\n"
" -A, --audio=file Extract SCO audio data\n"
" -B, --btsnoop Use BTSnoop file format\n"
" -V, --verbose Verbose decoding\n"
{ "hcrp", 1, 0, 'H' },
{ "obex", 1, 0, 'O' },
{ "ppp", 1, 0, 'P' },
+ { "pppdump", 1, 0, 'D' },
{ "audio", 1, 0, 'A' },
{ "btsnoop", 0, 0, 'B' },
{ "verbose", 0, 0, 'V' },
{
struct hostent *host;
struct in_addr addr;
- int opt, fd = -1;
+ int opt, pppdump_fd = -1, audio_fd = -1;
printf("HCI sniffer - Bluetooth packet analyzer ver %s\n", VERSION);
- while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:s:n:taxXRC:H:O:P:A:BVYZh", main_options, NULL)) != -1) {
+ while ((opt=getopt_long(argc, argv, "i:l:p:m:w:r:s:n:taxXRC:H:O:P:D:A:BVYZh", main_options, NULL)) != -1) {
switch(opt) {
case 'i':
if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system"))
set_proto(0, 0, atoi(optarg), SDP_UUID_LAN_ACCESS_PPP);
break;
+ case 'D':
+ pppdump_file = strdup(optarg);
+ break;
+
case 'A':
audio_file = strdup(optarg);
break;
if (!filter)
filter = ~0L;
+ if (pppdump_file)
+ pppdump_fd = open_file(pppdump_file, PPPDUMP, flags);
+
if (audio_file)
- fd = open_file(audio_file, AUDIO, flags);
+ audio_fd = open_file(audio_file, AUDIO, flags);
switch (mode) {
case PARSE:
- init_parser(flags, filter, defpsm, defcompid, fd);
+ init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
process_frames(device, open_socket(device, flags), -1, flags);
break;
case READ:
- init_parser(flags, filter, defpsm, defcompid, fd);
+ init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
read_dump(open_file(dump_file, mode, flags));
break;
break;
case RECEIVE:
- init_parser(flags, filter, defpsm, defcompid, fd);
+ init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);
read_dump(wait_connection(dump_addr, dump_port));
break;
diff --git a/tools/parser/hci.c b/tools/parser/hci.c
index 14f733c..9a4b265 100644
--- a/tools/parser/hci.c
+++ b/tools/parser/hci.c
hci_sco_hdr *hdr = (void *) frm->ptr;
uint16_t handle = btohs(hdr->handle);
- if (frm->audio_fd > 2)
+ if (frm->audio_fd > fileno(stderr))
write(frm->audio_fd, frm->ptr + HCI_SCO_HDR_SIZE, hdr->dlen);
if (!p_filter(FILT_SCO)) {
diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c
index 4855b20..a494198 100644
--- a/tools/parser/l2cap.c
+++ b/tools/parser/l2cap.c
return;
}
memcpy(fr->data, frm->ptr, frm->len);
- fr->data_len = dlen + L2CAP_HDR_SIZE;
- fr->len = frm->len;
- fr->ptr = fr->data;
- fr->dev_id = frm->dev_id;
- fr->in = frm->in;
- fr->ts = frm->ts;
- fr->handle = frm->handle;
- fr->cid = frm->cid;
- fr->num = frm->num;
- fr->dlci = frm->dlci;
- fr->channel = frm->channel;
- fr->audio_fd = frm->audio_fd;
+ fr->data_len = dlen + L2CAP_HDR_SIZE;
+ fr->len = frm->len;
+ fr->ptr = fr->data;
+ fr->dev_id = frm->dev_id;
+ fr->in = frm->in;
+ fr->ts = frm->ts;
+ fr->handle = frm->handle;
+ fr->cid = frm->cid;
+ fr->num = frm->num;
+ fr->dlci = frm->dlci;
+ fr->channel = frm->channel;
+ fr->pppdump_fd = frm->pppdump_fd;
+ fr->audio_fd = frm->audio_fd;
} else {
if (!(fr = get_frame(frm->handle))) {
fprintf(stderr, "Not enough connection handles\n");
diff --git a/tools/parser/parser.c b/tools/parser/parser.c
index cab8136..01d0e7e 100644
--- a/tools/parser/parser.c
+++ b/tools/parser/parser.c
void init_parser(unsigned long flags, unsigned long filter,
unsigned short defpsm, unsigned short defcompid,
- int audio_fd)
+ int pppdump_fd, int audio_fd)
{
if ((flags & DUMP_RAW) && !(flags & DUMP_TYPE_MASK))
flags |= DUMP_HEX;
- parser.flags = flags;
- parser.filter = filter;
- parser.defpsm = defpsm;
- parser.defcompid = defcompid;
- parser.state = 0;
- parser.audio_fd = audio_fd;
+ parser.flags = flags;
+ parser.filter = filter;
+ parser.defpsm = defpsm;
+ parser.defcompid = defcompid;
+ parser.state = 0;
+ parser.pppdump_fd = pppdump_fd;
+ parser.audio_fd = audio_fd;
}
#define PROTO_TABLE_SIZE 20
if (fr->data)
free(fr->data);
- fr->data = data;
- fr->data_len = fr->len + frm->len;
- fr->len = fr->data_len;
- fr->ptr = fr->data;
- fr->dev_id = frm->dev_id;
- fr->in = frm->in;
- fr->ts = frm->ts;
- fr->handle = frm->handle;
- fr->cid = frm->cid;
- fr->num = frm->num;
- fr->dlci = frm->dlci;
- fr->channel = frm->channel;
- fr->audio_fd = frm->audio_fd;
+ fr->data = data;
+ fr->data_len = fr->len + frm->len;
+ fr->len = fr->data_len;
+ fr->ptr = fr->data;
+ fr->dev_id = frm->dev_id;
+ fr->in = frm->in;
+ fr->ts = frm->ts;
+ fr->handle = frm->handle;
+ fr->cid = frm->cid;
+ fr->num = frm->num;
+ fr->dlci = frm->dlci;
+ fr->channel = frm->channel;
+ fr->pppdump_fd = frm->pppdump_fd;
+ fr->audio_fd = frm->audio_fd;
return fr;
}
diff --git a/tools/parser/parser.h b/tools/parser/parser.h
index ba16607..ee890fc 100644
--- a/tools/parser/parser.h
+++ b/tools/parser/parser.h
uint8_t channel;
unsigned long flags;
struct timeval ts;
+ int pppdump_fd;
int audio_fd;
};
unsigned short defpsm;
unsigned short defcompid;
int state;
+ int pppdump_fd;
int audio_fd;
};
void init_parser(unsigned long flags, unsigned long filter,
unsigned short defpsm, unsigned short defcompid,
- int audio_fd);
+ int pppdump_fd, int audio_fd);
static inline int p_filter(unsigned long f)
{
diff --git a/tools/parser/ppp.c b/tools/parser/ppp.c
index 67ba1f7..9d1ca45 100644
--- a/tools/parser/ppp.c
+++ b/tools/parser/ppp.c
void *ptr, *end;
int len, pos = 0;
+ if (frm->pppdump_fd > fileno(stderr)) {
+ unsigned char id;
+ uint16_t len = htons(frm->len);
+ uint32_t ts = htonl(frm->ts.tv_sec & 0xffffffff);
+
+ id = 0x07;
+ write(frm->pppdump_fd, &id, 1);
+ write(frm->pppdump_fd, &ts, 4);
+
+ id = frm->in ? 0x02 : 0x01;
+ write(frm->pppdump_fd, &id, 1);
+ write(frm->pppdump_fd, &len, 2);
+ write(frm->pppdump_fd, frm->ptr, frm->len);
+ }
+
if (!ppp_traffic) {
pos = check_for_ppp_traffic(frm->ptr, frm->len);
if (pos < 0) {
diff --git a/tools/parser/sdp.c b/tools/parser/sdp.c
index 9a3121e..9111277 100644
--- a/tools/parser/sdp.c
+++ b/tools/parser/sdp.c
if (fr->data)
free(fr->data);
- fr->data = data;
- fr->data_len = len + count;
- fr->len = fr->data_len;
- fr->ptr = fr->data;
- fr->dev_id = frm->dev_id;
- fr->in = frm->in;
- fr->ts = frm->ts;
- fr->handle = frm->handle;
- fr->cid = frm->cid;
- fr->num = frm->num;
- fr->channel = frm->channel;
- fr->audio_fd = frm->audio_fd;
+ fr->data = data;
+ fr->data_len = len + count;
+ fr->len = fr->data_len;
+ fr->ptr = fr->data;
+ fr->dev_id = frm->dev_id;
+ fr->in = frm->in;
+ fr->ts = frm->ts;
+ fr->handle = frm->handle;
+ fr->cid = frm->cid;
+ fr->num = frm->num;
+ fr->channel = frm->channel;
+ fr->pppdump_fd = frm->pppdump_fd;
+ fr->audio_fd = frm->audio_fd;
return pos;
}