0

i'm learning the tun/tap device of linux, there is a little problem i cannot figure out here is what i've done:

1: create a tap device, name is "tap1", get the file descriptor: tapfd

2: prepare an array huge enough, like: buf[2048]

3: write a ethernet frame into buf, inside it is an ip(udp) packet, 74bytes total. done it in a clumsy way, like:

    // 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: call write(), send the [74bytes] mentioned above into [tapfd]

    write(fd, buf, 74);

5: use "tcpdump -i tap1 -vv" to check, but the result is as below:

    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, so, where is the leading 4bytes?

first, i thought the leading 4bytes should be "preamble & Start of frame delimiter", but as the wiki says, preamble was 7 octets and Start of frame delimiter was 1 octet.

6: then i insert 4 bytes into my [buf], now the buf is like:

   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)

then check again, this time, tcp dump told me that is a legal ethernet frame!

    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

it works! but why? why the leading 4bytes was missing?(please ignore the bad udp checksum)

1 Answers1

1

This looks like a misconfiguration of the flags when opening your tap device.

The documentation for the Linux tun/tap kernel driver describes the following frame format.

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.

You can find more information here: /usr/src/linux/Documentation/networking/tuntap.rst

Just add IFF_NO_PI to your interface flags and the device driver will not strip away the leading 4 bytes.

jpihl
  • 7,941
  • 3
  • 37
  • 50
Hannes Küttner
  • 908
  • 7
  • 9