From a4ce81225086468afb927509414d8dc24ea44b1c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 11 Aug 2001 22:19:59 +0000 Subject: [PATCH] hcidump: Generic parser library. --- tools/hcidump.c | 175 ++++++++++-------------------------------- tools/parser/hci.c | 104 +++++++++++++++++++++++++ tools/parser/l2cap.c | 66 ++++++++++++++++ tools/parser/parser.c | 91 ++++++++++++++++++++++ tools/parser/parser.h | 37 +++++++++ 5 files changed, 338 insertions(+), 135 deletions(-) create mode 100644 tools/parser/hci.c create mode 100644 tools/parser/l2cap.c create mode 100644 tools/parser/parser.c create mode 100644 tools/parser/parser.h diff --git a/tools/hcidump.c b/tools/hcidump.c index e3242932c..75707d5f0 100644 --- a/tools/hcidump.c +++ b/tools/hcidump.c @@ -41,9 +41,10 @@ #include #include +#include "parser.h" + /* Default options */ int snap_len = 1 + HCI_ACL_HDR_SIZE + L2CAP_HDR_SIZE + 40; -int dump_type = 0; void usage(void) { @@ -52,127 +53,27 @@ void usage(void) printf("\thcidump <-i hciX> [-h]\n"); } -void raw_dump(char *pref, unsigned char *buf, int len) -{ - register char *ptr; - register int i; - char line[100]; - - if (!dump_type) - return; - - ptr = line; *ptr = 0; - for (i=0; iopcode); - - ptr += HCI_COMMAND_HDR_SIZE; - len -= HCI_COMMAND_HDR_SIZE; - - printf("Command: ogf 0x%x ocf 0x%x plen %d\n", - cmd_opcode_ogf(opcode), cmd_opcode_ocf(opcode), hdr->plen); - raw_dump(" ", ptr, len); -} - -static inline void event_dump(void *ptr, int len) -{ - hci_event_hdr *hdr = ptr; - - ptr += HCI_EVENT_HDR_SIZE; - len -= HCI_EVENT_HDR_SIZE; - - printf("Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen); - raw_dump(" ", ptr, len); -} - -static inline void l2cap_dump(void *ptr, int len) -{ - l2cap_hdr *hdr = ptr; - __u16 dlen = __le16_to_cpu(hdr->len); - __u16 cid = __le16_to_cpu(hdr->cid); - - ptr += L2CAP_HDR_SIZE; - len -= L2CAP_HDR_SIZE; - - if (cid == 0x1) { - l2cap_cmd_hdr *hdr = ptr; - __u16 len = __le16_to_cpu(hdr->len); - - ptr += L2CAP_CMD_HDR_SIZE; - len -= L2CAP_CMD_HDR_SIZE; - - printf(" L2CAP signaling: code 0x%2.2x ident %d len %d\n", - hdr->code, hdr->ident, len); - raw_dump(" ", ptr, len); - } else { - printf(" L2CAP data: cid 0x%x len %d\n", cid, dlen); - raw_dump(" ", ptr, len); - } -} - -static inline void acl_dump(void *ptr, int len) -{ - hci_acl_hdr *hdr = ptr; - __u16 handle = __le16_to_cpu(hdr->handle); - __u16 dlen = __le16_to_cpu(hdr->dlen); - - printf("ACL data: handle 0x%x flags 0x%x dlen %d\n", - acl_handle(handle), acl_flags(handle), dlen); - - ptr += HCI_ACL_HDR_SIZE; - len -= HCI_ACL_HDR_SIZE; - l2cap_dump(ptr, len); -} - -static inline void analyze(int type, unsigned char *ptr, int len) -{ - switch( type ){ - case HCI_COMMAND_PKT: - command_dump(ptr, len); - break; - - case HCI_EVENT_PKT: - event_dump(ptr, len); - break; - - case HCI_ACLDATA_PKT: - acl_dump(ptr, len); - break; - - default: - printf("Unknown: type 0x%2.2x len %d\n", - (__u8) type, len); - - raw_dump(" ", ptr, len); - break; - } -} - void process_frames(int dev, int fd) { - char data[HCI_MAX_FRAME_SIZE], ctrl[100], *ptr; + char *data, *ctrl; struct cmsghdr *cmsg; struct msghdr msg; struct iovec iv; - int len, type, in; + int len, in; - if (snap_len > sizeof(data)) - snap_len = sizeof(data); - else if (snap_len < 20) + if (snap_len < 20) snap_len = 20; + if (!(data = malloc(snap_len))) { + perror("Can't allocate data buffer"); + exit(1); + } + + if (!(ctrl = malloc(100))) { + perror("Can't allocate control buffer"); + exit(1); + } + printf("device: hci%d snap_len: %d filter: none\n", dev, snap_len); while (1) { @@ -182,7 +83,7 @@ void process_frames(int dev, int fd) msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = ctrl; - msg.msg_controllen = sizeof(ctrl); + msg.msg_controllen = 100; if( (len = recvmsg(fd, &msg, 0)) < 0 ){ perror("Receive failed"); @@ -201,45 +102,48 @@ void process_frames(int dev, int fd) cmsg = CMSG_NXTHDR(&msg, cmsg); } - ptr = data; - type = *ptr++; len--; - /* Print data direction */ printf("%c ", (in ? '>' : '<')); - analyze(type, ptr, len); + parse(data, len); fflush(stdout); } } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc, char *argv[]) { + extern int optind, opterr, optopt; + extern char *optarg; struct sockaddr_hci addr; struct hci_filter flt; int s, opt, dev; + long flags; dev = 0; - while( (opt=getopt(argc, argv,"i:s:h")) != EOF ) { + flags = 0; + + while ((opt=getopt(argc, argv,"i:s:ha")) != EOF) { switch(opt) { - case 'i': - dev = atoi(optarg+3); - break; + case 'i': + dev = atoi(optarg+3); + break; - case 'h': - dump_type = 1; - break; + case 'h': + flags |= DUMP_HEX; + break; + + case 'a': + flags |= DUMP_ASCII; + break; - case 's': - snap_len = atoi(optarg); - break; + case 's': + snap_len = atoi(optarg); + break; - default: - usage(); - exit(1); + default: + usage(); + exit(1); } } @@ -275,6 +179,7 @@ int main(int argc, char *argv[]) printf("HCIDump - HCI packet analyzer ver %s.\n", VERSION); + init_parser(flags); process_frames(dev, s); close(s); diff --git a/tools/parser/hci.c b/tools/parser/hci.c new file mode 100644 index 000000000..5c945d67a --- /dev/null +++ b/tools/parser/hci.c @@ -0,0 +1,104 @@ +/* + HCIDump - HCI packet analyzer + Copyright (C) 2000-2001 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "parser.h" + +static inline void command_dump(void *ptr, int len) +{ + hci_command_hdr *hdr = ptr; + __u16 opcode = __le16_to_cpu(hdr->opcode); + + ptr += HCI_COMMAND_HDR_SIZE; + len -= HCI_COMMAND_HDR_SIZE; + + printf("Command: ogf 0x%x ocf 0x%x plen %d\n", + cmd_opcode_ogf(opcode), cmd_opcode_ocf(opcode), hdr->plen); + raw_dump(1, ptr, len); +} + +static inline void event_dump(void *ptr, int len) +{ + hci_event_hdr *hdr = ptr; + + ptr += HCI_EVENT_HDR_SIZE; + len -= HCI_EVENT_HDR_SIZE; + + printf("Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen); + raw_dump(1, ptr, len); +} + +static inline void acl_dump(void *ptr, int len) +{ + hci_acl_hdr *hdr = ptr; + __u16 handle = __le16_to_cpu(hdr->handle); + __u16 dlen = __le16_to_cpu(hdr->dlen); + + printf("ACL data: handle 0x%x flags 0x%x dlen %d\n", + acl_handle(handle), acl_flags(handle), dlen); + + ptr += HCI_ACL_HDR_SIZE; + len -= HCI_ACL_HDR_SIZE; + l2cap_dump(1, ptr, len, acl_flags(handle)); +} + +void hci_dump(int level, __u8 *data, int len) +{ + unsigned char *ptr = data; + __u8 type; + + type = *ptr++; len--; + + switch (type) { + case HCI_COMMAND_PKT: + command_dump(ptr, len); + break; + + case HCI_EVENT_PKT: + event_dump(ptr, len); + break; + + case HCI_ACLDATA_PKT: + acl_dump(ptr, len); + break; + + default: + printf("Unknown: type 0x%2.2x len %d\n", type, len); + raw_dump(1, ptr, len); + break; + } +} diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c new file mode 100644 index 000000000..61bd621e8 --- /dev/null +++ b/tools/parser/l2cap.c @@ -0,0 +1,66 @@ +/* + HCIDump - HCI packet analyzer + Copyright (C) 2000-2001 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "parser.h" + +void l2cap_dump(int level, __u8 *ptr, int len, __u8 flags) +{ + l2cap_hdr *hdr = (void *) ptr; + __u16 dlen = __le16_to_cpu(hdr->len); + __u16 cid = __le16_to_cpu(hdr->cid); + + ptr += L2CAP_HDR_SIZE; + len -= L2CAP_HDR_SIZE; + + indent(level); + if (cid == 0x1) { + l2cap_cmd_hdr *hdr = (void *) ptr; + __u16 len = __le16_to_cpu(hdr->len); + + ptr += L2CAP_CMD_HDR_SIZE; + len -= L2CAP_CMD_HDR_SIZE; + + printf("L2CAP signaling: code 0x%2.2x ident %d len %d\n", + hdr->code, hdr->ident, len); + raw_dump(level, ptr, len); + } else { + printf("L2CAP data: cid 0x%x len %d\n", cid, dlen); + raw_dump(level, ptr, len); + } +} diff --git a/tools/parser/parser.c b/tools/parser/parser.c new file mode 100644 index 000000000..f6177aef4 --- /dev/null +++ b/tools/parser/parser.c @@ -0,0 +1,91 @@ +/* + HCIDump - HCI packet analyzer + Copyright (C) 2000-2001 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "parser.h" + +static long parser_flags; + +void init_parser(long flags) +{ + parser_flags = flags; +} + +static inline void hex_dump(int level, unsigned char *buf, int len) +{ + register unsigned char *ptr; + register int i; + char line[100]; + + ptr = line; *ptr = 0; + for (i=0; i + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#define indent(l) printf("%*c", (l*2), ' ') + +#define DUMP_HEX 0x01 +#define DUMP_ASCII 0x02 +#define DUMP_TYPE_MASK (DUMP_HEX | DUMP_ASCII) + +void init_parser(long flags); +#define parse(data, len) hci_dump(0, data, len) + +void raw_dump(int level, __u8 *data, int len); +void hci_dump(int level, __u8 *data, int len); +void l2cap_dump(int level, __u8 *data, int len, __u8 flags); -- 2.47.3