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

📄 l2cap.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *  Bluetooth packet analyzer - L2CAP parser * *  Copyright (C) 2000-2002  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2003-2005  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * *  $Id: l2cap.c,v 1.45 2005/05/15 20:28:18 holtmann Exp $ */#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/l2cap.h>#include "parser.h"#include "sdp.h"typedef struct {	uint16_t handle;	struct frame frm;} handle_info;#define HANDLE_TABLE_SIZE 10static handle_info handle_table[HANDLE_TABLE_SIZE];typedef struct {	uint16_t handle;	uint16_t cid;	uint16_t psm;	uint16_t num;	uint8_t mode;} cid_info;#define CID_TABLE_SIZE 20static cid_info cid_table[2][CID_TABLE_SIZE];#define SCID cid_table[0]#define DCID cid_table[1]static struct frame *add_handle(uint16_t handle){	register handle_info *t = handle_table;	register int i;	for (i = 0; i < HANDLE_TABLE_SIZE; i++)		if (!t[i].handle) {			t[i].handle = handle;			return &t[i].frm;		}	return NULL;}static struct frame *get_frame(uint16_t handle){	register handle_info *t = handle_table;	register int i;	for (i = 0; i < HANDLE_TABLE_SIZE; i++)		if (t[i].handle == handle)			return &t[i].frm;	return add_handle(handle);}static void add_cid(int in, uint16_t handle, uint16_t cid, uint16_t psm){	register cid_info *table = cid_table[in];	register int i, pos = -1;	uint16_t num = 1;	for (i = 0; i < CID_TABLE_SIZE; i++) {		if ((pos < 0 && !table[i].cid) || table[i].cid == cid)			pos = i;		if (table[i].psm == psm)			num++;	}	if (pos >= 0) {		table[pos].handle = handle;		table[pos].cid    = cid;		table[pos].psm    = psm;		table[pos].num    = num;		table[pos].mode   = 0;	}}static void del_cid(int in, uint16_t dcid, uint16_t scid){	register int t, i;	uint16_t cid[2];	if (!in) {		cid[0] = dcid;		cid[1] = scid;	} else {		cid[0] = scid;		cid[1] = dcid;	}	for (t = 0; t < 2; t++) {		for (i = 0; i < CID_TABLE_SIZE; i++)			if (cid_table[t][i].cid == cid[t]) {				cid_table[t][i].handle = 0;				cid_table[t][i].cid    = 0;				cid_table[t][i].psm    = 0;				cid_table[t][i].num    = 0;				cid_table[t][i].mode   = 0;				break;			}	}}static void del_handle(uint16_t handle){	register int t, i;	for (t = 0; t < 2; t++) {		for (i = 0; i < CID_TABLE_SIZE; i++)			if (cid_table[t][i].handle == handle) {				cid_table[t][i].handle = 0;				cid_table[t][i].cid    = 0;				cid_table[t][i].psm    = 0;				cid_table[t][i].num    = 0;				cid_table[t][i].mode   = 0;				break;			}	}}static uint16_t get_psm(int in, uint16_t cid){	register cid_info *table = cid_table[in];	register int i;	for (i = 0; i < CID_TABLE_SIZE; i++)		if (table[i].cid == cid)			return table[i].psm;	return parser.defpsm;}static uint16_t get_num(int in, uint16_t cid){	register cid_info *table = cid_table[in];	register int i;	for (i = 0; i < CID_TABLE_SIZE; i++)		if (table[i].cid == cid)			return table[i].num;	return 0;}static void set_mode(int in, uint16_t cid, uint8_t mode){	register cid_info *table = cid_table[in];	register int i;	for (i = 0; i < CID_TABLE_SIZE; i++)		if (table[i].cid == cid)			table[i].mode = mode;}static uint8_t get_mode(int in, uint16_t cid){	register cid_info *table = cid_table[in];	register int i;	for (i = 0; i < CID_TABLE_SIZE; i++)		if (table[i].cid == cid)			return table[i].mode;	return 0;}static uint32_t get_val(uint8_t *ptr, uint8_t len){	switch (len) {	case 1:		return *ptr;	case 2:		return btohs(bt_get_unaligned((uint16_t *) ptr));	case 4:		return btohl(bt_get_unaligned((uint32_t *) ptr));	}	return 0;}static char *reason2str(uint16_t reason){	switch (reason) {	case 0x0000:		return "Command not understood";	case 0x0001:		return "Signalling MTU exceeded";	case 0x0002:		return "Invalid CID in request";	default:		return "Reserved";	}}static char *connresult2str(uint16_t result){	switch (result) {	case 0x0000:		return "Connection successful";	case 0x0001:		return "Connection pending";	case 0x0002:		return "Connection refused - PSM not supported";	case 0x0003:		return "Connection refused - security block";	case 0x0004:		return "Connection refused - no resources available";	default:		return "Reserved";	}}static char *status2str(uint16_t status){	switch (status) {	case 0x0000:		return "No futher information available";	case 0x0001:		return "Authentication pending";	case 0x0002:		return "Authorization pending";	default:		return "Reserved";	}}static char *confresult2str(uint16_t result){	switch (result) {	case 0x0000:		return "Success";	case 0x0001:		return "Failure - unacceptable parameters";	case 0x0002:		return "Failure - rejected (no reason provided)";	case 0x0003:		return "Failure - unknown options";	default:		return "Reserved";	}}static char *inforesult2str(uint16_t result){	switch (result) {	case 0x0000:		return "Success";	case 0x0001:		return "Not supported";	default:		return "Reserved";	}}static char *type2str(uint8_t type){	switch (type) {	case 0x00:		return "No traffic";	case 0x01:		return "Best effort";	case 0x02:		return "Guaranteed";	default:		return "Reserved";	}}static char *mode2str(uint8_t mode){	switch (mode) {	case 0x00:		return "Basic";	case 0x01:		return "Retransmission";	case 0x02:		return "Flow control";	default:		return "Reserved";	}}static char *sar2str(uint8_t sar){	switch (sar) {	case 0x00:		return "Unsegmented";	case 0x01:		return "Start";	case 0x02:		return "End";	case 0x03:		return "Continuation";	default:		return "Bad SAR";	}}static char *supervisory2str(uint8_t supervisory){	switch (supervisory) {	case 0x00:		return "Receiver Ready (RR)";	case 0x01:		return "Reject (REJ)";	case 0x02:	case 0x03:		return "Reserved Supervisory";	default:		return "Bad Supervisory";	}}static inline void command_rej(int level, struct frame *frm){	l2cap_cmd_rej *h = frm->ptr;	uint16_t reason = btohs(h->reason);	uint32_t cid;	printf("Command rej: reason %d", reason);	switch (reason) {	case 0x0001:		printf(" mtu %d\n", get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 2));		break;	case 0x0002:		cid = get_val(frm->ptr + L2CAP_CMD_REJ_SIZE, 4);		printf(" dcid 0x%4.4x scid 0x%4.4x\n", cid & 0xffff, cid >> 16);		break;	default:		printf("\n");		break;	}	p_indent(level + 1, frm);	printf("%s\n", reason2str(reason));}static inline void conn_req(int level, struct frame *frm){	l2cap_conn_req *h = frm->ptr;	uint16_t psm = btohs(h->psm);	uint16_t scid = btohs(h->scid);	add_cid(frm->in, frm->handle, scid, psm);	if (p_filter(FILT_L2CAP))		return;	printf("Connect req: psm %d scid 0x%4.4x\n", psm, scid);}static inline void conn_rsp(int level, struct frame *frm){	l2cap_conn_rsp *h = frm->ptr;	uint16_t scid = btohs(h->scid);	uint16_t dcid = btohs(h->dcid);	uint16_t result = btohs(h->result);	uint16_t status = btohs(h->status);	uint16_t psm;	switch (h->result) {	case L2CAP_CR_SUCCESS:		if ((psm = get_psm(!frm->in, scid)))			add_cid(frm->in, frm->handle, dcid, psm);		break;	case L2CAP_CR_PEND:		break;	default:		del_cid(frm->in, dcid, scid);		break;	}	if (p_filter(FILT_L2CAP))		return;	printf("Connect rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n",		dcid, scid, result, status);	p_indent(level + 1, frm);	printf("%s", connresult2str(result));	if (result == 0x0001)		printf(" - %s\n", status2str(status));	else		printf("\n");}static void conf_opt(int level, void *ptr, int len, int in, uint16_t cid){	p_indent(level, 0);	while (len > 0) {		l2cap_conf_opt *h = ptr;		uint8_t mode;		ptr += L2CAP_CONF_OPT_SIZE + h->len;		len -= L2CAP_CONF_OPT_SIZE + h->len;		if (h->type & 0x80)			printf("[");		switch (h->type & 0x7f) {		case L2CAP_CONF_MTU:			printf("MTU");			if (h->len > 0)				printf(" %d", get_val(h->val, h->len));			break;		case L2CAP_CONF_FLUSH_TO:			printf("FlushTO");			if (h->len > 0)				printf(" %d", get_val(h->val, h->len));			break;		case L2CAP_CONF_QOS:			printf("QoS");			if (h->len > 0)				printf(" 0x%02x (%s)", *(h->val + 1), type2str(*(h->val + 1)));			break;		case L2CAP_CONF_RFC:			printf("Mode");			if (h->len > 0) {

⌨️ 快捷键说明

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