運用Raw Socket進行乙太網幀解析

2021-08-19 09:57:54 字數 3138 閱讀 5001

raw socket提供了一種方法來繞過整個網路堆疊遍歷,並直接將乙太網幀輸送到乙個應用程式的方法。

(跳過網路層和傳輸層的過濾解析,因而可以直接處理新的或是自定義的資料報格式)

常用建立raw socket格式的方法:af_packet和pf_socket。af_packet用於win和mac系統。本篇介紹基於linux的pf_packet建立方法。

使用socket模組讀取收到的包

對進行解釋和分析

>>> import socket

>>> import struct

>>> import binascii

>>>

>>> rawsocket = socket.socket(socket.pf_packet,socket.sock_raw,socket.htons(0x0800))

>>> pkt = rawsocket.recvfrom(2048)

>>> ethernetheader = pkt[0][0:14]

>>> ethernetheader

'\x90\xb1\x1cz\xa8\x89p\xf9myf\x9d\x08\x00'

>>> binascii.hexlify(eth_hdr[0])

'90b11c5aa889'

>>> binascii.hexlify(eth_hdr[1])

'70f96d59469d'

>>> binascii.hexlify(eth_hdr[2])

'0800'

>>> ipheader = pkt[0][14:34]

>>> ip_hdr = struct.unpack("!12s4s4s",ipheader)

>>> ip_hdr

('e\x00\x00(u\xe4@\x00~\x06\x91\xbe', '\xc0\xa8d\x9a', '\xc0\xa8/b')

>>> socket.inet_ntoa(ip_hdr[1])

'192.168.100.154'

>>> socket.inet_ntoa(ip_hdr[2])

'192.168.47.66'

>>> tcpheader = pkt[0][34:54]

由此進行資料報解析

由pf_packet進行自定義二層發包和收包(要求二層直連,兩台測試機沒有直連害我搞了一下午= =),簡易**

傳送端

import struct

import socket

s= socket.socket(socket.pf_packet, socket.sock_raw, socket.htons(0x0901))

s.bind(("eth1", 0))

#dst_addr = "\x90\xb1\x1c\x5a\xa8\x89"

dst_addr = "\x00\x0c\x29\x89\xaf\x38"

src_addr = "\x00\x0c\x29\xb6\xe5\xb7"

ethtype = "\x09\x01"

packet = struct.pack("!6s6sh", dst_addr, src_addr, 0x0901)

s.send(packet + "hello!")

接收端

import socket

import struct

import binascii

socket1 = socket.socket(socket.pf_packet, socket.sock_raw, socket.htons(0x0901))

while true:

pkt = socket1.recvfrom(2048)

eth_header = pkt[0][0:14]

eth_hdr = struct.unpack("!6s6sh",eth_header)

print repr(eth_hdr[0])

type = eth_hdr[2]

if( type == 0x0901):

print("get 0x0901")

print("end")

--------------------分割線------------------------

傳送端完整版

import socket

import struct

import binascii

def set_mac(hexstring):

mac_addr=

for i in xrange(0, len(hexstring)/2):

int_c = int(hexstring[i*2:i*2+2],16)

return mac_addr

def packed(dmac, smac, ethtype):

packed = b""

i =0

for value in dmac:

packed += struct.pack("!b", value)

for value in smac:

packed += struct.pack("!b", value)

packed += struct.pack("!h", ethtype)

return packed

socket2 = socket.socket(socket.af_packet, socket.sock_raw)

socket2.bind(('eth1', 0))

data = b""

d_mac = "000c2989af38"

s_mac = "000c29b6e5b7"

dmac = set_mac(d_mac)

smac = set_mac(s_mac)

ethtype = 0x0901

pack_res = packed(dmac, smac, ethtype)

data += pack_res

try:

socket2.send(data)

print('ok')

except:

raise exception("send failed")

運用chain進行跳轉

struts2裡的result的chain,可以將action串成乙個鏈,從而實現自定義的跳轉,redirect型別的url會變更,chain不會變更,這個是最大的差別,chain裡的值棧物件會被自動壓入新的action裡。看 struct.xml aaction baction a.jsp b.j...

emacs裡運用pomodoro進行蕃茄工作法

偶然之間按了m x 輸入乙個p,看到有pomodoro這個函式,於是就試了一下,結果發現乙個蕃茄時間只有15分鐘,不是很滿意.想重新定製一下 用的是陳斌一年成為emacs高手文章內的配置 於是輸入c h f pomodoro set end time,開啟乙個幫助緩衝區,提示要修改的話到pomodo...

運用CRF技術進行簡單分詞

input data codecs.open pku training,r utf 8 output data codecs.open pku training out,w utf 8 for line in input data.readlines word list line.strip spl...