// Copyright 2012 Google, Inc. All rights reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. // +build ignore // This binary tests that PCAP packet capture is working correctly by issuing // HTTP requests, then making sure we actually capture data off the wire. package main import ( "errors" "flag" "fmt" "log" "net" "net/http" "os" "time" "github.com/google/gopacket/pcap" ) var mode = flag.String("mode", "basic", "One of: basic,filtered,timestamp") func generatePackets() { if resp, err := http.Get("http://code.google.com"); err != nil { log.Printf("Could not get HTTP: %v", err) } else { resp.Body.Close() } } func main() { flag.Parse() ifaces, err := net.Interfaces() if err != nil { log.Fatal(err) } for _, iface := range ifaces { log.Printf("Trying capture on %q", iface.Name) if err := tryCapture(iface); err != nil { log.Printf("Error capturing on %q: %v", iface.Name, err) } else { log.Printf("Successfully captured on %q", iface.Name) return } } os.Exit(1) } func tryCapture(iface net.Interface) error { if iface.Name[:2] == "lo" { return errors.New("skipping loopback") } var h *pcap.Handle var err error switch *mode { case "basic": h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) if err != nil { return fmt.Errorf("openlive: %v", err) } defer h.Close() case "filtered": h, err = pcap.OpenLive(iface.Name, 65536, false, time.Second*3) if err != nil { return fmt.Errorf("openlive: %v", err) } defer h.Close() if err := h.SetBPFFilter("port 80 or port 443"); err != nil { return fmt.Errorf("setbpf: %v", err) } case "timestamp": u, err := pcap.NewInactiveHandle(iface.Name) if err != nil { return err } defer u.CleanUp() if err = u.SetSnapLen(65536); err != nil { return err } else if err = u.SetPromisc(false); err != nil { return err } else if err = u.SetTimeout(time.Second * 3); err != nil { return err } sources := u.SupportedTimestamps() if len(sources) == 0 { return errors.New("no supported timestamp sources") } else if err := u.SetTimestampSource(sources[0]); err != nil { return fmt.Errorf("settimestampsource(%v): %v", sources[0], err) } else if h, err = u.Activate(); err != nil { return fmt.Errorf("could not activate: %v", err) } defer h.Close() default: panic("Invalid --mode: " + *mode) } go generatePackets() h.ReadPacketData() // Do one dummy read to clear any timeouts. data, ci, err := h.ReadPacketData() if err != nil { return fmt.Errorf("readpacketdata: %v", err) } log.Printf("Read packet, %v bytes, CI: %+v", len(data), ci) return nil }