void rfcomm_dump(int level, struct frame *frm)
{
	uint8_t hdr_size, ctr_type;
	short_frame_head *short_head_p = (void *) frm->ptr;
	long_frame_head head;

	if (short_head_p->length.ea == EA) {
		head.addr = short_head_p->addr;
		head.control = short_head_p->control;
		head.length.bits.len = short_head_p->length.len;
		hdr_size = sizeof(short_frame_head);
	} else {
		head = *(long_frame_head *) frm->ptr;
		head.length.val = btohs(head.length.val);
		hdr_size = sizeof(long_frame_head);
	}

	frm->ptr += hdr_size;
	frm->len -= hdr_size;

	ctr_type = CLR_PF(head.control);

	if (ctr_type == UIH) {
		uih_frame(level, frm, &head);
	} else {
		p_indent(level, frm); 
		printf("RFCOMM(s): ");

		switch (ctr_type) {
		case SABM:
			printf("SABM: ");
			break;
		case UA:
			printf("UA: ");
			break;
		case DM:
			printf("DM: ");
			break;
		case DISC:
			printf("DISC: ");
			del_frame(frm->handle, GET_DLCI(head.addr));
			break;
		default:
			printf("ERR: ");
		}
		print_rfcomm_hdr(&head, frm->ptr, frm->len);
		printf("\n");
	}
}
Exemplo n.º 2
0
void rfcomm_packet(const struct l2cap_frame *frame)
{
	uint8_t ctype, length, ex_length, indent = 1;
	const char *frame_str, *frame_color;
	struct l2cap_frame *l2cap_frame, tmp_frame;
	struct rfcomm_frame rfcomm_frame;
	struct rfcomm_lhdr hdr;
	const struct rfcomm_data *rfcomm_data = NULL;
	int i;

	l2cap_frame_pull(&rfcomm_frame.l2cap_frame, frame, 0);

	l2cap_frame = &rfcomm_frame.l2cap_frame;

	if (frame->size < 4)
		goto fail;

	if (!l2cap_frame_get_u8(l2cap_frame, &hdr.address) ||
			!l2cap_frame_get_u8(l2cap_frame, &hdr.control) ||
			!l2cap_frame_get_u8(l2cap_frame, &length))
		goto fail;

	/* length maybe 1 or 2 octets */
	if (RFCOMM_TEST_EA(length))
		hdr.length = (uint16_t) GET_LEN8(length);
	else {
		if (!l2cap_frame_get_u8(l2cap_frame, &ex_length))
			goto fail;
		hdr.length = ((uint16_t)length << 8) | ex_length;
		hdr.length = GET_LEN16(hdr.length);
	}

	l2cap_frame_pull(&tmp_frame, l2cap_frame, l2cap_frame->size-1);

	if(!l2cap_frame_get_u8(&tmp_frame, &hdr.fcs))
		goto fail;

	/* Decoding frame type */
	ctype = RFCOMM_GET_TYPE(hdr.control);

	for (i = 0; rfcomm_table[i].str; i++) {
		if (rfcomm_table[i].frame == ctype) {
			rfcomm_data = &rfcomm_table[i];
			break;
		}
	}

	if (rfcomm_data) {
		if (frame->in)
			frame_color = COLOR_MAGENTA;
		else
			frame_color = COLOR_BLUE;
		frame_str = rfcomm_data->str;
	} else {
		frame_color = COLOR_WHITE_BG;
		frame_str = "Unknown";
	}

	if (!rfcomm_data) {
		packet_hexdump(frame->data, frame->size);
		return;
	}

	print_indent(6, frame_color, "RFCOMM: ", frame_str, COLOR_OFF,
						"(0x%2.2x)", ctype);

	rfcomm_frame.hdr = hdr;
	print_rfcomm_hdr(&rfcomm_frame, indent);

	/* UIH frame */
	if (ctype == 0xef)
		if (!uih_frame(&rfcomm_frame, indent))
			goto fail;

	return;

fail:
	print_text(COLOR_ERROR, "Frame too short");
	packet_hexdump(frame->data, frame->size);
	return;
}