// compileBPFFilter always returns an allocated _Ctype_struct_bpf_program // It is the callers responsibility to free the memory again, e.g. // // C.pcap_freecode(&bpf) // func (p *Handle) compileBPFFilter(expr string) (_Ctype_struct_bpf_program, error) { errorBuf := (*C.char)(C.calloc(errorBufferSize, 1)) defer C.free(unsafe.Pointer(errorBuf)) var netp uint32 var maskp uint32 // Only do the lookup on network interfaces. // No device indicates we're handling a pcap file. if len(p.device) > 0 { dev := C.CString(p.device) defer C.free(unsafe.Pointer(dev)) if -1 == C.pcap_lookupnet( dev, (*C.bpf_u_int32)(unsafe.Pointer(&netp)), (*C.bpf_u_int32)(unsafe.Pointer(&maskp)), errorBuf, ) { // We can't lookup the network, but that could be because the interface // doesn't have an IPv4. } } var bpf _Ctype_struct_bpf_program cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, C.bpf_u_int32(maskp)) { return bpf, p.Error() } return bpf, nil }
// NewBPF compiles the given string into a new filter program. // // BPF filters need to be created from activated handles, because they need to // know the underlying link type to correctly compile their offsets. func (p *Handle) NewBPF(expr string) (*BPF, error) { bpf := &BPF{orig: expr} cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) if C.pcap_compile(p.cptr, &bpf.bpf, cexpr /* optimize */, 1, C.PCAP_NETMASK_UNKNOWN) != 0 { return nil, p.Error() } runtime.SetFinalizer(bpf, destroyBPF) return bpf, nil }
func (p *Pcap) CompileAndSetFilter(filter string) error { var bpf C.struct_bpf_program if C.pcap_compile(p.pcap, &bpf, C.CString(filter), 1, 0) != 0 { return errors.New(p.GetErr()) } if C.pcap_setfilter(p.pcap, &bpf) != 0 { return errors.New(p.GetErr()) } return nil }
func (p *Pcap) Setfilter(expr string) (err string) { var bpf _Ctype_struct_bpf_program if -1 == C.pcap_compile(p.cptr, &bpf, C.CString(expr), 1, 0) { return p.Geterror() } if -1 == C.pcap_setfilter(p.cptr, &bpf) { C.pcap_freecode(&bpf) return p.Geterror() } C.pcap_freecode(&bpf) return "" }
func (p *Pcap) SetFilter(expr string) (err error) { var bpf _Ctype_struct_bpf_program cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, 0) { return p.Geterror() } if -1 == C.pcap_setfilter(p.cptr, &bpf) { C.pcap_freecode(&bpf) return p.Geterror() } C.pcap_freecode(&bpf) return nil }
func (p *Pcap) Setfilter(expr string) os.Error { var bpf C.struct_bpf_program cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) if C.pcap_compile(p.cptr, &bpf, cexpr, 1, 0) == -1 { return os.NewError(p.Geterror()) } defer C.pcap_freecode(&bpf) if C.pcap_setfilter(p.cptr, &bpf) == -1 { return os.NewError(p.Geterror()) } return nil }
// SetBPFFilter compiles and sets a BPF filter for the pcap handle. func (p *Handle) SetBPFFilter(expr string) (err error) { p.activate.Do(p.activation) var bpf _Ctype_struct_bpf_program cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, 0) { return p.Error() } if -1 == C.pcap_setfilter(p.cptr, &bpf) { C.pcap_freecode(&bpf) return p.Error() } C.pcap_freecode(&bpf) return 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) } } }
// Setfilter compiles a filter string into a bpf program and sets the filter. func (p *Pcap) Setfilter(expr string) error { cexpr := C.CString(expr) defer C.free(unsafe.Pointer(cexpr)) var bpf C.struct_bpf_program res := C.pcap_compile(p.cptr, &bpf, cexpr, C.int(OptimizeFilters), C.PCAP_NETMASK_UNKNOWN) if res == C.PCAP_ERROR { return p.GetErr() } res = C.pcap_setfilter(p.cptr, &bpf) if res == C.PCAP_ERROR { C.pcap_freecode(&bpf) return p.GetErr() } p.Filters = append(p.Filters, expr) C.pcap_freecode(&bpf) return nil }