| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <errno.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include "parser.h"
- static char *opcode2str(uint8_t opcode)
- {
- switch (opcode & 0x7f) {
- case 0x00:
- return "Connect";
- case 0x01:
- return "Disconnect";
- case 0x02:
- return "Put";
- case 0x03:
- return "Get";
- case 0x04:
- return "Reserved";
- case 0x05:
- return "SetPath";
- case 0x06:
- return "Action";
- case 0x07:
- return "Session";
- case 0x7f:
- return "Abort";
- case 0x10:
- return "Continue";
- case 0x20:
- return "Success";
- case 0x21:
- return "Created";
- case 0x22:
- return "Accepted";
- case 0x23:
- return "Non-authoritative information";
- case 0x24:
- return "No content";
- case 0x25:
- return "Reset content";
- case 0x26:
- return "Partial content";
- case 0x30:
- return "Multiple choices";
- case 0x31:
- return "Moved permanently";
- case 0x32:
- return "Moved temporarily";
- case 0x33:
- return "See other";
- case 0x34:
- return "Not modified";
- case 0x35:
- return "Use Proxy";
- case 0x40:
- return "Bad request";
- case 0x41:
- return "Unauthorized";
- case 0x42:
- return "Payment required";
- case 0x43:
- return "Forbidden";
- case 0x44:
- return "Not found";
- case 0x45:
- return "Method not allowed";
- case 0x46:
- return "Not acceptable";
- case 0x47:
- return "Proxy authentication required";
- case 0x48:
- return "Request timeout";
- case 0x49:
- return "Conflict";
- case 0x4a:
- return "Gone";
- case 0x4b:
- return "Length required";
- case 0x4c:
- return "Precondition failed";
- case 0x4d:
- return "Requested entity too large";
- case 0x4e:
- return "Requested URL too large";
- case 0x4f:
- return "Unsupported media type";
- case 0x50:
- return "Internal server error";
- case 0x51:
- return "Not implemented";
- case 0x52:
- return "Bad gateway";
- case 0x53:
- return "Service unavailable";
- case 0x54:
- return "Gateway timeout";
- case 0x55:
- return "HTTP version not supported";
- case 0x60:
- return "Database full";
- case 0x61:
- return "Database locked";
- default:
- return "Unknown";
- }
- }
- static char *hi2str(uint8_t hi)
- {
- switch (hi & 0x3f) {
- case 0x00:
- return "Count";
- case 0x01:
- return "Name";
- case 0x02:
- return "Type";
- case 0x03:
- return "Length";
- case 0x04:
- return "Time";
- case 0x05:
- return "Description";
- case 0x06:
- return "Target";
- case 0x07:
- return "HTTP";
- case 0x08:
- return "Body";
- case 0x09:
- return "End of Body";
- case 0x0a:
- return "Who";
- case 0x0b:
- return "Connection ID";
- case 0x0c:
- return "App. Parameters";
- case 0x0d:
- return "Auth. Challenge";
- case 0x0e:
- return "Auth. Response";
- case 0x0f:
- return "Creator ID";
- case 0x10:
- return "WAN UUID";
- case 0x11:
- return "Object Class";
- case 0x12:
- return "Session Parameters";
- case 0x13:
- return "Session Sequence Number";
- case 0x14:
- return "Action ID";
- case 0x15:
- return "DestName";
- case 0x16:
- return "Permission";
- case 0x17:
- return "Single Response Mode";
- case 0x18:
- return "Single Response Mode Parameters";
- default:
- return "Unknown";
- }
- }
- static void parse_headers(int level, struct frame *frm)
- {
- uint8_t hi, hv8;
- uint16_t len;
- uint32_t hv32;
- while (frm->len > 0) {
- hi = p_get_u8(frm);
- p_indent(level, frm);
- printf("%s (0x%02x)", hi2str(hi), hi);
- switch (hi & 0xc0) {
- case 0x00: /* Unicode */
- if (frm->len < 2) {
- printf("\n");
- return;
- }
- len = p_get_u16(frm) - 3;
- printf(" = Unicode length %d\n", len);
- if (frm->len < len)
- return;
- raw_ndump(level, frm, len);
- frm->ptr += len;
- frm->len -= len;
- break;
- case 0x40: /* Byte sequence */
- if (frm->len < 2) {
- printf("\n");
- return;
- }
- len = p_get_u16(frm) - 3;
- printf(" = Sequence length %d\n", len);
- if (frm->len < len)
- return;
- raw_ndump(level, frm, len);
- frm->ptr += len;
- frm->len -= len;
- break;
- case 0x80: /* One byte */
- if (frm->len < 1) {
- printf("\n");
- return;
- }
- hv8 = p_get_u8(frm);
- printf(" = %d\n", hv8);
- break;
- case 0xc0: /* Four bytes */
- if (frm->len < 4) {
- printf("\n");
- return;
- }
- hv32 = p_get_u32(frm);
- printf(" = %u\n", hv32);
- break;
- }
- }
- }
- void obex_dump(int level, struct frame *frm)
- {
- uint8_t last_opcode, opcode, status;
- uint8_t version, flags, constants;
- uint16_t length, pktlen;
- frm = add_frame(frm);
- while (frm->len > 2) {
- opcode = p_get_u8(frm);
- length = p_get_u16(frm);
- status = opcode & 0x7f;
- if ((int) frm->len < length - 3) {
- frm->ptr -= 3;
- frm->len += 3;
- return;
- }
- p_indent(level, frm);
- last_opcode = get_opcode(frm->handle, frm->dlci);
- if (!(opcode & 0x70)) {
- printf("OBEX: %s cmd(%c): len %d",
- opcode2str(opcode),
- opcode & 0x80 ? 'f' : 'c', length);
- set_opcode(frm->handle, frm->dlci, opcode);
- } else {
- printf("OBEX: %s rsp(%c): status %x%02d len %d",
- opcode2str(last_opcode),
- opcode & 0x80 ? 'f' : 'c',
- status >> 4, status & 0xf, length);
- opcode = last_opcode;
- }
- if (get_status(frm->handle, frm->dlci) == 0x10)
- printf(" (continue)");
- set_status(frm->handle, frm->dlci, status);
- if (frm->len == 0) {
- printf("\n");
- break;
- }
- switch (opcode & 0x7f) {
- case 0x00: /* Connect */
- if (frm->len < 4) {
- printf("\n");
- return;
- }
- version = p_get_u8(frm);
- flags = p_get_u8(frm);
- pktlen = p_get_u16(frm);
- printf(" version %d.%d flags %d mtu %d\n",
- version >> 4, version & 0xf, flags, pktlen);
- break;
- case 0x05: /* SetPath */
- if (frm->len < 2) {
- printf("\n");
- return;
- }
- flags = p_get_u8(frm);
- constants = p_get_u8(frm);
- printf(" flags %d constants %d\n", flags, constants);
- break;
- default:
- printf("\n");
- break;
- }
- if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) {
- p_indent(level, frm);
- printf("Status %x%02d = %s\n",
- status >> 4, status & 0xf,
- opcode2str(status));
- }
- parse_headers(level, frm);
- }
- }
|