golang使用原始套接字構造UDP包

2021-09-16 22:09:32 字數 2490 閱讀 9577

這裡先看ip頭結構:

其中16位總長度包括ip頭長度和資料的長度,8位協議填寫17,因為udp協議型別為17。這裡要說明一下ip頭中的首部校驗,這個值只校驗ip頭部,不包含資料。

這裡給出校驗演算法,ip頭和udp頭中使用的校驗演算法是一樣的。

func checksum(msg byte) uint16 

sum = (sum >> 16) + (sum & 0xffff)

sum += (sum >> 16)

var ans = uint16(^sum)

return ans

}

下面開始填充ip頭,這裡使用了golang.org/x/net下的ipv4包

//目的ip

dst := net.ipv4(192, 168, 1, 2)

//源ip

src := net.ipv4(192, 168, 1, 3)

//填充ip首部

iph := &ipv4.header

h, err := iph.marshal()

if err != nil

//計算ip頭部校驗值

iph.checksum = int(checksum(h))

下面開始處理udp頭部,先來看udp頭結構:

udp頭結構就很簡單了,16位udp校驗和涉及到乙個udp偽首部的東西,我們先來看下udp偽首部的構成。

-----------------------------------------

| 32bit source ip address |

-----------------------------------------

| 32bit destination ip addr |

-----------------------------------------

| 0 | 8bit proto| 16bit header length|

-----------------------------------------

偽首部包含了源ip,目的ip,協議號,16位的長度。這個偽首部僅僅參與校驗計算。

下面開始填充udp頭:

//填充udp首部

//udp偽首部

udph := make(byte, 20)

//源ip位址

udph[0], udph[1], udph[2], udph[3] = src[12], src[13], src[14], src[15]

//目的ip位址

udph[4], udph[5], udph[6], udph[7] = dst.ip[12], dst.ip[13], dst.ip[14], dst.ip[15]

//協議型別

udph[8], udph[9] = 0x00, 0x11

//udp頭長度

udph[10], udph[11] = 0x00, byte(len(buff)+8)

//下面開始就真正的udp頭部

//源埠號

udph[12], udph[13] = 0x27, 0x10

//目的埠號

udph[14], udph[15] = 0x17, 0x70

//udp頭長度

udph[16], udph[17] = 0x00, byte(len(buff)+8)

//校驗和

udph[18], udph[19] = 0x00, 0x00

//計算校驗值

udph[18], udph[19] = byte(check>>8&255), byte(check&255)

下面我們需要傳送自己構造的udp包,可以使用net下的listenpacket。

listener, err := net.listenpacket("ip4:udp", "192.168.1.104")

if err != nil

defer listener.close()

//listener 實現了net.packetconn介面

r, err := ipv4.newrawconn(c)

if err != nil

//傳送自己構造的udp包

log.fatal(err)

}

這個實現只在linux和mac上測試過,windows上需要借助於第三方吧,比如winpcap。

這裡只給出了udp的實現,tcp的實現比較複雜,以後也會給出tcp實現的例子。

原始套接字

資料出處 實際上,我們常用的網路程式設計都是在應用層的報文的收發操作,也就是大多數程式設計師接觸到的流式套接字 sock stream 和資料報式套接字 sock dgram 而這些資料報都是由系統提供的協議棧實現,使用者只需要填充應用層報文即可,由系統完成底層報文頭的填充並傳送。然而在某些情況下需...

原始套接字

參考1 原始套接字能幹什麼?參考2 原始套接字抓包實踐 參考3 各層頭結構 通過原始套接字,我們可以抓取所有傳送到本機的ip包 包括ip頭和tcp udp icmp包頭 也可以抓取所有本機收到的幀 包括資料鏈路層協議頭 普通的套接字無法處理icmp igmp等網路報文,而sock raw可以。利用原...

原始套接字

利用原始套接字實現乙個tcp syn flooding 程式 要求 客戶端不斷向攻擊端傳送syn連線請求 客戶端在傳送資料時,通過源位址隨機位址的方式隱藏自己的 位址 檢驗 在shell下通過 netstat tn 檢查syn recv連線數檢驗自己的程式是否成功 好像有點問題。不能偽造mac位址。...