接下來進入比較有趣的實作環節,第一步就是要能收到所有封包,Python真的是個好東西,只要五行程式碼就能監聽所有從router流過去的封包,而且不需要任何第三方的套件!
import socket
s = socket.socket( socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
while True:
packet, _ = s.recvfrom(65565)
print(packet)
上述用到的socket語法皆在前一天"Day05 Socket初探”提到,忘記的讀者可以翻到前一天看,唯獨socket.ntohs,網路的byte順序是統一的,但是CPU有分Little endian和Big-endian,由於這個原因不同體系結構的機器之間無法通信,所以要轉換成一種約定的數序,也就是網絡字節順序,這能根據你所用的CPU晶片進行編排
htonl()--"Host to Network Long"
ntohl()--"Network to Host Long"
htons()--"Host to Network Short"
ntohs()--"Network to Host Short”
在這裡,用ntohs或ntohl都可以
這時,可以把程式碼放在router上執行,並用HostA去ping HostB
ping hostb_ip -c 1
應該就能print出TCP/IP第三層,ICMP的封包'\x02B\xac\x11\x00\x02\x02B\xac\x11\x00\x05\x08\x00E\x00\x00TG\xe7@\x00@\x01\x9a\x96\xac\x11\x00\x05\xac\x12\x00\x03\x08\x00\xfd\xaa\x00#\x00\x01{\xa5T_\x00\x00\x00\x00_Y\x0c\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567’
雖然print出來是string,但是都是看不懂的亂碼,但裡面蘊涵著許多網路的重要訊息,沒關係,接下來每一天會為大家根據packet解析封包!
系列的成果將會放在這:https://github.com/kaichiachen/pytcpdump
文章配合著程式碼有助於學習 :)