/*******************************************
*Copyrights 2014
*
*All rights reserved.
*
*Filename:
* Ping.cpp
*Indentifier:
* 这里填入该文件的标识(参见软件配置管理)
*Description:
* Ping.h 头文件
*Version:
* V1.0
*Author: yxcheng
*
*Finished:2014-5-19
*
*History:
* (作者 日期 版本 说明)
* 文件修订历史纪录(一般情况下用中文)
********************************************/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include "resolve.h"
#include "iphdr.h"
#define DEFAULT_DATA_SIZE 32 // default data size
#define DEFAULT_SEND_COUNT 20 // number of ICMP requests to send
#define DEFAULT_RECV_TIMEOUT 6000 // six second
#define DEFAULT_TTL 128
#define MAX_RECV_BUF_LEN 0xFFFF // Max incoming packet size.
int gAddressFamily=AF_UNSPEC, // Address family to use
gProtocol=IPPROTO_ICMP, // Protocol value
gTtl=DEFAULT_TTL; // Default TTL value
int gDataSize=DEFAULT_DATA_SIZE; // Amount of data to send
BOOL bRecordRoute=FALSE; // Use IPv4 record route?
char *gDestination=NULL, // Destination
recvbuf[MAX_RECV_BUF_LEN]; // For received packets
int recvbuflen = MAX_RECV_BUF_LEN; // Length of received packets.
#include "Ping.h"
void NetTerminal::PrintPayload(char *buf, int bytes)
{
int hdrlen=0,
routes=0,
i;
UNREFERENCED_PARAMETER(bytes);
if (gAddressFamily == AF_INET)
{
SOCKADDR_IN hop;
IPV4_OPTION_HDR *v4opt=NULL;
IPV4_HDR *v4hdr=NULL;
hop.sin_family = (USHORT)gAddressFamily;
hop.sin_port = 0;
v4hdr = (IPV4_HDR *)buf;
hdrlen = (v4hdr->ip_verlen & 0x0F) * 4;
// If the header length is greater than the size of the basic IPv4
// header then there are options present. Find them and print them.
if (hdrlen > sizeof(IPV4_HDR))
{
v4opt = (IPV4_OPTION_HDR *)(buf + sizeof(IPV4_HDR));
routes = (v4opt->opt_ptr / sizeof(ULONG)) - 1;
for(i=0; i < routes ;i++)
{
hop.sin_addr.s_addr = v4opt->opt_addr[i];
// Print the route
if (i == 0)
printf(" Route: ");
else
printf(" ");
PrintAddress((SOCKADDR *)&hop, sizeof(hop));
if (i < routes-1)
printf(" ->\n");
else
printf("\n");
}
}
}
return;
}
int NetTerminal::PostRecvfrom(SOCKET s, char *buf, int buflen, SOCKADDR *from, int *fromlen, WSAOVERLAPPED *ol)
{
WSABUF wbuf;
DWORD flags,
bytes;
int rc;
wbuf.buf = buf;
wbuf.len = buflen;
flags = 0;
rc = WSARecvFrom(
s,
&wbuf,
1,
&bytes,
&flags,
from,
fromlen,
ol,
NULL
);
if (rc == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
fprintf(stderr, "WSARecvFrom failed: %d\n", WSAGetLastError());
return SOCKET_ERROR;
}
}
return NO_ERROR;
}
void NetTerminal::ComputeIcmpChecksum(SOCKET s, char *buf, int packetlen, struct addrinfo *dest)
{
if (gAddressFamily == AF_INET)
{
ICMP_HDR *icmpv4=NULL;
icmpv4 = (ICMP_HDR *)buf;
icmpv4->icmp_checksum = 0;
icmpv4->icmp_checksum = checksum((USHORT *)buf, packetlen);
}
else if (gAddressFamily == AF_INET6)
{
ICMPV6_HDR *icmpv6=NULL;
icmpv6 = (ICMPV6_HDR *)buf;
icmpv6->icmp6_checksum = 0;
icmpv6->icmp6_checksum = ComputeIcmp6PseudoHeaderChecksum(
s,
buf,
packetlen,
dest
);
}
}
USHORT NetTerminal::ComputeIcmp6PseudoHeaderChecksum(SOCKET s, char *icmppacket, int icmplen, struct addrinfo *dest)
{
SOCKADDR_STORAGE localif;
DWORD bytes;
char tmp[MAX_RECV_BUF_LEN] = {'\0'},
*ptr=NULL,
proto=0;
int rc, total, length, i;
// Find out which local interface for the destination
rc = WSAIoctl(
s,
SIO_ROUTING_INTERFACE_QUERY,
dest->ai_addr,
(DWORD) dest->ai_addrlen,
(SOCKADDR *) &localif,
(DWORD) sizeof(localif),
&bytes,
NULL,
NULL
);
if (rc == SOCKET_ERROR)
{
fprintf(stderr, "WSAIoctl failed: %d\n", WSAGetLastError());
return 0xFFFF;
}
// We use a temporary buffer to calculate the pseudo header.
ptr = tmp;
total = 0;
// Copy source address
memcpy(ptr, &((SOCKADDR_IN6 *)&localif)->sin6_addr, sizeof(struct in6_addr));
ptr += sizeof(struct in6_addr);
total += sizeof(struct in6_addr);
printf("%x%x%x%x\n",
((SOCKADDR_IN6 *) &localif)->sin6_addr.u.Byte[0],
((SOCKADDR_IN6 *) &localif)->sin6_addr.u.Byte[1],
((SOCKADDR_IN6 *) &localif)->sin6_addr.u.Byte[2],
((SOCKADDR_IN6 *) &localif)->sin6_addr.u.Byte[3]
);
// Copy destination address
memcpy(ptr, &((SOCKADDR_IN6 *)dest->ai_addr)->sin6_addr, sizeof(struct in6_addr));
ptr += sizeof(struct in6_addr);
total += sizeof(struct in6_addr);
// Copy ICMP packet length
length = htonl(icmplen);
memcpy(ptr, &length, sizeof(length));
ptr += sizeof(length);
total += sizeof(length);
printf("%x%x%x%x\n",
(char ) *(ptr - 4),
(char ) *(ptr - 3),
(char ) *(ptr - 2),
(char ) *(ptr - 1)
);
// Zero the 3 bytes
memset(ptr, 0, 3);
ptr += 3;
total += 3;
// Copy next hop header
proto = IPPROTO_ICMP6;
memcpy(ptr, &proto, sizeof(proto));
ptr += sizeof(proto);
total += sizeof(proto);
// Copy the ICMP header and payload
memcpy(ptr, icmppacket, icmplen);
ptr += icmplen;
total += icmplen;
for(i=0; i < icmplen%2 ;i++)
{
*ptr = 0;
ptr++;
total++;
}
return checksum((USHORT *)tmp, total);
}
void NetTerminal::SetIcmpSequence(char *buf)
{
ULONG sequence=0;
sequence = GetTickCount();
if (gAddressFamily == AF_INET)
{
ICMP_HDR *icmpv4=NULL;
icmpv4 = (ICMP_HDR *)buf;
icmpv4->icmp_sequence = (USHORT)sequence;
}
else if (gAddressFamily == AF_INET6)
{
ICMPV6_HDR *icmpv6=NULL;
ICMPV6_ECHO_REQUEST *req6=NULL;
icmpv6 = (ICMPV6_HDR *)buf;
req6 = (ICMPV6_ECHO_REQUEST *)(buf + sizeof(ICMPV6_HDR));
req6->icmp6_echo_sequence = (USHORT)sequence;
}
}
USHORT NetTerminal::checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
int NetTerminal::InitIcmp6Header(char *buf, int datasize)
{
ICMPV6_HDR *icmp6_hdr=NULL;
ICMPV6_ECHO_REQUEST *icmp6_req=NULL;
char *datapart=NULL;
// Initialize the ICMP6 headerf ields
icmp6_hdr = (ICMPV6_HDR *)buf;
icmp6_hdr->icmp6_type = ICMPV6_ECHO_REQUEST_TYPE;
icmp6_hdr->icmp6_code = ICMPV6_ECHO_REQUEST_CODE;
icmp6_hdr->icmp6_checksum = 0;
// Initialize the echo request fields
icmp6_req = (ICMPV6_ECHO_REQUEST *)(buf + sizeof(ICMPV6_HDR));
icmp6_req->icmp6_echo_id = (USHORT)GetCurrentProcessId();
icmp6_req->icmp6_echo_sequence = 0;
datapart = (char *)buf + sizeof(ICMPV6_HDR) + sizeof(ICMPV6_ECHO_REQUEST);
memset(datapart, '#', datasize);
return (sizeof(ICMPV6_HDR) + sizeof(ICMPV6_ECHO_REQUEST));
}
void NetTerminal::InitIcmpHeader(char *buf, int datasize)
{
ICMP_HDR *icmp_hdr=NULL;
char *datapart=NULL;
icmp_hdr = (ICMP_HDR *)buf;
icmp_hdr->icmp_type = ICMPV4_ECHO_REQUEST_TYPE; // request an ICMP echo
icmp_hdr->icmp_code = ICMPV4_ECHO_REQUEST_CODE;
icmp_hdr->icmp_id = (USHORT)GetCurrentProcessId();
icmp_hdr->icmp_checksum = 0;
icmp_hdr->icmp_sequence = 0;
datapart = buf + sizeof(ICMP_HDR);
//
// Place some data in the buffer.
//
memset(datapart, 'E', datasize);
}
void NetTerminal::run()
{
WSADATA wsd;
WSAOVERLAPPED recvol;
SOCKET s=INVALID_SOCKET;
char
Windows 完整PING功能实现
需积分: 50 177 浏览量
2014-05-19
21:47:14
上传
评论 1
收藏 43KB RAR 举报
liawof
- 粉丝: 3
- 资源: 9
最新资源
- 院校-课程网盘链接提取码下载 .txt
- SamsungeShop.apk
- 32Meg x 8, 16Meg x16 256Mb SYNCHRONOUS DRAM手册
- 手写字识别-基于Transformer实现手写字文本识别-附项目源码-优质项目实战.zip
- 基于 Swin-Transformer 网络对 眼底血管2分类识别项目【数据集+代码+训练好的所有结果】
- 采用P-f和Q-V滞控的去中心化逆变器型交流微电网的模拟(Simulink仿真实现)
- 彩虹聚合二级域名DNS管理系统源码v1.3
- 【TOF相机笔记3】Simulink使用方法
- 算法部署-基于C++和Python使用ONNXRuntime部署RT-DETR目标检测算法-附项目源码-优质项目实战.zip
- Bitree.cpp
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈