C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)
/*页面编码:GBK 开发环境 VS2019 */
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
std::string Utf8ToGbk(const char* src_str)
{
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0);
wchar_t* wszGBK = new wchar_t[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len);
len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
char* szGBK = new char[len + 1];
memset(szGBK, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
std::string strTemp(szGBK);
if (wszGBK) delete[] wszGBK;
if (szGBK) delete[] szGBK;
return strTemp;
}
typedef struct _IP_HEADER
{
char m_cVersionAndHanderLen; //版本信息(前4位),头长度(后4位)
char m_cTypeOfService; //服务类型8位
short m_sTotalLenOfPacket; //数据包长度
short m_sPacketID; //数据包标识
short m_sSliceinfo; //分片使用
char m_cTTL; //存活时间
char m_cTypeOfProtocol; //协议类型
short m_sChechSum; //校验和
unsigned int m_uiSourIp; //源IP地址
unsigned int m_uiDestIp; //目的IP地址
}IP_HEADER, * PIP_HEADER;
typedef struct _UDP_HEADER
{
unsigned short m_usSourPort; //源端口号16bit
unsigned short m_usDestPort; //目的端口号16bit
unsigned short m_usLength; //数据包长度16bit
unsigned short m_usCheckSum; //校验和16bit
}UDP_HEADER, * PUDP_HEADER;
int main()
{
WSADATA wsadata;
int ret = WSAStartup(MAKEWORD(2, 2), &wsadata); if (ret != 0) { printf("初始化winsock2失败!"); return -1; } //if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 2) { puts("版本号错误!"); return -1; }
SOCKADDR_IN saddr;
memset(&saddr, 0, sizeof(SOCKADDR_IN));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8080);
saddr.sin_addr.s_addr = inet_addr("192.168.125.9");
SOCKET sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (sockfd < 0) { puts("创建套接字失败!"); return system("pause"); }
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
ret = bind(sockfd, (SOCKADDR*)&saddr, sizeof(SOCKADDR)); if (ret != 0) { puts("绑定失败!"); return system("pause"); }
DWORD dwlen[10], dwlenrtned = 0, optval = 1;
WSAIoctl(sockfd, SIO_RCVALL, &optval, sizeof(optval), &dwlen, sizeof(dwlen), &dwlenrtned, NULL, NULL); //允许套接字接收所有经过本机的网络数据包
char buf[500] = "";
int len = sizeof(SOCKADDR);
IP_HEADER iph;
UDP_HEADER udph;
while (1)
{
puts("等待接收数据......");
ret = recvfrom(sockfd, buf, 200, 0, (SOCKADDR*)&saddr, &len); if (ret < 0) { puts("接收错误!"); }
memcpy(&iph, buf, 20);
memcpy(&udph, buf + 20, 8);
in_addr ias, iad;
ias.S_un.S_addr = iph.m_uiSourIp;
iad.S_un.S_addr = iph.m_uiDestIp;
printf("协议类型:%d\n", iph.m_cTypeOfProtocol);
switch (iph.m_cTypeOfProtocol)
{
case IPPROTO_ICMP:
puts("收到ICMP包");
break;
case IPPROTO_IGMP:
puts("收到IGMP包");
break;
case IPPROTO_UDP:
puts("收到UDP包");
break;
case IPPROTO_TCP:
puts("收到TCP包");
break;
default:
puts("未指定协议类型");
break;
}
char str1[20];
char str2[20];
strcpy_s(str1, inet_ntoa(ias));
strcpy_s(str2, inet_ntoa(iad));
printf("源地址IP:%s 源地址端口:%d \n目标地址IP:%s 目标地址端口:%d \n", str1, ntohs(udph.m_usSourPort), str2, ntohs(udph.m_usDestPort));
std::string str = "0";
str= Utf8ToGbk(buf+28);
std::cout << "接收到的数据段:" << str << std::endl;
puts("");
}
closesocket(sockfd);
WSACleanup();
return system("pause");
}
注意:使用管理员模式运行,因为原始套接字的使用是需要管理员权限的。
C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)的更多相关文章
- Linux系统编程(37)—— socket编程之原始套接字
原始套接字的特点 原始套接字(SOCK_RAW)可以用来自行组装IP数据包,然后将数据包发送到其他终端.也就是说原始套接字是基于IP数据包的编程(SOCK_PACKET是基于数据链路层的编程).另外, ...
- Linux网络编程——原始套接字能干什么?
通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式套接字(SOCK ...
- Linux网络编程:原始套接字简介
Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...
- UNIX网络编程——原始套接字的魔力【续】
如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...
- Linux原始套接字实现分析---转
http://blog.chinaunix.net/uid-27074062-id-3388166.html 本文从IPV4协议栈原始套接字的分类入手,详细介绍了链路层和网络层原始套接字的特点及其内核 ...
- Linux网络编程——原始套接字编程
原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...
- Linux基础(11)原始套接字
一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进 ...
- UNP——原始套接字
1.原始套接字的用处 使用原始套接字可以构造或读取网际层及其以上报文. 具体来说,可以构造 ICMP, IGMP 协议报文,通过开启 IP_HDRINCL 套接字选项,进而自定义 IPv4首部. 2. ...
- 005.TCP--拼接TCP头部IP头部,实现TCP三次握手的第一步(Linux,原始套接字)
一.目的: 自己拼接IP头,TCP头,计算效验和,将生成的报文用原始套接字发送出去. 若使用tcpdump能监听有对方服务器的包回应,则证明TCP报文是正确的! 二.数据结构: TCP首部结构图: s ...
随机推荐
- Git进阶:常用命令和问题案例整理
一.前言 整理常用git命令和以及在实际使用的过程中碰到的问题案例,旨在git进阶,提升工作开发效率,有需要补充的小伙伴欢迎下方留言,本篇持续更新中... 二.命令 配置用户名和邮箱 git conf ...
- python面向对象单继承,多继承和super()调用
python 目录 python 1.继承 1.单继承 2.多继承 3.子类重写父类的同名属性和方法 核心点: 4.多层继承 5.super()的使用 1.继承 1.单继承 说明: 虽然子类没有定义_ ...
- win10家庭版启用远程桌面
此电脑右键属性->远程设置->允许远程协助连接这台计算机 勾选 下载RDP Wrapper 地址:https://github.com/stascorp/rdpwrap/releases ...
- JavaFx在Main中获取Controller初始化相关配置和Fxml
Main中的方法 package sample; import javafx.application.Application; import javafx.fxml.FXMLLoader; impor ...
- JVM学习(二)JVM加载类
一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- 记一次磁盘UUID不能识别故障处理
早上zabbix报警,磁盘满了,登录服务器查看信息,一顿操作,突然发现最后lvextend命令不能扩容,查看LVM信息 报错信息"Couldn't find device with uuid ...
- BTRsys1~2系列靶机渗透
BTRsys系列靶机渗透 BTRsys1 端口发现加目录扫描. 发现目录:http://192.168.114.161/login.php 尝试弱密码失败,查看源代码. <script type ...
- http走私攻击
http走私攻击 前端服务器和后端服务器接收数据不同步,引起对客户端传入的数据理解不一致,从而导致漏洞. 因为当服务器同时在处理Content-Length和Transfer-Encoding,Con ...
- IDEA环境配置里的一些error
1. idea添加edit configuration 没有tomcat图标 File->Setting->Build,Execution,Deployment-->Applicat ...
- Spring事务管理(编码式、配置文件方式、注解方式)
1.事务(https://www.cnblogs.com/zhai1997/p/11710082.html) (1)事务的特性:acdi (2)事务的并发问题:丢失修改,脏读,不可重复读 (3)事务的 ...