简单的活动主机检测问题
来源:互联网 发布:天地诸神翅膀数据 编辑:程序博客网 时间:2024/06/07 09:57
#include<iostream>
#include<queue>
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment (lib,"ws2_32.lib")
#pragma comment (lib,"ipHlpApi.lib")
#pragma comment(lib,"wsock32.lib")
using namespace std;
char StartIp[20],EndIp[20];
//从命令行读取命令,加以分析
void AnalyCmd(int arg,char **str){
if(arg != 2){
cout<<"请输入正确的网段"<<endl;
exit(0);
}
//用0来填充内存中的区域
ZeroMemory(StartIp,20);
ZeroMemory(EndIp,20);
char ch = '-';
//查找ch出现的位置,返回出现字符的相关指针
char *pdest = strchr(str[1],ch);
int index = pdest-str[1]+1;
//提取相关IP地址
strncpy(StartIp,str[1],index-1);
strncpy(EndIp,str[1]+index,strlen(str[1]) - index);
}
//扫描目的主机是否存活,使用SendARP函数
/*
SendARP(
IPAddr DestIP, IP地址的网络字节顺序
IPAddr SrcIP, 填0
PULONG pMacAddr, MAc缓冲区指针
PULONG PhyAddrLen 指向一个DWORD型数值为6的指针
);
返回值为访问结果
*/
int Arp_ScanHoststate(char *ip){
IPAddr DestIp = inet_addr(ip);//将ip地址转换为网络字节序
ULONG pMacAddr[2];//将mac地址设为广播地址
memset(pMacAddr,0xff,sizeof(pMacAddr));
ULONG PhyAddrLen = 6;
HRESULT result = SendARP(DestIp,0,pMacAddr,&PhyAddrLen);
if(result == NO_ERROR){//正确返回
char strMacAddr[100]={0};
unsigned char* mac_addr = (unsigned char*)pMacAddr;//返回的远端主机的MAC地址是一个无符号的长整型数组
sprintf(strMacAddr,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
printf("主机%s 响应! MAC地址:%s\n",ip, strMacAddr);
return 1;
}
printf("主机%s 无响应!\n",ip);
return 0;
}
//需要目的主机在80,端口进行监听才可以获得主机存活信息
int Tcp_ScanHoststate(char *ip){
//初始化WSAStartup()函数
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0){
return 0;
}
SOCKET sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//创建socket
if(sock == INVALID_SOCKET){
printf("socket error !");
return 0;
}
//cout<<"++++++++++++++++++++++++++++++"<<endl;
sockaddr_in sin;
sin.sin_family = AF_INET ;
sin.sin_port = htons(80);
sin.sin_addr.S_un.S_addr = inet_addr(ip);
if(connect(sock, (sockaddr *)&sin, sizeof(sin)) == 0){
//
printf("主机%s 响应! ,主机存活\n",ip);
return 1;
}else{
printf("主机%s 无响应! ,主机不存活\n",ip);
}
return 0;
}
//定义ICMP首部
typedef struct icmp_hdr{
unsigned char icmp_type; // 消息类型
unsigned char icmp_code; // 代码
unsigned short icmp_checksum; // 校验和
unsigned short icmp_id; // 用来惟一标识此请求的ID号,通常设置为进程ID
unsigned short icmp_sequence; // 序列号
unsigned long icmp_timestamp; // 时间戳
} ICMP_HDR, *PICMP_HDR;
//校验和
USHORT checksum(USHORT* buff, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buff++;
size -= sizeof(USHORT);
}
// 是奇数
if(size)
{
cksum += *(UCHAR*)buff;
}
// 将32位的chsum高16位和低16位相加,然后取反
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16); // ???
return (USHORT)(~cksum);
}
USHORT nSeq=0;//序列号
int Icmp_ScanHoststate(char *ip){
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0){
printf("WSAStartup error !");
return 0;
}
SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP );//创建socket
if(sock == INVALID_SOCKET){
printf("socket error !");
return 0;
}
sockaddr_in sin;
sin.sin_family = AF_INET ;
sin.sin_port = htons(0);//ICMP为网络层协议,没有端口号
sin.sin_addr.S_un.S_addr = inet_addr(ip);
//创建ICMP数据报
char buff[sizeof(ICMP_HDR)+32];
ICMP_HDR * pIcmp=(ICMP_HDR *)buff;
//初始化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包
pIcmp->icmp_checksum=0;
pIcmp->icmp_timestamp=::GetTickCount();
pIcmp->icmp_sequence=nSeq++;
pIcmp->icmp_checksum=checksum((USHORT *)buff,sizeof(ICMP_HDR)+32);
//buff表示数据缓冲区的地址
int nRet=sendto(sock,buff,sizeof(ICMP_HDR)+32,0,(SOCKADDR *)&sin,sizeof(sin));
// int iRet = sendto(m_socket , (const char *) lpBuffer, dwSize, 0, (SOCKADDR *)&sin, sizeof(sin));
if(nRet==SOCKET_ERROR){
printf("sendto() failed:%d\n",::WSAGetLastError());
return 0;
}
//akrshm
char revBuf[1024];
sockaddr_in from;
int nLen=sizeof(from);
//设置为非阻塞模式
int iMode = 1; //0:阻塞
ioctlsocket(sock,FIONBIO, (u_long FAR*) &iMode);//非阻塞设置
nRet=recvfrom(sock,revBuf,1024,0,(sockaddr *)&from,&nLen);
if (nRet >-1){
printf("%s 主机存活!\n",ip);
WSACleanup();
return 1;
}else{
printf("%s 主机没有存活!\n",ip);
WSACleanup();
return 0;
}
WSACleanup();
return 0;
}
int main(int argc, char *argv[]){
AnalyCmd(argc,argv);
struct in_addr targetaddr; //目标机地址结构 \
unsigned long ips=inet_addr(StartIp); //计算起始IP地址的网络字节
unsigned long ipe=inet_addr(EndIp); //计算结束IP地址的网络字节
ips=ntohl(ips);//计算起始IP地址的主机字节 转换为主机字节
ipe=ntohl(ipe);//计算结束IP地址的主机字节
DWORD dwStart = GetTickCount();//记录开始时间
//开始循环探测主机
for(unsigned long k=ips;k<=ipe;k++){
targetaddr.S_un.S_addr=htonl(k);//转换为网络字节
cout<<"------------------------------------------------"<<endl;
Arp_ScanHoststate(inet_ntoa(targetaddr));//探测指定主机是否存活
Tcp_ScanHoststate(inet_ntoa(targetaddr));
Icmp_ScanHoststate(inet_ntoa(targetaddr));
}
printf("探测消耗时间:%d ms",GetTickCount()-dwStart);
return 0;
}
//>demo.exe 192.168.23.1-192.168.23.5
#include<queue>
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment (lib,"ws2_32.lib")
#pragma comment (lib,"ipHlpApi.lib")
#pragma comment(lib,"wsock32.lib")
using namespace std;
char StartIp[20],EndIp[20];
//从命令行读取命令,加以分析
void AnalyCmd(int arg,char **str){
if(arg != 2){
cout<<"请输入正确的网段"<<endl;
exit(0);
}
//用0来填充内存中的区域
ZeroMemory(StartIp,20);
ZeroMemory(EndIp,20);
char ch = '-';
//查找ch出现的位置,返回出现字符的相关指针
char *pdest = strchr(str[1],ch);
int index = pdest-str[1]+1;
//提取相关IP地址
strncpy(StartIp,str[1],index-1);
strncpy(EndIp,str[1]+index,strlen(str[1]) - index);
}
//扫描目的主机是否存活,使用SendARP函数
/*
SendARP(
IPAddr DestIP, IP地址的网络字节顺序
IPAddr SrcIP, 填0
PULONG pMacAddr, MAc缓冲区指针
PULONG PhyAddrLen 指向一个DWORD型数值为6的指针
);
返回值为访问结果
*/
int Arp_ScanHoststate(char *ip){
IPAddr DestIp = inet_addr(ip);//将ip地址转换为网络字节序
ULONG pMacAddr[2];//将mac地址设为广播地址
memset(pMacAddr,0xff,sizeof(pMacAddr));
ULONG PhyAddrLen = 6;
HRESULT result = SendARP(DestIp,0,pMacAddr,&PhyAddrLen);
if(result == NO_ERROR){//正确返回
char strMacAddr[100]={0};
unsigned char* mac_addr = (unsigned char*)pMacAddr;//返回的远端主机的MAC地址是一个无符号的长整型数组
sprintf(strMacAddr,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
printf("主机%s 响应! MAC地址:%s\n",ip, strMacAddr);
return 1;
}
printf("主机%s 无响应!\n",ip);
return 0;
}
//需要目的主机在80,端口进行监听才可以获得主机存活信息
int Tcp_ScanHoststate(char *ip){
//初始化WSAStartup()函数
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0){
return 0;
}
SOCKET sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//创建socket
if(sock == INVALID_SOCKET){
printf("socket error !");
return 0;
}
//cout<<"++++++++++++++++++++++++++++++"<<endl;
sockaddr_in sin;
sin.sin_family = AF_INET ;
sin.sin_port = htons(80);
sin.sin_addr.S_un.S_addr = inet_addr(ip);
if(connect(sock, (sockaddr *)&sin, sizeof(sin)) == 0){
//
printf("主机%s 响应! ,主机存活\n",ip);
return 1;
}else{
printf("主机%s 无响应! ,主机不存活\n",ip);
}
return 0;
}
//定义ICMP首部
typedef struct icmp_hdr{
unsigned char icmp_type; // 消息类型
unsigned char icmp_code; // 代码
unsigned short icmp_checksum; // 校验和
unsigned short icmp_id; // 用来惟一标识此请求的ID号,通常设置为进程ID
unsigned short icmp_sequence; // 序列号
unsigned long icmp_timestamp; // 时间戳
} ICMP_HDR, *PICMP_HDR;
//校验和
USHORT checksum(USHORT* buff, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buff++;
size -= sizeof(USHORT);
}
// 是奇数
if(size)
{
cksum += *(UCHAR*)buff;
}
// 将32位的chsum高16位和低16位相加,然后取反
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16); // ???
return (USHORT)(~cksum);
}
USHORT nSeq=0;//序列号
int Icmp_ScanHoststate(char *ip){
WORD sockVersion = MAKEWORD(2,2);
WSADATA data;
if(WSAStartup(sockVersion, &data) != 0){
printf("WSAStartup error !");
return 0;
}
SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP );//创建socket
if(sock == INVALID_SOCKET){
printf("socket error !");
return 0;
}
sockaddr_in sin;
sin.sin_family = AF_INET ;
sin.sin_port = htons(0);//ICMP为网络层协议,没有端口号
sin.sin_addr.S_un.S_addr = inet_addr(ip);
//创建ICMP数据报
char buff[sizeof(ICMP_HDR)+32];
ICMP_HDR * pIcmp=(ICMP_HDR *)buff;
//初始化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包
pIcmp->icmp_checksum=0;
pIcmp->icmp_timestamp=::GetTickCount();
pIcmp->icmp_sequence=nSeq++;
pIcmp->icmp_checksum=checksum((USHORT *)buff,sizeof(ICMP_HDR)+32);
//buff表示数据缓冲区的地址
int nRet=sendto(sock,buff,sizeof(ICMP_HDR)+32,0,(SOCKADDR *)&sin,sizeof(sin));
// int iRet = sendto(m_socket , (const char *) lpBuffer, dwSize, 0, (SOCKADDR *)&sin, sizeof(sin));
if(nRet==SOCKET_ERROR){
printf("sendto() failed:%d\n",::WSAGetLastError());
return 0;
}
//akrshm
char revBuf[1024];
sockaddr_in from;
int nLen=sizeof(from);
//设置为非阻塞模式
int iMode = 1; //0:阻塞
ioctlsocket(sock,FIONBIO, (u_long FAR*) &iMode);//非阻塞设置
nRet=recvfrom(sock,revBuf,1024,0,(sockaddr *)&from,&nLen);
if (nRet >-1){
printf("%s 主机存活!\n",ip);
WSACleanup();
return 1;
}else{
printf("%s 主机没有存活!\n",ip);
WSACleanup();
return 0;
}
WSACleanup();
return 0;
}
int main(int argc, char *argv[]){
AnalyCmd(argc,argv);
struct in_addr targetaddr; //目标机地址结构 \
unsigned long ips=inet_addr(StartIp); //计算起始IP地址的网络字节
unsigned long ipe=inet_addr(EndIp); //计算结束IP地址的网络字节
ips=ntohl(ips);//计算起始IP地址的主机字节 转换为主机字节
ipe=ntohl(ipe);//计算结束IP地址的主机字节
DWORD dwStart = GetTickCount();//记录开始时间
//开始循环探测主机
for(unsigned long k=ips;k<=ipe;k++){
targetaddr.S_un.S_addr=htonl(k);//转换为网络字节
cout<<"------------------------------------------------"<<endl;
Arp_ScanHoststate(inet_ntoa(targetaddr));//探测指定主机是否存活
Tcp_ScanHoststate(inet_ntoa(targetaddr));
Icmp_ScanHoststate(inet_ntoa(targetaddr));
}
printf("探测消耗时间:%d ms",GetTickCount()-dwStart);
return 0;
}
//>demo.exe 192.168.23.1-192.168.23.5
阅读全文
1 0
- 简单的活动主机检测问题
- 列出当前网络上的活动主机
- 活动的安排问题 .
- 基于多线程设计检测多台主机ICMP消息串位的问题
- 一次简单的微信秒杀活动
- 简单的Lua活动实现
- 6.1基于主机的入侵检测系统
- 内存泄漏检测问题的一种简单解决办法
- 活动规划问题的应用
- 活动安排问题的贪心
- 检测麦克风活动
- 虚拟机、主机ping的问题
- symbian中活动对象的简单使用
- symbian中活动对象的简单使用
- 主机安全检测
- 检测主机tcp端口是否开放的程序
- 如何检测远程主机上的某个端口是否开启?
- 如何检测远程主机上的某个端口是否开启
- Hello blog!
- Oracle创建用户并给用户授权查询指定表或视图的权限
- Android Butterknife 8.4.0 ButterKnife是一个专注于Android系统的View注入框架,可以减少大量的findViewById以及setOnClickListene
- Ubuntu 配置tomcat
- CSDN如何转载别人的博客
- 简单的活动主机检测问题
- 算术表达式的转换
- Linux中vnc的配置端口号的修改
- Tomcat连接数设置参数
- 【Tensorflow】安装spyder(tensorflow)后无法启动
- 面试中不足
- LRU缓存的JavaScript实现
- POJ 2155 Matrix 二维树状数组
- 我的第一个Vue.js输出信息