设为首页 加入收藏

TOP

vc++Ping命令模拟进阶----如何嗅探某个IP段(一)
2014-11-23 21:34:51 】 浏览:1293
Tags:Ping 命令 模拟 进阶 ---- 如何 某个

这次我将代码整合后,做一个实战的练习,扫描一个IP段,返回所有活动的IP

要完成这个练习,以下有几个步骤,作为程序员的我们就用代码说话
首先要做到如何证明一个IP是否在活动,代码如下
Java代码
BOOL IpCheck::IsIPActive(char *addr)
{
// 目的IP地址,即要Ping的IP地址
char *szDestIp = addr; // 127.0.0.1

// 创建原始套节字
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

// 设置接收超时
SetTimeout(sRaw, 100, TRUE);

// 设置目的地址
SOCKADDR_IN dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(0);
dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);

// 创建ICMP封包
char buff[sizeof(ICMP_HDR) + 32];
ICMP_HDR* pIcmp = (ICMP_HDR*)buff;

// 填写ICMP封包数据,请求一个ICMP回显
pIcmp->icmp_type = 8;
pIcmp->icmp_code = 0;
pIcmp->icmp_id = (USHORT)GetCurrentProcessId();
pIcmp->icmp_checksum = 0;
pIcmp->icmp_sequence = 0;

// 填充数据部分,可以为任意
memset(&buff[sizeof(ICMP_HDR)], 'E', 32);

// 开始发送和接收ICMP封包
USHORT nSeq = 0;
char recvBuf[1024];
SOCKADDR_IN from;
int nLen = sizeof(from);

static int nCount = 0;
int nRet;

pIcmp->icmp_checksum = 0;
pIcmp->icmp_timestamp = GetTickCount();
pIcmp->icmp_sequence = nSeq++;
pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32);
nRet = sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *)&dest, sizeof(dest));
if(nRet == SOCKET_ERROR)
{
printf(" sendto() failed: %d \n", ::WSAGetLastError());
return -1;
}
nRet = recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);
if(nRet == SOCKET_ERROR)
{
if(WSAGetLastError() == WSAETIMEDOUT)
{
printf("%s timed out\n", addr);
return FALSE;
}
printf("recvfrom() failed: %d\n", WSAGetLastError());
return FALSE;
}

// 下面开始解析接收到的ICMP封包
int nTick = ::GetTickCount();
if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR))
{
printf(" Too few bytes from %s \n", inet_ntoa(from.sin_addr));
}

// 接收到的数据中包含IP头,IP头大小为20个字节,所以加20得到ICMP头
// (ICMP_HDR*)(recvBuf + sizeof(IPHeader));
ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + 20);
if(pRecvIcmp->icmp_type == ICMP_TYPE_REACH_FAIL) // 回显
{
printf("%s reach fail, type %d recvd \n", addr, pRecvIcmp->icmp_type);
return FALSE;
}

if(pRecvIcmp->icmp_id != GetCurrentProcessId())
{
printf(" someone else's packet! \n");
return FALSE;
}

printf("从 %s 返回 %d 字节:", addr,nRet);
printf(" 数据包序列号 = %d. \t", pRecvIcmp->icmp_sequence);
printf(" 延时大小: %d ms", nTick - pRecvIcmp->icmp_timestamp);
printf(" \n");

s_array->Insert(addr);

WSACleanup();
closesocket(sRaw);

return TRUE;
}


这个是扫描一个指定的IP地址,但是我们想要扫描多个IP地址的话,必须对IP地址进行转化,转化为整数就可以进行累加操作
Java代码
unsigned long __fastcall IpCheck::InvertIp(unsigned long NormalIp)
{
unsigned char b1,b2,b3,b4;

b1 = NormalIp & 0x00FF;
b2 = (NormalIp >> 8) & 0x00FF;
b3 = (NormalIp >> 16) & 0x00FF;
b4 = (NormalIp >

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇VC程序调试和纠错技巧总结 下一篇VC多线程编程之线程创建与示例

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目