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에 따라 라이센스가 부여됩니다.