ЦЕЛЬ: написать фильтр BPF, который разрешает только UDP-пакеты с определенного адреса src, и прикреплять его к UDP-сокету.
ПРОБЛЕМА: если я запускаю программу и пытаюсь отправить udp-пакеты с виртуальной машины с правильным IP-адресом src, я не получаю ни одного из них.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <linux/filter.h>
/* udp and src 192.168.56.101 */
struct sock_filter bpfcode[] = {
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 6, 0, 0x000086dd },
{ 0x15, 0, 5, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 3, 0x00000011 },
{ 0x20, 0, 0, 0x0000001a },
{ 0x15, 0, 1, 0xc0a83865 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000000 },
};
int main(void)
{
struct sock_fprog bpf = {
sizeof(bpfcode) / sizeof(struct sock_filter),
bpfcode
};
struct sockaddr_in src = {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = htons(1025)
};
char buf[1024];
ssize_t res;
int fd, ret;
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
printf("error: socket\n");
exit(EXIT_FAILURE);
}
ret = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
if (ret < 0) {
perror("error: setsockopt\n");
close(fd);
exit(EXIT_FAILURE);
}
ret = bind(fd, (struct sockaddr *)&src, sizeof(src));
if (ret < 0) {
printf("error: bind\n");
close(fd);
exit(EXIT_FAILURE);
}
res = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0);
printf("res = %zi\n", res);
close(fd);
return 0;
}
tcpdump
, который использует сырые сокеты и должен анализировать заголовки L2 / L3, но с вашимSOCK_DGRAM, IPPROTO_UDP
вы можете с уверенностью предположить, что уже работаете с IPv4 и UDP. Он должен работать с изменениями, которые вы предлагаете, хотя вы можете даже удалить первые две инструкции из программы в своем комментарии (они проверяют, что пакет является UDP, но мы это уже знаем) и оставить только последние четыре. Я вижу, вы также обновили смещение для исходного адреса, так что все должно быть в порядке. - person Qeole   schedule 25.07.2019tcpdump udp and src 192.168.56.101
? Также, в отличие отtcpdump
, ваш сокет привязан к определенному порту UDP (1025), вы отправляете свои пакеты на правильный порт? - person Qeole   schedule 25.07.2019nc
команда не имеет правильного IP-адреса, это опечатка или ошибка в вашей настройке? - person Qeole   schedule 25.07.2019SOCK_DGRAM
на самом деле был даже более высоким уровнем, чем я думал, ваш пакет начинается непосредственно с заголовка L4 (например,{ 0x28, 0, 0, 0x00000002 }, { 0x15, 0, 1, 0x00000401 }, { 0x6, 0, 0, 0x00040000 }, { 0x6, 0, 0, 0x00000000 },
, поскольку программа соответствует порту UDP dst и работает). Вам нужно изменить тип сокета для фильтрации по IP-адресу, возможно, см. Пример в старом посте. - person Qeole   schedule 25.07.2019SOCK_RAW
, если вы хотите получить доступ к заголовкам L3. - person Qeole   schedule 25.07.2019#include
s), кстати. - person Qeole   schedule 25.07.2019