一个简单的抓包代码

// 抓包.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <winsock2.h>
#include <filesystem>
#include <mstcpip.h>

#pragma comment(lib, "WS2_32.lib")   //加载动态库 ws23_2.dll(system32)

#define OK 0
#define ERROR -1

#define HOST_NAME_LEN 256
#define MY_PORT 10001  //打开端口用1024以上的,1024以下的被系统或特定程序使用
#define BUFF_LEN 65535


void PrintData(char szBuf[], int iLen)
{
	//printf("RCV: %s\n", szBuf);
	//捕获的数据一定不是字符串
	//打印16进制数据
	printf("REC:\n");
	for (int i = 12; i < iLen; i++)
	{
		printf("%02x ", szBuf[i] & 0xff);
	}
	printf("\n");
	return;
}

int CaptureData(){
	SOCKET iFd;   //套接字
	char szHostName[HOST_NAME_LEN];   //计算机名
	HOSTENT *pHost;
	WSADATA stWsa;    //用于打开动态链接库
	SOCKADDR_IN stAddr = { 0 };
	DWORD dwInBuff = 1;
	DWORD dwOutBuff;
	DWORD dwBytesRet;
	int iRet;
	char szBuf[BUFF_LEN];


	//0x0202版本号
	//不等于就是加载失败
	if (WSAStartup(0x0202, &stWsa) != OK)   //对winsock服务初始化,第一个参数是版本号,第二个参数用来接收winsock实现的具体细节
	{
		printf("Wsa StartUp failed\n");
		return ERROR;
	}

	if (gethostname(szHostName, HOST_NAME_LEN) != OK)   //返回本地主机的主机名,两个参数分别是存放主机名的数组以及数组长度
	{
		WSACleanup();     //终止ws2_32.dll的使用
		return ERROR;
	}
	printf("hostName:%s\n", szHostName);
	pHost = gethostbyname(szHostName);    //返回指针,指向给定主机名的主机信息
	printf("MyIP: %d.%d.%d.%d\n", pHost->h_addr_list[0][0] & 0xff,       //取出后8位,每个数字由32位组成,前面全是1
		pHost->h_addr_list[0][1] & 0xff,
		pHost->h_addr_list[0][2] & 0xff,
		pHost->h_addr_list[0][3] & 0xff);

	//整数表示的ip
	stAddr.sin_addr.s_addr = *(unsigned long*)pHost->h_addr;   //设置IP地址
	//printf("%xu\n", stAddr.sin_addr.s_addr);
	stAddr.sin_family = AF_INET;    //设置协议族
	stAddr.sin_port = htons(MY_PORT);   //设置端口号

	//接收原始数据流,因为要接收的数据是发往所有端口的
	iFd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);   //创建一个套接字,af:地址描述, type:套接口类型, protocol:协议
	if (iFd == INVALID_SOCKET)
	{
		printf("socket failed:%d\n", WSAGetLastError());
		WSACleanup();
		return ERROR;
	}

	
	if (bind(iFd, (SOCKADDR*)&stAddr, sizeof(SOCKADDR)) != OK)   //将一固定的地址绑定在套接字描述符上
	{
		printf("bind failed:%d\n",WSAGetLastError());
		WSACleanup();
		closesocket(iFd);
		return ERROR;
	}
	//设置iFd守包规则,SIO_RCVALL接收所有的包,输入缓冲区地址及大小,输出缓冲区大小及地址,输出实际字节数的地址
	iRet = WSAIoctl(iFd, SIO_RCVALL, &dwInBuff, sizeof(dwInBuff),
		&dwOutBuff, sizeof(dwOutBuff), &dwBytesRet, NULL, NULL);
	if (iRet != OK)
	{
		printf("IOCTL failed.\n");
		WSACleanup();
		closesocket(iFd);
		return ERROR;
	}

	while (true)
	{
		memset(szBuf, 0, BUFF_LEN);
		iRet = recv(iFd, szBuf, BUFF_LEN, 0);
		if (iRet < 0)
		{
			break;
		}
		else{
			PrintData(szBuf, iRet);
		}
	}



	WSACleanup();
	closesocket(iFd);
	return OK;
}

int _tmain(int argc, _TCHAR* argv[])
{

	CaptureData();
	system("pause");
	return 0;
}


  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值