请教,各位高手
   如何编写虚拟网卡和把IP绑定到此网卡,但是不要重启机器。
或许如何编写发送和接受伪装IP包程序?我要源代码,谢谢!

解决方案 »

  1.   

    伪装IP包程序可以通过Raw Socket实现,VC的代码比较多虚拟网卡要编写驱动的,Delphi无法写
      

  2.   

    伪装IP包程序可以通过Raw Socket实现,那么,怎样区分不同伪装IP接受到的数据
      

  3.   

    不通过编写驱动,伪装IP不能接受到任何数据
    伪装IP事实上是无效的IP,除非有驱动支持的虚拟网卡
      

  4.   

    哦,那微软的loopback网卡,算不算虚拟网卡,
    能不能使用伪装IP接受(或发送)数据。谢谢
      

  5.   

    二、IP头结构 
         我们知道,TCP/IP网络数据全部是通过封装在IP数据包中在Internet网上传送的,也就是封装建立起一个包含IP头和数据的IP数据报。一般来说,网络软件总是以多个32位字产生IP头,即使必须用附加的0填充IP头。IP头包含了传输IP数据包中封装数据的所有必要信息。IP头的数据结构和描述如下: 成员 长度(Bit) 描述 
    Version 4 IP头的版本号,目前是IPv4,最新是IPv6 
    Header Length 4 IP头的长度,若没有特殊选择,IP头总是20字节长 
    Type of Service 8 服务类型,定义了数据传输的优先级、延迟、吞吐量和可靠性等特性 
    Total Packet Length 16 IP包的长度,若没有特殊选项,一般为20字节长 
    Identification 16 IP包标识,主机使用它唯一确定每个发送的数据报 
    Flag 3 IP数据分割标志 
    Fragment Offset 13 IP数据分割偏移 
    Time to Live 8 数据报在网络上的存活时间,每通过一个路由器,该数值减一 
    Protocol 8 TCP/IP协议类型,比如:ICMP为1,IGMP为2,TCP为6,UDP为17等 
    Header Checksum 16 头部检验和 
    Source IP Address 32 源IP地址 
    Destination IP Address 32 目的IP地址 
    Other ? 其他选项 
    Data ? 数据 
         实现自己定义的IP头是一件非常有意义的事情,比如,通过改变IP头里的TOS的优先级和TTL,你可以使自己的数据包有更强的传输能力和寿命,通过修改IP头里的源IP地址就可以隐藏自己机器的IP地址等等。象著名攻击程序“泪滴TearDrop”就是通过故意制造系统不能处理的分片IP包而实现的,还有SYN Flooder和UDP Flooder就是通过产生随机源IP实现欺骗的。 三、实现原理 
         一般来说,自定义IP头是通过使用socket的库函数setsockopt()的选项IP_HDRINCL来实现的,尽管这在unix和linux平台上很容易实现,但遗憾的是在Windows平台的Winsock1.1和Winsock2.0函数库里setsockopt()不支持IP_HDRINCL选项,所以在Windows 9x/NT里是无法通过Winsock函数库来实现IP头自定义的,当然可以通过编写虚拟设备驱动程序来实现,不过比较复杂,但Windows 2000的出现打破了这种局面,Windows2000的Winsock2.2函数库里全面支持setsockopt()的选项IP_HDRINCL,使得我们轻松就可以实现自定义的IP头。实现方法如下: 四、代码部分 

    1. 本程序只能运行于 Window 2000. 
    2. 你必须有 Administrator 权限. 
    3. 程序需要用到一个 button 和一个 memo. 
    ---------------------------------------------------------------------- 
    运行程序前,请根据自己的需要改变 SrcIP、SrcPort、DestIP和DestPort的值 
    ---------------------------------------------------------------------- 
    如果你看不懂以下代码,最好不要去运行它。 
    ---------------------------------------------------------------------- 

    unit Unit1; 
    interface 
    uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
    StdCtrls, OleCtrls, Registry; Const 
    SrcIP = '123.123.123.1';//发送方IP地址 
    SrcPort = 1234;         file://发送方端口 
    DestIP = '127.0.0.2';   file://目的IP地址 
    DestPort = 4321;        file://目的端口 Max_Message = 4068; 
    Max_Packet = 4096; type TPacketBuffer = Array[0..Max_Packet-1] of byte; TForm1 = class(TForm) 
    Button1: TButton; 
    Memo1: TMemo; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    procedure SendIt; 
    end; // IP 头 
    type 
    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 头 
    Type 
    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 //  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; file://定义一些 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 Header Include SOCK_RAW = 3; // raw-protocol interface IPPROTO_IP = 0; // dummy for IP 
    IPPROTO_TCP = 6; // tcp 
    IPPROTO_UDP = 17; // user datagram protocol 
    IPPROTO_RAW = 255; // raw IP packet INVALID_SOCKET = TSocket(NOT(0)); 
    SOCKET_ERROR = -1; var 
    Form1: TForm1; implementation // Import Winsock 2 functions 
    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'; 
      

  6.   

    {$R *.DFM} 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); 
    inc(i); 
    Size := Size - SizeOf(Word); 
    end; if Size=1 then ChkSum := ChkSum + Byte(TWordArray(Buffer)); ChkSum := (ChkSum shr 16) + (ChkSum and $FFFF); 
    ChkSum := ChkSum + (Chksum shr 16); Result := Word(ChkSum); 
    end; 
    procedure BuildHeaders( 
    FromIP : String; 
    iFromPort : Word; 
    ToIP : String; 
    iToPort : Word; 
    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 
    // Convert ip address'ss 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); 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; // Time to live 
    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 ; 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; // 
    // 现在 IP 和 UDP 头OK了,我们可以把它发送出去。 
    // 
    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)); 
    remote.sin_family := AF_INET; 
    remote.sin_port := htons(iToPort); 
    remote.sin_addr.s_addr := dwToIP; 
    end; procedure TForm1.SendIt; 
    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 
    memo1.lines.add('WSA Startup failed.'); 
    exit; 
    end; 
    with memo1.lines do begin 
    add('WSA Startup:'); 
    add('Desc.: '+wsData.szDescription); 
    add('Status: '+wsData.szSystemStatus); 
    end; try 
    // Create socket 
    sh := Socket(AF_INET, SOCK_RAW, IPPROTO_UDP); 
    if (sh = INVALID_SOCKET) then begin 
    memo1.lines.add('Socket() failed: '+IntToStr(WSAGetLastError)); 
    exit; 
    end; 
    Memo1.lines.add('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 
    Memo1.lines.add('setsockopt(IP_HDRINCL) failed: '+IntToStr(WSAGetLastError)); 
    exit; 
    end; // Build the packet 
    BuildHeaders( SrcIP, SrcPort, 
    DestIP, DestPort, 
    'THIS IS A TEST PACKET', 
    Buf, Remote, iTotalSize ); // Send the packet 
    ret := SendTo(sh, buf, iTotalSize, 0, Remote, SizeOf(Remote)); 
    if ret = SOCKET_ERROR then 
    Memo1.Lines.Add('sendto() failed: '+IntToStr(WSAGetLastError)) 
    else 
    Memo1.Lines.Add('send '+IntToStr(ret)+' bytes.'); // Close socket 
    CloseSocket(sh); 
    finally 
    // Close Winsock 2 
    WSACleanup; 
    end; 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    SendIt; 
    end; end.
      

  7.   

    可以用一下WinPcap(有源代码,源代码开放你自己去找)
    www.winpcap.???(我忘记了)
      

  8.   

    TO: coolfilm(苏飞工作室)  
    这份资料好像是delphi的一个资料集上的,作者:james吧?
    这段代码可以实现IP地址的子定义,代码很简单的,楼主你可以看看
    我是运行通过,并且在此基础上做了一些小小的改动~~~~