waini1110 发表于 2019-2-12 12:46

通过gopacket构造以太网帧结构发送二层报文

本帖最后由 waini1110 于 2019-2-12 12:56 编辑

使用工具。
1. windows10
2. golang version 1.11.5
3. gopacket 1.11.5
4. wireshark 2.6.6
5. npcap 0.99
6. gcc 8.1.0
代码。

package main
import (
    "fmt"
    "log"
    "net"
    "time"

    "github.com/google/gopacket/layers"

    "github.com/google/gopacket"
    "github.com/google/gopacket/pcap"
)
var (
    snapshot_len int32 = 65535
    promiscuousbool= false
    err          error
    timeout      time.Duration = 30 * time.Second
    handle       *pcap.Handle
    buffer       gopacket.SerializeBuffer
    options      gopacket.SerializeOptions
)
func main() {
    devices, err := pcap.FindAllDevs()
    if err != nil {
      log.Fatal(err)
    }

    for _, value := range devices {
      if value.Description == "Realtek PCIe GbE Family Controller" {
            //Open device
            handle, err = pcap.OpenLive(value.Name, snapshot_len, promiscuous, timeout)
            if err != nil {
                log.Fatal(err)
            }
      }
      fmt.Println(value.Description, value.Name)
    }
    // Send raw bytes over wire
    rawBytes := []byte{'A', 'b', 'C'}

    // This time lets fill out some information
    ipLayer := &layers.IPv4{
      Protocol: 17,
      Flags:    0x0000,
      IHL:      0x45,
      TTL:      0x80,
      Id:       0x1234,
      Length:   0x014e,
      SrcIP:    net.IP{0, 0, 0, 0},
      DstIP:    net.IP{255, 255, 255, 255},
    }
    ethernetLayer := &layers.Ethernet{
      EthernetType: 0x0800,
      SrcMAC:       net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA},
      DstMAC:       net.HardwareAddr{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
    }
    udpLayer := &layers.UDP{
      SrcPort: layers.UDPPort(68),
      DstPort: layers.UDPPort(67),
      Length:0x013a,
    }
    // And create the packet with the layers
    buffer = gopacket.NewSerializeBuffer()
    gopacket.SerializeLayers(buffer, options,
      ethernetLayer,
      ipLayer,
      udpLayer,
      gopacket.Payload(rawBytes),
    )
    outgoingPacket := buffer.Bytes()
    for {
      time.Sleep(time.Second * 3)
      err = handle.WritePacketData(outgoingPacket)
      if err != nil {
            log.Fatal(err)
      }
    }

    handle.Close()
}

代码就不多讲了,官方的例子,这里构造了以太网帧结构,IP包头,和UDP包头,模拟构造的是bootp,也就是dhcp报文的格式。
##注意事项
1.在pacp.go中,作者写死了路径,所以需要改为npcap的路径
#cgo windows CFLAGS: -I C:/npcap/Include
#cgo windows,386 LDFLAGS: -L C:/npcap/Lib -lwpcap
#cgo windows,amd64 LDFLAGS: -L C:/npcap/Lib/x64 -lwpcap
2.pcap.go中,第63行-78行是win32的东西,注释掉,
//#ifdef WIN32
//#define pcap_statustostr pcap_strerror
//
//// WinPcap also doesn't export pcap_can_set_rfmon and pcap_set_rfmon,
//// as those are handled by separate libraries (airpcap).
//// https://www.winpcap.org/docs/docs_412/html/group__wpcapfunc.html
//// Stub out those functions here, returning values that indicate rfmon
//// setting is unavailable/unsuccessful.
//int pcap_can_set_rfmon(pcap_t *p) {
//    return 0;
//}
//
//int pcap_set_rfmon(pcap_t *p, int rfmon) {
//    return PCAP_ERROR;
//}
//#endif
3.下载npcap的SDK,安装npcap
https://static.studygolang.com/190130/ed763f8610a79c1877468ed56c15affa.png
4.替换windows自带的wincap.dll和Packet.dll. 将C:\Windows\System32\Npcap下的wincap.dll和Packet.dll.复制到C:\Windows\System32\下
5.编译成功
6.查看报文结构

https://static.studygolang.com/190130/b43b57800ded98b6bae24460d814fda7.png

ttttyyyy 发表于 2019-2-12 13:14



谢谢分享。

Junle 发表于 2019-2-12 13:58

谢谢楼主分享

markfinad 发表于 2019-3-6 13:44

感谢分享,希望能用!

罂粟花 发表于 2019-4-5 14:42


linux运行报错什么问题
# github.com/google/gopacket/pcap
/home/go/src/github.com/google/gopacket/pcap/pcap.go:30:22: undefined: pcapErrorNotActivated
/home/go/src/github.com/google/gopacket/pcap/pcap.go:52:17: undefined: pcapTPtr
/home/go/src/github.com/google/gopacket/pcap/pcap.go:64:10: undefined: pcapPkthdr

waini1110 发表于 2019-4-12 10:11

罂粟花 发表于 2019-4-5 14:42
linux运行报错什么问题
# github.com/google/gopacket/pcap
/home/go/src/github.com/google/gopacket/ ...

linux不能用npcap

罂粟花 发表于 2019-4-12 14:24

waini1110 发表于 2019-4-12 10:11
linux不能用npcap

找到原因了,golang的工作目录设置有问题
页: [1]
查看完整版本: 通过gopacket构造以太网帧结构发送二层报文