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

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])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章