gpt4 book ai didi

linux - PACKET_MMAP 数据偏移量

转载 作者:IT王子 更新时间:2023-10-29 00:31:57 25 4
gpt4 key购买 nike

我正在编写使用 PACKET_TX_RING 环发送 UDP 数据包的代码,但我不理解此处描述的示例代码: http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap#Kernel_Patch

/usr/src/linux/Documentation/networking/packet_mmap.txt说框架结构是这样的:

/* 框架结构:

  • 开始。框架必须与 TPACKET_ALIGNMENT=16 对齐
  • 构造 tpacket_hdr
  • 填充到 TPACKET_ALIGNMENT=16
  • 结构 sockaddr_ll
  • 间隙,选择为使数据包数据 (Start+tp_net) 对齐 TPACKET_ALIGNMENT=16
  • Start+tp_mac: [可选的 MAC 头]
  • Start+tp_net:数据包数据,对齐到 TPACKET_ALIGNMENT=16。
  • 填充以对齐 TPACKET_ALIGNMENT=16

    */

如果数据从 Start + tp_net 开始,那么为什么示例中的代码减去 sizeof(struct sockaddr_ll) 而不是求和,这是行:

/* get data offset */
data_offset = TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
printf("data offset = %d bytes\n", data_offset);

计算出包数据指针后,复制数据:

  // fill data
off = ((void *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll));
memcpy(off, pkt, pktlen);

在我看来这像是数据损坏,套接字地址和可选的 mac 地址将被要传输的数据覆盖。就我而言,如果我使用此代码,UDP 数据包 header 将被覆盖,是否正确?

提前致谢

最佳答案

对不起,我来晚了。我遇到了同样的问题,不幸的是使用 PACKET_TX_RING 没有很好的记录。但幸运的是,使用链接的示例程序仍然很容易理解。

首先,您需要 tshark(或 wireshark)和您发布的链接中的 packet_mm 源。示例源用 0 到 150 填充缓冲区,然后将其直接发送到给定设备。使用 tshark 我们将读出发送的内容。

在一个 shell 中运行 tshark(点击环回设备):

$ tshark -V -i lo

并在另一个 shell 中运行 packet_mm:

$ packet_mm lo

查看一帧:

Frame 1 (150 bytes on wire, 150 bytes captured)
Arrival Time: Nov 12, 2011 13:07:02.636424000
[Time delta from previous captured frame: 0.000005000 seconds] [Time delta from previous displayed frame: 0.000005000 seconds]
[Time since reference or first frame: 337.280499000 seconds]
Frame Number: 1001
Frame Length: 150 bytes
Capture Length: 150 bytes
[Frame is marked: False]
[Protocols in frame: eth:data]
Ethernet II, Src: 06:07:08:09:0a:0b (06:07:08:09:0a:0b), Dst: 3com_03:04:05 (00:01:02:03:04:05)
Destination: 3com_03:04:05 (00:01:02:03:04:05)
Address: 3com_03:04:05 (00:01:02:03:04:05)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: 06:07:08:09:0a:0b (06:07:08:09:0a:0b)
Address: 06:07:08:09:0a:0b (06:07:08:09:0a:0b)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
Type: Unknown (0x0c0d)
Data (136 bytes)

0000 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d ................
0010 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d .. !"#$%&'()*+,-
0020 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d ./0123456789:;<=
0030 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d >?@ABCDEFGHIJKLM
0040 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d NOPQRSTUVWXYZ[\]
0050 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d ^_`abcdefghijklm
0060 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d nopqrstuvwxyz{|}
0070 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d ~...............
0080 8e 8f 90 91 92 93 94 95 ........
Data: 0E0F101112131415161718191A1B1C1D1E1F202122232425...
[Length: 136]

目标 MAC 为 00:01:02:03:04:05,源 MAC 为 06:07:08:09:0a:0b。数据以 0x0e (14) 开始(紧跟在以太网报头之后)。

因此示例程序的数据偏移量是要发送的(以太网)数据包的开始。

所以这确实是填充发送缓冲区的正确方法(确保 pktlen 不大于您的帧大小):

// fill data
off = ((uint8_t *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll));
memcpy(off, pkt, pktlen);

并且不会覆盖任何数据。但是您必须自己提供以太网、IP 和 UDP header 。

编辑:对于 TX_Ring,帧结构似乎是:

  • 开始。框架必须与 TPACKET_ALIGNMENT=16 对齐
  • 结构 tpacket_hdr(大小 = 32 字节)
  • 填充到 TPACKET_ALIGNMENT=16(因此有效填充大小为 0)
  • 分组数据
  • 填充对齐到 TPACKET_ALIGNMENT=16(所以下一帧是 16 位对齐)

关于linux - PACKET_MMAP 数据偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7768844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com