Python使用原始套接字发送二层包(链路层帧)的方法

宋时安
宋时安
发布时间:2026-10-13 | 5人浏览过
原创

本文介绍如何在Python中使用原始套接字(Raw Socket)发送链路层(二层)数据包。通过设置PF_PACKET和SOCK_RAW,自定义协议类型如0x1234,并手动构造包含目的MAC、源MAC及协议类型的以太网头部。文章提供发送端与接收端的完整代码示例,演示如何绑定网卡、打包数据及接收处理,适用于网络协议分析与底层通信开发。

Python原始套接字发送二层帧实现

发送端代码实现如下:

发送端代码详解


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import socket
import struct

raw_socket = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.htons(0x1234))
raw_socket.bind(("eth0", 0))
packet = struct.pack("!6s6sH", "\xff\xff\xff\xff\xff\xff", "\xaa\xaa\xaa\xaa\xaa\xaa", 0x1234)
while True:
 print repr(packet)
 raw_socket.send(packet + "hello,world!")

首先,创建套接字时需指定地址家族为PF_PACKET,类型设为SOCK_RAW,并自定义协议类型为0x1234,这与C语言中的用法一致。若选择使用0X0800(即ETH_P_IP),则需自行填充IP头部和MAC头部以模拟IP包。此处采用0x1234这一系统未定义的协议类型,以便在特定场景下进行测试或自定义通信。

由于发送的是二层数据包,且默认网卡未配置网络层地址(即无法通过ping连通),因此直接将套接字绑定到指定网卡接口上。

在Linux内核中,以太网头部结构定义如下:

以太网头部结构分析


struct ethhdr
{
 unsigned char h_dest[6];
 unsigned char h_source[6];
 uint16_t h_proto; //0x1234
};

该结构包含目的MAC地址、源MAC地址以及协议类型字段。其中,协议类型必须正确填写,以确保接收方在识别到该自定义类型时,能将数据包正确交付给对应的套接字。利用struct模块中的pack函数,格式字符串为“!6s6sH”,分别对应6字节的目的MAC、6字节的源MAC以及2字节的协议类型。本例中使用广播地址(全F)进行发送。接收端代码实现如下:

接收端代码示例


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import socket
import struct

raw_socket = socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x1234))
while True :
 packet = raw_socket.recv(1024)
 data = struct.unpack("!6s6sH12s", packet)
 print repr(data[0])
 print repr(data[1])
 print repr(data[2])
 print repr(data[3])

以上关于Python使用原始套接字发送二层包(链路层帧)的方法即为完整分享内容,供读者参考与实践,欢迎支持相关技术社区。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表