123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086 |
- package pcap
- import "C"
- import (
- "errors"
- "fmt"
- "io"
- "net"
- "reflect"
- "runtime"
- "strconv"
- "sync"
- "sync/atomic"
- "syscall"
- "time"
- "unsafe"
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- )
- const errorBufferSize = 256
- const ErrNotActive = int(C.PCAP_ERROR_NOT_ACTIVATED)
- const MaxBpfInstructions = 4096
- const bpfInstructionBufferSize = 8 * MaxBpfInstructions
- type Handle struct {
-
- cptr *C.pcap_t
- timeout time.Duration
- device string
- deviceIndex int
- mu sync.Mutex
- closeMu sync.Mutex
-
-
- stop uint64
-
-
-
-
- pkthdr *C.struct_pcap_pkthdr
- bufptr *C.u_char
- }
- type Stats struct {
- PacketsReceived int
- PacketsDropped int
- PacketsIfDropped int
- }
- type Interface struct {
- Name string
- Description string
- Flags uint32
- Addresses []InterfaceAddress
- }
- type Datalink struct {
- Name string
- Description string
- }
- type InterfaceAddress struct {
- IP net.IP
- Netmask net.IPMask
- Broadaddr net.IP
- P2P net.IP
- }
- type BPF struct {
- orig string
- bpf _Ctype_struct_bpf_program
- }
- type BPFInstruction struct {
- Code uint16
- Jt uint8
- Jf uint8
- K uint32
- }
- const BlockForever = -time.Millisecond * 10
- func timeoutMillis(timeout time.Duration) C.int {
-
- if timeout < 0 {
- timeout *= -1
- }
-
- if timeout != 0 && timeout < time.Millisecond {
- timeout = time.Millisecond
- }
- return C.int(timeout / time.Millisecond)
- }
- func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) {
- buf := (*C.char)(C.calloc(errorBufferSize, 1))
- defer C.free(unsafe.Pointer(buf))
- var pro C.int
- if promisc {
- pro = 1
- }
- p := &Handle{timeout: timeout, device: device}
- ifc, err := net.InterfaceByName(device)
- if err != nil {
-
-
- p.deviceIndex = 0
- } else {
- p.deviceIndex = ifc.Index
- }
- dev := C.CString(device)
- defer C.free(unsafe.Pointer(dev))
- p.cptr = C.pcap_open_live(dev, C.int(snaplen), pro, timeoutMillis(timeout), buf)
- if p.cptr == nil {
- return nil, errors.New(C.GoString(buf))
- }
-
-
-
- if p.timeout > 0 {
- if err := p.setNonBlocking(); err != nil {
- C.pcap_close(p.cptr)
- return nil, err
- }
- }
- return p, nil
- }
- func OpenOffline(file string) (handle *Handle, err error) {
- buf := (*C.char)(C.calloc(errorBufferSize, 1))
- defer C.free(unsafe.Pointer(buf))
- cf := C.CString(file)
- defer C.free(unsafe.Pointer(cf))
- cptr := C.pcap_open_offline(cf, buf)
- if cptr == nil {
- return nil, errors.New(C.GoString(buf))
- }
- h := &Handle{cptr: cptr}
- return h, nil
- }
- type NextError int32
- func (n NextError) Error() string {
- switch n {
- case NextErrorOk:
- return "OK"
- case NextErrorTimeoutExpired:
- return "Timeout Expired"
- case NextErrorReadError:
- return "Read Error"
- case NextErrorNoMorePackets:
- return "No More Packets In File"
- case NextErrorNotActivated:
- return "Not Activated"
- }
- return strconv.Itoa(int(n))
- }
- const (
- NextErrorOk NextError = 1
- NextErrorTimeoutExpired NextError = 0
- NextErrorReadError NextError = -1
-
-
- NextErrorNoMorePackets NextError = -2
- NextErrorNotActivated NextError = -3
- )
- func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
- p.mu.Lock()
- err = p.getNextBufPtrLocked(&ci)
- if err == nil {
- data = C.GoBytes(unsafe.Pointer(p.bufptr), C.int(ci.CaptureLength))
- }
- p.mu.Unlock()
- if err == NextErrorTimeoutExpired {
- runtime.Gosched()
- }
- return
- }
- type activateError C.int
- const (
- aeNoError = 0
- aeActivated = C.PCAP_ERROR_ACTIVATED
- aePromisc = C.PCAP_WARNING_PROMISC_NOTSUP
- aeNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE
- aeDenied = C.PCAP_ERROR_PERM_DENIED
- aeNotUp = C.PCAP_ERROR_IFACE_NOT_UP
- aeWarning = C.PCAP_WARNING
- )
- func (a activateError) Error() string {
- switch a {
- case aeNoError:
- return "No Error"
- case aeActivated:
- return "Already Activated"
- case aePromisc:
- return "Cannot set as promisc"
- case aeNoSuchDevice:
- return "No Such Device"
- case aeDenied:
- return "Permission Denied"
- case aeNotUp:
- return "Interface Not Up"
- case aeWarning:
- return fmt.Sprintf("Warning: %v", activateErrMsg.Error())
- default:
- return fmt.Sprintf("unknown activated error: %d", a)
- }
- }
- func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error {
- if p.cptr == nil {
- return io.EOF
- }
-
-
-
-
- pp := C.uintptr_t(uintptr(unsafe.Pointer(&p.pkthdr)))
- bp := C.uintptr_t(uintptr(unsafe.Pointer(&p.bufptr)))
-
- var waited bool
- for atomic.LoadUint64(&p.stop) == 0 {
-
- result := NextError(C.pcap_next_ex_escaping(p.cptr, pp, bp))
- switch result {
- case NextErrorOk:
-
- sec := int64(p.pkthdr.ts.tv_sec)
-
- nanos := int64(p.pkthdr.ts.tv_usec) * 1000
- ci.Timestamp = time.Unix(sec, nanos)
- ci.CaptureLength = int(p.pkthdr.caplen)
- ci.Length = int(p.pkthdr.len)
- ci.InterfaceIndex = p.deviceIndex
- return nil
- case NextErrorNoMorePackets:
-
- return io.EOF
- case NextErrorTimeoutExpired:
-
-
-
-
-
- if waited && p.timeout > 0 {
- return result
- }
-
- p.waitForPacket()
- waited = true
- default:
- return result
- }
- }
-
- return io.EOF
- }
- func (p *Handle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
- p.mu.Lock()
- err = p.getNextBufPtrLocked(&ci)
- if err == nil {
- slice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
- slice.Data = uintptr(unsafe.Pointer(p.bufptr))
- slice.Len = ci.CaptureLength
- slice.Cap = ci.CaptureLength
- }
- p.mu.Unlock()
- if err == NextErrorTimeoutExpired {
- runtime.Gosched()
- }
- return
- }
- func (p *Handle) Close() {
- p.closeMu.Lock()
- defer p.closeMu.Unlock()
- if p.cptr == nil {
- return
- }
- atomic.StoreUint64(&p.stop, 1)
-
- p.mu.Lock()
- defer p.mu.Unlock()
- C.pcap_close(p.cptr)
- p.cptr = nil
- }
- func (p *Handle) Error() error {
- return errors.New(C.GoString(C.pcap_geterr(p.cptr)))
- }
- func (p *Handle) Stats() (stat *Stats, err error) {
- var cstats _Ctype_struct_pcap_stat
- if -1 == C.pcap_stats(p.cptr, &cstats) {
- return nil, p.Error()
- }
- return &Stats{
- PacketsReceived: int(cstats.ps_recv),
- PacketsDropped: int(cstats.ps_drop),
- PacketsIfDropped: int(cstats.ps_ifdrop),
- }, nil
- }
- func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) {
- var dltbuf *C.int
- n := int(C.pcap_list_datalinks(p.cptr, &dltbuf))
- if -1 == n {
- return nil, p.Error()
- }
- defer C.pcap_free_datalinks(dltbuf)
- datalinks = make([]Datalink, n)
- dltArray := (*[100]C.int)(unsafe.Pointer(dltbuf))
- for i := 0; i < n; i++ {
- expr := C.pcap_datalink_val_to_name((*dltArray)[i])
- datalinks[i].Name = C.GoString(expr)
- expr = C.pcap_datalink_val_to_description((*dltArray)[i])
- datalinks[i].Description = C.GoString(expr)
- }
- return datalinks, nil
- }
- var pcapCompileMu sync.Mutex
- 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
-
-
- 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,
- ) {
-
-
- }
- }
- var bpf _Ctype_struct_bpf_program
- cexpr := C.CString(expr)
- defer C.free(unsafe.Pointer(cexpr))
- pcapCompileMu.Lock()
- defer pcapCompileMu.Unlock()
- if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, C.bpf_u_int32(maskp)) {
- return bpf, p.Error()
- }
- return bpf, nil
- }
- func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error) {
- cptr := C.pcap_open_dead(C.int(linkType), C.int(captureLength))
- if cptr == nil {
- return nil, errors.New("error opening dead capture")
- }
- h := Handle{cptr: cptr}
- defer h.Close()
- return h.CompileBPFFilter(expr)
- }
- func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) {
- bpf, err := p.compileBPFFilter(expr)
- defer C.pcap_freecode(&bpf)
- if err != nil {
- return nil, err
- }
- bpfInsn := (*[bpfInstructionBufferSize]_Ctype_struct_bpf_insn)(unsafe.Pointer(bpf.bf_insns))[0:bpf.bf_len:bpf.bf_len]
- bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn))
- for i, v := range bpfInsn {
- bpfInstruction[i].Code = uint16(v.code)
- bpfInstruction[i].Jt = uint8(v.jt)
- bpfInstruction[i].Jf = uint8(v.jf)
- bpfInstruction[i].K = uint32(v.k)
- }
- return bpfInstruction, nil
- }
- func (p *Handle) SetBPFFilter(expr string) (err error) {
- bpf, err := p.compileBPFFilter(expr)
- defer C.pcap_freecode(&bpf)
- if err != nil {
- return err
- }
- if -1 == C.pcap_setfilter(p.cptr, &bpf) {
- return p.Error()
- }
- return nil
- }
- func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error) {
- bpf, err := bpfInstructionFilter(bpfInstructions)
- if err != nil {
- return err
- }
- if -1 == C.pcap_setfilter(p.cptr, &bpf) {
- C.pcap_freecode(&bpf)
- return p.Error()
- }
- C.pcap_freecode(&bpf)
- return nil
- }
- func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_bpf_program, err error) {
- if len(bpfInstructions) < 1 {
- return bpf, errors.New("bpfInstructions must not be empty")
- }
- if len(bpfInstructions) > MaxBpfInstructions {
- return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions)
- }
- bpf.bf_len = C.u_int(len(bpfInstructions))
- cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0])))
- copy((*[bpfInstructionBufferSize]BPFInstruction)(cbpfInsns)[0:len(bpfInstructions)], bpfInstructions)
- bpf.bf_insns = (*_Ctype_struct_bpf_insn)(cbpfInsns)
- return
- }
- func (p *Handle) NewBPF(expr string) (*BPF, error) {
- bpf := &BPF{orig: expr}
- cexpr := C.CString(expr)
- defer C.free(unsafe.Pointer(cexpr))
- pcapCompileMu.Lock()
- defer pcapCompileMu.Unlock()
- if C.pcap_compile(p.cptr, &bpf.bpf, cexpr , 1, C.PCAP_NETMASK_UNKNOWN) != 0 {
- return nil, p.Error()
- }
- runtime.SetFinalizer(bpf, destroyBPF)
- return bpf, nil
- }
- func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) {
- var err error
- bpf := &BPF{orig: "BPF Instruction Filter"}
- bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
- if err != nil {
- return nil, err
- }
- runtime.SetFinalizer(bpf, destroyBPF)
- return bpf, nil
- }
- func destroyBPF(bpf *BPF) {
- C.pcap_freecode(&bpf.bpf)
- }
- func (b *BPF) String() string {
- return b.orig
- }
- func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool {
- var hdr C.struct_pcap_pkthdr
- hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix())
- hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000)
- hdr.caplen = C.bpf_u_int32(len(data))
- hdr.len = C.bpf_u_int32(ci.Length)
- dataptr := (*C.u_char)(unsafe.Pointer(&data[0]))
- return C.pcap_offline_filter(&b.bpf, &hdr, dataptr) != 0
- }
- func Version() string {
- return C.GoString(C.pcap_lib_version())
- }
- func (p *Handle) LinkType() layers.LinkType {
- return layers.LinkType(C.pcap_datalink(p.cptr))
- }
- func (p *Handle) SetLinkType(dlt layers.LinkType) error {
- if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) {
- return p.Error()
- }
- return nil
- }
- func DatalinkValToName(dlt int) string {
- return C.GoString(C.pcap_datalink_val_to_name(C.int(dlt)))
- }
- func DatalinkValToDescription(dlt int) string {
- return C.GoString(C.pcap_datalink_val_to_description(C.int(dlt)))
- }
- func DatalinkNameToVal(name string) C.int {
- cptr := C.CString(name)
- defer C.free(unsafe.Pointer(cptr))
- return C.int(C.pcap_datalink_name_to_val(cptr))
- }
- func FindAllDevs() (ifs []Interface, err error) {
- var buf *C.char
- buf = (*C.char)(C.calloc(errorBufferSize, 1))
- defer C.free(unsafe.Pointer(buf))
- var alldevsp *C.pcap_if_t
- if -1 == C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp), buf) {
- return nil, errors.New(C.GoString(buf))
- }
- defer C.pcap_freealldevs((*C.pcap_if_t)(alldevsp))
- dev := alldevsp
- var i uint32
- for i = 0; dev != nil; dev = (*C.pcap_if_t)(dev.next) {
- i++
- }
- ifs = make([]Interface, i)
- dev = alldevsp
- for j := uint32(0); dev != nil; dev = (*C.pcap_if_t)(dev.next) {
- var iface Interface
- iface.Name = C.GoString(dev.name)
- iface.Description = C.GoString(dev.description)
- iface.Addresses = findalladdresses(dev.addresses)
- iface.Flags = uint32(dev.flags)
- ifs[j] = iface
- j++
- }
- return
- }
- func findalladdresses(addresses *_Ctype_struct_pcap_addr) (retval []InterfaceAddress) {
-
- retval = make([]InterfaceAddress, 0, 1)
- for curaddr := addresses; curaddr != nil; curaddr = (*_Ctype_struct_pcap_addr)(curaddr.next) {
-
-
-
- if curaddr.addr == nil {
- continue
- }
- var a InterfaceAddress
- var err error
- if a.IP, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.addr))); err != nil {
- continue
- }
-
- if curaddr.netmask == nil {
- continue
- }
- if a.Netmask, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.netmask))); err != nil {
-
-
- a.Netmask = nil
- }
- if a.Broadaddr, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.broadaddr))); err != nil {
- a.Broadaddr = nil
- }
- if a.P2P, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.dstaddr))); err != nil {
- a.P2P = nil
- }
- retval = append(retval, a)
- }
- return
- }
- func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) {
- if unsafe.Pointer(rsa) == nil {
- err = errors.New("Value not set")
- return
- }
- switch rsa.Family {
- case syscall.AF_INET:
- pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
- IP = make([]byte, 4)
- for i := 0; i < len(IP); i++ {
- IP[i] = pp.Addr[i]
- }
- return
- case syscall.AF_INET6:
- pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
- IP = make([]byte, 16)
- for i := 0; i < len(IP); i++ {
- IP[i] = pp.Addr[i]
- }
- return
- }
- err = errors.New("Unsupported address type")
- return
- }
- func (p *Handle) WritePacketData(data []byte) (err error) {
- if -1 == C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) {
- err = p.Error()
- }
- return
- }
- type Direction uint8
- const (
- DirectionIn Direction = C.PCAP_D_IN
- DirectionOut Direction = C.PCAP_D_OUT
- DirectionInOut Direction = C.PCAP_D_INOUT
- )
- func (p *Handle) SetDirection(direction Direction) error {
- if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut {
- return fmt.Errorf("Invalid direction: %v", direction)
- }
- if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 {
- return statusError(status)
- }
- return nil
- }
- func (p *Handle) SnapLen() int {
- len := C.pcap_snapshot(p.cptr)
- return int(len)
- }
- type TimestampSource C.int
- func (t TimestampSource) String() string {
- return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t)))
- }
- func TimestampSourceFromString(s string) (TimestampSource, error) {
- cs := C.CString(s)
- defer C.free(unsafe.Pointer(cs))
- t := C.pcap_tstamp_type_name_to_val(cs)
- if t < 0 {
- return 0, statusError(t)
- }
- return TimestampSource(t), nil
- }
- func statusError(status C.int) error {
- return errors.New(C.GoString(C.pcap_statustostr(status)))
- }
- type InactiveHandle struct {
-
- cptr *C.pcap_t
- device string
- deviceIndex int
- timeout time.Duration
- }
- var activateErrMsg error
- func (p *InactiveHandle) Error() error {
- return errors.New(C.GoString(C.pcap_geterr(p.cptr)))
- }
- func (p *InactiveHandle) Activate() (*Handle, error) {
- err := activateError(C.pcap_activate(p.cptr))
- if err != aeNoError {
- if err == aeWarning {
- activateErrMsg = p.Error()
- }
- return nil, err
- }
- h := &Handle{
- cptr: p.cptr,
- timeout: p.timeout,
- device: p.device,
- deviceIndex: p.deviceIndex,
- }
- p.cptr = nil
- return h, nil
- }
- func (p *InactiveHandle) CleanUp() {
- if p.cptr != nil {
- C.pcap_close(p.cptr)
- }
- }
- 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))
-
-
- deviceIndex := 0
- ifc, err := net.InterfaceByName(device)
- if err == nil {
- deviceIndex = ifc.Index
- }
-
- 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
- }
- func (p *InactiveHandle) SetSnapLen(snaplen int) error {
- if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 {
- return statusError(status)
- }
- return nil
- }
- func (p *InactiveHandle) SetPromisc(promisc bool) error {
- var pro C.int
- if promisc {
- pro = 1
- }
- if status := C.pcap_set_promisc(p.cptr, pro); status < 0 {
- return statusError(status)
- }
- return nil
- }
- func (p *InactiveHandle) SetTimeout(timeout time.Duration) error {
- if status := C.pcap_set_timeout(p.cptr, timeoutMillis(timeout)); status < 0 {
- return statusError(status)
- }
- p.timeout = timeout
- return nil
- }
- func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) {
- var types *C.int
- n := int(C.pcap_list_tstamp_types(p.cptr, &types))
- defer C.pcap_free_tstamp_types(types)
- typesArray := (*[100]C.int)(unsafe.Pointer(types))
- for i := 0; i < n; i++ {
- out = append(out, TimestampSource((*typesArray)[i]))
- }
- return
- }
- func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error {
- if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 {
- return statusError(status)
- }
- return nil
- }
- var CannotSetRFMon = errors.New("Cannot set rfmon for this handle")
- func (p *InactiveHandle) SetRFMon(monitor bool) error {
- var mon C.int
- if monitor {
- mon = 1
- }
- switch canset := C.pcap_can_set_rfmon(p.cptr); canset {
- case 0:
- return CannotSetRFMon
- case 1:
-
- default:
- return statusError(canset)
- }
- if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 {
- return statusError(status)
- }
- return nil
- }
- func (p *InactiveHandle) SetBufferSize(bufferSize int) error {
- if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 {
- return statusError(status)
- }
- return nil
- }
- func (p *InactiveHandle) SetImmediateMode(mode bool) error {
- var md C.int
- if mode {
- md = 1
- }
- if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 {
- return statusError(status)
- }
- return nil
- }
|