У меня есть следующая функция проверки пакетов, которая анализирует протоколы транспортного уровня, такие как TCP и UDP. Мне нужно углубиться в пакет и получить протоколы прикладного уровня, такие как HTTP и TLS. Моя текущая теория состоит в том, чтобы реализовать функцию сопоставления с образцом для полезной нагрузки, но это было бы дорого с вычислительной точки зрения. Любые подсказки о том, как действовать?
void inspect_packet(struct rte_mbuf *pkt, unsigned port_id, int i)
{
uint8_t *data = (uint8_t *)(pkt->buf_addr + pkt->data_off);
unsigned int offset = 0;
struct rte_ether_hdr *eth = (struct rte_ether_hdr *)data;
offset += sizeof(struct rte_ether_hdr);
a_counter[i].pkts_counter++;
a_counter[i].bits_counter += pkt->pkt_len;
if (eth->ether_type != htons(RTE_ETHER_TYPE_IPV4) && eth->ether_type != htons(RTE_ETHER_TYPE_IPV6)
&& eth->ether_type != htons(RTE_ETHER_TYPE_ARP))
{
return;
}
if (eth->ether_type == RTE_ETHER_TYPE_ARP)
{
a_counter[i].arp_counter++;
return;
}
struct rte_ipv4_hdr *iph = (struct rte_ipv4_hdr *)(data + offset);
struct rte_ipv6_hdr *iph6 = (struct rte_ipv6_hdr *)(data + offset);
struct rte_tcp_hdr *tcph = NULL;
struct rte_udp_hdr *udph = NULL;
if (eth->ether_type == htons(RTE_ETHER_TYPE_IPV4))
{
offset += 20; //header length
switch (iph->next_proto_id)
{
case PROTOCOL_TCP:
a_counter[i].tcp_counter++;
tcph = (struct rte_tcp_hdr *)(data + offset);
break;
case PROTOCOL_UDP:
a_counter[i].udp_counter++;
udph = (struct rte_udp_hdr *)(data + offset);
break;
default:
break;
}
}
else if (eth->ether_type == htons(RTE_ETHER_TYPE_IPV6))
{
offset += 40; //header length
switch (iph6->proto)
{
case PROTOCOL_TCP:
tcph = (struct rte_tcp_hdr *)(data + offset);
break;
case PROTOCOL_UDP:
udph = (struct rte_udp_hdr *)(data + offset);
break;
}
}
data = nullptr;
}
@JesperJuhl причина, по которой я выбрал dpdk, заключается в том, что я хочу провести анализ трафика на скоростях линии (до 10 Гбит/с), что невозможно с wirehark
Это не значит, что вы не можете использовать его для вдохновения/идей.
@AbhinavGupta на основе объяснения вопроса My current theory is to implement a pattern matching function on the payload but that would be computationally expensive. Any leads on how to proceed?
. Поэтому сначала, пожалуйста, обновите заголовок reflecting the intent
. Что касается сопоставления с образцом, можно использовать regex
как hyperscan library from intel
. В 22.02 DPDK также есть регулярное выражение PMD.
@VipinVarghese эта теория больше похожа на «лучшее предположение о том, как действовать дальше». Я обновлю заголовок, если вы считаете, что сопоставление с образцом - лучший способ ответить на этот вопрос. Пожалуйста, подтвердите, если это так.
@AbhinavGupta Я не следил за вашим последним комментарием, вы действительно хотите need help in sample reference code for using packet parsing using DPDK libraries
. Если да, пожалуйста, обновите заголовок. Иначе я не уследил за вашим вопросом can you explain what is that you are looking for
. Кстати, я уже использовал гиперскан для разбора и сравнения пакетов | полезной нагрузки при использовании DPDK. Таким образом, предыдущий комментарий не является best guess
.
@VipinVarghese я ищу способ получить данные прикладного уровня (независимо от того, принадлежит ли пакет HTTP, HTTPS, QUIC и т. д.). Получить данные транспортного уровня легко через заголовки (rte_tcp_hdr и rte_udp_hdr). Но мне нужно получить доступ к полезной нагрузке, чтобы получить данные прикладного уровня. Мы можем подробно обсудить это по почте, если это сработает для вас. Я могу поделиться своим текущим рабочим кодом для лучшего понимания моей проблемы. Я опубликую свой вывод здесь, как только найду решение.
@VipinVarghese, можете ли вы поделиться примером кода, как реализовать гиперсканирование?
@AbhinavGupta Теперь я могу быть доступен, Google Meet, Skype Zoom работает для меня.
[на основе живого обсуждения]
Вопрос: Моя текущая теория состоит в том, чтобы реализовать функцию сопоставления с образцом для полезной нагрузки, но это было бы дорого с точки зрения вычислений. Любые подсказки о том, как действовать?
Ответ: Логика приложения для идентификации протоколов и приложения будет иметь фиксированную стоимость. Таким образом, первая цель состоит в том, чтобы этапы предварительной и последующей обработки приводили к минимальным потерям. Они также варьируются от физического сетевого адаптера до виртуального сетевого адаптера.
Итак, позвольте мне объяснить несколько советов, которым я следую для достижения наилучшего результата.
(Физическая разгрузка сетевой карты)
rte_eth_dev_set_ptypes
позволяет rte_mbuf передавать информацию о ptype из дескриптора.Таким образом, хорошо настроенные (BIOS и командная строка ядра) ядра теперь смогут получать RX-пакеты DMA с достаточным количеством метаданных. Это позволит уменьшить дополнительные накладные расходы на анализ каждого пакета, поскольку выбранный трафик отправляется в определенную очередь, а PTYPE в очереди RSS помогает выполнять предварительную фильтрацию.
Затем разделите разработку на несколько этапов
если присутствуют потери пакетов, это означает, что трафик одной очереди необходимо либо распределить по нескольким очередям (больше очередей RX) в случае модели выполнения до завершения. В противном случае изучите возможность использования eventdev or flow distributor
с несколькими потоками lcore в качестве парсеров приложений.
Примечание:
using rte_flow to carry 32bit marker
.Приведенная выше логика верна для режима IDS. В случае режима IPS
иногда могут возникать требования для обеспечения порядка пакетов. Так что используйте atomic eventdev для всех трех этапов.
Может быть, взгляните на то, что делают такие инструменты, как wireshark (это открытый исходный код, поэтому вы можете проверить код, а также анализ протоколов мирового класса)?