利用原始套接字(sock_raw)编写的抓取ip数据包的小程序

这是一个使用原始套接字在Windows环境下编写的C++小程序,用于捕获并打印IP数据包的相关信息,包括版本、长度、协议、源地址和目的地址。程序首先初始化Winsock,创建一个SOCKET,设置IP_HDRINCL选项以包含IP头,然后绑定到本地主机的指定端口,并不断接收和解析数据包。
摘要由CSDN通过智能技术生成
 

#include <iostream.h>
#include <stdio.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#define MAX_SIZE 65535
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)

struct iphead{
 union{
  unsigned char hl;
  unsigned char version;
 };
 unsigned char tos;
 unsigned short tot_len;
 unsigned short id;
 union{
  unsigned short flags;
  unsigned short off;
 };
 unsigned char ttl;
 unsigned char protocol;
 unsigned check;
 unsigned int saddr;
 unsigned int daddr;
};
void main(){
 WORD rv;
 WSADATA WSAData;
 rv=MAKEWORD(2,2);
 WSAStartup(rv,&WSAData);
 
 SOCKET sockRaw=socket(AF_INET,SOCK_RAW,IPPROTO_IP);

 BOOL optval=TRUE;
 setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&optval,sizeof

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用Python自带的`socket`模块来创建原始套接字,并使用`struct`模块来解析IP协议。 首先,你需要创建一个原始套接字对象: ```python import socket # 创建一个原始套接字对象 s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) ``` 然后,你可以设置套接字选项来让操作系统不过滤掉非本机地址的数据包: ```python # 设置套接字选项,让操作系统不过滤掉非本机地址的数据包 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('0.0.0.0', 0)) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) ``` 现在,你可以使用`recvfrom()`方法来接收数据包: ```python # 接收数据包 data, address = s.recvfrom(65535) ``` 接下来,你需要使用`struct`模块来解析IP头部。IP头部的长度是可变的,它的长度保存在IP头部的第一个字节中,所以你需要取出第一个字节来计算IP头部的长度。IP头部的结构如下: ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` 下面是一个解析IP头部的示例代码: ```python import struct # 解析IP头部 version_ihl, type_of_service, total_length, identification, flags, fragment_offset, ttl, protocol, checksum, source_address, destination_address = struct.unpack('!BBHHHBBH4s4s', data[:20]) version = version_ihl >> 4 ihl = version_ihl & 0xF header_length = ihl * 4 print('Version:', version) print('Header Length:', header_length) print('Source Address:', socket.inet_ntoa(source_address)) print('Destination Address:', socket.inet_ntoa(destination_address)) print('Protocol:', protocol) ``` 这段代码将从接收到的数据包中取出前20个字节,按照IP头部的格式使用`struct.unpack()`方法解析各个字段,并输出相关信息。 需要注意的是,这段代码假设接收到的数据包中只包含一个IP数据包。如果你想要处理多个数据包,需要将上述代码放入一个循环中,直到你接收到想要的数据包为止。同时,你也需要在循环结束后关闭原始套接字: ```python s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) s.close() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值