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)