Method for python to send Layer 2 packet of link layer frame using raw socket

  • 2021-07-24 11:20:57
  • OfStack

Sender code:


#!/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. Create a socket using the address family PF_PACKET, type SOCK_RAW, custom type 0x1234, this and C language 1 model 1. We can also use 0X0800 for custom type, which is ETH_P_IP, which is equivalent to simulating ip packet to send, so ip header and mac header need to be filled in by ourselves. Now we use 0x1234, a protocol type outside the system definition.

2. Because we send Layer 2 packets, our default network card is not configured with a network, that is, when ping is blocked, it is directly bound to the network card.

3. mac packet header structure defined in linux kernel


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

The first is the destination mac address, the second is the native mac address, and the third is the custom type that must be filled in, so that when the other party also cares about this custom type, the protocol stack can correctly give the socket to the other party after receiving the Layer 2 packet. Through this structure, so use pack, "! 6s6sH". I use the broadcast address here to send.
Receiver code:


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


Related articles: