Пишу программу, где два потока читают/отправляют (один поток читает все входящие пакеты, другой отправляет пакеты) через разные сокеты в один и тот же интерфейс, например eth0.
Проблема: Пакеты которые были отправлены одним потоком, тут же читаются другим потоком, а я хочу скипать эти пакеты. Как это сделать и возможно ли вообще?(фильтрация по адресам не возможна так как адреса отправителя и получателя всегда рандомные)Подробнее:
Я создал два сокета канального уровня:
sd = socket(PF_PACKET, SOCK_ROW, htons(ETH_P_ALL));
td = socket(PF_PACKET, SOCK_ROW, htons(ETH_P_ALL));привязал оба к одному и тому же интефейсу:
struct sockaddr_ll s_ll;s_ll.sll_family = PF_PACKET; // тип сокета
s_ll.sll_protocol = htons(ETH_P_ALL); // тип принимаемого протокола
s_ll.sll_ifindex = index; // индекс сетевого интерфейса eth0bind(sd, (struct sockaddr *)&s_ll, sizeof(struct sockaddr_ll));
struct sockaddr_ll t_ll;
t_ll.sll_family = PF_PACKET; // тип сокета
t_ll.sll_protocol = htons(ETH_P_ALL); // тип принимаемого протокола
t_ll.sll_ifindex = index; // индекс сетевого интерфейса eth0bind(td, (struct sockaddr *)&t_ll, sizeof(struct sockaddr_ll));
Засэтил на интефейсе PROMISC MODE чтобы приходили все пакеты.
struct ifreq ifr;
ifr.ifr_name = "eth0";
ioctl(fd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_PROMISC;
ioctl(fd, SIOCSIFFLAGS, &ifr);
Теперь один поток читает из сокета sd:
recvfrom(sd, (char *)buff, 1500, 0, NULL, NULL);Другой пишет в сокет td:
sendto(td, (char *)buff, 1500, 0, NULL, NULL);И когда второй поток отправляет пакет в td, первый тут же читает его через сокет sd. Возможно ли слеать так, чтобы первый поток не обращал внимание на исходящие пакеты отправленные через td, а читал только входящие. При этом фильтрации пакетов по адресам не может быть, так как приходящие и исходящие пакеты имеют имеют рандомные адреса.
читать все равно придется все пакеты, но обрабатывать можно только входящие:
struct sockaddr_ll from;
socklen_t fromlen;
fromlen = sizeof(from);
recvfrom(sd, buff, 1500, MSG_TRUNC,(struct sockaddr *)&from, &fromlen);
if (from.sll_pkttype == PACKET_OUTGOING) {
/* Ignore. */
} else {
/* Process. */
}А вообще проще/лучше использовать libpcap )))
>[оверквотинг удален]
>socklen_t fromlen;
>fromlen = sizeof(from);
>recvfrom(sd, buff, 1500, MSG_TRUNC,(struct sockaddr *)&from, &fromlen);
>if (from.sll_pkttype == PACKET_OUTGOING) {
> /* Ignore. */
>} else {
> /* Process. */
>}
>
>А вообще проще/лучше использовать libpcap )))Спасибо!!! Я только, что наткнулся на ман с описанием этого флажка!!!