golang監(jiān)聽(tīng)ip數(shù)據(jù)包的實(shí)現(xiàn)步驟(golang純享版)
golang 監(jiān)聽(tīng)ip數(shù)據(jù)包(golang純享版)
【注】本機(jī)編譯運(yùn)行平臺(tái)為linux,如需測(cè)試代碼請(qǐng)移至linux平臺(tái)進(jìn)行代碼測(cè)試
本文以ip4 作為案例進(jìn)行包抓取示范,ip6抓取與ip4方式異曲同工,可自行舉一反三得出
第一步,通過(guò)wireshark抓包拿到ip4下的tcp/udp包,通過(guò)wireshark可視化我們可以很容易找到我們需要的源/目的地址信息所在ip包字節(jié)數(shù). 這里兩張截圖,一張ip4,一張ip6的
第二步,編寫(xiě)我們秘制的簡(jiǎn)易抓包工具,此處以直接輸出來(lái)源和去向地址為例,自己可以根據(jù)需求做更改
package inet import ( "encoding/binary" "fmt" "strconv" "syscall" "unsafe" ) func reverse(b []byte) { var ( mid uint8 blen = len(b) ) if blen > 1 { for i := 0; i < blen/2; i++ { mid = b[i] b[i] = b[blen-i-1] b[blen-i-1] = mid } } } //主機(jī)字節(jié)序變網(wǎng)絡(luò)字節(jié)序 func Htons[T uint | uint16 | uint32 | uint64](t T) T { var ( b []byte = make([]byte, unsafe.Sizeof(t)) ptr *T = (*T)(unsafe.Pointer(&b[0])) ) *ptr = t reverse(b) return *ptr } //ip包必選,ip6自行根據(jù)wireshark進(jìn)行編寫(xiě),此處ip4為例 type IPHeader struct { Version_And_Len uint8//前4個(gè)bit為version(4 ip4,6 ip6),后bit個(gè)字節(jié)為首部length xxxx xxxx DiffernetialtedService uint8 Tot_Len uint16 Id uint16 Flag_And_Seek uint16//前3bit 為flag后面13bit為seek TTL uint8 Protocol uint8 CheckSum uint16 Source uint32 Dest uint32 } type PortInfo struct { Source uint16 Dest uint16 } var ( __IP_DEFAULT IPHeader IPHEADER_SIZE = int(unsafe.Sizeof(__IP_DEFAULT)) ) func Watch(watcher func([]byte, int)) error { //socket af_packet 會(huì)抓取全部網(wǎng)卡的IP數(shù)據(jù)包,如需監(jiān)聽(tīng)特定的網(wǎng)卡請(qǐng)自行判斷 fd, _, err_ := syscall.Syscall(syscall.SYS_SOCKET, syscall.AF_PACKET, syscall.SOCK_DGRAM, uintptr(Htons[uint16](syscall.ETH_P_IP))) if int(fd) < 0 { return err_ } ifd := int(fd) var ( buff []byte = make([]byte, 512) lang int err error ) defer syscall.Close(ifd) fmt.Println("start watch raw stream", ifd) for { lang, _, err = syscall.Recvfrom(ifd, buff, 0) if lang <= 0 { break } watcher(buff, lang) } return err } //輸出所有來(lái)源去向 func print_info(info []byte, size int) { if size <= IPHEADER_SIZE { return } var ( ipheader *IPHeader = (*IPHeader)(unsafe.Pointer(&info[0])) portinfo *PortInfo ) if size > IPHEADER_SIZE+4 { portinfo = (*PortInfo)(unsafe.Pointer(&info[IPHEADER_SIZE])) fmt.Printf("src %s:%d dst %s:%d\n", Raw2String(ipheader.Source), portinfo.Source, Raw2String(ipheader.Dest), portinfo.Dest) } else { fmt.Printf("src %s dst %s\n", Raw2String(ipheader.Source), Raw2String(ipheader.Dest)) } } func Raw2String(src uint32) string { raw := make([]byte, 4) binary.LittleEndian.PutUint32(raw, src) return strconv.FormatUint(uint64(raw[0]), 10) + "." + strconv.FormatUint(uint64(raw[1]), 10) + "." + strconv.FormatUint(uint64(raw[2]), 10) + "." + strconv.FormatUint(uint64(raw[3]), 10) } func Print_Info() func([]byte, int) { return print_info }
測(cè)試主函數(shù)
func main() { fmt.Fprintln(os.Stderr, inet.Watch(inet.Print_Info())) }
效果
以上就是golang監(jiān)聽(tīng)ip數(shù)據(jù)包的實(shí)現(xiàn)步驟(golang純享版)的詳細(xì)內(nèi)容,更多關(guān)于golang監(jiān)聽(tīng)ip數(shù)據(jù)包的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang使用Gin框架實(shí)現(xiàn)http分塊傳輸
這篇文章主要為大家詳細(xì)介紹了Golang中如何使用Gin框架實(shí)現(xiàn)http分塊傳輸功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下2023-05-05深入淺出Golang中select的實(shí)現(xiàn)原理
在go語(yǔ)言中,select語(yǔ)句就是用來(lái)監(jiān)聽(tīng)和channel有關(guān)的IO操作,當(dāng)IO操作發(fā)生時(shí),觸發(fā)相應(yīng)的case操作,有了select語(yǔ)句,可以實(shí)現(xiàn)main主線(xiàn)程與goroutine線(xiàn)程之間的互動(dòng)。本文就來(lái)詳細(xì)講講select的實(shí)現(xiàn)原理,需要的可以參考一下2022-08-08Golang?Gin框架獲取請(qǐng)求參數(shù)的幾種常見(jiàn)方式
在我們平常添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫(xiě)業(yè)務(wù)處理代碼了,但在此之前我們往往需要獲取請(qǐng)求參數(shù),本文就詳細(xì)的講解下gin獲取請(qǐng)求參數(shù)常見(jiàn)的幾種方式,需要的朋友可以參考下2024-02-02Go語(yǔ)言入門(mén)之基礎(chǔ)語(yǔ)法和常用特性解析
這篇文章主要給大家講解了Go語(yǔ)言的基礎(chǔ)語(yǔ)法和常用特性解析,比較適合入門(mén)小白,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的朋友可以參考下2023-07-07在Colaboratory上運(yùn)行Go程序的詳細(xì)過(guò)程
這篇文章主要介紹了在Colaboratory上運(yùn)行Go程序,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Go語(yǔ)言類(lèi)型轉(zhuǎn)換的方式有哪些
本文主要介紹了Go語(yǔ)言類(lèi)型轉(zhuǎn)換的方式有哪些,類(lèi)型轉(zhuǎn)換主要有4種,分別為斷言類(lèi)型轉(zhuǎn)換、顯式類(lèi)型轉(zhuǎn)換、隱式類(lèi)型轉(zhuǎn)換、強(qiáng)制類(lèi)型轉(zhuǎn)換,感興趣的可以了解一下2023-11-11Golang并發(fā)控制的三種實(shí)現(xiàn)方法
在Golang中,有多種方式可以進(jìn)行并發(fā)控制,本文詳細(xì)的介紹了三種實(shí)現(xiàn)方法,Channel優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,清晰易懂,WaitGroup優(yōu)點(diǎn)是子協(xié)程個(gè)數(shù)動(dòng)態(tài)可調(diào)整,Context 優(yōu)點(diǎn)是對(duì)子協(xié)程派生出來(lái)的孫子協(xié)程的控制,缺點(diǎn)是相對(duì)而言的,要結(jié)合實(shí)例應(yīng)用場(chǎng)景進(jìn)行選擇2023-08-08go語(yǔ)言單元測(cè)試基準(zhǔn)測(cè)試及表驅(qū)動(dòng)測(cè)試示例詳解
這篇文章主要為大家介紹了go語(yǔ)言單元測(cè)試基準(zhǔn)測(cè)試及表驅(qū)動(dòng)測(cè)試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08