// getNextBufPtrLocked is shared code for ReadPacketData and // ZeroCopyReadPacketData. func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { if p.cptr == nil { return io.EOF } var result NextError for { result = NextError(C.pcap_next_ex(p.cptr, &p.pkthdr, &p.buf_ptr)) if p.blockForever && result == NextErrorTimeoutExpired { continue } break } if result != NextErrorOk { if result == NextErrorNoMorePackets { return io.EOF } else { return result } } ci.Timestamp = time.Unix(int64(p.pkthdr.ts.tv_sec), int64(p.pkthdr.ts.tv_usec)*1000) // convert micros to nanos ci.CaptureLength = int(p.pkthdr.caplen) ci.Length = int(p.pkthdr.len) return nil }
// Capture a single packet from the packet source. This will block until a // packet is received. func (h *Handle) Capture() ([]byte, error) { var buf *C.u_char var pkt_hdr *C.struct_pcap_pkthdr for { err := C.pcap_next_ex(h.pcap, &pkt_hdr, &buf) switch err { case -2: return nil, nil case -1: return nil, fmt.Errorf( "Could not read packet: %s", h.get_error(), ) case 0: continue case 1: return C.GoBytes(unsafe.Pointer(buf), C.int(pkt_hdr.len)), nil } } return nil, fmt.Errorf("WTF") }
func (p *Pcap) NextEx() (pkt *Packet, result int32) { var pkthdr_ptr *_Ctype_struct_pcap_pkthdr var pkthdr _Ctype_struct_pcap_pkthdr var buf_ptr *_Ctypedef_u_char var buf unsafe.Pointer result = int32(C.pcap_next_ex(p.cptr, &pkthdr_ptr, &buf_ptr)) buf = unsafe.Pointer(buf_ptr) pkthdr = *pkthdr_ptr if nil == buf { pkt = nil return } pkt = new(Packet) pkt.Time.Sec = int32(pkthdr.ts.tv_sec) pkt.Time.Usec = int32(pkthdr.ts.tv_usec) pkt.Caplen = uint32(pkthdr.caplen) pkt.Len = uint32(pkthdr.len) pkt.Data = make([]byte, pkthdr.caplen) for i := uint32(0); i < pkt.Caplen; i++ { pkt.Data[i] = *(*byte)(unsafe.Pointer(uintptr(buf) + uintptr(i))) } return }
func (p *Pcap) Next() (*Packet, os.Error) { var header *C.struct_pcap_pkthdr var buf *C.u_char switch C.pcap_next_ex(p.cptr, &header, &buf) { case 0: return nil, os.NewError("read time out") case -1: return nil, os.NewError(p.Geterror()) case -2: return nil, os.NewError("savefile eof") } ret := new(Packet) ret.Time.Sec = int32(header.ts.tv_sec) ret.Time.Usec = int32(header.ts.tv_usec) ret.Caplen = uint32(header.caplen) ret.Len = uint32(header.len) ret.Data = make([]byte, header.caplen) if header.caplen > 0 { C.memcpy(unsafe.Pointer(&ret.Data[0]), unsafe.Pointer(buf), C.size_t(header.caplen)) } return ret, nil }
func (p *Pcap) Next() (*Packet, error) { var packet Packet rc := C.pcap_next_ex(p.pcap, &packet.header, &packet.data) if rc == 1 { return &packet, nil } else if rc == 0 || rc == -2 { return nil, nil } return nil, errors.New(p.GetErr()) }
// NextEx reads the next packet and returns a success/failure indication: // // 1 the packet was read without problems // 0 packets are being read from a live capture, and the timeout expired // -1 an error occurred while reading the packet // -2 packets are being read from a file, and there are no more packets to read func (p *Pcap) NextEx() (*pkt.Packet, int32) { var pkthdr_ptr *C.struct_pcap_pkthdr var buf_ptr *C.u_char res := int32(C.pcap_next_ex(p.cptr, &pkthdr_ptr, &buf_ptr)) if res == 1 { p.m.Lock() packet := pkt.NewPacket(unsafe.Pointer(pkthdr_ptr), unsafe.Pointer(buf_ptr)) p.m.Unlock() p.pktCnt++ return packet, res } return nil, res }
// getNextBufPtrLocked is shared code for ReadPacketData and // ZeroCopyReadPacketData. func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error { p.activate.Do(p.activation) result := NextError(C.pcap_next_ex(p.cptr, &p.pkthdr, &p.buf_ptr)) if result != NextErrorOk { if result == NextErrorNoMorePackets { return io.EOF } else { return result } } ci.Timestamp = time.Unix(int64(p.pkthdr.ts.tv_sec), int64(p.pkthdr.ts.tv_usec)*1000) // convert micros to nanos ci.CaptureLength = int(p.pkthdr.caplen) ci.Length = int(p.pkthdr.len) 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) } } }