Итак, ось - win 2003 сервер код примерно такой: hSocket:=Socket(AF_INET, SOCK_RAW, IPPROTO_IP); ZeroMemory(@SockAddr, SizeOf(SockAddr)); SockAddr.sin_family:=AF_INET; SockAddr.sin_addr.S_addr:=inet_addr('192.168.0.20'); sockaddrlen:=SizeOf(SockAddr); Bind(hSocket, SockAddr, sockaddrlen); opt:=1; SetSockOpt(hSocket, IPPROTO_IP, IP_HDRINCL, @Opt, SizeOf(Opt)); далее пытаемся принять пакет recv'ом или recvfrom'ом не суть, на системном вызове повисает, хотя по идее должен подсасывать пакет адресованый интерфейсу 192.168.0.20 так в чём трабл почему этого не происходит? з.ы. смена IPPROTO_IP на IPPROTO_RAW ничего не даёт.
Интерфейс который пытаешься слушать физический? Версия WinSock 2.2? Ещё, после bind, обязательно надо включить неразборчивй режим, иначе работать не будет(у меня не работало). Код (Text): long flag = 1; // Флаг PROMISC Вкл/выкл. // Включение promiscuous mode. ioctlsocket(hSocket, SIO_RCVALL, &flag);
IP_HDRINCL вообще чему равна? где-то пишут 2, где то - 3 а кстати если в promisc переключить всё - ок, но в этом случае слушаем и то что нам особо не надо - както колхозно по идее и без промиск мод должно работать... кроме того зачем тогда setsockopt если он зафейливает?
int_13h Я не знаю, у меня в разборчевом режиме не вышло. Может это ограничение Win 2003 сервер, хз. Если откопаешь инфу по-этому, будет тебе респект. А SetSockOpt в данном случае влияет на сборку пакетов(если сам будешь формировать для отправки), а не на прослушку.
Booster а смысл.. я тестил на WinXP (SP0), Win2k, Win2k3 везде результат одинаковый - фейлит что так, что так... Задача вобщем привязаться к 2м интерфейсам и принимть/отправлять пакеты и походу менять ИП адреса в оных - tcp, udp, icmp насколько понял из МСДН виндовый сервер это разрешает в отличии от кастрированной WinXP...
стормозил... либо bind либо setsockopt - отстойно, лучше уж winpcap взять, чем так извращаться - отдельный сокет для приёма и отправки.
да думал штатными средствами обойтись, без установок лишних компонентов в систему но видимо придётся заюзать winpcap... хотя ещё поиграюсь попробую написать NAT, если всё заработает посмотрим на скорость и сравним с winpcap.
Booster получится даже 3и - приём с двух сетевух, и отправка один... только вот пакеты с "посылающего" сокета не уходят: -1 возвращает, а как нистранно слушающий сокет другой сетевухи пакет успешно отправляет... только вот походу IP, TCP заголовки не пересчитывает потому как ACK не приходит =( вообще как там расчитать контрольную сумму? - на CRC чтото непохоже
Вообще похоже RawSock на Tcp уровне в Win2003 не работают. Но на IP работают нормально. Функции расчёта контрольной суммы везде валяются. Код (Text): unsigned short csum (unsigned short *buf, int nwords) { unsigned long sum; for (sum = 0; nwords > 0; nwords--) sum += *buf++; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum; }
Да как там отправлять смотри: Пишу нат - приходит пакет - меняю src ИП на ИП внешней сетки, если SYN добавляю в таблицу трансляции порт:внутр ИП, приходит на внешний интерфейс пакет - смотрю порт и ставлю dst ИП на ИП компа во внутр сетки и на src адрес своего интервейса висящего на внутр сетке... всё элементарно только пакетики с внешней сетки почему то не возвращаются - единственный возможный баг стек не пересчитывает контрольную сумму ИП заголовка ибо с ICMP пакетами такая ж хрень, я перед посылкой обнуляю контр суммы - везде написано что типа стек сам их вычислит...
На уровне Ip считать контрольную сумму действительно необязательно, но на более высоких уровнях надо. В tcp ещё нужно считать с псевдо tcp заголовком.