为什么在将原始字节数据发送到tap设备时缺少前导4字节数据?

时间:2017-04-17 10:26:07

标签: linux network-programming tun-tap

我正在学习linux的tun / tap设备,有一点我无法弄清楚的问题     这就是我所做的:

1:创建一个点击设备,名称为“tap1”,获取文件描述符:tapfd

2:准备一个足够大的数组,如:buf [2048]

3:将一个以太网帧写入buf,其中是一个ip(udp)数据包,总共74bytes。以笨拙的方式完成,如:

    // mac dst
    buf[0] = 0xbb;
    buf[1] = 0xaa;
    buf[2] = 0xbb;
    ...
    // mac src
    buf[6] = 0xaa;
    buf[7] = 0xbb;
    ...
    // eth type
    ...
    // ip ver & ip hdr_len
    ...
    ...
    ...
    // data offset=42 length=32
    buf[42] = 0x61;
    ...
    buf[73] = 0x61

4:调用write(),将上面提到的[74bytes]发送到[tapfd]

    write(fd, buf, 74);

5:使用“tcpdump -i tap1 -vv”进行检查,但结果如下:

    18:06:40.466971 aa:bb:08:00:45:00 (oui Unknown) Unknown SSAP 0x18 > bb:aa:aa:bb:aa:bb (oui Unknown) Unknown DSAP 0x78 Information, send seq 0, rcv seq 0, Flags [Response], length 56
        0x0000:  7919 0000 4011 ed95 0a00 0001 0a00 0001  y...@...........
        0x0010:  5b25 5f7c 0028 1ae4 6161 6161 6161 6161  [%_|.(..aaaaaaaa
        0x0020:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa
        0x0030:  6161 6161 6161 6161                      aaaaaaaa

total = 56bytes + 12bytes mac src& dst + 2bytes eth type = 70 bytes,那么,前导4bytes在哪里?

首先,我认为领先的4字节应该是“前导码和帧开始分隔符”,但正如维基所说,前导码是7个八位字节,帧起始分隔符是1个八位字节。

6:然后我在我的[buf]中插入4个字节,现在buf就像:

   buf[0] = 0xab;
   buf[1] = 0xab;
   buf[2] = 0xab;
   buf[3] = 0xcc;
   buf = buf + 4;
   { buf[0] ~ buf[73] just as before }


then retry to send 78 bytes to fd

    write(fd, buf, 78)

然后再次检查,这次,tcp dump告诉我这是一个合法的以太网帧!

    18:13:57.676562 IP (tos 0x0, ttl 64, id 31001, offset 0, flags [none], proto UDP (17), length 60, bad cksum ed95 (->ed96)!)
        localhost.23333 > localhost.24444: [bad udp cksum 0x1ae4 -> 0x1ae5!] UDP, length 32

它有效!但为什么?为什么领先的4字节缺失?(请忽略坏的udp校验和)

1 个答案:

答案 0 :(得分:0)

这看起来像打开点按设备时标记配置错误。

Linux tun / tap内核驱动程序的文档描述了以下帧格式。

3.2 Frame format:
    If flag IFF_NO_PI is not set each frame format is: 
    Flags [2 bytes]
    Proto [2 bytes]
    Raw protocol(IP, IPv6, etc) frame.

您可以在此处找到更多信息:/usr/src/linux/Documentation/networking/tuntap.txt

只需将IFF_NO_PI添加到接口标志中,设备驱动程序就不会删除前4个字节。