// OpenLive opens a device and returns a *Handle. // It takes as arguments the name of the device ("eth0"), the maximum size to // read for each packet (snaplen), whether to put the interface in promiscuous // mode, and a timeout. func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) { var buf *C.char buf = (*C.char)(C.calloc(errorBufferSize, 1)) defer C.free(unsafe.Pointer(buf)) var pro C.int if promisc { pro = 1 } dev := C.CString(device) defer C.free(unsafe.Pointer(dev)) // This copies a bunch of the pcap_open_live implementation from pcap.c: cptr := C.pcap_create(dev, buf) if cptr == nil { return nil, errors.New(C.GoString(buf)) } var status C.int if status = C.pcap_set_snaplen(cptr, C.int(snaplen)); status < 0 { goto fail } else if status = C.pcap_set_promisc(cptr, pro); status < 0 { goto fail } else if status = C.pcap_set_timeout(cptr, C.int(timeout/time.Millisecond)); status < 0 { goto fail } return newHandle(cptr), nil fail: C.pcap_close(cptr) return nil, statusError(status) }
// NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle. // Callers of NewInactiveHandle should immediately defer 'CleanUp', as in: // inactive := NewInactiveHandle("eth0") // defer inactive.CleanUp() func NewInactiveHandle(device string) (*InactiveHandle, error) { buf := (*C.char)(C.calloc(errorBufferSize, 1)) defer C.free(unsafe.Pointer(buf)) dev := C.CString(device) defer C.free(unsafe.Pointer(dev)) // This copies a bunch of the pcap_open_live implementation from pcap.c: cptr := C.pcap_create(dev, buf) if cptr == nil { return nil, errors.New(C.GoString(buf)) } return &InactiveHandle{cptr: cptr, device: device}, nil }
// Create a new capture handle from the given network interface. Noe that this // may require root privileges. func Open(dev_name string) (*Handle, error) { handle := &Handle{Device: dev_name} dev_str := C.CString(dev_name) defer C.free(unsafe.Pointer(dev_str)) err_str := (*C.char)(C.calloc(256, 1)) defer C.free(unsafe.Pointer(err_str)) handle.pcap = C.pcap_create(dev_str, err_str) if handle == nil { return nil, fmt.Errorf( "Could not open device: %s", C.GoString(err_str), ) } return handle, nil }
func main() { var errbuf = (*C.char)(C.malloc(C.PCAP_ERRBUF_SIZE)) defer C.free(unsafe.Pointer(errbuf)) var source = C.CString("any") defer C.free(unsafe.Pointer(source)) pcap_handle := C.pcap_create(source, errbuf) if pcap_handle == nil { panic("pcap_handle") } C.pcap_set_buffer_size(pcap_handle, 2*1024*1024) C.pcap_set_promisc(pcap_handle, 1) C.pcap_set_snaplen(pcap_handle, 512) // more than enough to recognize a WOL packet C.pcap_setdirection(pcap_handle, C.PCAP_D_IN) if C.pcap_activate(pcap_handle) != 0 { panic(C.GoString(C.pcap_geterr(pcap_handle))) } var bpf_program C.struct_bpf_program if C.pcap_compile(pcap_handle, &bpf_program, pcap_filter, 0, 0) != 0 { panic(C.GoString(C.pcap_geterr(pcap_handle))) } if C.pcap_setfilter(pcap_handle, &bpf_program) != 0 { panic(C.GoString(C.pcap_geterr(pcap_handle))) } for { var pkt_header *C.struct_pcap_pkthdr var pkt_data *C.u_char if C.pcap_next_ex(pcap_handle, &pkt_header, &pkt_data) < 0 { panic(C.GoString(C.pcap_geterr(pcap_handle))) } if pkt_data == nil { continue } data := make([]byte, pkt_header.caplen) copy(data, (*(*[10000000]byte)(unsafe.Pointer(pkt_data)))[0:]) from_mac, to_mac := checkwol(data) if from_mac != "" { fmt.Printf("%v: %v sends WOL to %v\n", time.Now(), from_mac, to_mac) } } }
func Create(device string) (handle *Pcap, err error) { var buf *C.char buf = (*C.char)(C.calloc(ERRBUF_SIZE, 1)) h := new(Pcap) dev := C.CString(device) defer C.free(unsafe.Pointer(dev)) h.cptr = C.pcap_create(dev, buf) if nil == h.cptr { handle = nil err = &pcapError{C.GoString(buf)} } else { handle = h } C.free(unsafe.Pointer(buf)) return }
// Create will construct a pcap that can be used to set custom settings like a // larger buffer. The resulting Pcap must then be started with a call to // Activate. See Open for an example list of calls that should be made. func Create(device string) (*Pcap, error) { p := &Pcap{ Device: device, Pchan: make(chan *pkt.Packet, ChanBuffSize), m: &sync.Mutex{}, } buf := (*C.char)(C.calloc(C.PCAP_ERRBUF_SIZE, 1)) defer C.free(unsafe.Pointer(buf)) dev := C.CString(p.Device) defer C.free(unsafe.Pointer(dev)) p.cptr = C.pcap_create(dev, buf) if p.cptr == nil { return p, errors.New(C.GoString(buf)) } return p, nil }
// NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle. // Callers of NewInactiveHandle should immediately defer 'CleanUp', as in: // inactive := NewInactiveHandle("eth0") // defer inactive.CleanUp() func NewInactiveHandle(device string) (*InactiveHandle, error) { buf := (*C.char)(C.calloc(errorBufferSize, 1)) defer C.free(unsafe.Pointer(buf)) dev := C.CString(device) defer C.free(unsafe.Pointer(dev)) // Try to get the interface index, but iy could be something like "any" // in which case use 0, which doesn't exist in nature deviceIndex := 0 ifc, err := net.InterfaceByName(device) if err == nil { deviceIndex = ifc.Index } // This copies a bunch of the pcap_open_live implementation from pcap.c: cptr := C.pcap_create(dev, buf) if cptr == nil { return nil, errors.New(C.GoString(buf)) } return &InactiveHandle{cptr: cptr, device: device, deviceIndex: deviceIndex}, nil }