github.com/gopacket/gopacket@v1.1.0/pcap/pcap_tester.go (about)

     1  // Copyright 2012 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  //go:build ignore
     8  // +build ignore
     9  
    10  // This binary tests that PCAP packet capture is working correctly by issuing
    11  // HTTP requests, then making sure we actually capture data off the wire.
    12  package main
    13  
    14  import (
    15  	"errors"
    16  	"flag"
    17  	"fmt"
    18  	"log"
    19  	"net/http"
    20  	"os"
    21  	"time"
    22  
    23  	"github.com/gopacket/gopacket/pcap"
    24  )
    25  
    26  var mode = flag.String("mode", "basic", "One of: basic,filtered,timestamp")
    27  
    28  func generatePackets() {
    29  	if resp, err := http.Get("http://code.google.com"); err != nil {
    30  		log.Printf("Could not get HTTP: %v", err)
    31  	} else {
    32  		resp.Body.Close()
    33  	}
    34  }
    35  
    36  func main() {
    37  	flag.Parse()
    38  	ifaces, err := pcap.FindAllDevs()
    39  	if err != nil {
    40  		log.Fatal(err)
    41  	}
    42  	for _, iface := range ifaces {
    43  		log.Printf("Trying capture on %q", iface.Name)
    44  		if err := tryCapture(iface); err != nil {
    45  			log.Printf("Error capturing on %q: %v", iface.Name, err)
    46  		} else {
    47  			log.Printf("Successfully captured on %q", iface.Name)
    48  			return
    49  		}
    50  	}
    51  	os.Exit(1)
    52  }
    53  
    54  func tryCapture(iface pcap.Interface) error {
    55  	if iface.Name[:2] == "lo" {
    56  		return errors.New("skipping loopback")
    57  	}
    58  	var h *pcap.Handle
    59  	var err error
    60  	switch *mode {
    61  	case "basic":
    62  		h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3)
    63  		if err != nil {
    64  			return fmt.Errorf("openlive: %v", err)
    65  		}
    66  		defer h.Close()
    67  	case "filtered":
    68  		h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3)
    69  		if err != nil {
    70  			return fmt.Errorf("openlive: %v", err)
    71  		}
    72  		defer h.Close()
    73  		if err := h.SetBPFFilter("port 80 or port 443"); err != nil {
    74  			return fmt.Errorf("setbpf: %v", err)
    75  		}
    76  	case "timestamp":
    77  		u, err := pcap.NewInactiveHandle(iface.Name)
    78  		if err != nil {
    79  			return err
    80  		}
    81  		defer u.CleanUp()
    82  		if err = u.SetSnapLen(65536); err != nil {
    83  			return err
    84  		} else if err = u.SetPromisc(false); err != nil {
    85  			return err
    86  		} else if err = u.SetTimeout(time.Second * 3); err != nil {
    87  			return err
    88  		}
    89  		sources := u.SupportedTimestamps()
    90  		if len(sources) == 0 {
    91  			return errors.New("no supported timestamp sources")
    92  		} else if err := u.SetTimestampSource(sources[0]); err != nil {
    93  			return fmt.Errorf("settimestampsource(%v): %v", sources[0], err)
    94  		} else if h, err = u.Activate(); err != nil {
    95  			return fmt.Errorf("could not activate: %v", err)
    96  		}
    97  		defer h.Close()
    98  	default:
    99  		panic("Invalid --mode: " + *mode)
   100  	}
   101  	go generatePackets()
   102  	h.ReadPacketData() // Do one dummy read to clear any timeouts.
   103  	data, ci, err := h.ReadPacketData()
   104  	if err != nil {
   105  		return fmt.Errorf("readpacketdata: %v", err)
   106  	}
   107  	log.Printf("Read packet, %v bytes, CI: %+v", len(data), ci)
   108  	return nil
   109  }