func newPcapIO(ifName string, promisc bool, snaplen int, bufSz int) (handle *PcapIO, err error) { inactive, err := pcap.NewInactiveHandle(ifName) if err != nil { return } defer inactive.CleanUp() if err = inactive.SetPromisc(promisc); err != nil { return } if err = inactive.SetSnapLen(snaplen); err != nil { return } if err = inactive.SetTimeout(-1); err != nil { return } if err = inactive.SetImmediateMode(true); err != nil { return } if err = inactive.SetBufferSize(bufSz); err != nil { return } active, err := inactive.Activate() if err != nil { return } if err = active.SetDirection(pcap.DirectionIn); err != nil { return } return &PcapIO{handle: active}, nil }
func tryCapture(iface net.Interface) error { if iface.Name[:2] == "lo" { return fmt.Errorf("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 fmt.Errorf("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 }
func newPcapIO(ifName string, promisc bool, snaplen int, bufSz int) (handle *PcapIO, err error) { inactive, err := pcap.NewInactiveHandle(ifName) if err != nil { return } defer inactive.CleanUp() if err = inactive.SetPromisc(promisc); err != nil { return } if err = inactive.SetSnapLen(snaplen); err != nil { return } if err = inactive.SetTimeout(MaxDuration); err != nil { return } if err = inactive.SetImmediateMode(true); err != nil { // If gopacket is compiled against an older pcap.h that // doesn't have pcap_set_immediate_mode, it supplies a dummy // definition that always returns PCAP_ERROR. That becomes // "Generic error", which is not very helpful. The real // pcap_set_immediate_mode never returns PCAP_ERROR, so this // turns it into a more informative message. if fmt.Sprint(err) == "Generic error" { err = fmt.Errorf("compiled against an old version of libpcap; please compile against libpcap-1.5.0 or later") } return } if err = inactive.SetBufferSize(bufSz); err != nil { return } active, err := inactive.Activate() if err != nil { return } if err = active.SetDirection(pcap.DirectionIn); err != nil { return } return &PcapIO{handle: active}, nil }