собрал довольно таки известный в сети код: Code: unit Spoof; interface const Max_Packet_Size = 4096; type TPacketBuffer = Array[0..Max_Packet_Size-1] of byte; // Заголовок IP пакета T_IP_Header = record ip_verlen : Byte; ip_tos : Byte; ip_totallength : Word; ip_id : Word; ip_offset : Word; ip_ttl : Byte; ip_protocol : Byte; ip_checksum : Word; ip_srcaddr : LongWord; ip_destaddr : LongWord; end; // Заголовок UDP пакета T_UDP_Header = record src_portno : Word; dst_portno : Word; udp_length : Word; udp_checksum : Word; end; // Некоторые объявления типов для Winsock 2 u_char = Char; u_short = Word; u_int = Integer; u_long = Longint; SunB = packed record s_b1, s_b2, s_b3, s_b4: u_char; end; SunW = packed record s_w1, s_w2: u_short; end; in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end; TInAddr = in_addr; Sockaddr_in = record case Integer of 0: (sin_family: u_short; sin_port: u_short; sin_addr: TInAddr; sin_zero: array[0..7] of Char); 1: (sa_family: u_short; sa_data: array[0..13] of Char) end; TSockAddr = Sockaddr_in; TSocket = u_int; const WSADESCRIPTION_LEN = 256; WSASYS_STATUS_LEN = 128; type PWSAData = ^TWSAData; WSAData = record // !!! also WSDATA wVersion: Word; wHighVersion: Word; szDescription: array[0..WSADESCRIPTION_LEN] of Char; szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char; iMaxSockets: Word; iMaxUdpDg: Word; lpVendorInfo: PChar; end; TWSAData = WSAData; // Определяем необходимые функции winsock 2 function closesocket(s: TSocket): Integer; stdcall; function socket(af, Struct, protocol: Integer): TSocket; stdcall; function sendto(s: TSocket; var Buf; len, flags: Integer; var addrto: TSockAddr; tolen: Integer): Integer; stdcall;{} function setsockopt(s: TSocket; level, optname: Integer; optval: PChar; optlen: Integer): Integer; stdcall; function inet_addr(cp: PChar): u_long; stdcall; {PInAddr;} { TInAddr } function htons(hostshort: u_short): u_short; stdcall; function WSAGetLastError: Integer; stdcall; function WSAStartup(wVersionRequired: word; var WSData: TWSAData): Integer; stdcall; function WSACleanup: Integer; stdcall; const AF_INET = 2; // internetwork: UDP, TCP, etc. IP_HDRINCL = 2; // включаем заголовок IP пакета SOCK_RAW = 3; // интерфейс raw-протокола IPPROTO_IP = 0; // dummy for IP IPPROTO_TCP = 6; // tcp IPPROTO_UDP = 17; // user datagram protocol IPPROTO_RAW = 255; // raw IP пакет INVALID_SOCKET = TSocket(NOT(0)); SOCKET_ERROR = -1; procedure SendPack( const SrcIP, DestIP : String; const SrcPort, DestPort:WORD); implementation // Импортируем функции Winsock 2 const WinSocket = 'WS2_32.DLL'; function closesocket; external winsocket name 'closesocket'; function socket; external winsocket name 'socket'; function sendto; external winsocket name 'sendto'; function setsockopt; external winsocket name 'setsockopt'; function inet_addr; external winsocket name 'inet_addr'; function htons; external winsocket name 'htons'; function WSAGetLastError; external winsocket name 'WSAGetLastError'; function WSAStartup; external winsocket name 'WSAStartup'; function WSACleanup; external winsocket name 'WSACleanup'; function IntToStr(I: Int64): String; var S: String; begin Str(I, S); Result := S; end; // Function: checksum // Description: // This function calculates the 16-bit one's complement sum // for the supplied buffer function CheckSum(Var Buffer; Size : integer) : Word; type TWordArray = Array[0..1] of Word; var ChkSum : LongWord; i : Integer; begin ChkSum := 0; i := 0; while Size > 1 do begin ChkSum := ChkSum + TWordArray(Buffer)[i]; inc(i); Size := Size - SizeOf(Word); end; if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)[i]); ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF); ChkSum := ChkSum + (Chksum shr 16); Result := Word(ChkSum); end; procedure BuildHeaders( const FromIP : String; const iFromPort : Word; const ToIP : String; const iToPort : Word; const StrMessage: String; var Buf : TPacketBuffer; var remote : TSockAddr; var iTotalSize : Word); var dwFromIP : LongWord; dwToIP : LongWord; iIPVersion : Word; iIPSize : Word; ipHdr : T_IP_Header; udpHdr : T_UDP_Header; iUdpSize : Word; iUdpChecksumSize : Word; cksum : Word; Ptr : ^Byte; procedure IncPtr(Value : Integer); begin ptr := pointer(integer(ptr) + Value); end; begin // преобразуем ip адреса dwFromIP := inet_Addr(PChar(FromIP)); dwToIP := inet_Addr(PChar(ToIP)); // Инициализируем заголовок IP пакета iTotalSize := sizeof(ipHdr) + sizeof(udpHdr) + length(strMessage); iIPVersion := 4; iIPSize := sizeof(ipHdr) div sizeof(LongWord); // IP version goes in the high order 4 bits of ip_verlen. The // IP header length (in 32-bit words) goes in the lower 4 bits. ipHdr.ip_verlen := (iIPVersion shl 4) or iIPSize; ipHdr.ip_tos := 0; // IP type of service ipHdr.ip_totallength := htons(iTotalSize); // Total packet len ipHdr.ip_id := 0; // Unique identifier: set to 0 ipHdr.ip_offset := 0; // Fragment offset field ipHdr.ip_ttl := 128; // время жизни пакета ipHdr.ip_protocol := $11; // Protocol(UDP) ipHdr.ip_checksum := 0 ; // IP checksum ipHdr.ip_srcaddr := dwFromIP; // Source address ipHdr.ip_destaddr := dwToIP; // Destination address // Инициализируем заголовок UDP пакета iUdpSize := sizeof(udpHdr) + length(strMessage); udpHdr.src_portno := htons(iFromPort) ; udpHdr.dst_portno := htons(iToPort) ; udpHdr.udp_length := htons(iUdpSize) ; udpHdr.udp_checksum := 0 ; // Build the UDP pseudo-header for calculating the UDP checksum. // The pseudo-header consists of the 32-bit source IP address, // the 32-bit destination IP address, a zero byte, the 8-bit // IP protocol field, the 16-bit UDP length, and the UDP // header itself along with its data (padded with a 0 if // the data is odd length). iUdpChecksumSize := 0; ptr := @buf[0]; FillChar(Buf, SizeOf(Buf), 0); Move(ipHdr.ip_srcaddr, ptr^, SizeOf(ipHdr.ip_srcaddr)); IncPtr(SizeOf(ipHdr.ip_srcaddr)); iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_srcaddr); Move(ipHdr.ip_destaddr, ptr^, SizeOf(ipHdr.ip_destaddr)); IncPtr(SizeOf(ipHdr.ip_destaddr)); iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_destaddr); IncPtr(1); Inc(iUdpChecksumSize); Move(ipHdr.ip_protocol, ptr^, sizeof(ipHdr.ip_protocol)); IncPtr(sizeof(ipHdr.ip_protocol)); iUdpChecksumSize := iUdpChecksumSize + sizeof(ipHdr.ip_protocol); Move(udpHdr.udp_length, ptr^, sizeof(udpHdr.udp_length)); IncPtr(sizeof(udpHdr.udp_length)); iUdpChecksumSize := iUdpChecksumSize + sizeof(udpHdr.udp_length); move(udpHdr, ptr^, sizeof(udpHdr)); IncPtr(sizeof(udpHdr)); iUdpChecksumSize := iUdpCheckSumSize + sizeof(udpHdr); Move(StrMessage[1], ptr^, Length(strMessage)); IncPtr(Length(StrMessage)); iUdpChecksumSize := iUdpChecksumSize + length(strMessage); cksum := checksum(buf, iUdpChecksumSize); udpHdr.udp_checksum := cksum; // Now assemble the IP and UDP headers along with the data // so we can send it FillChar(Buf, SizeOf(Buf), 0); Ptr := @Buf[0]; Move(ipHdr, ptr^, SizeOf(ipHdr)); IncPtr(SizeOf(ipHdr)); Move(udpHdr, ptr^, SizeOf(udpHdr)); IncPtr(SizeOf(udpHdr)); Move(StrMessage[1], ptr^, length(StrMessage)); // Apparently, this SOCKADDR_IN structure makes no difference. // Whatever we put as the destination IP addr in the IP header // is what goes. Specifying a different destination in remote // will be ignored. remote.sin_family := AF_INET; remote.sin_port := htons(iToPort); remote.sin_addr.s_addr := dwToIP; end; procedure SendPack( const SrcIP, DestIP : String; const SrcPort, DestPort:WORD); var sh : TSocket; bOpt : Integer; ret : Integer; Buf : TPacketBuffer; Remote : TSockAddr; Local : TSockAddr; iTotalSize : Word; wsdata : TWSAdata; begin // Startup Winsock 2 ret := WSAStartup($0002, wsdata); if ret<>0 then begin WriteLn('WSA Startup failed.'); exit; end; WriteLn('WSA Startup:',#13#10, 'Desc.: ',wsData.szDescription,#13#10, 'Status: ',wsData.szSystemStatus); try // Создаём сокет sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP); if (sh = INVALID_SOCKET) then begin WriteLn('Socket() failed: '+IntToStr(WSAGetLastError)); exit; end; WriteLn('Socket Handle = '+IntToStr(sh)); // Option: Header Include bOpt := 1; ret := SetSockOpt(sh, IPPROTO_IP, IP_HDRINCL, @bOpt, SizeOf(bOpt)); if ret = SOCKET_ERROR then begin WriteLn('setsockopt(IP_HDRINCL) failed: '+IntToStr(WSAGetLastError)); exit; end; // строим пакет BuildHeaders(SrcIP, SrcPort, DestIP, DestPort, 'THIS IS A TEST PACKET', Buf, Remote, iTotalSize ); // Отправляем пакет ret := SendTo(sh, buf, iTotalSize, 0, Remote, SizeOf(Remote)); if ret = SOCKET_ERROR then WriteLn('sendto() failed: '+IntToStr(WSAGetLastError)) else WriteLn('send '+IntToStr(ret)+' bytes.'); // Закрываем сокет CloseSocket(sh); finally // Закрываем Winsock 2 WSACleanup; end; end; end. вызываю Code: SendPack('1.2.3.4','127.0.0.1',7,7); и получаю ошибку Code: WSA Startup: Desc.: WinSock 2.0 Status: Running Socket Handle = 1960 sendto() failed: 10004 в описании кода ошибки говорится Code: Системный вызов прерван. Это может произойти, если выполняется вызов сокета, а сокет закрыт но мне это ничего не говорит %( . как избежать этой ошибки?
по ссылке идет другая ссылка __http://www.codeproject.com/KB/IP/rawsocket.aspx?df=100&forumid=372728&exp=0&select=1904971#xx1904971xx как я понял в статье написанно что на XP+SP2 поддержка UDP спуфинга есть. проблема остается открытой
ммм, а как можно это реализовать на уровне ядра? то есть как я понимаю надо написать драйвер, вообще как можно представить такую систему? существует ли уже готовая реализация?
xpsp2tcpipfix.exe - патч поможет с сырыми сокетами Суть ограничения: http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/7c815a9d-d8af-4e57-b64a-371002e8487f/ Также хорошим решением является пакет WinPCAP, которые с открытым исходным кодом, документацией, к тому же Delimiter писал на ачате про использование его (правда про ARP так и не закончил)
Тут А еще мне в свое время помогли вот эти ссылки: Примерно с этой темы начинаются мои "мучения" с winpcap'ом А потом появилось: RST киллер или все через "призму" WinPCap Спасибо Delimiter'у
а те что в статье делиметра (там сырцы на слил ру) вообще опыта нету на Си работы, скачал себе Дев-С++ сижу мозги разминаю.
Дев-С++ отложи в сторонку лучше поставь себе Microsoft Visual Studio C++ или Borland Builder C++, при всем уважении к GCC
качаю Visual.Studio.2005.Express (вроде там ток с++ если верно понял) но нашел вроде какуюто библиотеку для делфи вот линк http://www.misalpina.net/ghost3k/mypcap.zip не пойму как заюзать. помогите plz
может это тебе поможет вот исходник генератора пакетов, написал давно и иногда пользуюсь. В файле, имя которого надо передавать в аргументах, должен быть пакет канального уровня - с ethernet заголовком. Также надо указать номер адаптера Code: //Утилита передает содержимое файла //напрямую сетевому адаптеру([к]анальный уровень) program Generator; {$APPTYPE CONSOLE} uses windows; //Описания структур type packet = packed record OVERLAPPED: OverLapped; Buffer: pointer; Length: cardinal; Next: pointer; ulBytesReceived: cardinal; bIoComplete: boolean; end; ADAPTER = packed record hFile:cardinal; SymbolicLink: PAnsiChar; end; //описания констант const SIMULTANEOU_READS = 10; MAX_ETHERNET_FRAME_SIZE = 1513; Max_Num_Adapter=5; NDIS_PACKET_TYPE_PROMISCUOUS = $0020; NumberOfPacket:cardinal=1; //How mutch send Packets //импортируемые функции function PacketGetAdapterNames(pStr:pointer; BufferSize:pointer):longint;stdcall; external 'packet.dll'; function PacketOpenAdapter(AdapterName:pointer):pointer; stdcall; external 'packet.dll'; function PacketAllocatePacket:pointer; stdcall; external 'packet.dll'; function PacketSetHwFilter(AdapterObject:pointer; Filter:cardinal):boolean; stdcall; external 'packet.dll'; procedure PacketInitPacket(lpPacket:pointer; Buffer:pointer; Length:cardinal); stdcall; external 'packet.dll'; function PacketSetNumWrites(AdapterObject:pointer; nwrites:integer):boolean; stdcall; external 'packet.dll'; function PacketSendPacket(AdapterObject:pointer; lpPacket:pointer; Sync:boolean):boolean; stdcall; external 'packet.dll'; procedure PacketFreePacket(lpPacket:pointer); stdcall; external 'packet.dll'; procedure PacketCloseAdapter(lpAdapter:pointer); stdcall; external 'packet.dll'; //Описания переменных var //Список идентификаторов сетевых адаптеров AdapterList: array[0..Max_Num_Adapter-1, 0..255] of char; //Список имён сетевых адаптреров AdapterNameList: array[0..Max_Num_Adapter-1, 0..255]of char; //Хэндл проекции файла hMap:cardinal; //Указатель на область памяти с отображенным файлом pBuf:pointer; //Номер используемого адаптера NAdapter:integer; //Указательн на структуру сетевого пакета lppacket:^Packet; //Указатель на структуру открытого адаптера lpadapter:^ADAPTER; //Хэндл файла hFile:cardinal; //Буфер для списка адаптеров и их названий AdapterBuffer:array [0..4095] of char; dwFileSize:word; AdapterBufferLength: cardinal; i,j,n:integer; begin //Формирование списка адаптеров AdapterBufferLength := sizeof(AdapterBuffer); PacketGetAdapterNames(@AdapterBuffer, @AdapterBufferLength); n:=0; j:=0; while AdapterBuffer[j]<>#0 do begin lstrcpy(@AdapterList[n], @AdapterBuffer[j]); j:=j+lstrlen(@AdapterBuffer[j])+1; inc(n); end; while AdapterBuffer[j] = #0 do j:=j+1; for i:=0 to n-1 do begin lstrcpy(@AdapterNameList[i], @AdapterBuffer[j]); j:=j+lstrlen(@AdapterBuffer[j]) + 1; end; writeln('# Packet Generator on packet.dll'); writeln('# ',n,' adapters detected'); for j:=0 to n-1 do writeln(j+1,'. ', pChar(@AdapterNameList[j]), ' - ', pChar(@AdapterList[j])); writeln; if ParamCount<2 then begin writeln('Usage: generator N_adapter packet_file'); exit; end; //Выбор используемого адаптера if n=1 then NAdapter:=0 else begin val(ParamStr(1), NAdapter, i); if (NAdapter>n) or (NAdapter=0) then begin writeln ('Invalid number'); exit; end; NAdapter := NAdapter-1; end; writeln('# Selected adapter - ',pChar(@AdapterNameList[NAdapter])); //Адаптер нужно открыть lpAdapter := PacketOpenAdapter(@AdapterList[NAdapter]); if lpadapter.hFile=INVALID_HANDLE_VALUE then begin writeln('Error open adapter'); exit; end; //Перевод адаптера в режим принятия всех пакетов if not PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_PROMISCUOUS) then begin writeln('! Could not set promiscuous type'); //PacketCloseAdapter(lpAdapter); exit; end; writeln('# promiscuous type success'); //Выделяется память для пакета lpPacket:= PacketAllocatePacket; if lpPacket=nil then begin writeln('! Could not allocate packet'); //PacketCloseAdapter(lpAdapter); exit; end; writeln('# packet allocated success'); //Открывается файл с пакетом hFile:=CreateFile(pChar(ParamStr(2)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile = INVALID_HANDLE_VALUE then begin writeln('Could not open file'); //PacketFreePacket(lpPacket); //PacketCloseAdapter(lpAdapter); exit; end; dwFileSize:=GetFileSize(hFile, nil); hMap:=CreateFileMapping(hFile, nil, PAGE_WRITECOPY, 0, 0, nil); pBuf:=MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0, 0); writeln; writeln('# File open success'); writeln('# File size - ', dwFileSize); //Инициализация структуры пакета PacketInitPacket (lppacket, pBuf, dwFileSize); //Установка количества посылаемых пакетов PacketSetNumWrites (lpAdapter, NumberOfPacket); writeln('# Start sending'); PacketSendPacket (lpAdapter, lpPacket,false); writeln('# All done.'); //Проекция файла уничтожается UnmapViewOfFile(pBuf); CloseHandle(hMap); CloseHandle(hFile); end.