как мне послать пакет на локальный интерфейс,
суть в том что libpcap'ом я перехватил пакет, поменял там source IP и хочу теперь его отправить, как мне это сделать?
>как мне послать пакет на локальный интерфейс,
>суть в том что libpcap'ом я перехватил пакет, поменял там source IP
>и хочу теперь его отправить, как мне это сделать?AFAIR, libpcap в некоторых модификациях может отправлять пакеты. Что мешает посмотреть исходные тексты схожих проектов?!
ps: изменить source IP мало, нужно пересчитать checksum.
>>как мне послать пакет на локальный интерфейс,
>>суть в том что libpcap'ом я перехватил пакет, поменял там source IP
>>и хочу теперь его отправить, как мне это сделать?
>
>AFAIR, libpcap в некоторых модификациях может отправлять пакеты. Что мешает посмотреть исходные
>тексты схожих проектов?!
>
>ps: изменить source IP мало, нужно пересчитать checksum.
ну а вообще каким образом можно отправить ? без lipcap?
>>>как мне послать пакет на локальный интерфейс,
>>>суть в том что libpcap'ом я перехватил пакет, поменял там source IP
>>>и хочу теперь его отправить, как мне это сделать?
>>
>>AFAIR, libpcap в некоторых модификациях может отправлять пакеты. Что мешает посмотреть исходные
>>тексты схожих проектов?!
>>
>>ps: изменить source IP мало, нужно пересчитать checksum.
>
>
>ну а вообще каким образом можно отправить ? без lipcap?raw sockets
>>ну а вообще каким образом можно отправить ? без lipcap?
>
>raw socketsда что то не выходит...
пытаюсь отправить с sendto
Или ещё как можно?
>>>ну а вообще каким образом можно отправить ? без lipcap?
>>
>>raw sockets
>
>да что то не выходит...
>пытаюсь отправить с sendto
>Или ещё как можно?"Послать на локальный интерфейс" и "поменял Source IP". Не ясно что хотите в результате.
Если изменили source IP и пытаетесь отправить в lo этот пакет то кто его там будет ловить при dest IP не локальном (ведь не изменен)?В общем
Если открыть raw socket и привязать (bind) к конкретному интерфейсу, то в этот интерфейс можно посылать хоть из /dev/urandom.p.s.
iptables off/on ? :)
>"Послать на локальный интерфейс" и "поменял Source IP". Не ясно что хотите
>в результате.
>Если изменили source IP и пытаетесь отправить в lo этот пакет то
>кто его там будет ловить при dest IP не локальном (ведь
>не изменен)?
>
>В общем
>Если открыть raw socket и привязать (bind) к конкретному интерфейсу, то в
>этот интерфейс можно посылать хоть из /dev/urandom.
>
>p.s.
>iptables off/on ? :)объясню немного подробнее, вобщем так
С помощью libpcap ловлю пакет адресованный например на IP 192.168.1.1 порт 80 с IP 192.168.1.2
Меняю 192.168.1.2 на 192.168.1.3, как теперь мне отправить этот пакет не присоединяясь напрямую к 192.168.1.1?
тоесть отправить пакет в одну сторону
>>"Послать на локальный интерфейс" и "поменял Source IP". Не ясно что хотите
>>в результате.
>>Если изменили source IP и пытаетесь отправить в lo этот пакет то
>>кто его там будет ловить при dest IP не локальном (ведь
>>не изменен)?
>>
>>В общем
>>Если открыть raw socket и привязать (bind) к конкретному интерфейсу, то в
>>этот интерфейс можно посылать хоть из /dev/urandom.
>>
>>p.s.
>>iptables off/on ? :)
>
>объясню немного подробнее, вобщем так
>С помощью libpcap ловлю пакет адресованный например на IP 192.168.1.1 порт 80
>с IP 192.168.1.2
>Меняю 192.168.1.2 на 192.168.1.3, как теперь мне отправить этот пакет не присоединяясь
>напрямую к 192.168.1.1?
>тоесть отправить пакет в одну сторонудумаю проще iptables настроить и не мучаться.
>думаю проще iptables настроить и не мучаться.
во первых это freebsd и там ipfw
и iptables эту задачу не решит
>>думаю проще iptables настроить и не мучаться.
>во первых это freebsd и там ipfw
Ok (а я подумал линух). Либо решить посредством (если возможно) ipfw, либо смотреть в сторону divert sockets.
Так как поймать пакет недостаточно, его (оригинал) еще надо не пустить дальше.>и iptables эту задачу не решит
не пробовал, но судя по man'у извернуться можно.
>>>думаю проще iptables настроить и не мучаться.
>>во первых это freebsd и там ipfw
>Ok (а я подумал линух). Либо решить посредством (если возможно) ipfw, либо
>смотреть в сторону divert sockets.
>Так как поймать пакет недостаточно, его (оригинал) еще надо не пустить дальше.
>
>
>>и iptables эту задачу не решит
>не пробовал, но судя по man'у извернуться можно.тут ещё суть в том что пакет должен уйти только в одну сторону с изменённым IP адресом, и чтобы машина кому был отправлен этот пакет ответила на него
у меня проблема возникает при создании raw_sock, sendto не отправляет пакет данных, видимо там нужно что то ещё обработать, я просто уже запутался :)
>>>>думаю проще iptables настроить и не мучаться.
>>>во первых это freebsd и там ipfw
>>Ok (а я подумал линух). Либо решить посредством (если возможно) ipfw, либо
>>смотреть в сторону divert sockets.
>>Так как поймать пакет недостаточно, его (оригинал) еще надо не пустить дальше.
>>
>>
>>>и iptables эту задачу не решит
>>не пробовал, но судя по man'у извернуться можно.
>
>тут ещё суть в том что пакет должен уйти только в одну
>сторону с изменённым IP адресом, и чтобы машина кому был отправлен
>этот пакет ответила на него
>у меня проблема возникает при создании raw_sock, sendto не отправляет пакет данных,
>видимо там нужно что то ещё обработать, я просто уже запутался
>:)
А ipfw fwd не помогает? (только надо фрю до 5 ветки брать - в 5-ой глюк именно в этой функции, мне победить до сих пор не удалось - придется делать dowgrade)
>А ipfw fwd не помогает? (только надо фрю до 5 ветки брать
>- в 5-ой глюк именно в этой функции, мне победить до
>сих пор не удалось - придется делать dowgrade)
например?
ipfw форвардит пакеты только локально
>>А ipfw fwd не помогает? (только надо фрю до 5 ветки брать
>>- в 5-ой глюк именно в этой функции, мне победить до
>>сих пор не удалось - придется делать dowgrade)
>например?
>ipfw форвардит пакеты только локальноЯ данную задачу решал так:
NAT from ipfilter and fastroute option
Значит через rdr-правило соединение приходит на первый интерфейс, я делаю bind на второй интерфейс, смотрю через SIOCGNATL реальный адрес назначения и добавляю map-правило на замену адреса на реальный. А правила фильтра выполняются раньше, чем NAT-правила на outbound-трафике и там стоит отправлять все с первого интерфейса на второй (fastroute), что соответствует условиям map-правила. А у map-правила стоит второй интерфейс в качестве in_ifname, поэтому оно срабатывает и через второй интерфейс уходит соединение. Это true transparent proxy. Все сводится к одному правилу фильтра, одному правилу ната и динамической замене адреса для нужного соединения. Почему нужен второй интерфейс? Все правила ipf работают на указанном интерфейсе, алиасы интерфейсов не поддерживаются, поэтому для предотвращения взаимного исключения правил используется второй интерфейс.
>как мне послать пакет на локальный интерфейс,
>суть в том что libpcap'ом я перехватил пакет, поменял там source IP
>и хочу теперь его отправить, как мне это сделать?если это все делать на C (C++) во FreeBSD есть несколько способов:
netgraph(4) - самая универсальная система, можешь отправлять любые пакеты на любом сетевом уровне.библиотека /usr/ports/net/libdnet - это попроще, позволяет формировать любые Ethernet кадры, т.е. посылать в сеть вообще что угодно, с любыми MAC, IP - адресами, и не обязательно IP пакеты (например, ARP).
Есть еще похожие вещи, но dnet мне понравилась больше всего, все просто и понятно.
>библиотека /usr/ports/net/libdnet - это попроще, позволяет формировать любые Ethernet кадры, т.е. посылать
>в сеть вообще что угодно, с любыми MAC, IP - адресами,
>и не обязательно IP пакеты (например, ARP).
>
>Есть еще похожие вещи, но dnet мне понравилась больше всего, все просто
>и понятно.
Это не производительно! Всю работу должен делать пакетный фильтр в области ядра. См. выще NAT + fastroute
>>библиотека /usr/ports/net/libdnet - это попроще, позволяет формировать любые Ethernet кадры, т.е. посылать
>>в сеть вообще что угодно, с любыми MAC, IP - адресами,
>>и не обязательно IP пакеты (например, ARP).
>>
>>Есть еще похожие вещи, но dnet мне понравилась больше всего, все просто
>>и понятно.
>
>
>Это не производительно! Всю работу должен делать пакетный фильтр в области ядра.
>См. выще NAT + fastrouteСм. выше условия задачи: перехватил libcap'ом пакет... ;)
>>>библиотека /usr/ports/net/libdnet - это попроще, позволяет формировать любые Ethernet кадры, т.е. посылать
>>>в сеть вообще что угодно, с любыми MAC, IP - адресами,
>>>и не обязательно IP пакеты (например, ARP).
>>>
>>>Есть еще похожие вещи, но dnet мне понравилась больше всего, все просто
>>>и понятно.
>>
>>
>>Это не производительно! Всю работу должен делать пакетный фильтр в области ядра.
>>См. выще NAT + fastroute
>
>См. выше условия задачи: перехватил libcap'ом пакет... ;)
чот у меня с утра не прёт или хз, как собирать то dnet?
undefined reference to `eth_open'
undefined reference to `eth_send'
undefined reference to `eth_close'
>чот у меня с утра не прёт или хз, как собирать то
>dnet?
>undefined reference to `eth_open'
>undefined reference to `eth_send'
>undefined reference to `eth_close'
да точно туплю с утра, -ldnet помогло
>библиотека /usr/ports/net/libdnet - это попроще, позволяет формировать любые Ethernet кадры, т.е. посылать
>в сеть вообще что угодно, с любыми MAC, IP - адресами,
>и не обязательно IP пакеты (например, ARP).
>
>Есть еще похожие вещи, но dnet мне понравилась больше всего, все просто
>и понятно.пытаюсь отправить пакет, tcpdump пишет
12:40:10.538702 IP0 bad-hlen 0
пакет на уровне ethernet пойман libpcap'ом пытаюсь послать этот же пакет
>пытаюсь отправить пакет, tcpdump пишет
>12:40:10.538702 IP0 bad-hlen 0
>пакет на уровне ethernet пойман libpcap'ом пытаюсь послать этот же пакет
тьфу не то совсем, прошу прощения, tcpdump вообще ничего не показываетchar dev[] ="rl0";
static eth_t *dnet_eth;
if ((dnet_eth = eth_open(dev)) == NULL)
errx(1, "eth_open");if (eth_send(dnet_eth, packet, sizeof(packet)) != sizeof(packet))
syslog(LOG_ERR, "couldn't send packet: %m");
eth_close(dnet_eth);вот примерный код написал, нифига ничего не посылает
>char dev[] ="rl0";
>static eth_t *dnet_eth;
>if ((dnet_eth = eth_open(dev)) == NULL)
>
> errx(1, "eth_open");
>
>if (eth_send(dnet_eth, packet, sizeof(packet)) != sizeof(packet))
>
> syslog(LOG_ERR, "couldn't send packet: %m");
>eth_close(dnet_eth);
>
>вот примерный код написал, нифига ничего не посылает
packet - это указатель на Ethernet frame, т.е. должны быть указаны корректные адреса,
в кадре указан тип сетевого пакета/usr/include/net/ethernet.h:
struct ether_header {
u_char ether_dhost[ETHER_ADDR_LEN];
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
}ether_type= ETHERTYPE_IP
IP пакет должен быть сформирован верно (адреса, флаги, контрольная сумма).
Вот такой запуск tcpdump поможет в более подробном анализе Ethernet кадров:
tcpdump -XX -v -n -s 256 -i <ifname>
>packet - это указатель на Ethernet frame, т.е. должны быть указаны корректные
>адреса,
>в кадре указан тип сетевого пакета
>
>/usr/include/net/ethernet.h:
>struct ether_header {
> u_char ether_dhost[ETHER_ADDR_LEN];
> u_char ether_shost[ETHER_ADDR_LEN];
> u_short ether_type;
>}
>
>ether_type= ETHERTYPE_IP
>
>IP пакет должен быть сформирован верно (адреса, флаги, контрольная сумма).
>
>Вот такой запуск tcpdump поможет в более подробном анализе Ethernet кадров:
>tcpdump -XX -v -n -s 256 -i <ifname>tcpdump ничего не показывает, пробовал даже через ip_send послать ip пакет
ip_t *ip;
if ((ip = ip_open()) == NULL)
printf("error");if((ip_send(ip,iph, size_ip)) != size_ip)
printf("error 2");ip_close(ip);
>>IP пакет должен быть сформирован верно (адреса, флаги, контрольная сумма).
>>
>>Вот такой запуск tcpdump поможет в более подробном анализе Ethernet кадров:
>>tcpdump -XX -v -n -s 256 -i <ifname>
>
>tcpdump ничего не показывает, пробовал даже через ip_send послать ip пакет
>
>ip_t *ip;
>
>if ((ip = ip_open()) == NULL)
>printf("error");
>
>if((ip_send(ip,iph, size_ip)) != size_ip)
>printf("error 2");
>
>ip_close(ip);Для примера привожу куски реально работающего кода, при передаче tcpdump все показывает.
Попробуй запускать tcpdump на приемной стороне, а так же смотреть на светодиоды активности сети на интерфейсах (коммутаторе). В качестве примера формирования пакетов различных протоколов смотри исходники tcpdump (функции разборки пакетов), там довольно все понятно, в каком поле пакета что должно лежать. Плюс соответствующие RFC по форматам пакетов.------- открытие интерфейса -------
if((m_eth= eth_open(m_ifname)) == NULL)
{
VLOG(fm_log, 1, "Ошибка eth_open('%s'), errno: %d (%s)", m_ifname, errno, strerror(errno));
return(-1);
}
---------------------- метод передачи кадра через интерфейс ------
frame.set_mac_addr(m_mac);
return( eth_send(m_eth, frame.get_raw(), frame.get_size()));
}
--------------
------- часть метода формирования кадра UDP пакета -------
union // буфер кадра
{
...
struct // UDP пакет (RFC 768)
{
struct ether_header hdr;
struct ip ip;
struct udphdr udp;
uint8_t data[1];
} __packed udp;
...
uint8_t raw[ETHER_MAX_LEN - ETHER_CRC_LEN]; // сырой Ethernet кадр (без контрольной суммы)
} m_frame;// формирование кадра
struct pseudo_udp_hdr {
in_addr_t src;
in_addr_t dst;
uint8_t zero;
uint8_t proto;
uint16_t length;
} __packed *pseudo;// зануление заголовков
memset(m_frame.raw, 0, sizeof(m_frame.udp));// UDP заголовок + данные
m_frame.udp.udp.uh_sport = htons(sport);
m_frame.udp.udp.uh_dport = htons(dport);
m_frame.udp.udp.uh_ulen = htons(sizeof(m_frame.udp.udp) + data_size);if(data_size)
memcpy( m_frame.udp.data, data, data_size);// псевдозаголовок для контрольной суммы (заполняется на месте IP заголовка перед UDP пакетом)
pseudo = (struct pseudo_udp_hdr *) ( (uint8_t *)(&m_frame.udp.udp) - sizeof(*pseudo)) ;
pseudo->src = src.s_addr;
pseudo->dst = dst.s_addr;
pseudo->proto = IPPROTO_UDP;
pseudo->length = htons(sizeof(m_frame.udp.udp) + data_size);m_frame.udp.udp.uh_sum = ip_checksum((uint8_t *)pseudo, sizeof(*pseudo) + sizeof(m_frame.udp.udp) + data_size);
// IP заголовок
memset(pseudo, 0, sizeof(*pseudo));m_frame.udp.ip.ip_v = IPVERSION;
m_frame.udp.ip.ip_hl = 5; // 20/4
m_frame.udp.ip.ip_len = htons(sizeof(m_frame.udp.ip) + sizeof(m_frame.udp.udp) + data_size);
m_frame.udp.ip.ip_id = htons(get_number());
m_frame.udp.ip.ip_ttl = 255;
m_frame.udp.ip.ip_p = IPPROTO_UDP;
m_frame.udp.ip.ip_src.s_addr = src.s_addr;
m_frame.udp.ip.ip_dst.s_addr= dst.s_addr;
m_frame.udp.ip.ip_sum = ip_checksum((uint8_t *) &m_frame.udp.ip, sizeof(m_frame.udp.ip));m_size = sizeof(m_frame.udp.hdr) + sizeof(m_frame.udp.ip) + sizeof(m_frame.udp.udp) + data_size;
// заполенение Ether заголовка
m_frame.udp.hdr.ether_type= htons(ETHERTYPE_IP);
--------------
с eth_send то всё работает
не получается через ip_send
>с eth_send то всё работает
>не получается через ip_sendпосмотри, что делает внутри ip_send() и задай вопрос: нужна ли она вообще?
ip_open -> socket(AF_INET, SOCK_RAW, IPPROTO_RAW)
ip_send -> sendto
ip_close -> closeСовершенно бесполезные накрывашки.
eth_send делает гораздо больше работы, поэтому я использовал ее.
Если не получается отправлять пакет через SOCK_RAW, то проблема в коде, а не в libdnet.
Код в форум. ;)
>>с eth_send то всё работает
>>не получается через ip_send
>
>посмотри, что делает внутри ip_send() и задай вопрос: нужна ли она вообще?
>
>ip_open -> socket(AF_INET, SOCK_RAW, IPPROTO_RAW)
>ip_send -> sendto
>ip_close -> close
>
>Совершенно бесполезные накрывашки.
>eth_send делает гораздо больше работы, поэтому я использовал ее.
>Если не получается отправлять пакет через SOCK_RAW, то проблема в коде, а
>не в libdnet.
>Код в форум. ;)
чёрт, не глянул в сорцы dnet'a, не думал что через RAW сокеты отправляет
исходник слишком большой :)
я тут пытаюсь с libpcap'ом отправить, но он отправляет через сетевой интерфейс, eth_send от dnet'a также, а мне нужно чтобы пакет посылался напрямую...
>чёрт, не глянул в сорцы dnet'a, не думал что через RAW сокеты
>отправляет
>исходник слишком большой :)
>я тут пытаюсь с libpcap'ом отправить, но он отправляет через сетевой интерфейс,
>eth_send от dnet'a также, а мне нужно чтобы пакет посылался напрямую...
>Напрямую это как? Прямо из буфера твоего процесса через DMA в память контроллера?
Придется затачивать драйвер специально для этого, отучать его работать с остальным стеком, убирать из него все очереди пакетов. Смысл? Цепочка вызовов от sendto(), ip_output(), до начала копирования в сетевой контроллер не такая уж большая, система mbuf'ов довольно оптимизирована. Что ты ждешь от сетевой подсистемы?