WIN32汇编语言教程:第16章 TCP/IP和网络通信 · 16.5 ICMP协议编程(4)

              local  @szBuffer[256]:byte

              local  @dwIP

 

      invoke inet_addr,_lpszHostName

      .if    eax != INADDR_NONE

;********************************************************************

; 输入的是IP地址

;********************************************************************

             mov    @dwIP,eax

              invoke inet_ntoa,eax

              invoke wsprintf,addr szBuffer,addr szPingOneIP,eax

      .else

;********************************************************************

; 输入的是主机名称

;********************************************************************

              invoke gethostbyname,_lpszHostName

             .if    eax

                       xor    edi,edi    ;用edi做计数器

                     mov    eax,[eax+hostent.h_list]

                      .while dword ptr [eax]

                              mov    ebx,[eax]

                            push      [ebx]

                              inc    edi

                             add    eax,4

                      .endw

                      pop    eax

                      mov    @dwIP,eax

                      invoke inet_ntoa,eax

                     mov    ebx,eax

                       .if    edi == 1  ;主机对应一个IP地址

                             invoke wsprintf,addr szBuffer,\

                                      addr szHostOneIP,_lpszHostName,ebx

                             invoke wsprintf,addr @szBuffer,\

                                      addr szPingOneIP,ebx

                       .else              ;主机对应多个IP地址

                             invoke wsprintf,addr szBuffer,\

                                     addr szHostMoreIP,_lpszHostName,edi

                              invoke lstrcat,addr szBuffer,ebx

                             invoke wsprintf,addr @szBuffer,\

                                      addr szPingMoreIP,ebx

                              .while edi > 1

                                      invoke lstrcat,addr szBuffer,\

                                              addr szSpar

                                     pop eax

                                     invoke inet_ntoa,eax

                                     invoke lstrcat,addr szBuffer,eax

                                      dec    edi

                             .endw

                      .endif

                     invoke lstrcat,addr szBuffer,addr @szBuffer

             .else

                      invoke wsprintf,addr szBuffer,\

                            addr szErrHost,addr szHostName

                      invoke _ConsolePrint,addr szBuffer

                    xor    eax,eax

                      ret

              .endif

      .endif

      invoke _ConsolePrint,addr szBuffer

      mov    eax,@dwIP

      ret

 

_HostnameToIP  endp

;####################################################################

; Ping 主程序

;####################################################################

_Ping     proc      _dwIP

              local  @szBuffer[256]:byte

              local  @stDest:sockaddr_in

             local  @stFrom:sockaddr_in

              local  @hSocket,@dwSize

              local  @stFdSet:fd_set

             local  @stTimeval:timeval

             local  @dwID:word,@dwSeq:word

 

      pushad

      mov    @stDest.sin_port,0

      mov    @stDest.sin_family,AF_INET

      push      _dwIP

      pop    @stDest.sin_addr

;********************************************************************

; 初始化一个 socket 发送 ICMP 的 RAW 数据

;********************************************************************

      invoke socket,AF_INET,SOCK_RAW,IPPROTO_ICMP

      .if    eax == INVALID_SOCKET

              invoke _ConsolePrint,addr szErrSocket

              jmp    _Ping_Ret

      .endif

      mov    @hSocket,eax

;********************************************************************

; 循环 Ping

;********************************************************************

      xor    ebx,ebx

      mov    @dwID,1

      mov    @dwSeq,1

      .while TRUE

              .break .if (dwOption & F_ABORT) || (ebx >= 4)

             inc    ebx

             assume esi:ptr icmp_hdr

             mov    esi,offset szBigBuffer

              invoke RtlZeroMemory,esi,sizeof szBigBuffer

;********************************************************************

; 构造 Echo Request 数据包

;********************************************************************

              mov    ax,@dwID

             mov    [esi].icmp_id,ax

              mov    ax,@dwSeq

             mov    [esi].icmp_seq,ax

               mov    [esi].icmp_type,ICMP_ECHOREQ

             invoke GetTickCount

               mov    dword ptr [esi].icmp_data,eax  ;将当前时间当做数据

              mov    ecx,PACKET_SIZE

             add    ecx,sizeof icmp_hdr-1

             invoke _CalcCheckSum,addr szBigBuffer,ecx

              mov    [esi].icmp_cksum,ax

;********************************************************************

; 发送 Echo Request 数据包

;********************************************************************

             invoke sendto,@hSocket,addr szBigBuffer,ecx,\

                       0,addr @stDest,sizeof sockaddr_in

              .if    eax == SOCKET_ERROR

                     invoke _ConsolePrint,addr szErrUnreach

                      .continue

             .endif

             assume esi:nothing

;********************************************************************

; 等待回复

;********************************************************************

              @@:

             mov    @stFdSet.fd_count,1

              push      @hSocket

              pop    @stFdSet.fd_array

上页:第16章 TCP/IP和网络通信 · 16.5 ICMP协议编程(3) 下页:第16章 TCP/IP和网络通信 · 16.5 ICMP协议编程(5)

第16章 TCP/IP和网络通信

版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号