Как получить размер MTU (язык с++) ОС:Ubuntu?
Необходимо получить размеры MTU и MSS из пакета Ethernet. Я знаю, что получить MSS можно используя правило:
MSS = MTU — 40 — для IPv4
MSS = MTU — 60 — для IPv6
Ответы (1 шт):
Необходимо получить размеры MTU и MSS из пакета Ethernet
Фраза несколько бессмысленная т.к. в «пакетах Ethernet» нет ни какой информации ни о MTU, ни о MSS.
Есть MTU. Это свойство сети, физической или виртуальной и конкретного интерфейса ведущего в эту сеть. В Linux запросить его можно с помощью
ioctl/SIOCGIFMTU(см.man 7 netdevices):int fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP); struct ifreq req; strcpy(req.ifr_name, "eth0"); ioctl (fd, SIOCGIFMTU, &req); int mtu = req.ifr_mtu;Список/Имя конкретного интерфейса можно определить многими способами, например, с помощью
ioctlSIOCGIFCONFна том же сокете,/proc/net/devилиgetifaddrs().Есть также т.н. path MTU — это минимальное значение MTU на пути между двумя конкретными узлами. В Linux для TCP-сокетов по умолчанию он устанавливается автомагически, если очередной пакет отправленный в сеть оказывается слишком большим и не может пройти через неё. Текущее значение для конкретного сокета можно получить с помощью
getsockopt/IP_MTU:int mtu = 0; socklen_t sz = sizeof(mtu); getsockopt(fd, IPPROTO_IP, IP_MTU, &mtu, sz);Определить непосредственно его можно с помощью Path MTU Discovery. Если кратко, то просто отправлять заведомо большой пакет (icmp или udp) с флагом
DF(Don't Fragment) на удалённый хост. Ответ от первого маршрутизатора, MTU сети которого будет превышен вернёт свой MTU в ICMP-сообщение Destination Unreachable/Fragmentation Needed, затем попытка повторяется пока не будет достигнут достаточно маленький размер, который дойдёт до назначения. Так, например, работаетtracepath.MSS — это параметр протокола tcp, по факту это просто значение, которое декларируют хосты в момент установки соединения. Это просто заявление конкретного хоста (локального или удалённого), что сегмент больше данного размера он не сможет принять или обработать. Собственно с MTU он связан условно, хотя на большинстве систем, значение, которое будет сообщено удалённому хосту по умолчанию вычисляется на основе MTU, но это не строгое правило. Запросить для конкретного соединения это значение можно с помощью
getsockopt/TCP_MAXSEG:int mss = 0; socklen_t sz = sizeof(mss); getsockopt(fd, IPPROTO_IP, TCP_MAXSEG, &mss, sz);