亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用原始套接字發送自定義以太網數據包

使用原始套接字發送自定義以太網數據包

Go
哈士奇WWW 2022-10-24 15:44:11
我搜索了如何使用自定義以太網類型發送原始以太網數據包,但很多人都在談論 tcp 和 udp 協議。我需要打開一個原始套接字,獲取所有具有我自定義以太網類型的數據包,讀取有效負載并發送回具有不同自定義以太網類型的數據包。func main() {    //set promiscuos mode    cmd := exec.Command("ifconfig", "eth0", "promisc")    err := cmd.Run()    if err != nil {        fmt.Println("Error: " + err.Error())        return    }    //open raw socket with custom ethertype_1 and bind to interface    fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, Htons(ETHER_TYPE_1))    if err != nil {        fmt.Println("Error: " + err.Error())        return    }    err = syscall.BindToDevice(fd, "eth0")    if err != nil {        fmt.Println("Error: " + err.Error())        return    }    f := os.NewFile(uintptr(fd), fmt.Sprintf("fd %d", fd))    for {        buf := make([]byte, 1024)        numRead, err := f.Read(buf)        if err != nil {            fmt.Println(err)        }        go ReadSocket(buf, numRead)    }func ReadSocket(buf []byte, numRead int) {    packet := BufToEthPacket(buf, numRead)    fmt.Printf("Destination MAC: % X\n", packet.dstMac)    fmt.Printf("Source MAC:      % X\n", packet.srcMac)    fmt.Printf("ether type:      %X\n", packet.ethType)    fmt.Printf("Payload:         % X\n", packet.payload)    var myPacket EthPacket    myPacket.srcMac = packet.dstMac    myPacket.dstMac = packet.srcMac    myPacket.ethType = ETHER_TYPE_2    myPacket.payload = packet.payload    var myBuf = EthPacketToBuf(myPacket)    //open raw socket with custom ethertype_2 and bind to interface    fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, Htons(ETHER_TYPE_2))    if err != nil {        fmt.Println("Error: " + err.Error())        return    }    err = syscall.BindToDevice(fd, "eth0")    if err != nil {        fmt.Println("Error: " + err.Error())        return    }}我收到了數據包,但f.Write(myBuf)返回以下錯誤:Error: write fd 5: no such device or address我做錯了什么?
查看完整描述

1 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

Usingos.Write將在后臺執行write系統調用,這意味著實際文件。要將數據“寫入”到網絡套接字,您需要使用sendto系統調用。


以下示例使用自定義以太類型發送數據。所以只是一個帶有一些數據的以太網數據包。


package main


import (

    "log"

    "net"

    "os"

    "syscall"

)


func main() {

    ifname := os.Args[1]

    iface, err := net.InterfaceByName(ifname)

    if err != nil {

        log.Fatal("get link by name:", err)

    }


    srcMac := iface.HardwareAddr

    if len(srcMac) == 0 {

        srcMac = []byte{0, 0, 0, 0, 0, 0}

    }

    dstMac := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}


    fd, _ := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))

    addr := syscall.SockaddrLinklayer{

        Ifindex: iface.Index,

        Halen:   6, // Ethernet address length is 6 bytes

        Addr: [8]uint8{

            dstMac[0],

            dstMac[1],

            dstMac[2],

            dstMac[3],

            dstMac[4],

            dstMac[5],

        },

    }


    ethHeader := []byte{

        dstMac[0], dstMac[1], dstMac[2], dstMac[3], dstMac[4], dstMac[5],

        srcMac[0], srcMac[1], srcMac[2], srcMac[3], srcMac[4], srcMac[5],

        0x12, 0x34, // your custom ethertype

    }


    // Your custom data

    p := append(ethHeader, []byte("Hello World")...)


    err = syscall.Sendto(fd, p, 0, &addr)

    if err != nil {

        log.Fatal("Sendto:", err)

    }

}


// htons converts a short (uint16) from host-to-network byte order.

func htons(i uint16) uint16 {

    return (i<<8)&0xff00 | i>>8

}


查看完整回答
反對 回復 2022-10-24
  • 1 回答
  • 0 關注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號