ODPM 266: Go-libmemif + 2 examples.
[govpp.git] / vendor / github.com / google / gopacket / pcap / pcap.go
1 // Copyright 2012 Google, Inc. All rights reserved.
2 // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style license
5 // that can be found in the LICENSE file in the root of the source
6 // tree.
7
8 package pcap
9
10 /*
11 #cgo solaris LDFLAGS: -L /opt/local/lib -lpcap
12 #cgo linux LDFLAGS: -lpcap
13 #cgo dragonfly LDFLAGS: -lpcap
14 #cgo freebsd LDFLAGS: -lpcap
15 #cgo openbsd LDFLAGS: -lpcap
16 #cgo netbsd LDFLAGS: -lpcap
17 #cgo darwin LDFLAGS: -lpcap
18 #cgo windows CFLAGS: -I C:/WpdPack/Include
19 #cgo windows,386 LDFLAGS: -L C:/WpdPack/Lib -lwpcap
20 #cgo windows,amd64 LDFLAGS: -L C:/WpdPack/Lib/x64 -lwpcap
21 #include <stdlib.h>
22 #include <pcap.h>
23
24 // Some old versions of pcap don't define this constant.
25 #ifndef PCAP_NETMASK_UNKNOWN
26 #define PCAP_NETMASK_UNKNOWN 0xffffffff
27 #endif
28
29 // libpcap doesn't actually export its version in a #define-guardable way,
30 // so we have to use other defined things to differentiate versions.
31 // We assume at least libpcap v1.1 at the moment.
32 // See http://upstream-tracker.org/versions/libpcap.html
33
34 #ifndef PCAP_ERROR_TSTAMP_PRECISION_NOTSUP  // < v1.5
35
36 int pcap_set_immediate_mode(pcap_t *p, int mode) {
37   return PCAP_ERROR;
38 }
39
40 #ifndef PCAP_TSTAMP_HOST  // < v1.2
41
42 int pcap_set_tstamp_type(pcap_t* p, int t) { return -1; }
43 int pcap_list_tstamp_types(pcap_t* p, int** t) { return 0; }
44 void pcap_free_tstamp_types(int *tstamp_types) {}
45 const char* pcap_tstamp_type_val_to_name(int t) {
46         return "pcap timestamp types not supported";
47 }
48 int pcap_tstamp_type_name_to_val(const char* t) {
49         return PCAP_ERROR;
50 }
51
52 #endif  // < v1.2
53 #endif  // < v1.5
54
55 #ifndef PCAP_ERROR_PROMISC_PERM_DENIED
56 #define PCAP_ERROR_PROMISC_PERM_DENIED -11
57 #endif
58
59 // WinPcap doesn't export a pcap_statustostr, so use the less-specific
60 // pcap_strerror.  Note that linking against something like cygwin libpcap
61 // may result is less-specific error messages.
62 #ifdef WIN32
63 #define pcap_statustostr pcap_strerror
64
65 // WinPcap also doesn't export pcap_can_set_rfmon and pcap_set_rfmon,
66 // as those are handled by separate libraries (airpcap).
67 // https://www.winpcap.org/docs/docs_412/html/group__wpcapfunc.html
68 // Stub out those functions here, returning values that indicate rfmon
69 // setting is unavailable/unsuccessful.
70 int pcap_can_set_rfmon(pcap_t *p) {
71         return 0;
72 }
73
74 int pcap_set_rfmon(pcap_t *p, int rfmon) {
75         return PCAP_ERROR;
76 }
77 #endif
78
79 // Windows, Macs, and Linux all use different time types.  Joy.
80 #ifdef WIN32
81 #define gopacket_time_secs_t long
82 #define gopacket_time_usecs_t long
83 #elif __APPLE__
84 #define gopacket_time_secs_t __darwin_time_t
85 #define gopacket_time_usecs_t __darwin_suseconds_t
86 #elif __GLIBC__
87 #define gopacket_time_secs_t __time_t
88 #define gopacket_time_usecs_t __suseconds_t
89 #else  // Some form of linux/bsd/etc...
90 #include <sys/param.h>
91 #ifdef __OpenBSD__
92 #define gopacket_time_secs_t u_int32_t
93 #define gopacket_time_usecs_t u_int32_t
94 #else
95 #define gopacket_time_secs_t time_t
96 #define gopacket_time_usecs_t suseconds_t
97 #endif
98 #endif
99 */
100 import "C"
101
102 import (
103         "errors"
104         "fmt"
105         "io"
106         "net"
107         "reflect"
108         "runtime"
109         "strconv"
110         "sync"
111         "sync/atomic"
112         "syscall"
113         "time"
114         "unsafe"
115
116         "github.com/google/gopacket"
117         "github.com/google/gopacket/layers"
118 )
119
120 const errorBufferSize = 256
121
122 // MaxBpfInstructions is the maximum number of BPF instructions supported (BPF_MAXINSNS),
123 // taken from Linux kernel: include/uapi/linux/bpf_common.h
124 //
125 // https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf_common.h
126 const MaxBpfInstructions = 4096
127
128 // 8 bytes per instruction, max 4096 instructions
129 const bpfInstructionBufferSize = 8 * MaxBpfInstructions
130
131 // Handle provides a connection to a pcap handle, allowing users to read packets
132 // off the wire (Next), inject packets onto the wire (Inject), and
133 // perform a number of other functions to affect and understand packet output.
134 //
135 // Handles are already pcap_activate'd
136 type Handle struct {
137         // cptr is the handle for the actual pcap C object.
138         cptr        *C.pcap_t
139         timeout     time.Duration
140         device      string
141         deviceIndex int
142         mu          sync.Mutex
143         closeMu     sync.Mutex
144         // stop is set to a non-zero value by Handle.Close to signal to
145         // getNextBufPtrLocked to stop trying to read packets
146         stop uint64
147
148         // Since pointers to these objects are passed into a C function, if
149         // they're declared locally then the Go compiler thinks they may have
150         // escaped into C-land, so it allocates them on the heap.  This causes a
151         // huge memory hit, so to handle that we store them here instead.
152         pkthdr *C.struct_pcap_pkthdr
153         bufptr *C.u_char
154 }
155
156 // Stats contains statistics on how many packets were handled by a pcap handle,
157 // and what was done with those packets.
158 type Stats struct {
159         PacketsReceived  int
160         PacketsDropped   int
161         PacketsIfDropped int
162 }
163
164 // Interface describes a single network interface on a machine.
165 type Interface struct {
166         Name        string
167         Description string
168         Addresses   []InterfaceAddress
169         // TODO: add more elements
170 }
171
172 // Datalink describes the datalink
173 type Datalink struct {
174         Name        string
175         Description string
176 }
177
178 // InterfaceAddress describes an address associated with an Interface.
179 // Currently, it's IPv4/6 specific.
180 type InterfaceAddress struct {
181         IP      net.IP
182         Netmask net.IPMask // Netmask may be nil if we were unable to retrieve it.
183         // TODO: add broadcast + PtP dst ?
184 }
185
186 // BPF is a compiled filter program, useful for offline packet matching.
187 type BPF struct {
188         orig string
189         bpf  _Ctype_struct_bpf_program // takes a finalizer, not overriden by outsiders
190 }
191
192 // BPFInstruction is a byte encoded structure holding a BPF instruction
193 type BPFInstruction struct {
194         Code uint16
195         Jt   uint8
196         Jf   uint8
197         K    uint32
198 }
199
200 // BlockForever causes it to block forever waiting for packets, when passed
201 // into SetTimeout or OpenLive, while still returning incoming packets to userland relatively
202 // quickly.
203 const BlockForever = -time.Millisecond * 10
204
205 func timeoutMillis(timeout time.Duration) C.int {
206         // Flip sign if necessary.  See package docs on timeout for reasoning behind this.
207         if timeout < 0 {
208                 timeout *= -1
209         }
210         // Round up
211         if timeout != 0 && timeout < time.Millisecond {
212                 timeout = time.Millisecond
213         }
214         return C.int(timeout / time.Millisecond)
215 }
216
217 // OpenLive opens a device and returns a *Handle.
218 // It takes as arguments the name of the device ("eth0"), the maximum size to
219 // read for each packet (snaplen), whether to put the interface in promiscuous
220 // mode, and a timeout.
221 //
222 // See the package documentation for important details regarding 'timeout'.
223 func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) {
224         buf := (*C.char)(C.calloc(errorBufferSize, 1))
225         defer C.free(unsafe.Pointer(buf))
226
227         var pro C.int
228         if promisc {
229                 pro = 1
230         }
231         p := &Handle{timeout: timeout, device: device}
232
233         ifc, err := net.InterfaceByName(device)
234         if err != nil {
235                 // The device wasn't found in the OS, but could be "any"
236                 // Set index to 0
237                 p.deviceIndex = 0
238         } else {
239                 p.deviceIndex = ifc.Index
240         }
241
242         dev := C.CString(device)
243         defer C.free(unsafe.Pointer(dev))
244
245         p.cptr = C.pcap_open_live(dev, C.int(snaplen), pro, timeoutMillis(timeout), buf)
246         if p.cptr == nil {
247                 return nil, errors.New(C.GoString(buf))
248         }
249
250         if err := p.openLive(); err != nil {
251                 C.pcap_close(p.cptr)
252                 return nil, err
253         }
254
255         return p, nil
256 }
257
258 // OpenOffline opens a file and returns its contents as a *Handle.
259 func OpenOffline(file string) (handle *Handle, err error) {
260         buf := (*C.char)(C.calloc(errorBufferSize, 1))
261         defer C.free(unsafe.Pointer(buf))
262         cf := C.CString(file)
263         defer C.free(unsafe.Pointer(cf))
264
265         cptr := C.pcap_open_offline(cf, buf)
266         if cptr == nil {
267                 return nil, errors.New(C.GoString(buf))
268         }
269         return &Handle{cptr: cptr}, nil
270 }
271
272 // NextError is the return code from a call to Next.
273 type NextError int32
274
275 // NextError implements the error interface.
276 func (n NextError) Error() string {
277         switch n {
278         case NextErrorOk:
279                 return "OK"
280         case NextErrorTimeoutExpired:
281                 return "Timeout Expired"
282         case NextErrorReadError:
283                 return "Read Error"
284         case NextErrorNoMorePackets:
285                 return "No More Packets In File"
286         case NextErrorNotActivated:
287                 return "Not Activated"
288         }
289         return strconv.Itoa(int(n))
290 }
291
292 // NextError values.
293 const (
294         NextErrorOk             NextError = 1
295         NextErrorTimeoutExpired NextError = 0
296         NextErrorReadError      NextError = -1
297         // NextErrorNoMorePackets is returned when reading from a file (OpenOffline) and
298         // EOF is reached.  When this happens, Next() returns io.EOF instead of this.
299         NextErrorNoMorePackets NextError = -2
300         NextErrorNotActivated  NextError = -3
301 )
302
303 // ReadPacketData returns the next packet read from the pcap handle, along with an error
304 // code associated with that packet.  If the packet is read successfully, the
305 // returned error is nil.
306 func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
307         p.mu.Lock()
308         err = p.getNextBufPtrLocked(&ci)
309         if err == nil {
310                 data = C.GoBytes(unsafe.Pointer(p.bufptr), C.int(ci.CaptureLength))
311         }
312         p.mu.Unlock()
313         if err == NextErrorTimeoutExpired {
314                 runtime.Gosched()
315         }
316         return
317 }
318
319 type activateError C.int
320
321 const (
322         aeNoError      = 0
323         aeActivated    = C.PCAP_ERROR_ACTIVATED
324         aePromisc      = C.PCAP_WARNING_PROMISC_NOTSUP
325         aeNoSuchDevice = C.PCAP_ERROR_NO_SUCH_DEVICE
326         aeDenied       = C.PCAP_ERROR_PERM_DENIED
327         aeNotUp        = C.PCAP_ERROR_IFACE_NOT_UP
328 )
329
330 func (a activateError) Error() string {
331         switch a {
332         case aeNoError:
333                 return "No Error"
334         case aeActivated:
335                 return "Already Activated"
336         case aePromisc:
337                 return "Cannot set as promisc"
338         case aeNoSuchDevice:
339                 return "No Such Device"
340         case aeDenied:
341                 return "Permission Denied"
342         case aeNotUp:
343                 return "Interface Not Up"
344         default:
345                 return fmt.Sprintf("unknown activated error: %d", a)
346         }
347 }
348
349 // getNextBufPtrLocked is shared code for ReadPacketData and
350 // ZeroCopyReadPacketData.
351 func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error {
352         if p.cptr == nil {
353                 return io.EOF
354         }
355
356         for atomic.LoadUint64(&p.stop) == 0 {
357                 // try to read a packet if one is immediately available
358                 result := NextError(C.pcap_next_ex(p.cptr, &p.pkthdr, &p.bufptr))
359
360                 switch result {
361                 case NextErrorOk:
362                         // got a packet, set capture info and return
363                         sec := int64(p.pkthdr.ts.tv_sec)
364                         // convert micros to nanos
365                         nanos := int64(p.pkthdr.ts.tv_usec) * 1000
366
367                         ci.Timestamp = time.Unix(sec, nanos)
368                         ci.CaptureLength = int(p.pkthdr.caplen)
369                         ci.Length = int(p.pkthdr.len)
370                         ci.InterfaceIndex = p.deviceIndex
371
372                         return nil
373                 case NextErrorNoMorePackets:
374                         // no more packets, return EOF rather than libpcap-specific error
375                         return io.EOF
376                 case NextErrorTimeoutExpired:
377                         // Negative timeout means to loop forever, instead of actually returning
378                         // the timeout error.
379                         if p.timeout < 0 {
380                                 // must have had a timeout... wait before trying again
381                                 p.waitForPacket()
382                                 continue
383                         }
384                 default:
385                         return result
386                 }
387         }
388
389         // stop must be set
390         return io.EOF
391 }
392
393 // ZeroCopyReadPacketData reads the next packet off the wire, and returns its data.
394 // The slice returned by ZeroCopyReadPacketData points to bytes owned by the
395 // the Handle.  Each call to ZeroCopyReadPacketData invalidates any data previously
396 // returned by ZeroCopyReadPacketData.  Care must be taken not to keep pointers
397 // to old bytes when using ZeroCopyReadPacketData... if you need to keep data past
398 // the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies
399 // the bytes into a new buffer for you.
400 //  data1, _, _ := handle.ZeroCopyReadPacketData()
401 //  // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
402 //  data2, _, _ := handle.ZeroCopyReadPacketData()  // invalidates bytes in data1
403 func (p *Handle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
404         p.mu.Lock()
405         err = p.getNextBufPtrLocked(&ci)
406         if err == nil {
407                 slice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
408                 slice.Data = uintptr(unsafe.Pointer(p.bufptr))
409                 slice.Len = ci.CaptureLength
410                 slice.Cap = ci.CaptureLength
411         }
412         p.mu.Unlock()
413         if err == NextErrorTimeoutExpired {
414                 runtime.Gosched()
415         }
416         return
417 }
418
419 // Close closes the underlying pcap handle.
420 func (p *Handle) Close() {
421         p.closeMu.Lock()
422         defer p.closeMu.Unlock()
423
424         if p.cptr == nil {
425                 return
426         }
427
428         atomic.StoreUint64(&p.stop, 1)
429
430         // wait for packet reader to stop
431         p.mu.Lock()
432         defer p.mu.Unlock()
433
434         C.pcap_close(p.cptr)
435         p.cptr = nil
436 }
437
438 // Error returns the current error associated with a pcap handle (pcap_geterr).
439 func (p *Handle) Error() error {
440         return errors.New(C.GoString(C.pcap_geterr(p.cptr)))
441 }
442
443 // Stats returns statistics on the underlying pcap handle.
444 func (p *Handle) Stats() (stat *Stats, err error) {
445         var cstats _Ctype_struct_pcap_stat
446         if -1 == C.pcap_stats(p.cptr, &cstats) {
447                 return nil, p.Error()
448         }
449         return &Stats{
450                 PacketsReceived:  int(cstats.ps_recv),
451                 PacketsDropped:   int(cstats.ps_drop),
452                 PacketsIfDropped: int(cstats.ps_ifdrop),
453         }, nil
454 }
455
456 // ListDataLinks obtains a list of all possible data link types supported for an interface.
457 func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) {
458         var dltbuf *C.int
459
460         n := int(C.pcap_list_datalinks(p.cptr, &dltbuf))
461         if -1 == n {
462                 return nil, p.Error()
463         }
464
465         defer C.pcap_free_datalinks(dltbuf)
466
467         datalinks = make([]Datalink, n)
468
469         dltArray := (*[100]C.int)(unsafe.Pointer(dltbuf))
470
471         for i := 0; i < n; i++ {
472                 expr := C.pcap_datalink_val_to_name((*dltArray)[i])
473                 datalinks[i].Name = C.GoString(expr)
474
475                 expr = C.pcap_datalink_val_to_description((*dltArray)[i])
476                 datalinks[i].Description = C.GoString(expr)
477         }
478
479         return datalinks, nil
480 }
481
482 // pcap_compile is NOT thread-safe, so protect it.
483 var pcapCompileMu sync.Mutex
484
485 // compileBPFFilter always returns an allocated _Ctype_struct_bpf_program
486 // It is the callers responsibility to free the memory again, e.g.
487 //
488 //    C.pcap_freecode(&bpf)
489 //
490 func (p *Handle) compileBPFFilter(expr string) (_Ctype_struct_bpf_program, error) {
491         errorBuf := (*C.char)(C.calloc(errorBufferSize, 1))
492         defer C.free(unsafe.Pointer(errorBuf))
493
494         var netp uint32
495         var maskp uint32
496
497         // Only do the lookup on network interfaces.
498         // No device indicates we're handling a pcap file.
499         if len(p.device) > 0 {
500                 dev := C.CString(p.device)
501                 defer C.free(unsafe.Pointer(dev))
502                 if -1 == C.pcap_lookupnet(
503                         dev,
504                         (*C.bpf_u_int32)(unsafe.Pointer(&netp)),
505                         (*C.bpf_u_int32)(unsafe.Pointer(&maskp)),
506                         errorBuf,
507                 ) {
508                         // We can't lookup the network, but that could be because the interface
509                         // doesn't have an IPv4.
510                 }
511         }
512
513         var bpf _Ctype_struct_bpf_program
514         cexpr := C.CString(expr)
515         defer C.free(unsafe.Pointer(cexpr))
516
517         pcapCompileMu.Lock()
518         defer pcapCompileMu.Unlock()
519         if -1 == C.pcap_compile(p.cptr, &bpf, cexpr, 1, C.bpf_u_int32(maskp)) {
520                 return bpf, p.Error()
521         }
522
523         return bpf, nil
524 }
525
526 // CompileBPFFilter compiles and returns a BPF filter with given a link type and capture length.
527 func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error) {
528         cptr := C.pcap_open_dead(C.int(linkType), C.int(captureLength))
529         if cptr == nil {
530                 return nil, errors.New("error opening dead capture")
531         }
532
533         h := Handle{cptr: cptr}
534         defer h.Close()
535         return h.CompileBPFFilter(expr)
536 }
537
538 // CompileBPFFilter compiles and returns a BPF filter for the pcap handle.
539 func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) {
540         bpf, err := p.compileBPFFilter(expr)
541         defer C.pcap_freecode(&bpf)
542         if err != nil {
543                 return nil, err
544         }
545
546         bpfInsn := (*[bpfInstructionBufferSize]_Ctype_struct_bpf_insn)(unsafe.Pointer(bpf.bf_insns))[0:bpf.bf_len:bpf.bf_len]
547         bpfInstruction := make([]BPFInstruction, len(bpfInsn), len(bpfInsn))
548
549         for i, v := range bpfInsn {
550                 bpfInstruction[i].Code = uint16(v.code)
551                 bpfInstruction[i].Jt = uint8(v.jt)
552                 bpfInstruction[i].Jf = uint8(v.jf)
553                 bpfInstruction[i].K = uint32(v.k)
554         }
555
556         return bpfInstruction, nil
557 }
558
559 // SetBPFFilter compiles and sets a BPF filter for the pcap handle.
560 func (p *Handle) SetBPFFilter(expr string) (err error) {
561         bpf, err := p.compileBPFFilter(expr)
562         defer C.pcap_freecode(&bpf)
563         if err != nil {
564                 return err
565         }
566
567         if -1 == C.pcap_setfilter(p.cptr, &bpf) {
568                 return p.Error()
569         }
570
571         return nil
572 }
573
574 // SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format.
575 //
576 // Simplest way to generate BPF asm byte code is with tcpdump:
577 //     tcpdump -dd 'udp'
578 //
579 // The output may be used directly to add a filter, e.g.:
580 //     bpfInstructions := []pcap.BpfInstruction{
581 //                      {0x28, 0, 0, 0x0000000c},
582 //                      {0x15, 0, 9, 0x00000800},
583 //                      {0x30, 0, 0, 0x00000017},
584 //                      {0x15, 0, 7, 0x00000006},
585 //                      {0x28, 0, 0, 0x00000014},
586 //                      {0x45, 5, 0, 0x00001fff},
587 //                      {0xb1, 0, 0, 0x0000000e},
588 //                      {0x50, 0, 0, 0x0000001b},
589 //                      {0x54, 0, 0, 0x00000012},
590 //                      {0x15, 0, 1, 0x00000012},
591 //                      {0x6, 0, 0, 0x0000ffff},
592 //                      {0x6, 0, 0, 0x00000000},
593 //              }
594 //
595 // An other posibility is to write the bpf code in bpf asm.
596 // Documentation: https://www.kernel.org/doc/Documentation/networking/filter.txt
597 //
598 // To compile the code use bpf_asm from
599 // https://github.com/torvalds/linux/tree/master/tools/net
600 //
601 // The following command may be used to convert bpf_asm output to c/go struct, usable for SetBPFFilterByte:
602 // bpf_asm -c tcp.bpf
603 func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error) {
604         bpf, err := bpfInstructionFilter(bpfInstructions)
605         if err != nil {
606                 return err
607         }
608
609         if -1 == C.pcap_setfilter(p.cptr, &bpf) {
610                 C.pcap_freecode(&bpf)
611                 return p.Error()
612         }
613
614         C.pcap_freecode(&bpf)
615
616         return nil
617 }
618 func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_bpf_program, err error) {
619         if len(bpfInstructions) < 1 {
620                 return bpf, errors.New("bpfInstructions must not be empty")
621         }
622
623         if len(bpfInstructions) > MaxBpfInstructions {
624                 return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions)
625         }
626
627         bpf.bf_len = C.u_int(len(bpfInstructions))
628         cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0])))
629
630         copy((*[bpfInstructionBufferSize]BPFInstruction)(cbpfInsns)[0:len(bpfInstructions)], bpfInstructions)
631         bpf.bf_insns = (*_Ctype_struct_bpf_insn)(cbpfInsns)
632
633         return
634 }
635
636 // NewBPF compiles the given string into a new filter program.
637 //
638 // BPF filters need to be created from activated handles, because they need to
639 // know the underlying link type to correctly compile their offsets.
640 func (p *Handle) NewBPF(expr string) (*BPF, error) {
641         bpf := &BPF{orig: expr}
642         cexpr := C.CString(expr)
643         defer C.free(unsafe.Pointer(cexpr))
644
645         pcapCompileMu.Lock()
646         defer pcapCompileMu.Unlock()
647         if C.pcap_compile(p.cptr, &bpf.bpf, cexpr /* optimize */, 1, C.PCAP_NETMASK_UNKNOWN) != 0 {
648                 return nil, p.Error()
649         }
650
651         runtime.SetFinalizer(bpf, destroyBPF)
652         return bpf, nil
653 }
654
655 // NewBPFInstructionFilter sets the given BPFInstructions as new filter program.
656 //
657 // More details see func SetBPFInstructionFilter
658 //
659 // BPF filters need to be created from activated handles, because they need to
660 // know the underlying link type to correctly compile their offsets.
661 func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) {
662         var err error
663         bpf := &BPF{orig: "BPF Instruction Filter"}
664
665         bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
666         if err != nil {
667                 return nil, err
668         }
669
670         runtime.SetFinalizer(bpf, destroyBPF)
671         return bpf, nil
672 }
673 func destroyBPF(bpf *BPF) {
674         C.pcap_freecode(&bpf.bpf)
675 }
676
677 // String returns the original string this BPF filter was compiled from.
678 func (b *BPF) String() string {
679         return b.orig
680 }
681
682 // Matches returns true if the given packet data matches this filter.
683 func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool {
684         var hdr C.struct_pcap_pkthdr
685         hdr.ts.tv_sec = C.gopacket_time_secs_t(ci.Timestamp.Unix())
686         hdr.ts.tv_usec = C.gopacket_time_usecs_t(ci.Timestamp.Nanosecond() / 1000)
687         hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length.
688         hdr.len = C.bpf_u_int32(ci.Length)
689         dataptr := (*C.u_char)(unsafe.Pointer(&data[0]))
690         return C.pcap_offline_filter(&b.bpf, &hdr, dataptr) != 0
691 }
692
693 // Version returns pcap_lib_version.
694 func Version() string {
695         return C.GoString(C.pcap_lib_version())
696 }
697
698 // LinkType returns pcap_datalink, as a layers.LinkType.
699 func (p *Handle) LinkType() layers.LinkType {
700         return layers.LinkType(C.pcap_datalink(p.cptr))
701 }
702
703 // SetLinkType calls pcap_set_datalink on the pcap handle.
704 func (p *Handle) SetLinkType(dlt layers.LinkType) error {
705         if -1 == C.pcap_set_datalink(p.cptr, C.int(dlt)) {
706                 return p.Error()
707         }
708         return nil
709 }
710
711 // FindAllDevs attempts to enumerate all interfaces on the current machine.
712 func FindAllDevs() (ifs []Interface, err error) {
713         var buf *C.char
714         buf = (*C.char)(C.calloc(errorBufferSize, 1))
715         defer C.free(unsafe.Pointer(buf))
716         var alldevsp *C.pcap_if_t
717
718         if -1 == C.pcap_findalldevs((**C.pcap_if_t)(&alldevsp), buf) {
719                 return nil, errors.New(C.GoString(buf))
720         }
721         defer C.pcap_freealldevs((*C.pcap_if_t)(alldevsp))
722         dev := alldevsp
723         var i uint32
724         for i = 0; dev != nil; dev = (*C.pcap_if_t)(dev.next) {
725                 i++
726         }
727         ifs = make([]Interface, i)
728         dev = alldevsp
729         for j := uint32(0); dev != nil; dev = (*C.pcap_if_t)(dev.next) {
730                 var iface Interface
731                 iface.Name = C.GoString(dev.name)
732                 iface.Description = C.GoString(dev.description)
733                 iface.Addresses = findalladdresses(dev.addresses)
734                 // TODO: add more elements
735                 ifs[j] = iface
736                 j++
737         }
738         return
739 }
740
741 func findalladdresses(addresses *_Ctype_struct_pcap_addr) (retval []InterfaceAddress) {
742         // TODO - make it support more than IPv4 and IPv6?
743         retval = make([]InterfaceAddress, 0, 1)
744         for curaddr := addresses; curaddr != nil; curaddr = (*_Ctype_struct_pcap_addr)(curaddr.next) {
745                 // Strangely, it appears that in some cases, we get a pcap address back from
746                 // pcap_findalldevs with a nil .addr.  It appears that we can skip over
747                 // these.
748                 if curaddr.addr == nil {
749                         continue
750                 }
751                 var a InterfaceAddress
752                 var err error
753                 if a.IP, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.addr))); err != nil {
754                         continue
755                 }
756                 // To be safe, we'll also check for netmask.
757                 if curaddr.netmask == nil {
758                         continue
759                 }
760                 if a.Netmask, err = sockaddrToIP((*syscall.RawSockaddr)(unsafe.Pointer(curaddr.netmask))); err != nil {
761                         // If we got an IP address but we can't get a netmask, just return the IP
762                         // address.
763                         a.Netmask = nil
764                 }
765                 retval = append(retval, a)
766         }
767         return
768 }
769
770 func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) {
771         switch rsa.Family {
772         case syscall.AF_INET:
773                 pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
774                 IP = make([]byte, 4)
775                 for i := 0; i < len(IP); i++ {
776                         IP[i] = pp.Addr[i]
777                 }
778                 return
779         case syscall.AF_INET6:
780                 pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
781                 IP = make([]byte, 16)
782                 for i := 0; i < len(IP); i++ {
783                         IP[i] = pp.Addr[i]
784                 }
785                 return
786         }
787         err = errors.New("Unsupported address type")
788         return
789 }
790
791 // WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle.
792 func (p *Handle) WritePacketData(data []byte) (err error) {
793         if -1 == C.pcap_sendpacket(p.cptr, (*C.u_char)(&data[0]), (C.int)(len(data))) {
794                 err = p.Error()
795         }
796         return
797 }
798
799 // Direction is used by Handle.SetDirection.
800 type Direction uint8
801
802 // Direction values for Handle.SetDirection.
803 const (
804         DirectionIn    Direction = C.PCAP_D_IN
805         DirectionOut   Direction = C.PCAP_D_OUT
806         DirectionInOut Direction = C.PCAP_D_INOUT
807 )
808
809 // SetDirection sets the direction for which packets will be captured.
810 func (p *Handle) SetDirection(direction Direction) error {
811         if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut {
812                 return fmt.Errorf("Invalid direction: %v", direction)
813         }
814         if status := C.pcap_setdirection(p.cptr, (C.pcap_direction_t)(direction)); status < 0 {
815                 return statusError(status)
816         }
817         return nil
818 }
819
820 // TimestampSource tells PCAP which type of timestamp to use for packets.
821 type TimestampSource C.int
822
823 // String returns the timestamp type as a human-readable string.
824 func (t TimestampSource) String() string {
825         return C.GoString(C.pcap_tstamp_type_val_to_name(C.int(t)))
826 }
827
828 // TimestampSourceFromString translates a string into a timestamp type, case
829 // insensitive.
830 func TimestampSourceFromString(s string) (TimestampSource, error) {
831         cs := C.CString(s)
832         defer C.free(unsafe.Pointer(cs))
833         t := C.pcap_tstamp_type_name_to_val(cs)
834         if t < 0 {
835                 return 0, statusError(t)
836         }
837         return TimestampSource(t), nil
838 }
839
840 func statusError(status C.int) error {
841         return errors.New(C.GoString(C.pcap_statustostr(status)))
842 }
843
844 // InactiveHandle allows you to call pre-pcap_activate functions on your pcap
845 // handle to set it up just the way you'd like.
846 type InactiveHandle struct {
847         // cptr is the handle for the actual pcap C object.
848         cptr        *C.pcap_t
849         device      string
850         deviceIndex int
851         timeout     time.Duration
852 }
853
854 // Activate activates the handle.  The current InactiveHandle becomes invalid
855 // and all future function calls on it will fail.
856 func (p *InactiveHandle) Activate() (*Handle, error) {
857         err := activateError(C.pcap_activate(p.cptr))
858         if err != aeNoError {
859                 return nil, err
860         }
861         h := &Handle{
862                 cptr:        p.cptr,
863                 timeout:     p.timeout,
864                 device:      p.device,
865                 deviceIndex: p.deviceIndex,
866         }
867         p.cptr = nil
868         return h, nil
869 }
870
871 // CleanUp cleans up any stuff left over from a successful or failed building
872 // of a handle.
873 func (p *InactiveHandle) CleanUp() {
874         if p.cptr != nil {
875                 C.pcap_close(p.cptr)
876         }
877 }
878
879 // NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle.
880 // Callers of NewInactiveHandle should immediately defer 'CleanUp', as in:
881 //   inactive := NewInactiveHandle("eth0")
882 //   defer inactive.CleanUp()
883 func NewInactiveHandle(device string) (*InactiveHandle, error) {
884         buf := (*C.char)(C.calloc(errorBufferSize, 1))
885         defer C.free(unsafe.Pointer(buf))
886         dev := C.CString(device)
887         defer C.free(unsafe.Pointer(dev))
888
889         // Try to get the interface index, but iy could be something like "any"
890         // in which case use 0, which doesn't exist in nature
891         deviceIndex := 0
892         ifc, err := net.InterfaceByName(device)
893         if err == nil {
894                 deviceIndex = ifc.Index
895         }
896
897         // This copies a bunch of the pcap_open_live implementation from pcap.c:
898         cptr := C.pcap_create(dev, buf)
899         if cptr == nil {
900                 return nil, errors.New(C.GoString(buf))
901         }
902         return &InactiveHandle{cptr: cptr, device: device, deviceIndex: deviceIndex}, nil
903 }
904
905 // SetSnapLen sets the snap length (max bytes per packet to capture).
906 func (p *InactiveHandle) SetSnapLen(snaplen int) error {
907         if status := C.pcap_set_snaplen(p.cptr, C.int(snaplen)); status < 0 {
908                 return statusError(status)
909         }
910         return nil
911 }
912
913 // SetPromisc sets the handle to either be promiscuous (capture packets
914 // unrelated to this host) or not.
915 func (p *InactiveHandle) SetPromisc(promisc bool) error {
916         var pro C.int
917         if promisc {
918                 pro = 1
919         }
920         if status := C.pcap_set_promisc(p.cptr, pro); status < 0 {
921                 return statusError(status)
922         }
923         return nil
924 }
925
926 // SetTimeout sets the read timeout for the handle.
927 //
928 // See the package documentation for important details regarding 'timeout'.
929 func (p *InactiveHandle) SetTimeout(timeout time.Duration) error {
930         if status := C.pcap_set_timeout(p.cptr, timeoutMillis(timeout)); status < 0 {
931                 return statusError(status)
932         }
933         p.timeout = timeout
934         return nil
935 }
936
937 // SupportedTimestamps returns a list of supported timstamp types for this
938 // handle.
939 func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) {
940         var types *C.int
941         n := int(C.pcap_list_tstamp_types(p.cptr, &types))
942         defer C.pcap_free_tstamp_types(types)
943         typesArray := (*[100]C.int)(unsafe.Pointer(types))
944         for i := 0; i < n; i++ {
945                 out = append(out, TimestampSource((*typesArray)[i]))
946         }
947         return
948 }
949
950 // SetTimestampSource sets the type of timestamp generator PCAP uses when
951 // attaching timestamps to packets.
952 func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error {
953         if status := C.pcap_set_tstamp_type(p.cptr, C.int(t)); status < 0 {
954                 return statusError(status)
955         }
956         return nil
957 }
958
959 // CannotSetRFMon is returned by SetRFMon if the handle does not allow
960 // setting RFMon because pcap_can_set_rfmon returns 0.
961 var CannotSetRFMon = errors.New("Cannot set rfmon for this handle")
962
963 // SetRFMon turns on radio monitoring mode, similar to promiscuous mode but for
964 // wireless networks.  If this mode is enabled, the interface will not need to
965 // associate with an access point before it can receive traffic.
966 func (p *InactiveHandle) SetRFMon(monitor bool) error {
967         var mon C.int
968         if monitor {
969                 mon = 1
970         }
971         switch canset := C.pcap_can_set_rfmon(p.cptr); canset {
972         case 0:
973                 return CannotSetRFMon
974         case 1:
975                 // success
976         default:
977                 return statusError(canset)
978         }
979         if status := C.pcap_set_rfmon(p.cptr, mon); status != 0 {
980                 return statusError(status)
981         }
982         return nil
983 }
984
985 // SetBufferSize sets the buffer size (in bytes) of the handle.
986 func (p *InactiveHandle) SetBufferSize(bufferSize int) error {
987         if status := C.pcap_set_buffer_size(p.cptr, C.int(bufferSize)); status < 0 {
988                 return statusError(status)
989         }
990         return nil
991 }
992
993 // SetImmediateMode sets (or unsets) the immediate mode of the
994 // handle. In immediate mode, packets are delivered to the application
995 // as soon as they arrive.  In other words, this overrides SetTimeout.
996 func (p *InactiveHandle) SetImmediateMode(mode bool) error {
997         var md C.int
998         if mode {
999                 md = 1
1000         }
1001         if status := C.pcap_set_immediate_mode(p.cptr, md); status < 0 {
1002                 return statusError(status)
1003         }
1004         return nil
1005 }