python使用原始套接字发送二层包(链路层帧)

本文介绍了一个使用Python进行网络编程的具体示例,包括如何利用PF_PACKET和SOCK_RAW创建套接字来发送和接收自定义协议的数据包。发送端程序通过绑定特定网卡并设置MAC地址与自定义类型来发送数据,而接收端则解析接收到的数据包。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发送端代码:

#!/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!")

1.创建套接字使用地址家族PF_PACKET,类型为SOCK_RAW,自定义类型为0x1234,这个和C语言一模一样。自定义类型我们也可以使用0X0800,这个是ETH_P_IP,相当于我们模拟ip包来发送,那么ip包头和mac包头都需要我们自己填写。现在我们使用0x1234,系统定义之外的协议类型。
2.由于是发送二层包,我们默认网卡没有配置网络,也就是ping不通的情况下,直接绑定网卡上。
3.linux内核中定义的mac包头结构

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

第一个是目的mac地址,第二个是本机mac地址,第三个是自定义类型必须填写,这样对方也关心这个自定义类型时,协议栈收到二层包才能正确给到对方的套接字。通过这个结构体,所以使用了pack,”!6s6sH”。我这里使用的广播地址发送。
接收端代码:

#!/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])
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值