0

I want to create a packet from raw bytes using gopacket and write the packets to a pcap file.

I created a UDP packet from raw bytes as below.

package main

import (
        "fmt"
        "net"
        "log"
        "os"
        "time"
        //"encoding/hex"
        "github.com/google/gopacket"
        "github.com/google/gopacket/layers"
        "github.com/google/gopacket/pcap"
        "github.com/google/gopacket/pcapgo"
)

var (
        device       string = "eth0"
        snapshot_len int32  = 65535
        promiscuous  bool   = false
        err          error
        timeout      time.Duration = 30 * time.Second
        handle       *pcap.Handle
        buffer       gopacket.SerializeBuffer
        options      gopacket.SerializeOptions
)

func main() {
        ethernetLayer := &layers.Ethernet{
            SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA},
            DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD},
        }
        ipLayer := &layers.IPv4{
            SrcIP: net.IP{127,0,0,1},
            DstIP: net.IP{8,8,8,8},
        }
        udpLayer := &layers.UDP{
            SrcPort: 51190,
            DstPort: 4789,
        }
        rawBytes := []byte{10, 20, 30}
        buffer = gopacket.NewSerializeBuffer()
        gopacket.SerializeLayers(buffer, options,
                ethernetLayer,
                ipLayer,
                udpLayer,
                gopacket.Payload(rawBytes),
        )
        outgoingPacket := buffer.Bytes()
        fmt.Println(outgoingPacket)
        ethpacket := gopacket.NewPacket(outgoingPacket,
                                    layers.LayerTypeEthernet,
                                    gopacket.Default )

I am struck how to write these packets to a pcap file. This is that part of the code.

        f, err := os.Create("temp.pcap")
        if err != nil {
                log.Fatal(err)
                os.Exit(1)
        }
        defer f.Close()

        //handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
        //if err != nil {
        //        log.Fatal(err)
        //}
        //defer handle.Close()

        //handle.WritePacketData(outgoingPacket)
        w := pcapgo.NewWriter(f)
        w.WriteFileHeader(uint32(snapshot_len), layers.LinkTypeEthernet)
        w.WritePacket(ethpacket.Metadata().CaptureInfo, ethpacket.Data())
       

This is the error I am getting. Please help how to proceed further

[root@centos-sqa-blr01 gopacket]# go run create_pcap.go
#command-line-arguments
./create_pcap.go:75:26: packet.MetaData undefined (type gopacket.Packet has no field or method MetaData, but does have Metadata)

mmeda
  • 11
  • 4

1 Answers1

1

Notice the error info: "MetaData" is not "Metadata".

Guess you need to modify:

-            w.WritePacket(packet.MetaData().CaptureInfo, ethpacket.Data())
+            w.WritePacket(packet.Metadata().CaptureInfo, ethpacket.Data())

UPDATE:

If u just want to create and write a packet, comment the following codes. It works for me.

    // handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
    // if err != nil {
    //  log.Fatal(err)
    // }
    // defer handle.Close()
p1gd0g
  • 631
  • 5
  • 16
  • Thanks @p1gd0g. I corrected the error, but the pcap is still empty with no packets. – mmeda Aug 22 '21 at 07:01
  • Please give us a least executable example. @mmeda – p1gd0g Aug 22 '21 at 08:39
  • I have edited my original code. So the code that you see is what I have executed. Please let me know if you need any more details – mmeda Aug 22 '21 at 13:08
  • Thanks @p1gd0g, I ran with the updated code by commenting those lines. I see that there are no errors when I execute my program. However, the pcap file is empty. It does not contain any packets – mmeda Aug 23 '21 at 16:42
  • @mmeda Did the file exist? Could u run `ls -l` to show the file size? – p1gd0g Aug 24 '21 at 02:19
  • # ls -l -rw-r--r-- 1 root root 2043 Aug 24 05:05 create_pcap.go -rw-r--r-- 1 root root 1193 Aug 17 07:31 dump.pcap -rw-r--r-- 1 root root 78 Aug 4 07:14 go.mod **-rw-r--r-- 1 root root 24 Aug 24 05:05 temp.pcap** – mmeda Aug 24 '21 at 05:09
  • @mmeda That 24 byte file is what u want. `hexdump temp.pcap` to show it. – p1gd0g Aug 24 '21 at 05:39
  • yes you are right. It shows the hexdump. But it doesn't show as an UDP packet when opening in a pcap file [root@centos-sqa-blr01 gopacket]# hexdump temp.pcap 0000000 c3d4 a1b2 0002 0004 0000 0000 0000 0000 0000010 ffff 0000 0001 0000 0000018 – mmeda Aug 24 '21 at 05:57
  • @mmeda What a UDP packet should be? Could u give an example? On my side, a packet is constructed by some bytes just like this. – p1gd0g Aug 24 '21 at 06:03
  • as you can see in my code, I am constructing a UDP packet with ethernet layer ,ip layer , udp layer followed by udp payload. Looks like, the pcap file has only 24 byte file header and not the actual packet which I constructed. – mmeda Aug 24 '21 at 06:09
  • @mmeda Please catch the error of `w.WritePacket`. I'll check it later (working now). – p1gd0g Aug 24 '21 at 06:18
  • **2021/08/24 06:34:22 capture length 0 does not match data length 60** exit status 1 – mmeda Aug 24 '21 at 06:46
  • After adding these 2 lines, i am able to see the packet is getting generated `ethpacket.Metadata().CaptureLength = len(ethpacket.Data()) ethpacket.Metadata().Length = len(ethpacket.Data())` – mmeda Aug 24 '21 at 11:40
  • @mmeda That's good! Is there anything I can help? – p1gd0g Aug 24 '21 at 12:47
  • Thanks a lot @p1gd0g for your help!! – mmeda Aug 24 '21 at 16:41
  • @mmeda Why not mark the answer as accepted if it addresses your issue? – Zeke Lu May 03 '23 at 10:52