⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hcidump.c

📁 Linux下蓝牙探测工具
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -1;	}	opt = 1;	if (setsockopt(sk, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {		perror("Can't enable data direction info");		return -1;	}	opt = 1;	if (setsockopt(sk, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {		perror("Can't enable time stamp");		return -1;	}	/* Setup filter */	hci_filter_clear(&flt);	hci_filter_all_ptypes(&flt);	hci_filter_all_events(&flt);	if (setsockopt(sk, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {		perror("Can't set filter");		return -1;	}	/* Bind socket to the HCI device */	addr.hci_family = AF_BLUETOOTH;	addr.hci_dev = dev;	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		printf("Can't attach to device hci%d. %s(%d)\n", 					dev, strerror(errno), errno);		return -1;	}	return sk;}static int open_connection(char *addr, char *port){	struct sockaddr_storage ss;	struct addrinfo hints, *res0, *res;	int sk = -1, opt = 1;	memset(&hints, 0, sizeof(hints));	hints.ai_family = af;	hints.ai_socktype = SOCK_STREAM;	hints.ai_protocol = IPPROTO_TCP;	if (getaddrinfo(addr, port, &hints, &res0))		if(getaddrinfo(NULL, port, &hints, &res0)) {			perror("getaddrinfo");			exit(1);		}		for (res = res0; res; res = res->ai_next) {		sk = socket(res->ai_family, res->ai_socktype, res->ai_protocol);		if (sk < 0) {			if (res->ai_next)				continue;			perror("Can't create socket");			freeaddrinfo(res0);			exit(1);		}		setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));		memcpy(&ss, res->ai_addr, res->ai_addrlen);		switch(ss.ss_family) {		case AF_INET:			((struct sockaddr_in *) &ss)->sin_addr.s_addr = htonl(INADDR_ANY);			((struct sockaddr_in *) &ss)->sin_port = 0;			break;		case AF_INET6:			memcpy(&((struct sockaddr_in6 *) &ss)->sin6_addr,						&in6addr_any, sizeof(in6addr_any));			((struct sockaddr_in6 *) &ss)->sin6_port = 0;			break;		}		if (bind(sk, (struct sockaddr *) &ss, sizeof(ss)) < 0) {			perror("Can't bind socket");			close(sk);			freeaddrinfo(res0);			exit(1);		}				if (connect(sk, res->ai_addr, res->ai_addrlen) < 0) {			perror("Can't connect socket");			close(sk);			freeaddrinfo(res0);			exit(1);		}	}	freeaddrinfo(res0);	return sk;}static int create_datagram(unsigned short port){	struct sockaddr_in addr;	int sk, opt = 1;	sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (sk < 0)		return -1;	if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {		close(sk);		return -1;	}	memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_port = htons(port);	addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		close(sk);		return -1;	}	return sk;}static unsigned char ping_data[] = { 'p', 'i', 'n', 'g' };static unsigned char pong_data[] = { 'p', 'o', 'n', 'g' };static void handle_datagram(int sk){	struct sockaddr_in addr;	socklen_t addr_len = sizeof(addr);	unsigned char buf[64];	ssize_t len;	len = recvfrom(sk, buf, sizeof(buf), MSG_DONTWAIT,				(struct sockaddr *) &addr, &addr_len);	if (len != sizeof(ping_data))		return;	if (memcmp(buf, ping_data, sizeof(ping_data)) != 0)		return;	len = sendto(sk, pong_data, sizeof(pong_data), 0,				(struct sockaddr *) &addr, sizeof(addr));}static int wait_connection(char *addr, char *port){	char hname[100], hport[10];	struct addrinfo *ai, *runp;	struct addrinfo hints;	struct pollfd fds[3];	int err, opt, datagram, nfds = 0;	memset(&hints, 0, sizeof (hints));	hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;	hints.ai_socktype = SOCK_STREAM;	hints.ai_protocol = IPPROTO_TCP;	err = getaddrinfo(dump_addr, dump_port, &hints, &ai);	if (err < 0) {		printf("Can't get address info: %s\n", gai_strerror(err));		return -1;	}	runp = ai;	datagram = create_datagram(atoi(dump_port));	if (datagram < 0) {		printf("server: no discover protocol\n");	} else {		fds[nfds].fd = datagram;		fds[nfds].events = POLLIN;		nfds++;	}	while (runp != NULL && nfds < sizeof(fds) / sizeof(fds[0])) {		fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype,							runp->ai_protocol);		if (fds[nfds].fd < 0) {			perror("Can't create socket");			return -1;		}		fds[nfds].events = POLLIN;		opt = 1;		setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR,							&opt, sizeof(opt));		opt = 0;		setsockopt(fds[nfds].fd, SOL_SOCKET, SO_KEEPALIVE,							&opt, sizeof(opt));		if (bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen) < 0) {			if (errno != EADDRINUSE) {				perror("Can't bind socket");				return -1;			}			close(fds[nfds].fd);		} else {			if (listen(fds[nfds].fd, SOMAXCONN) < 0) {				perror("Can't listen on socket");				return -1;			}			getnameinfo(runp->ai_addr, runp->ai_addrlen,							hname, sizeof(hname),							hport, sizeof(hport),							NI_NUMERICSERV);			printf("server: %s:%s snap_len: %d filter: 0x%lx\n",					hname, hport, snap_len, parser.filter);			nfds++;		}		runp = runp->ai_next;	}	freeaddrinfo(ai);	while (1) {		int i, n = poll(fds, nfds, -1);		if (n <= 0)			continue;		for (i = 0; i < nfds; i++) {			struct sockaddr_storage rem;			socklen_t remlen = sizeof(rem);			int sk;			if (!(fds[i].revents & POLLIN))				continue;			if (fds[i].fd == datagram) {				handle_datagram(datagram);				continue;			}			sk = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen);			if (sk < 0)				continue;			getnameinfo((struct sockaddr *) &rem, remlen,							hname, sizeof(hname),							hport, sizeof(hport),							NI_NUMERICSERV);			printf("client: %s:%s snap_len: %d filter: 0x%lx\n",					hname, hport, snap_len, parser.filter);			for (n = 0; n < nfds; n++)				close(fds[n].fd);			return sk;		}	}	return -1;}static int run_server(int dev, char *addr, char *port, unsigned long flags){	while (1) {		int dd, sk;		sk = wait_connection(addr, port);		if (sk < 0)			continue;		//fcntl(sk, F_SETFL, O_NONBLOCK);		dd = open_socket(dev, flags);		if (dd < 0) {			close(sk);			continue;		}		process_frames(dev, dd, sk, flags);		close(dd);		close(sk);	}	return 0;}static struct {	char *name;	int  flag;} filters[] = {	{ "lmp",	FILT_LMP	},	{ "hci",	FILT_HCI	},	{ "sco",	FILT_SCO	},	{ "l2cap",	FILT_L2CAP	},	{ "rfcomm",	FILT_RFCOMM	},	{ "sdp",	FILT_SDP	},	{ "bnep",	FILT_BNEP	},	{ "cmtp",	FILT_CMTP	},	{ "hidp",	FILT_HIDP	},	{ "hcrp",	FILT_HCRP	},	{ "avdtp",	FILT_AVDTP	},	{ "avctp",	FILT_AVCTP	},	{ "obex",	FILT_OBEX	},	{ "capi",	FILT_CAPI	},	{ "ppp",	FILT_PPP	},	{ "csr",	FILT_CSR	},	{ "dga",	FILT_DGA	},	{ 0 }};static unsigned long parse_filter(int argc, char **argv){	unsigned long filter = 0;	int i,n;	for (i = 0; i < argc; i++) {		for (n = 0; filters[n].name; n++) {			if (!strcasecmp(filters[n].name, argv[i])) {				filter |= filters[n].flag;				break;			}		}	}	return filter;}static void usage(void){	printf(	"Usage: hcidump [OPTION...] [filter]\n"	"  -i, --device=hci_dev       HCI device\n"	"  -l, --snap-len=len         Snap len (in bytes)\n"	"  -p, --psm=psm              Default PSM\n"	"  -m, --manufacturer=compid  Default manufacturer\n"	"  -w, --save-dump=file       Save dump to a file\n"	"  -r, --read-dump=file       Read dump from a file\n"	"  -s, --send-dump=host       Send dump to a host\n"	"  -n, --recv-dump=host       Receive dump on a host\n"	"  -d, --wait-dump=host       Wait on a host and send\n"	"  -t, --ts                   Display time stamps\n"	"  -a, --ascii                Dump data in ascii\n"	"  -x, --hex                  Dump data in hex\n"	"  -X, --ext                  Dump data in hex and ascii\n"	"  -R, --raw                  Dump raw data\n"	"  -C, --cmtp=psm             PSM for CMTP\n"	"  -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"	"  -Y, --novendor             No vendor commands or events\n"	"  -N, --noappend             No appending to existing files\n"	"  -4, --ipv4                 Use IPv4 as transport\n"	"  -6  --ipv6                 Use IPv6 as transport\n"	"  -h, --help                 Give this help list\n"	"      --usage                Give a short usage message\n"	);}static struct option main_options[] = {	{ "device",		1, 0, 'i' },	{ "snap-len",		1, 0, 'l' },	{ "psm",		1, 0, 'p' },	{ "manufacturer",	1, 0, 'm' },	{ "save-dump",		1, 0, 'w' },	{ "read-dump",		1, 0, 'r' },	{ "send-dump",		1, 0, 's' },	{ "recv-dump",		1, 0, 'n' },	{ "wait-dump",		1, 0, 'd' },	{ "timestamp",		0, 0, 't' },	{ "ascii",		0, 0, 'a' },	{ "hex",		0, 0, 'x' },	{ "ext",		0, 0, 'X' },	{ "raw",		0, 0, 'R' },	{ "cmtp",		1, 0, 'C' },	{ "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' },	{ "novendor",		0, 0, 'Y' },	{ "nopermcheck",	0, 0, 'Z' },	{ "noappend",		0, 0, 'N' },	{ "ipv4",		0, 0, '4' },	{ "ipv6",		0, 0, '6' },	{ "help",		0, 0, 'h' },	{ 0 }};int main(int argc, char *argv[]){	unsigned long flags = 0;	unsigned long filter = 0;	int device = 0;	int defpsm = 0;	int defcompid = DEFAULT_COMPID;	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:d:taxXRC:H:O:P:D:A:BVYZN46h", main_options, NULL)) != -1) {		switch(opt) {		case 'i':			if (strcasecmp(optarg, "none") && strcasecmp(optarg, "system"))				device = atoi(optarg + 3);			else				device = HCI_DEV_NONE;			break;		case 'l': 			snap_len = atoi(optarg);			break;		case 'p': 			defpsm = atoi(optarg);			break;		case 'm':			defcompid = atoi(optarg);			break;		case 'w':			mode = WRITE;			dump_file = strdup(optarg);			break;		case 'r':			mode = READ;			dump_file = strdup(optarg);			break;		case 's':			mode = SEND;			dump_addr = optarg;			break;		case 'n':			mode = RECEIVE;			dump_addr = optarg;			break;		case 'd':			mode = SERVER;			dump_addr = optarg;			break;		case 't': 			flags |= DUMP_TSTAMP;			break;		case 'a': 			flags |= DUMP_ASCII;			break;		case 'x':			flags |= DUMP_HEX;			break;		case 'X':			flags |= DUMP_EXT;			break;		case 'R': 			flags |= DUMP_RAW;			break;		case 'C': 			set_proto(0, atoi(optarg), 0, SDP_UUID_CMTP);			break;		case 'H':			set_proto(0, atoi(optarg), 0, SDP_UUID_HARDCOPY_CONTROL_CHANNEL);			break;		case 'O':			set_proto(0, 0, atoi(optarg), SDP_UUID_OBEX);			break;		case 'P':			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;		case 'B':			flags |= DUMP_BTSNOOP;			break;		case 'V':			flags |= DUMP_VERBOSE;			break;		case 'Y':			flags |= DUMP_NOVENDOR;			break;		case 'Z':			permcheck = 0;			break;		case 'N':			noappend = 1;			break;		case '4':			af = AF_INET;			break;		case '6':			af = AF_INET6;			break;		case 'h':		default:			usage();			exit(0);		}	}	argc -= optind;	argv += optind;	optind = 0;	if (argc > 0)		filter = parse_filter(argc, argv);	/* Default settings */	if (!filter)		filter = ~0L;	if (pppdump_file)		pppdump_fd = open_file(pppdump_file, PPPDUMP, flags);	if (audio_file)		audio_fd = open_file(audio_file, AUDIO, flags);	switch (mode) {	case PARSE:		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, pppdump_fd, audio_fd);		read_dump(open_file(dump_file, mode, flags));		break;	case WRITE:		process_frames(device, open_socket(device, flags),				open_file(dump_file, mode, flags), flags);		break;	case RECEIVE:		init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);		read_dump(wait_connection(dump_addr, dump_port));		break;	case SEND:		process_frames(device, open_socket(device, flags),				open_connection(dump_addr, dump_port), flags);		break;	case SERVER:		init_parser(flags, filter, defpsm, defcompid, pppdump_fd, audio_fd);		run_server(device, dump_addr, dump_port, flags);		break;	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -