ICMP 검사
                                            
 6969 단어  scan
                    
원리는 스캔이 필요한 ip처럼 icmp로 리셋을 요청하고 icmp 리셋 응답을 받으면 이 ip는 활동 상태에 있다. 그렇지 않으면 아니다. 여기서 내가 개발한 환경은 win7+vs2013이다. 구축된 일반 컨트롤 게이지 프로그램은 socket을 사용하면 된다.
1. 헤드를 정의합니다.h 헤더 파일, 필요한 헤더 정의에 사용
#include"winsock2.h"
#pragma comment(lib,"ws2_32")
#include"WS2TCPIP.H"
#include "mstcpip.h"  //ip  ,         ip    ,              ,    ,  http://blog.csdn.net/u012198947/article/details/51078214     
typedef struct _iphdr
{
	unsigned char h_lenver;
	unsigned char tos;
	unsigned short total_len;
	unsigned short ident;
	unsigned short frag_and_flags;
	unsigned char ttl;
	unsigned char proto;
	unsigned short checksum;
	unsigned int sourceIP;
	unsigned int destIP;
}IPHEADER;
  //icmp  
typedef struct _icmphdr
{
	BYTE i_type;
	BYTE i_code;
	USHORT i_cksum;
	USHORT i_id;
	USHORT i_seq;
	ULONG timestamp;
}ICMPHEADER;
//    
typedef struct
{
	USHORT usSeqNo;		  //    
	DWORD dwRoundTripTime; //    
	in_addr dwIPaddr;	  //  IP  
} DECODE_RESULT;//ip    ,    ,  ip      2. 패킷을 보내는 함수
//       ,    icmp     //        ,  0,  -1  //             ,            int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr)
{
	int nRet; //
	char IcmpSendBuf[sizeof(ICMPHEADER)];//       
	//     
	memset(IcmpSendBuf, 0, sizeof(IcmpSendBuf));
	ICMPHEADER *pIcmpHeader = (ICMPHEADER*)IcmpSendBuf;
	pIcmpHeader->i_type = 8; //      
	pIcmpHeader->i_code = 0;
	pIcmpHeader->i_id = (USHORT)GetCurrentProcessId();//     ,             
	pIcmpHeader->i_seq = 0x0;//
	pIcmpHeader->i_cksum = 0;
	pIcmpHeader->timestamp = 0x01020304;//  ,  ,      ,      4B
	pIcmpHeader->i_cksum = CheckSum((USHORT*)pIcmpHeader, sizeof(ICMPHEADER));//     ,    :
	nRet = sendto(s, IcmpSendBuf, sizeof(IcmpSendBuf),0, (LPSOCKADDR)lpstToAddr, sizeof(SOCKADDR_IN));//  
	if (nRet == SOCKET_ERROR)
	{
		cout << "sento Error" << endl;
		return -1;
	}
	return 0;
}
  //       
USHORT CheckSum(USHORT *buffer, int size)
{
	unsigned long cksum = 0;
	while (size > 1)
	{
		cksum += *buffer++;
		size -= sizeof(USHORT);
	}
	if (size)
	{
		cksum += *(UCHAR*)buffer;
	}
	while (cksum >> 16)
		cksum = (cksum >> 16) + (cksum & 0xffff);
	return (USHORT)(~cksum);
}
  3. 수신된 패키지를 분석하는 함수
/********************************************************
   :DecodeIcmpResponse
    :char* pBuf:         (  IP  )
int iPacketSize:       
DECODE_RESULT *stDecodeResult:      
    :       ,true:  ,false:  
  :          ,    ICMP             
*********************************************************/
BOOL DecodeIcmpResponse(char* pBuf, int iPacketSize, DECODE_RESULT& stDecodeResult)
{
	IPHEADER* pIpHdr = (IPHEADER*)pBuf;
	int iIpHdrLen = 20;//ip  ,  20  
	
	//ip    20  ,   icmp  
	ICMPHEADER* pIcmpHdr = (ICMPHEADER*)(pBuf + iIpHdrLen);
	USHORT usID, usSquNo;
	if (pIcmpHdr->i_type == 0)//    
	{
		usID = pIcmpHdr->i_id;
		usSquNo = pIcmpHdr->i_seq;
	}
	else
		return FALSE;
	//       ICMP   ,  type=0 icmp      ,      code
	if (pIcmpHdr->i_type == 0 )
	{
		//      
		stDecodeResult.dwIPaddr.s_addr = pIpHdr->sourceIP;
		stDecodeResult.dwRoundTripTime = GetTickCount() - stDecodeResult.dwRoundTripTime;
		return TRUE;
	}
	return FALSE;
}  4. 수신 패킷 함수
/********************************************************
   :RecvEchoReply
    :SOCKET s:     
SOCKADDR_IN *saFrom:        
SOCKADDR_IN *saDest:        
DECODE_RESULT *stDecodeResult:      
    :       ,true:  ,false:  
  :    ,   DecodeIcmpResponse     ICMP      
*********************************************************/
DWORD RecvEchoReply(SOCKET s, SOCKADDR_IN *saFrom, SOCKADDR_IN *saDest, DECODE_RESULT *stDecodeResult)
{
	int nRet;
	int nAddrLen = sizeof(struct sockaddr_in);
	//  ICMP      
	char IcmpRecvBuf[1024];
	memset(IcmpRecvBuf, 0, sizeof(IcmpRecvBuf));
	//   	
	nRet = recvfrom(s,					// socket
		(LPSTR)&IcmpRecvBuf,	// buffer
		1024,	// size of buffer
		0,					// flags
		(LPSOCKADDR)saFrom,	// From address
		&nAddrLen);			// pointer to address len
	//    
	if (nRet != SOCKET_ERROR) //      
	{
		//        ,                  EchoRequest 
		if (DecodeIcmpResponse(IcmpRecvBuf, nRet, *stDecodeResult))
		{
			if (stDecodeResult->dwIPaddr.s_addr == saDest->sin_addr.s_addr)
			{
				printf("         
");
				return 1;
			}
		}
		else
			return -1;
	}
	else if (WSAGetLastError() == WSAETIMEDOUT) //    ,     ,             icmp  ,       ip          ,  //    icmp  ,    arp    ip    ,   ip  ,       icmp  ,     ,       ,          
	{
		printf("          
");
	}
	else
	{
		printf("recvfrom      ,   : %d
", WSAGetLastError());
		return -1;
	}
	return 0;
}  5. 다음은 주 함수
 int main() 
{ 
int iResult; 
SOCKET sockRaw; 
sockaddr_in addrDest, addrSrc; 
DECODE_RESULT stDecodeResult; 
USHORT usSeqNo = 0; 
WSADATA wsaData; 
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
if (iResult != 0)  
{ 
//사용 가능한 Winsock DLL을 찾을 수 없음 알림
printf("WSAstartup 함수 호출 오류, 오류 번호:%d", WSAGetLastError();
return -1; 
} 
//원래 소켓 작성
sockRaw= socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
//수신 제한 시간 설정
int iTimeout = 1000; 
iResult = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeout, sizeof(iTimeout)); 
memset(&stDecodeResult, 0, sizeof(DECODE_RESULT)); 
//스캔이 필요한 IP는 필요에 따라 값을 매겨라
addrDest.sin_addr.S_un.S_addr = inet_addr("192.168.218.18"); 
addrDest.sin_family = AF_INET; 
//ICMP Echo 요청 보내기
iResult = SendEchoRequest(sockRaw, &addrDest); 
if (iResult == SOCKET_ERROR) 
{ 
if (WSAGetLastError() == WSAEHOSTUNREACH){ 
printf ("목적 호스트가 도달할 수 없음,traceroute 탐지 종료!");
return -1; 
} 
} 
//ICMP의 EchoReply 데이터 보고서 수신
iResult = RecvEchoReply(sockRaw, &addrSrc, &addrDest, &stDecodeResult); 
return 0; 
} 
자, 이렇게 하면 ok 이다 
  
                              
                        
                이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
nrich - 오픈 포트와 취약점을 신속하게 파악나는 NRICH로 몇 가지 테스트를 할 기회가 있다. 이것은 매우 빠른 명령행 도구로 IP를 분석하고 개방 포트와 빈틈의 결과를 되돌릴 수 있다! 테스트 환경에 대해 예상대로 작동하는지 확인하기 위해 Ubuntu 2...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.