如何仅修改 MQTT CONNECT 消息中的客户端 ID?

物联网 MQTT 蚊子
2021-06-25 02:51:54

我在玩 MQTT CONNECT 消息。我有一个简单的 C 程序,它向在我的笔记本电脑上运行的 Mosquitto 代理打开 TCP/IP 套接字,发送 MQTT CONNECT 消息,(通常)接收 4 字节长的 CONNACK 回复,然后关闭套接字并退出程序。

目前我没有构建自己的 CONNECT 消息,而是使用来自 Wireshark 捕获的消息。

Wireshark 捕获屏幕截图

可以导出为C数组,MQTT部分:

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

使用这个未修改的数组一切正常,这是代理的输出:

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.

当我想修改消息中的客户端 ID 时,问题就开始了。我最简单的尝试是4从 ID 的末尾切掉最后一个字符

我认为这需要在实际代码中进行三处修改。

  1. 从数组中删除最后一个字节,0x34.
  2. 递减消息中的Remaining Length字段(数组中的第二个字节)。所以从 32 到 31,0x20--> 0x1F
  3. 递减send函数的字节数参数从 34 到 33。(+2 因为Header FlagsRemaining Length字段)

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

它不起作用,这是经纪人的输出:

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

我知道该Remaining Length领域需要特殊的编码,但不能低于 128。

剩余长度表

我在这里错过了什么,我应该在Remaining Length字段旁边修改什么

1个回答

我设法找到了我的错误。我错误地认为客户端 ID 是一个固定字段,但它只是消息有效负载的一部分,因此需要一个长度前缀规格

CONNECT 数据包的有效载荷包含一个或多个长度前缀字段,其存在由可变报头中的标志确定。这些字段,如果存在,必须以客户标识符、遗嘱主题、遗嘱消息、用户名、密码的顺序出现

所以应该在消息中再减少一个字节。正确的步骤:

  1. 从数组中删除最后一个字节 0x34。
  2. 递减消息中的剩余长度字段(数组中的第二个字节)。所以从 32 到 31,0x20 --> 0x1F。
  3. 减少负载中客户端 ID 的长度前缀字节。在我的情况下,它是第 16 个字节(从 1 开始计数)0x12---> 0x11
  4. 递减发送函数的字节数参数。从 34 到 33。(+2 因为 Header Flags 和 Remaining Length 字段)

在这个额外的步骤之后,代理发回了 CONNACK 消息。