diff options
Diffstat (limited to 'pand')
| -rw-r--r-- | pand/Makefile.am | 22 | ||||
| -rw-r--r-- | pand/bnep.c | 311 | ||||
| -rw-r--r-- | pand/main.c | 798 | ||||
| -rw-r--r-- | pand/pand.1 | 77 | ||||
| -rw-r--r-- | pand/pand.h | 42 | ||||
| -rw-r--r-- | pand/sdp.c | 247 | 
6 files changed, 0 insertions, 1497 deletions
diff --git a/pand/Makefile.am b/pand/Makefile.am deleted file mode 100644 index 85d70542..00000000 --- a/pand/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ - -if PAND -bin_PROGRAMS = pand - -pand_SOURCES = main.c pand.h bnep.c sdp.c - -pand_LDADD = @BLUEZ_LIBS@ -endif - -AM_CFLAGS = @BLUEZ_CFLAGS@ - -INCLUDES = -I$(top_srcdir)/common - -if PAND -if MANPAGES -man_MANS = pand.1 -endif -endif - -EXTRA_DIST = pand.1 - -MAINTAINERCLEANFILES = Makefile.in diff --git a/pand/bnep.c b/pand/bnep.c deleted file mode 100644 index 604ed552..00000000 --- a/pand/bnep.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> - *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/bnep.h> - -#include <netinet/in.h> - -#include "pand.h" - -static int ctl; - -/* Compatibility with old ioctls */ -#define OLD_BNEPCONADD      1 -#define OLD_BNEPCONDEL      2 -#define OLD_BNEPGETCONLIST  3 -#define OLD_BNEPGETCONINFO  4 - -static unsigned long bnepconnadd; -static unsigned long bnepconndel; -static unsigned long bnepgetconnlist; -static unsigned long bnepgetconninfo; - -static struct { -	char     *str; -	uint16_t uuid; -} __svc[] = { -	{ "PANU", BNEP_SVC_PANU }, -	{ "NAP",  BNEP_SVC_NAP  }, -	{ "GN",   BNEP_SVC_GN   }, -	{ NULL } -}; - -int bnep_str2svc(char *svc, uint16_t *uuid) -{ -	int i; -	for (i = 0; __svc[i].str; i++) -		if (!strcasecmp(svc, __svc[i].str)) { -			*uuid = __svc[i].uuid; -			return 0; -		} -	return -1; -} - -char *bnep_svc2str(uint16_t uuid) -{ -	int i; -	for (i = 0; __svc[i].str; i++) -		if (__svc[i].uuid == uuid) -			return __svc[i].str; -	return NULL; -} - -int bnep_init(void) -{ -	ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); -	if (ctl < 0) { -		perror("Failed to open control socket"); -		return 1; -	} - -	/* Temporary ioctl compatibility hack */ -	{  -		struct bnep_connlist_req req; -		struct bnep_conninfo ci[1]; - -		req.cnum = 1; -		req.ci   = ci; - -		if (!ioctl(ctl, BNEPGETCONNLIST, &req)) { -			/* New ioctls */ -			bnepconnadd     = BNEPCONNADD; -			bnepconndel     = BNEPCONNDEL; -			bnepgetconnlist = BNEPGETCONNLIST; -			bnepgetconninfo = BNEPGETCONNINFO; -		} else { -			/* Old ioctls */ -			bnepconnadd     = OLD_BNEPCONADD; -			bnepconndel     = OLD_BNEPCONDEL; -			bnepgetconnlist = OLD_BNEPGETCONLIST; -			bnepgetconninfo = OLD_BNEPGETCONINFO; -		} -	} - -	return 0; -} - -int bnep_cleanup(void) -{ -	close(ctl); -	return 0; -} - -int bnep_show_connections(void) -{ -	struct bnep_connlist_req req; -	struct bnep_conninfo ci[48]; -	int i; - -	req.cnum = 48; -	req.ci   = ci; -	if (ioctl(ctl, bnepgetconnlist, &req)) { -		perror("Failed to get connection list"); -		return -1; -	} - -	for (i=0; i < req.cnum; i++) { -		printf("%s %s %s\n", ci[i].device, -			batostr((bdaddr_t *) ci[i].dst), -			bnep_svc2str(ci[i].role)); -	} -	return 0; -} - -int bnep_kill_connection(uint8_t *dst) -{ -	struct bnep_conndel_req req; - -	memcpy(req.dst, dst, ETH_ALEN); -	req.flags = 0; -	if (ioctl(ctl, bnepconndel, &req)) { -		perror("Failed to kill connection"); -		return -1; -	} -	return 0; -} - -int bnep_kill_all_connections(void) -{ -	struct bnep_connlist_req req; -	struct bnep_conninfo ci[48]; -	int i; - -	req.cnum = 48; -	req.ci   = ci; -	if (ioctl(ctl, bnepgetconnlist, &req)) { -		perror("Failed to get connection list"); -		return -1; -	} - -	for (i=0; i < req.cnum; i++) { -		struct bnep_conndel_req req; -		memcpy(req.dst, ci[i].dst, ETH_ALEN); -		req.flags = 0; -		ioctl(ctl, bnepconndel, &req); -	} -	return 0; -} - -static int bnep_connadd(int sk, uint16_t role, char *dev) -{ -	struct bnep_connadd_req req; - -	strncpy(req.device, dev, 16); -	req.device[15] = '\0'; -	req.sock = sk; -	req.role = role; -	if (ioctl(ctl, bnepconnadd, &req)) -		return -1; -	strncpy(dev, req.device, 16); -	return 0; -} - -struct __service_16 {  -	uint16_t dst; -	uint16_t src; -} __attribute__ ((packed)); - -struct __service_32 {  -	uint16_t unused1; -	uint16_t dst; -	uint16_t unused2; -	uint16_t src; -} __attribute__ ((packed)); - -struct __service_128 {  -	uint16_t unused1; -	uint16_t dst; -	uint16_t unused2[8]; -	uint16_t src; -	uint16_t unused3[7]; -} __attribute__ ((packed)); - -int bnep_accept_connection(int sk, uint16_t role, char *dev) -{ -	struct bnep_setup_conn_req *req; -	struct bnep_control_rsp *rsp; -	unsigned char pkt[BNEP_MTU]; -	int r; - -	r = recv(sk, pkt, BNEP_MTU, 0); -	if (r <= 0) -		return -1; - -	errno = EPROTO; - -	if (r < sizeof(*req)) -		return -1; - -	req = (void *) pkt; -	if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) -		return -1; - -	/* FIXME: Check role UUIDs */ - -	rsp = (void *) pkt; -	rsp->type = BNEP_CONTROL; -	rsp->ctrl = BNEP_SETUP_CONN_RSP; -	rsp->resp = htons(BNEP_SUCCESS); -	if (send(sk, rsp, sizeof(*rsp), 0) < 0) -		return -1; - -	return bnep_connadd(sk, role, dev); -} - -/* Create BNEP connection  - * sk      - Connect L2CAP socket - * role    - Local role - * service - Remote service - * dev     - Network device (contains actual dev name on return) - */ -int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev) -{ -	struct bnep_setup_conn_req *req; -	struct bnep_control_rsp *rsp; -	struct __service_16 *s; -	unsigned char pkt[BNEP_MTU]; -	int r; - -	/* Send request */ -	req = (void *) pkt; -	req->type = BNEP_CONTROL; -	req->ctrl = BNEP_SETUP_CONN_REQ; -	req->uuid_size = 2;	/* 16bit UUID */ -	s = (void *) req->service; -	s->dst = htons(svc); -	s->src = htons(role); - -	if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) < 0) -		return -1; - -receive: -	/* Get response */ -	r = recv(sk, pkt, BNEP_MTU, 0); -	if (r <= 0) -		return -1; - -	errno = EPROTO; - -	if (r < sizeof(*rsp)) -		return -1; -	 -	rsp = (void *) pkt; -	if (rsp->type != BNEP_CONTROL) -		return -1; - -	if (rsp->ctrl != BNEP_SETUP_CONN_RSP) -		goto receive; - -	r = ntohs(rsp->resp); - -	switch (r) { -	case BNEP_SUCCESS: -		break; - -	case BNEP_CONN_INVALID_DST: -	case BNEP_CONN_INVALID_SRC: -	case BNEP_CONN_INVALID_SVC: -		errno = EPROTO; -		return -1; - -	case BNEP_CONN_NOT_ALLOWED: -		errno = EACCES; -		return -1; -	} - -	return bnep_connadd(sk, role, dev); -} diff --git a/pand/main.c b/pand/main.c deleted file mode 100644 index ce3b8ebb..00000000 --- a/pand/main.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> - *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <signal.h> -#include <getopt.h> -#include <sys/poll.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/bnep.h> - -#include "pand.h" - -#ifdef NEED_PPOLL -#include "ppoll.h" -#endif - -static uint16_t role    = BNEP_SVC_PANU;	/* Local role (ie service) */ -static uint16_t service = BNEP_SVC_NAP;		/* Remote service */ - -static int detach = 1; -static int persist; -static int use_sdp = 1; -static int use_cache; -static int link_mode = 0; -static int cleanup; -static int search_duration = 10; - -static struct { -	int      valid; -	char     dst[40]; -	bdaddr_t bdaddr; -} cache; - -static char netdev[16] = "bnep%d"; -static char *pidfile = NULL; -static char *devupcmd = NULL; -static char *devdowncmd = NULL; - -static bdaddr_t src_addr = *BDADDR_ANY; -static int src_dev = -1; - -static volatile int terminate; - -static void do_kill(char *dst); - -enum { -	NONE, -	SHOW, -	LISTEN, -	CONNECT, -	KILL -} modes; - -struct script_arg { -	char	dev[20]; -	char	dst[20]; -	int	sk; -	int	nsk; -}; - -static void run_script(char *script, char *dev, char *dst, int sk, int nsk) -{ -	char *argv[4]; -	struct sigaction sa; - -	if (!script) -		return; - -	if (access(script, R_OK | X_OK)) -		return; - -	if (fork()) -		return; - -	if (sk >= 0) -		close(sk); - -	if (nsk >= 0) -		close(nsk); - -	memset(&sa, 0, sizeof(sa)); -	sa.sa_handler = SIG_DFL; -	sigaction(SIGCHLD, &sa, NULL); -	sigaction(SIGPIPE, &sa, NULL); - -	argv[0] = script; -	argv[1] = dev; -	argv[2] = dst; -	argv[3] = NULL; - -	execv(script, argv); - -	exit(1); -} - -/* Wait for disconnect or error condition on the socket */ -static int w4_hup(int sk, struct script_arg *down_cmd) -{ -	struct pollfd pf; -	sigset_t sigs; -	int n; - -	sigfillset(&sigs); -	sigdelset(&sigs, SIGCHLD); -	sigdelset(&sigs, SIGPIPE); -	sigdelset(&sigs, SIGTERM); -	sigdelset(&sigs, SIGINT); -	sigdelset(&sigs, SIGHUP); - -	while (!terminate) { -		pf.fd = sk; -		pf.events = POLLERR | POLLHUP; - -		n = ppoll(&pf, 1, NULL, &sigs); - -		if (n < 0) { -			if (errno == EINTR || errno == EAGAIN) -				continue; - -			syslog(LOG_ERR, "Poll failed. %s(%d)", -						strerror(errno), errno); - -			return 1; -		} - -		if (n) { -			int err = 0; -			socklen_t olen = sizeof(err); - -			getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen); - -			syslog(LOG_INFO, "%s disconnected%s%s", netdev, -				err ? " : " : "", err ? strerror(err) : ""); - -			if (down_cmd) -				run_script(devdowncmd, -						down_cmd->dev, down_cmd->dst, -						down_cmd->sk, down_cmd->nsk); - -			close(sk); - -			return 0; -		} -	} - -	return 0; -} - -static int do_listen(void) -{ -	struct l2cap_options l2o; -	struct sockaddr_l2 l2a; -	socklen_t olen; -	int sk, lm; - -	if (use_sdp) -		bnep_sdp_register(&src_addr, role); - -	/* Create L2CAP socket and bind it to PSM BNEP */ -	sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); -	if (sk < 0) { -		syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	memset(&l2a, 0, sizeof(l2a)); -	l2a.l2_family = AF_BLUETOOTH; -	bacpy(&l2a.l2_bdaddr, &src_addr); -	l2a.l2_psm = htobs(BNEP_PSM); - -	if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { -		syslog(LOG_ERR, "Bind failed. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	/* Setup L2CAP options according to BNEP spec */ -	memset(&l2o, 0, sizeof(l2o)); -	olen = sizeof(l2o); -	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { -		syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	l2o.imtu = l2o.omtu = BNEP_MTU; -	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { -		syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	/* Set link mode */ -	lm = link_mode; -	if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { -		syslog(LOG_ERR, "Failed to set link mode. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	listen(sk, 10); - -	while (!terminate) { -		socklen_t alen = sizeof(l2a); -		char devname[16]; -		int nsk; - -		nsk = accept(sk, (struct sockaddr *) &l2a, &alen); -		if (nsk < 0) { -			syslog(LOG_ERR, "Accept failed. %s(%d)", -						strerror(errno), errno); -			continue; -		} - -		switch (fork()) { -		case 0: -			break; -		case -1: -			syslog(LOG_ERR, "Fork failed. %s(%d)", -						strerror(errno), errno); -		default: -			close(nsk); -			continue; -		} - -		strncpy(devname, netdev, 16); -		devname[15] = '\0'; - -		if (!bnep_accept_connection(nsk, role, devname)) { -			char str[40]; -			struct script_arg down_cmd; - -			ba2str(&l2a.l2_bdaddr, str); - -			syslog(LOG_INFO, "New connection from %s at %s", -								str, devname); - -			run_script(devupcmd, devname, str, sk, nsk); - -			memset(&down_cmd, 0, sizeof(struct script_arg)); -			strncpy(down_cmd.dev, devname, strlen(devname) + 1); -			strncpy(down_cmd.dst, str, strlen(str) + 1); -			down_cmd.sk = sk; -			down_cmd.nsk = nsk; -			w4_hup(nsk, &down_cmd); -		} else { -			syslog(LOG_ERR, "Connection failed. %s(%d)", -						strerror(errno), errno); -		} - -		close(nsk); -		exit(0); -	} - -	if (use_sdp) -		bnep_sdp_unregister(); - -	return 0; -} - -/* Connect and initiate BNEP session - * Returns: - *   -1 - critical error (exit persist mode) - *   1  - non critical error - *   0  - success - */ -static int create_connection(char *dst, bdaddr_t *bdaddr) -{ -	struct l2cap_options l2o; -	struct sockaddr_l2 l2a; -	socklen_t olen; -	int sk, r = 0; -	struct script_arg down_cmd; - -	syslog(LOG_INFO, "Connecting to %s", dst); - -	sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); -	if (sk < 0) { -		syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", -						strerror(errno), errno); -		return -1; -	} - -	/* Setup L2CAP options according to BNEP spec */ -	memset(&l2o, 0, sizeof(l2o)); -	olen = sizeof(l2o); -	getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); -	l2o.imtu = l2o.omtu = BNEP_MTU; -	setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); - -	memset(&l2a, 0, sizeof(l2a)); -	l2a.l2_family = AF_BLUETOOTH; -	bacpy(&l2a.l2_bdaddr, &src_addr); - -	if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) -		syslog(LOG_ERR, "Bind failed. %s(%d)", -						strerror(errno), errno); - -	memset(&l2a, 0, sizeof(l2a)); -	l2a.l2_family = AF_BLUETOOTH; -	bacpy(&l2a.l2_bdaddr, bdaddr); -	l2a.l2_psm = htobs(BNEP_PSM); - -	if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) &&  -			!bnep_create_connection(sk, role, service, netdev)) { - -		syslog(LOG_INFO, "%s connected", netdev); - -		run_script(devupcmd, netdev, dst, sk, -1); - -		if (persist || devdowncmd) { -				memset(&down_cmd, 0, sizeof(struct script_arg)); -				strncpy(down_cmd.dev, netdev, strlen(netdev) + 1); -				strncpy(down_cmd.dst, dst, strlen(dst) + 1); -				down_cmd.sk = sk; -				down_cmd.nsk = -1; -				w4_hup(sk, &down_cmd); - -			if (terminate && cleanup) { -				syslog(LOG_INFO, "Disconnecting from %s.", dst); -				do_kill(dst); -			} -		} - -		r = 0; -	} else { -		syslog(LOG_ERR, "Connect to %s failed. %s(%d)", -						dst, strerror(errno), errno); -		r = 1; -	} - -	close(sk); - -	if (use_cache) { -		if (!r) { -			/* Succesesful connection, validate cache */ -			strcpy(cache.dst, dst); -			bacpy(&cache.bdaddr, bdaddr); -			cache.valid = use_cache; -		} else -			cache.valid--; -	} - -	return r; -} - -/* Search and connect - * Returns: - *   -1 - critical error (exit persist mode) - *   1  - non critical error - *   0  - success - */ -static int do_connect(void) -{ -	inquiry_info *ii; -	int reconnect = 0; -	int i, n, r = 0; - -	do { -		if (reconnect) -			sleep(persist); -		reconnect = 1; - -		if (cache.valid > 0) { -			/* Use cached bdaddr */ -			r = create_connection(cache.dst, &cache.bdaddr); -			if (r < 0) { -				terminate = 1; -				break; -			} -			continue; -		} - -		syslog(LOG_INFO, "Inquiring"); - -		/* FIXME: Should we use non general LAP here ? */ - -		ii = NULL; -		n  = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); -		if (n < 0) { -			syslog(LOG_ERR, "Inquiry failed. %s(%d)", -						strerror(errno), errno); -			continue; -		} - -		for (i = 0; i < n; i++) { -			char dst[40]; -			ba2str(&ii[i].bdaddr, dst); - -			if (use_sdp) { -				syslog(LOG_INFO, "Searching for %s on %s",  -						bnep_svc2str(service), dst); - -				if (bnep_sdp_search(&src_addr, &ii[i].bdaddr, service) <= 0) -					continue; -			} - -			r = create_connection(dst, &ii[i].bdaddr); -			if (r < 0) { -				terminate = 1; -				break; -			} -		} -		bt_free(ii); -	} while (!terminate && persist); - -	return r; -} - -static void do_show(void) -{ -	bnep_show_connections(); -} - -static void do_kill(char *dst) -{ -	if (dst) -		bnep_kill_connection((void *) strtoba(dst)); -	else -		bnep_kill_all_connections(); -} - -static void sig_hup(int sig) -{ -	return; -} - -static void sig_term(int sig) -{ -	terminate = 1; -} - -static int write_pidfile(void) -{ -	int fd; -	FILE *f; -	pid_t pid; - -	do { -		fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644); -		if (fd == -1) { -			/* Try to open the file for read. */ -			fd = open(pidfile, O_RDONLY); -			if (fd < 0) { -				syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", -							strerror(errno), errno); -				return -1; -			} -			 -			/* We're already running; send a SIGHUP (we presume that they -			 * are calling ifup for a reason, so they probably want to -			 * rescan) and then exit cleanly and let things go on in the -			 * background.  Muck with the filename so that we don't go -			 * deleting the pid file for the already-running instance. -			 */ -			f = fdopen(fd, "r"); -			if (!f) { -				syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", -							strerror(errno), errno); -				close(fd); -				return -1; -			} - -			pid = 0; -			if (fscanf(f, "%d", &pid) != 1) -				pid = 0; -			fclose(f); - -			if (pid) { -				/* Try to kill it. */ -				if (kill(pid, SIGHUP) == -1) { -					/* No such pid; remove the bogus pid file. */ -					syslog(LOG_INFO, "Removing stale pidfile"); -					unlink(pidfile); -					fd = -1; -				} else { -					/* Got it.  Don't mess with the pid file on -					 * our way out. */ -					syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid); -					pidfile = NULL; -					return -1; -				} -			} -		} -	} while(fd == -1); - -	f = fdopen(fd, "w"); -	if (!f) { -		syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", -						strerror(errno), errno); -		close(fd); -		unlink(pidfile); -		return -1; -	} - -	fprintf(f, "%d\n", getpid()); -	fclose(f); - -	return 0; -} - -static struct option main_lopts[] = { -	{ "help",     0, 0, 'h' }, -	{ "listen",   0, 0, 's' }, -	{ "connect",  1, 0, 'c' }, -	{ "search",   2, 0, 'Q' }, -	{ "kill",     1, 0, 'k' }, -	{ "killall",  0, 0, 'K' }, -	{ "role",     1, 0, 'r' }, -	{ "service",  1, 0, 'd' }, -	{ "ethernet", 1, 0, 'e' }, -	{ "device",   1, 0, 'i' }, -	{ "nosdp",    0, 0, 'D' }, -	{ "list",     0, 0, 'l' }, -	{ "show",     0, 0, 'l' }, -	{ "nodetach", 0, 0, 'n' }, -	{ "persist",  2, 0, 'p' }, -	{ "auth",     0, 0, 'A' }, -	{ "encrypt",  0, 0, 'E' }, -	{ "secure",   0, 0, 'S' }, -	{ "master",   0, 0, 'M' }, -	{ "cache",    0, 0, 'C' }, -	{ "pidfile",  1, 0, 'P' }, -	{ "devup",    1, 0, 'u' }, -	{ "devdown",  1, 0, 'o' }, -	{ "autozap",  0, 0, 'z' }, -	{ 0, 0, 0, 0 } -}; - -static char main_sopts[] = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:u:o:z"; - -static char main_help[] =  -	"Bluetooth PAN daemon version " VERSION " \n" -	"Usage:\n" -	"\tpand <options>\n" -	"Options:\n" -	"\t--show --list -l          Show active PAN connections\n" -	"\t--listen -s               Listen for PAN connections\n" -	"\t--connect -c <bdaddr>     Create PAN connection\n" -	"\t--autozap -z              Disconnect automatically on exit\n" -	"\t--search -Q[duration]     Search and connect\n" -	"\t--kill -k <bdaddr>        Kill PAN connection\n" -	"\t--killall -K              Kill all PAN connections\n" -	"\t--role -r <role>          Local PAN role (PANU, NAP, GN)\n" -	"\t--service -d <role>       Remote PAN service (PANU, NAP, GN)\n" -	"\t--ethernet -e <name>      Network interface name\n" -	"\t--device -i <bdaddr>      Source bdaddr\n" -	"\t--nosdp -D                Disable SDP\n" -	"\t--auth -A                 Enable authentication\n" -	"\t--encrypt -E              Enable encryption\n" -	"\t--secure -S               Secure connection\n" -	"\t--master -M               Become the master of a piconet\n" -	"\t--nodetach -n             Do not become a daemon\n" -	"\t--persist -p[interval]    Persist mode\n" -	"\t--cache -C[valid]         Cache addresses\n" -	"\t--pidfile -P <pidfile>    Create PID file\n" -	"\t--devup -u <script>       Script to run when interface comes up\n" -	"\t--devdown -o <script>     Script to run when interface comes down\n"; - -int main(int argc, char *argv[]) -{ -	char *dst = NULL, *src = NULL; -	struct sigaction sa; -	int mode = NONE; -	int opt; - -	while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { -		switch(opt) { -		case 'l': -			mode = SHOW; -			detach = 0; -			break; - -		case 's': -			mode = LISTEN; -			break; - -		case 'c': -			mode = CONNECT; -			dst  = strdup(optarg); -			break; - -		case 'Q': -			mode = CONNECT; -			if (optarg) -				search_duration = atoi(optarg); -			break; - -		case 'k': -			mode = KILL; -			detach = 0; -			dst  = strdup(optarg); -			break; - -		case 'K': -			mode = KILL; -			detach = 0; -			break; - -		case 'i': -			src = strdup(optarg); -			break; - -		case 'r': -			bnep_str2svc(optarg, &role); -			break; - -		case 'd': -			bnep_str2svc(optarg, &service); -			break; - -		case 'D': -			use_sdp = 0; -			break; - -		case 'A': -			link_mode |= L2CAP_LM_AUTH; -			break; - -		case 'E': -			link_mode |= L2CAP_LM_ENCRYPT; -			break; - -		case 'S': -			link_mode |= L2CAP_LM_SECURE; -			break; - -		case 'M': -			link_mode |= L2CAP_LM_MASTER; -			break; - -		case 'e': -			strncpy(netdev, optarg, 16); -			netdev[15] = '\0'; -			break; - -		case 'n': -			detach = 0; -			break; - -		case 'p': -			if (optarg) -				persist = atoi(optarg); -			else -				persist = 5; -			break; - -		case 'C': -			if (optarg) -				use_cache = atoi(optarg); -			else -				use_cache = 2; -			break; - -		case 'P': -			pidfile = strdup(optarg); -			break; - -		case 'u': -			devupcmd = strdup(optarg); -			break; - -		case 'o': -			devdowncmd = strdup(optarg); -			break; - -		case 'z': -			cleanup = 1; -			break; - -		case 'h': -		default: -			printf(main_help); -			exit(0); -		} -	} - -	argc -= optind; -	argv += optind; -	optind = 0; - -	if (bnep_init()) -		return -1; - -	/* Check non daemon modes first */ -	switch (mode) { -	case SHOW: -		do_show(); -		return 0; - -	case KILL: -		do_kill(dst); -		return 0; - -	case NONE: -		printf(main_help); -		return 0; -	} - -	/* Initialize signals */ -	memset(&sa, 0, sizeof(sa)); -	sa.sa_flags   = SA_NOCLDSTOP; -	sa.sa_handler = SIG_IGN; -	sigaction(SIGCHLD, &sa, NULL); -	sigaction(SIGPIPE, &sa, NULL); - -	sa.sa_handler = sig_hup; -	sigaction(SIGHUP, &sa, NULL); - -	sa.sa_handler = sig_term; -	sigaction(SIGTERM, &sa, NULL); -	sigaction(SIGINT,  &sa, NULL); - -	if (detach && daemon(0, 0)) { -		perror("Can't start daemon"); -		exit(1); -	} - -	openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); -	syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION); - -	if (src) { -		src_dev = hci_devid(src); -		if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { -			syslog(LOG_ERR, "Invalid source. %s(%d)", -						strerror(errno), errno); -			return -1; -		} -	} - -	if (pidfile && write_pidfile()) -		return -1; - -	if (dst) { -		/* Disable cache invalidation */ -		use_cache = 0; - -		strncpy(cache.dst, dst, sizeof(cache.dst) - 1); -		str2ba(dst, &cache.bdaddr); -		cache.valid = 1; -		free(dst); -	} - -	switch (mode) { -	case CONNECT: -		do_connect(); -		break; - -	case LISTEN: -		do_listen(); -		break; -	} - -	if (pidfile) -		unlink(pidfile); - -	return 0; -} diff --git a/pand/pand.1 b/pand/pand.1 deleted file mode 100644 index 4603b8bf..00000000 --- a/pand/pand.1 +++ /dev/null @@ -1,77 +0,0 @@ -.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.29. -.TH BlueZ "1" "February 2003" "PAN daemon" "User Commands" -.SH NAME -pand \- BlueZ Bluetooth PAN daemon -.SH DESCRIPTION -The pand PAN daemon allows your computer to connect to ethernet -networks using Bluetooth. -.SH SYNPOSIS -pand <options> -.SH OPTIONS -.TP -\fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR -Show active PAN connections -.TP -\fB\-\-listen\fR \fB\-s\fR -Listen for PAN connections -.TP -\fB\-\-connect\fR \fB\-c\fR <bdaddr> -Create PAN connection -.TP -\fB\-\-search\fR \fB\-Q[duration]\fR -Search and connect -.TP -\fB\-\-kill\fR \fB\-k\fR <bdaddr> -Kill PAN connection -.TP -\fB\-\-killall\fR \fB\-K\fR -Kill all PAN connections -.TP -\fB\-\-role\fR \fB\-r\fR <role> -Local PAN role (PANU, NAP, GN) -.TP -\fB\-\-service\fR \fB\-d\fR <role> -Remote PAN service (PANU, NAP, GN) -.TP -\fB\-\-ethernet\fR \fB\-e\fR <name> -Network interface name -.TP -\fB\-\-device\fR \fB\-i\fR <bdaddr> -Source bdaddr -.TP -\fB\-\-nosdp\fR \fB\-D\fR -Disable SDP -.TP -\fB\-\-encrypt\fR \fB\-E\fR -Enable encryption -.TP -\fB\-\-secure\fR \fB\-S\fR -Secure connection -.TP -\fB\-\-master\fR \fB\-M\fR -Become the master of a piconet -.TP -\fB\-\-nodetach\fR \fB\-n\fR -Do not become a daemon -.TP -\fB\-\-persist\fR \fB\-p[interval]\fR -Persist mode -.TP -\fB\-\-cache\fR \fB\-C[valid]\fR -Cache addresses -.TP -\fB\-\-pidfile\fR \fB\-P <pidfile>\fR -Create PID file -.TP -\fB\-\-devup\fR \fB\-u <script>\fR -Script to run when interface comes up -.TP -\fB\-\-devdown\fR \fB\-o <script>\fR -Script to run when interface comes down -.TP -\fB\-\-autozap\fR \fB\-z\fR -Disconnect automatically on exit - -.SH SCRIPTS -The devup/devdown script will be called with bluetooth device as first argument -and bluetooth destination address as second argument. diff --git a/pand/pand.h b/pand/pand.h deleted file mode 100644 index 3e91f82d..00000000 --- a/pand/pand.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> - *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -/* BNEP functions */ -int bnep_init(void); -int bnep_cleanup(void); - -int bnep_str2svc(char *svc, uint16_t *uuid); -char *bnep_svc2str(uint16_t uuid); - -int bnep_show_connections(void); -int bnep_kill_connection(uint8_t *dst); -int bnep_kill_all_connections(void); - -int bnep_accept_connection(int sk, uint16_t role, char *dev); -int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev); - -/* SDP functions */ -int  bnep_sdp_register(bdaddr_t *device, uint16_t role); -void bnep_sdp_unregister(void); -int  bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service); diff --git a/pand/sdp.c b/pand/sdp.c deleted file mode 100644 index 05e2e182..00000000 --- a/pand/sdp.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> - *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  This program is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with this program; if not, write to the Free Software - *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/sdp.h> -#include <bluetooth/sdp_lib.h> -#include <bluetooth/bnep.h> - -#include "pand.h" - -static sdp_record_t  *record; -static sdp_session_t *session; - -void bnep_sdp_unregister(void)  -{ -	if (record && sdp_record_unregister(session, record)) -		syslog(LOG_ERR, "Service record unregistration failed."); - -	sdp_close(session); -} - -static void add_lang_attr(sdp_record_t *r) -{ -	sdp_lang_attr_t base_lang; -	sdp_list_t *langs = 0; - -	/* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ -	base_lang.code_ISO639 = (0x65 << 8) | 0x6e; -	base_lang.encoding = 106; -	base_lang.base_offset = SDP_PRIMARY_LANG_BASE; -	langs = sdp_list_append(0, &base_lang); -	sdp_set_lang_attr(r, langs); -	sdp_list_free(langs, 0); -} - -int bnep_sdp_register(bdaddr_t *device, uint16_t role) -{ -	sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; -	uuid_t root_uuid, pan, l2cap, bnep; -	sdp_profile_desc_t profile[1]; -	sdp_list_t *proto[2]; -	sdp_data_t *v, *p; -	uint16_t psm = 15, version = 0x0100; -	uint16_t security_desc = 0; -	uint16_t net_access_type = 0xfffe; -	uint32_t max_net_access_rate = 0; -	char *name = "BlueZ PAN"; -	char *desc = "BlueZ PAN Service"; -	int status; - -	session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); -	if (!session) { -		syslog(LOG_ERR, "Failed to connect to the local SDP server. %s(%d)", -							strerror(errno), errno); -		return -1; -	} - -	record = sdp_record_alloc(); -	if (!record) { -		syslog(LOG_ERR, "Failed to allocate service record %s(%d)", -							strerror(errno), errno); -		sdp_close(session); -		return -1; -	} - -	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); -	root = sdp_list_append(NULL, &root_uuid); -	sdp_set_browse_groups(record, root); -	sdp_list_free(root, 0); - -	sdp_uuid16_create(&l2cap, L2CAP_UUID); -	proto[0] = sdp_list_append(NULL, &l2cap); -	p = sdp_data_alloc(SDP_UINT16, &psm); -	proto[0] = sdp_list_append(proto[0], p); -	apseq    = sdp_list_append(NULL, proto[0]); - -	sdp_uuid16_create(&bnep, BNEP_UUID); -	proto[1] = sdp_list_append(NULL, &bnep); -	v = sdp_data_alloc(SDP_UINT16, &version); -	proto[1] = sdp_list_append(proto[1], v); - -	/* Supported protocols */ -	{ -		uint16_t ptype[4] = {  -			0x0800,  /* IPv4 */ -			0x0806,  /* ARP */ -		}; -		sdp_data_t *head, *pseq; -		int p; - -		for (p = 0, head = NULL; p < 2; p++) { -			sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); -			if (head) -				sdp_seq_append(head, data); -			else -				head = data; -		} -		pseq = sdp_data_alloc(SDP_SEQ16, head); -		proto[1] = sdp_list_append(proto[1], pseq); -	} - -	apseq = sdp_list_append(apseq, proto[1]); - -	aproto = sdp_list_append(NULL, apseq); -	sdp_set_access_protos(record, aproto); - -	add_lang_attr(record); - -	sdp_list_free(proto[0], NULL); -	sdp_list_free(proto[1], NULL); -	sdp_list_free(apseq, NULL); -	sdp_list_free(aproto, NULL); -	sdp_data_free(p); -	sdp_data_free(v); -	sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security_desc); - -	switch (role) { -	case BNEP_SVC_NAP: -		sdp_uuid16_create(&pan, NAP_SVCLASS_ID); -		svclass = sdp_list_append(NULL, &pan); -		sdp_set_service_classes(record, svclass); - -		sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); -		profile[0].version = 0x0100; -		pfseq = sdp_list_append(NULL, &profile[0]); -		sdp_set_profile_descs(record, pfseq); - -		sdp_set_info_attr(record, "Network Access Point", name, desc); - -		sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &net_access_type); -		sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, SDP_UINT32, &max_net_access_rate); -		break; - -	case BNEP_SVC_GN: -		sdp_uuid16_create(&pan, GN_SVCLASS_ID); -		svclass = sdp_list_append(NULL, &pan); -		sdp_set_service_classes(record, svclass); - -		sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); -		profile[0].version = 0x0100; -		pfseq = sdp_list_append(NULL, &profile[0]); -		sdp_set_profile_descs(record, pfseq); -		 -		sdp_set_info_attr(record, "Group Network Service", name, desc); -		break; - -	case BNEP_SVC_PANU: -		sdp_uuid16_create(&pan, PANU_SVCLASS_ID); -		svclass = sdp_list_append(NULL, &pan); -		sdp_set_service_classes(record, svclass); -		sdp_list_free(svclass, 0); - -		sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); -		profile[0].version = 0x0100; -		pfseq = sdp_list_append(NULL, &profile[0]); -		sdp_set_profile_descs(record, pfseq); -		sdp_list_free(pfseq, 0); - -		sdp_set_info_attr(record, "PAN User", name, desc); -		break; -	} - -	status = sdp_device_record_register(session, device, record, 0); -	if (status) { -		syslog(LOG_ERR, "SDP registration failed."); -		sdp_record_free(record); record = NULL; -		sdp_close(session); -		return -1; -	} - -	return 0; -} - -/* Search for PAN service. - * Returns 1 if service is found and 0 otherwise. */ -int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service) -{ -	sdp_list_t *srch, *rsp = NULL; -	sdp_session_t *s; -	uuid_t svclass; -	int err; - -	switch (service) { -	case BNEP_SVC_PANU: -		sdp_uuid16_create(&svclass, PANU_SVCLASS_ID); -		break; -	case BNEP_SVC_NAP: -		sdp_uuid16_create(&svclass, NAP_SVCLASS_ID); -		break; -	case BNEP_SVC_GN: -		sdp_uuid16_create(&svclass, GN_SVCLASS_ID); -		break; -	} - -	srch = sdp_list_append(NULL, &svclass); - -	s = sdp_connect(src, dst, 0); -	if (!s) { -		syslog(LOG_ERR, "Failed to connect to the SDP server. %s(%d)", -							strerror(errno), errno); -		return 0; -	} - -	err = sdp_service_search_req(s, srch, 1, &rsp); -	sdp_close(s); - -	/* Assume that search is successeful -	 * if at least one record is found */ -	if (!err && sdp_list_len(rsp)) -		return 1; - -	return 0; -}  | 
