Esempio n. 1
0
// 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
}
Esempio n. 2
0
// 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")
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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
}
Esempio n. 5
0
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())
}
Esempio n. 6
0
// 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
}
Esempio n. 7
0
// 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
}
Esempio n. 8
0
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)
		}
	}

}