From cde05014b346ce1084029ca42b497321d25bd73b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 5 Aug 2001 16:57:21 +0000 Subject: [PATCH] hcidump: Improved packet parser and output format. --- tools/hcidump.c | 194 ++++++++++++++++++++++++++---------------------- 1 file changed, 106 insertions(+), 88 deletions(-) diff --git a/tools/hcidump.c b/tools/hcidump.c index 701fc88c8..e3242932c 100644 --- a/tools/hcidump.c +++ b/tools/hcidump.c @@ -41,19 +41,9 @@ #include #include -#define HEXDUMP 0 -#define ANALYZE 1 - /* Default options */ -int action = ANALYZE; - -char * hci_pkt_type[] = { - "Unknown", - "Command", - "ACL Data", - "SCO Data", - "Event" -}; +int snap_len = 1 + HCI_ACL_HDR_SIZE + L2CAP_HDR_SIZE + 40; +int dump_type = 0; void usage(void) { @@ -62,62 +52,83 @@ void usage(void) printf("\thcidump <-i hciX> [-h]\n"); } -void hex_dump(char *pref, unsigned char *buf, int len) +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); - printf("ogf 0x%x ocf 0x%x plen %d\n", + + 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); } -void inline event_dump(void *ptr, int len) +static inline void event_dump(void *ptr, int len) { hci_event_hdr *hdr = ptr; - printf("code 0x%2.2x plen %d\n", hdr->evt, hdr->plen); + + 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); } -void inline l2cap_dump(void *ptr, int 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); - printf(" L2CAP: cid 0x%x len %d\n", cid, dlen); - ptr += L2CAP_HDR_SIZE; + len -= L2CAP_HDR_SIZE; + if (cid == 0x1) { l2cap_cmd_hdr *hdr = ptr; __u16 len = __le16_to_cpu(hdr->len); - printf(" signaling: code 0x%x ident %d len %d\n", + + 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); } } -void inline acl_dump(void *ptr, int 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("handle 0x%x flags 0x%x dlen %d\n", + printf("ACL data: handle 0x%x flags 0x%x dlen %d\n", acl_handle(handle), acl_flags(handle), dlen); ptr += HCI_ACL_HDR_SIZE; @@ -125,7 +136,7 @@ void inline acl_dump(void *ptr, int len) l2cap_dump(ptr, len); } -void analyze(int type, unsigned char *ptr, int len) +static inline void analyze(int type, unsigned char *ptr, int len) { switch( type ){ case HCI_COMMAND_PKT: @@ -141,37 +152,89 @@ void analyze(int type, unsigned char *ptr, int len) break; default: - printf("\n"); + 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; + struct cmsghdr *cmsg; + struct msghdr msg; + struct iovec iv; + int len, type, in; + + if (snap_len > sizeof(data)) + snap_len = sizeof(data); + else if (snap_len < 20) + snap_len = 20; + + printf("device: hci%d snap_len: %d filter: none\n", dev, snap_len); + + while (1) { + iv.iov_base = data; + iv.iov_len = snap_len; + + msg.msg_iov = &iv; + msg.msg_iovlen = 1; + msg.msg_control = ctrl; + msg.msg_controllen = sizeof(ctrl); + + if( (len = recvmsg(fd, &msg, 0)) < 0 ){ + perror("Receive failed"); + exit(1); + } + + /* Process control message */ + in = 0; + cmsg = CMSG_FIRSTHDR(&msg); + while( cmsg ){ + switch(cmsg->cmsg_type){ + case HCI_CMSG_DIR: + in = *((int *)CMSG_DATA(cmsg)); + break; + } + cmsg = CMSG_NXTHDR(&msg, cmsg); + } + + ptr = data; + type = *ptr++; len--; + + /* Print data direction */ + printf("%c ", (in ? '>' : '<')); + + analyze(type, ptr, len); + + fflush(stdout); + } +} + extern int optind,opterr,optopt; extern char *optarg; int main(int argc, char *argv[]) { - char data[HCI_MAX_FRAME_SIZE], ctrl[100], *ptr; - int s, len, type, opt, dev, in; struct sockaddr_hci addr; struct hci_filter flt; - struct cmsghdr *cmsg; - struct msghdr msg; - struct iovec iv; + int s, opt, dev; dev = 0; - while( (opt=getopt(argc, argv,"i:h")) != EOF ) { + while( (opt=getopt(argc, argv,"i:s:h")) != EOF ) { switch(opt) { case 'i': dev = atoi(optarg+3); break; case 'h': - action = HEXDUMP; + dump_type = 1; break; - case 'a': - action = ANALYZE; + case 's': + snap_len = atoi(optarg); break; default: @@ -205,60 +268,15 @@ int main(int argc, char *argv[]) addr.hci_family = AF_BLUETOOTH; addr.hci_dev = dev; if( bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) { - printf("Can't attach to device hci%d. %s(%d)\n", dev, strerror(errno), errno); + printf("Can't attach to device hci%d. %s(%d)\n", + dev, strerror(errno), errno); exit(1); } - printf("HCIDump version %s\n", VERSION); + printf("HCIDump - HCI packet analyzer ver %s.\n", VERSION); - while( 1 ) { - iv.iov_base = data; - iv.iov_len = sizeof(data); + process_frames(dev, s); - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = ctrl; - msg.msg_controllen = sizeof(ctrl); - - if( (len = recvmsg(s, &msg, 0)) < 0 ){ - perror("Receive failed"); - exit(1); - } - - /* Process controll message */ - in = 0; - cmsg = CMSG_FIRSTHDR(&msg); - while( cmsg ){ - switch(cmsg->cmsg_type){ - case HCI_CMSG_DIR: - in = *((int *)CMSG_DATA(cmsg)); - break; - } - cmsg = CMSG_NXTHDR(&msg, cmsg); - } - - ptr = data; - type = *ptr++; len--; - if( type < 0 || type > 4 ) - type = 0; - - switch (action) { - case ANALYZE: - printf("%c %s: ", (in ? '>' : '<'), - hci_pkt_type[type] ); - - analyze(type, ptr, len); - break; - - case HEXDUMP: - printf("%c type 0x%2.2x len %d\n", - (in ? '>' : '<'), - (__u8) type, len); - - hex_dump(" ", ptr, len); - break; - } - - fflush(stdout); - } + close(s); + return 0; } -- 2.47.3