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; -} |