Почему лидирующие 4-байтовые данные отсутствуют при отправке необработанных байтовых данных на устройство крана?
Я изучаю устройство Tun/ Tap в Linux, есть небольшая проблема, которую я не могу понять, вот что я сделал:
1: создать устройство "tap", имя "tap1", получить дескриптор файла: tapfd
2: подготовить достаточно большой массив, например: buf [2048]
3: записать кадр Ethernet в buf, внутри него находится пакет ip(udp), всего 74 байта. сделал это неуклюже, как:
// 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 (), отправьте вышеупомянутые [74 байта] в [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
итого = 56 байт + 12 байт mac src&dst + 2 байт eth type = 70 байт, так где же ведущие 4 байта?
Во-первых, я думал, что старшие 4 байта должны быть "преамбула и начало разделителя кадра", но, как говорит вики, преамбула была 7 октетов, а начало разделителя кадра было 1 октет.
6: затем я вставляю 4 байта в свой [buf], теперь 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 сказал мне, что это допустимый фрейм Ethernet!
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 ответ
Это похоже на неправильную настройку флагов при открытии вашего устройства крана.
Документация для драйвера ядра 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 байта.