Как nfq_get_payload структурирует возвращаемые данные?

Прежде всего, я пытаюсь получить адрес источника и порт назначения из полезной нагрузки полезной нагрузки очереди Netfilter (полезная нагрузка извлекается с помощью функции nfq_get_payload). Следующий вопрос задает то же самое и получает правильный ответ:

Как извлечь номер порта источника и получателя из пакета в очереди iptables

К сожалению, нет объяснения, почему добавление 20 и 22 к адресу приводит вас в нужное место для чтения информации. Я предполагаю, что это из-за структуры данных (очевидно), но если есть определенная структура, то что это?

В документации явно не объясняется, как форматируются данные, только то, что «тип данных, извлекаемых этой функцией, будет зависеть от режима, установленного с помощью функции nfq_set_mode()», но тогда документы для set_mode ничего не упоминают о данных типа и источник ничего сразу не раскрывает.

Я чувствую, что это должно быть что-то очень важное для общих структур сетевого программирования, которые я упускаю или не понимаю.

Примечания: функция nfq_get_payload: http://www.netfilter.org/projects/libnetfilter_queue/doxygen/group__Parsing.html#gaf79628558c94630e25dbfcbde09f2933


person Community    schedule 03.04.2013    source источник


Ответы (1)


Мне удалось это выяснить, и я оставлю это здесь, чтобы другие могли найти.

Полезная нагрузка начинается со структуры iphdr. Структура iphdr имеет поле протокола, например, tcp, если это tcp, то данные после структуры iphdr являются структурой tcphdr, если это udp, то для этого есть другая структура hdr и т. д. для icmp и т. д.

Для доступа к порту предположим, что q_data является указателем на структуру nfq_data:

unsigned char *data;
nfq_get_payload(q_data, (unsigned char**)&data);
struct iphdr * ip_info = (struct iphdr *)data;
if(ip_info->protocol == IPPROTO_TCP) {
    struct tcphdr * tcp_info = (struct tcphdr*)(data + sizeof(*ip_info));
    unsigned short dest_port = ntohs(tcp_info->dest);
} else if(ip_info->protocol == IPPROTO_UDP) {
    //etc etc
}
person Community    schedule 03.04.2013
comment
Разве это не должно быть: struct iphdr * ip_info = (struct iphdr *) (data + sizeof(struct ethhdr)); ? Почему бы вам не пропустить struct ethhdr, чтобы перейти к `struct iphdr'? - person elmazzun; 14.07.2015