/*页面编码: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包)的更多相关文章

  1. Linux系统编程(37)—— socket编程之原始套接字

    原始套接字的特点 原始套接字(SOCK_RAW)可以用来自行组装IP数据包,然后将数据包发送到其他终端.也就是说原始套接字是基于IP数据包的编程(SOCK_PACKET是基于数据链路层的编程).另外, ...

  2. Linux网络编程——原始套接字能干什么?

    通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式套接字(SOCK ...

  3. Linux网络编程:原始套接字简介

    Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...

  4. UNIX网络编程——原始套接字的魔力【续】

    如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...

  5. Linux原始套接字实现分析---转

    http://blog.chinaunix.net/uid-27074062-id-3388166.html 本文从IPV4协议栈原始套接字的分类入手,详细介绍了链路层和网络层原始套接字的特点及其内核 ...

  6. Linux网络编程——原始套接字编程

    原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...

  7. Linux基础(11)原始套接字

    一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进 ...

  8. UNP——原始套接字

    1.原始套接字的用处 使用原始套接字可以构造或读取网际层及其以上报文. 具体来说,可以构造 ICMP, IGMP 协议报文,通过开启 IP_HDRINCL 套接字选项,进而自定义 IPv4首部. 2. ...

  9. 005.TCP--拼接TCP头部IP头部,实现TCP三次握手的第一步(Linux,原始套接字)

    一.目的: 自己拼接IP头,TCP头,计算效验和,将生成的报文用原始套接字发送出去. 若使用tcpdump能监听有对方服务器的包回应,则证明TCP报文是正确的! 二.数据结构: TCP首部结构图: s ...

随机推荐

  1. [记录点滴]授人以渔,从Tensorflow找不到dll扩展到如何排查问题

    [记录点滴]授人以渔,从Tensorflow找不到dll扩展到如何排查问题 目录 [记录点滴]授人以渔,从Tensorflow找不到dll扩展到如何排查问题 0x00 摘要 0x01 引言 0x02 ...

  2. java8--排序

    排序的传统的写法是: Collections.sort( SortTest.users, new Comparator<User>() { @Override public int com ...

  3. Redis5设计与源码分析读后感(一)认识Redis

    一.初识redis 定义 Redis是一个开源的Key-Value数据库,通常被称为数据结构服务器,其值可以是多种常见的数据格式,且读写性能极高,且所有操作都是原子性的. 高性能的主要原因 1.基于内 ...

  4. TP6 数据库管理工具,生成前后台CRUD页面

    Tp6 数据库管理工具,数据库内容的搬运工 支持MySQL数据库,可视化配置直接生成前后台CRUD页面减少重复劳动,可以直接作为后台页面使用.前端页面技术基于 iszsw/surface 支持多表关联 ...

  5. pwnable.kr-coin1-witeup

    是一个小游戏,会给100堆小硬币,在每堆硬币中找到假币(重量为9,其他重量为10),其中每堆硬币都设置了金币数和固定的尝试次数. 思路是:在每堆硬币中,在有限的尝试次数中对硬币通过二分法计算硬币重量不 ...

  6. 码云+Git配置仓库

    版本库Git安装 概述 Git是一个开源的分布式控制系统,可以有效高速的处理从很小的到非常大的项目版本管理,是目前使用范围最广的版本管理工具. 下载安装 下载后傻瓜式一键安装,建议安装在英文目录下,安 ...

  7. 获取IP 地址,失败!解决方法

    命令ip addr 获取IP地址失败,见下图: 解决方法,查看ens33网卡的配置: 控制台,路径输入: vi /etc/sysconfig/network-scripts/ifcfg-ens33 然 ...

  8. spring的AspectJ基于XML和注解(前置、后置、环绕、抛出异常、最终通知)

    1.概念 (1)AspectJ是一个基于Java语言的AOP框架 (2)Spring2.0以后新增了对AspectJ切入点表达式的支持 (3)AspectJ是AspectJ1.5的新增功能,通过JDK ...

  9. uni-app支付功能

    扫码查看原文 前言 近期一直在使用APP开发多端应用,IOS的APP.安卓的APP和H5网页,其中开发的APP使用到了微信和支付宝的支付,在此给大家分享出来,一起使用 前置条件: 开发环境:windo ...

  10. 分页查询对象Page

    1 public class Page { 2 //当前页码 3 private Integer pageNo = 1; 4 //每页显示条数 5 private Integer pageSize = ...