github.com/notti/go-dynamic@v0.0.0-20190619201224-fc443047424c/examplelibpcap/main.go (about)

     1  // Example using libpcap to read packets from a networkdevice and decode them with gopacket.
     2  package main
     3  
     4  import (
     5  	"flag"
     6  	"log"
     7  	"syscall"
     8  	"time"
     9  	"unsafe"
    10  
    11  	"github.com/google/gopacket"
    12  	"github.com/google/gopacket/layers"
    13  	"github.com/notti/nocgo"
    14  )
    15  
    16  type pkthdr struct {
    17  	ts     syscall.Timeval
    18  	caplen uint32
    19  	len    uint32
    20  }
    21  
    22  func main() {
    23  	dev := flag.String("dev", "lo", "The device to listen to")
    24  	snaplen := flag.Int("snaplen", 1500, "Maximum capture length")
    25  	promisc := flag.Bool("promisc", true, "Set device to promiscous mode")
    26  
    27  	flag.Parse()
    28  
    29  	p := int32(0)
    30  	if *promisc {
    31  		p = 1
    32  	}
    33  
    34  	lib, err := nocgo.Open("libpcap.so")
    35  	if err != nil {
    36  		log.Fatalln("Couldn't load libpcap: ", err)
    37  	}
    38  
    39  	var pcapOpenLive func(device []byte, snaplen int32, promisc int32, toMS int32, errbuf []byte) uintptr
    40  	if err := lib.Func("pcap_open_live", &pcapOpenLive); err != nil {
    41  		log.Fatalln("Couldn't get pcap_open_live: ", err)
    42  	}
    43  
    44  	var pcapNextEx func(p uintptr, hdr **pkthdr, data *unsafe.Pointer) int32
    45  	if err := lib.Func("pcap_next_ex", &pcapNextEx); err != nil {
    46  		log.Fatalln("Couldn't load pcap_next_ex: ", err)
    47  	}
    48  
    49  	errbuf := make([]byte, 512)
    50  	pcapHandle := pcapOpenLive(nocgo.MakeCString(*dev), int32(*snaplen), p, 100, errbuf)
    51  
    52  	if pcapHandle == 0 {
    53  		log.Fatalf("Couldn't open %s: %s\n", *dev, nocgo.MakeGoStringFromSlice(errbuf))
    54  	}
    55  
    56  	var hdr *pkthdr
    57  	var dataptr unsafe.Pointer
    58  
    59  	for {
    60  		if ret := pcapNextEx(pcapHandle, &hdr, &dataptr); ret != 1 {
    61  			log.Fatalln("Unexpected error code ", ret)
    62  		}
    63  
    64  		log.Printf("Received packet at %s length %d\n", time.Unix(hdr.ts.Sec, hdr.ts.Usec), hdr.len)
    65  		packet := gopacket.NewPacket((*[1 << 30]byte)(dataptr)[:hdr.caplen], layers.LayerTypeEthernet, gopacket.Default)
    66  		log.Println(packet.Dump())
    67  	}
    68  }