使用原始套接字:SOCK_RAW

需要ICMP

代码如下:

#include<iostream>
#include<WinSock2.h> using namespace std; #pragma comment(lib, "WS2_32.lib") typedef struct icmp_hdr{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
unsigned short icmp_id;
unsigned short icmp_sequence;
unsigned long icmp_timnestamp;
}ICMP_HDR, *PICMP_HDR; typedef struct _IPHeader{
UCHAR iphVerLen;
UCHAR ipTOS;
USHORT ipLength;
USHORT ipID;
USHORT ipFlags;
UCHAR ipTTL;
UCHAR ipProtocol;
USHORT ipChecksum;
ULONG ipSource;
ULONG ipDestination;
}IPHeader, *PIPHeader; USHORT checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0; while(size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
} // 奇数,将最后一个字节扩展到双字, 再累加
if(size)
cksum += *(UCHAR*)buffer; //高16 低16相加,取反
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
} int main(void)
{
char szDestIp[] = "127.0.0.1";
SOCKET sRaw= ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
//SetTimeout(sRaw, 1000, TRUE); SOCKADDR_IN dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(5674);
dest.sin_addr.S_un.S_addr = inet_addr(szDestIp); char buff[sizeof(ICMP_HDR) + 32];
ICMP_HDR *pIcmp = (ICMP_HDR*)buff;
pIcmp->icmp_type = 8;
pIcmp->icmp_code = 0;
pIcmp->icmp_id = (USHORT)::GetCurrentProcess();
pIcmp->icmp_checksum = 0;
pIcmp->icmp_sequence = 0;
memset(&buff[sizeof(ICMP_HDR)], 'E', 32); //发送
USHORT nSeq = 0;
char recvBuf[1024];
SOCKADDR_IN from;
int nLen = sizeof(from);
while(TRUE)
{
static int nCount = 0;
int nRet;
if(nCount++ == 4)
break;
pIcmp->icmp_checksum = 0;
pIcmp->icmp_timnestamp = ::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)
{
cout << "sendto error:" << ::WSAGetLastError() << endl;
return -1;
} nRet = ::recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);
if(nRet == SOCKET_ERROR)
{
if(::WSAGetLastError() == WSAETIMEDOUT)
{
cout << "time out" << endl;
continue;
}
cout << "recvfrom failed:" << ::WSAGetLastError() << endl;
return -1;
} //解析
int nTick = ::GetTickCount();
if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR))
{
cout << "Too few bytes from " << ::inet_ntoa(from.sin_addr) << endl;
} ICMP_HDR *pRecvIcmp = (ICMP_HDR*)(recvBuf + sizeof(IPHeader));
if(pRecvIcmp->icmp_type != 0)
{
cout << "nonecho type " << pRecvIcmp->icmp_type << " recvd" << endl;
return -1;
}
if(pRecvIcmp->icmp_id != ::GetCurrentProcessId())
{
cout << "someone ele's packet!" << endl;
return -1;
} cout << nRet << " bytes from " << inet_ntoa(from.sin_addr) ;
cout << "icmp_seq = " << pRecvIcmp->icmp_sequence ;
cout << "time: " << nTick - pRecvIcmp->icmp_timnestamp << " ms";
cout << endl;
Sleep(1000);
} return 0;
}

jofranks  13.7.24 于南昌

最新文章

  1. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定
  2. OSX unable to write &#39;random state&#39;
  3. [Node.js] 闭包和高阶函数
  4. Android App 开发技能图谱
  5. SQL存储过程来调用webservice
  6. [问题2015S10] 复旦高等代数 II(14级)每周一题(第十一教学周)
  7. ARGB32 to YUV12 利用 SDL1.2 SDL_ttf 在视频表面输出文本
  8. getch()函数
  9. 【CCS仿真】用matlab把CCS保存的32位16进制的数据转换为十进制的数
  10. FFMPEG-数据结构解释(AVCodecContext,AVStream,AVFormatContext)
  11. mysql主要应用场景 转载
  12. css显示省略号
  13. VSC#2010打开视图编辑器假死/卡死
  14. ORA-00959: tablespace &#39;PSAPTEMP&#39; does not exist
  15. 浅谈Kotlin(二):基本类型、基本语法、代码风格
  16. 买二手iphone的建议
  17. Java并发-懒汉式单例设计模式加volatile的原因
  18. C# 在webapi项目中配置Swagger(最新版2017)
  19. BZOJ2388: 旅行规划(分块 凸包)
  20. CI框架 -- 核心文件 之 Benchmark.php

热门文章

  1. Java 9的14个新特性总结
  2. Retrofit全攻略——基础篇
  3. 虚拟机oracle virtualbox 上安装centos6.5 网络设置
  4. windows内核编程--头文件包括的奇葩的问题
  5. 乌云主站所有漏洞综合分析&amp;乌云主站漏洞统计
  6. unity web项目发布服务器Data file is corrupt (not a Unity W
  7. HBase源代码分析之MemStore的flush发起时机、推断条件等详情(二)
  8. javascript 字符串对象新增 replaceAll 方法
  9. C# 匿名类型 分组 求和
  10. centos 7 查看修改时区