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