diff options
Diffstat (limited to 'tools/l2ping.c')
-rw-r--r-- | tools/l2ping.c | 123 |
1 files changed, 72 insertions, 51 deletions
diff --git a/tools/l2ping.c b/tools/l2ping.c index 45ddbe922..0e7a4be14 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2004 Marcel Holtmann <marcel@holtmann.org> + * Copyright (C) 2002-2005 Marcel Holtmann <marcel@holtmann.org> * * * This program is free software; you can redistribute it and/or modify @@ -33,37 +33,32 @@ #endif #include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <unistd.h> -#include <syslog.h> -#include <string.h> #include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <malloc.h> +#include <getopt.h> #include <signal.h> #include <sys/time.h> #include <sys/poll.h> #include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <resolv.h> -#include <netdb.h> - #include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> #include <bluetooth/l2cap.h> /* Defaults */ -bdaddr_t bdaddr; -int size = 20; -int ident = 200; -int delay = 1; -int count = -1; -int timeout = 10; +static bdaddr_t bdaddr; +static int size = 20; +static int ident = 200; +static int delay = 1; +static int count = -1; +static int timeout = 10; /* Stats */ -int sent_pkt = 0, recv_pkt = 0; +static int sent_pkt = 0; +static int recv_pkt = 0; static float tv2fl(struct timeval tv) { @@ -79,53 +74,77 @@ static void stat(int sig) static void ping(char *svr) { - struct sockaddr_l2 addr; struct sigaction sa; - char buf[2048]; + struct sockaddr_l2 addr; + socklen_t optlen; + unsigned char *buf; char str[18]; - int s, i, opt, lost; + int i, sk, lost; uint8_t id; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stat; sigaction(SIGINT, &sa, NULL); - if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { - perror("Can't create socket."); + buf = malloc(L2CAP_CMD_HDR_SIZE + size); + if (!buf) { + perror("Can't allocate buffer"); + exit(1); + } + + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); + if (sk < 0) { + perror("Can't create socket"); + free(buf); exit(1); } + /* Bind to local address */ memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; - addr.l2_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't bind socket."); + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket"); + close(sk); + free(buf); exit(1); } + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; str2ba(svr, &addr.l2_bdaddr); - if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't connect."); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't connect"); + close(sk); + free(buf); exit(1); } /* Get local address */ - opt = sizeof(addr); - if (getsockname(s, (struct sockaddr *)&addr, &opt) < 0) { - perror("Can't get local address."); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { + perror("Can't get local address"); + close(sk); + free(buf); exit(1); } - ba2str(&addr.l2_bdaddr, str); + ba2str(&addr.l2_bdaddr, str); printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ - for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) - buf[i] = (i % 40) + 'A'; + for (i = 0; i < size; i++) + buf[L2CAP_CMD_HDR_SIZE + i] = (i % 40) + 'A'; id = ident; - while( count == -1 || count-- > 0 ){ + while (count == -1 || count-- > 0) { struct timeval tv_send, tv_recv, tv_diff; l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; @@ -137,7 +156,7 @@ static void ping(char *svr) gettimeofday(&tv_send, NULL); /* Send Echo Request */ - if (send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0) { + if (send(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) { perror("Send failed"); exit(1); } @@ -146,9 +165,11 @@ static void ping(char *svr) lost = 0; while (1) { struct pollfd pf[1]; - register int err; + int err; + + pf[0].fd = sk; + pf[0].events = POLLIN; - pf[0].fd = s; pf[0].events = POLLIN; if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); exit(1); @@ -159,7 +180,7 @@ static void ping(char *svr) break; } - if ((err = recv(s, buf, sizeof(buf), 0)) < 0) { + if ((err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0)) < 0) { perror("Recv failed"); exit(1); } @@ -210,21 +231,25 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-S source addr] [-s size] [-c count] [-t timeout] [-f] <bd_addr>\n"); + printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-f] <bdaddr>\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc, char *argv[]) { - register int opt; + int opt; /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"s:c:t:fS:")) != EOF) { + while ((opt=getopt(argc,argv,"i:s:c:t:f")) != EOF) { switch(opt) { + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'f': /* Kinda flood ping */ delay = 0; @@ -242,10 +267,6 @@ int main(int argc, char *argv[]) size = atoi(optarg); break; - case 'S': - str2ba(optarg, &bdaddr); - break; - default: usage(); exit(1); |