9

I am playing around with MQTT CONNECT messages. I have a simple C program which opens a TCP/IP socket towards an Mosquitto broker running on my laptop, sends an MQTT CONNECT message, (normally) receives the 4 byte long CONNACK reply then closes the socket and exits the program.

Currently I do not build my own CONNECT message but use one from a Wireshark capture.

Wireshark Capture Screenshot

It can be exported as a C array, the MQTT part:

char packet_bytes[] = {
  0x10, 0x20, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39, 0x34
};

Using this unmodified array everything works just fine, here is the broker's output:

1486237905: New connection from 192.168.1.2 on port 1883.
1486237905: New client connected from 192.168.1.2 as root.1485890857194 (c1, k60).
1486237905: Sending CONNACK to root.1485890857194 (0, 0)
1486237905: Socket error on client root.1485890857194, disconnecting.

The problems start when I want to modify the Client ID in the message. My simplest attempt is chopping the last character 4 from the end of the ID.

I think this requires three modifications in the actual code.

  1. Deleting the last byte from the array, the 0x34.
  2. Decrementing the the Remaining Length field (2nd byte in the array) in the message. So from 32 to 31, 0x20 --> 0x1F.
  3. Decrementing the number of bytes parameter of the send function. From 34 to 33. (+2 because of the Header Flags and Remaining Length fields)

char packet_bytes[] = {
  0x10, 0x1F, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39
};


if( send(s , packet_bytes , 33, 0) < 0)
{
    puts("Send failed");
    return 1;
}

It does not work, here is the broker's output:

1486239491: New connection from 192.168.1.2 on port 1883.
1486239491: Socket error on client <unknown>, disconnecting.

I know that the Remaining Length field requires special enconding but not under 128.

Remaining Length Table

What did I miss here, what should I modify beside the Remaining Length field?

Helmar
  • 8,450
  • 6
  • 36
  • 84
Bence Kaulics
  • 7,843
  • 8
  • 42
  • 90

1 Answers1

5

I managed to find my mistake. Mistakenly I assumed that the Client ID is a fix field but it is only part of the Payload of the message thus a length-prefix is needed. From the specifications:

The payload of the CONNECT Packet contains one or more length-prefixed fields, whose presence is determined by the flags in the variable header. These fields, if present, MUST appear in the order Client Identifier, Will Topic, Will Message, User Name, Password

So one more byte should be decremented in the message. The correct steps:

  1. Deleting the last byte from the array, the 0x34.
  2. Decrementing the the Remaining Length field (2nd byte in the array) in the message. So from 32 to 31, 0x20 --> 0x1F.
  3. Decrementing the length-prefix byte of the Client ID in the payload. In my case it is the 16th byte (counting from 1) 0x12 ---> 0x11.
  4. Decrementing the number of bytes parameter of the send function. From 34 to 33. (+2 because of the Header Flags and Remaining Length fields)

After this additional step the broker sent back the CONNACK message.

Bence Kaulics
  • 7,843
  • 8
  • 42
  • 90