pcap.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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. package pcap
  8. import (
  9. "errors"
  10. "fmt"
  11. "io"
  12. "net"
  13. "os"
  14. "reflect"
  15. "runtime"
  16. "strconv"
  17. "sync"
  18. "sync/atomic"
  19. "syscall"
  20. "time"
  21. "unsafe"
  22. "github.com/google/gopacket"
  23. "github.com/google/gopacket/layers"
  24. )
  25. // ErrNotActive is returned if handle is not activated
  26. const ErrNotActive = pcapErrorNotActivated
  27. // MaxBpfInstructions is the maximum number of BPF instructions supported (BPF_MAXINSNS),
  28. // taken from Linux kernel: include/uapi/linux/bpf_common.h
  29. //
  30. // https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf_common.h
  31. const MaxBpfInstructions = 4096
  32. // 8 bytes per instruction, max 4096 instructions
  33. const bpfInstructionBufferSize = 8 * MaxBpfInstructions
  34. // Handle provides a connection to a pcap handle, allowing users to read packets
  35. // off the wire (Next), inject packets onto the wire (Inject), and
  36. // perform a number of other functions to affect and understand packet output.
  37. //
  38. // Handles are already pcap_activate'd
  39. type Handle struct {
  40. // stop is set to a non-zero value by Handle.Close to signal to
  41. // getNextBufPtrLocked to stop trying to read packets
  42. // This must be the first entry to ensure alignment for sync.atomic
  43. stop uint64
  44. // cptr is the handle for the actual pcap C object.
  45. cptr pcapTPtr
  46. timeout time.Duration
  47. device string
  48. deviceIndex int
  49. mu sync.Mutex
  50. closeMu sync.Mutex
  51. nanoSecsFactor int64
  52. // Since pointers to these objects are passed into a C function, if
  53. // they're declared locally then the Go compiler thinks they may have
  54. // escaped into C-land, so it allocates them on the heap. This causes a
  55. // huge memory hit, so to handle that we store them here instead.
  56. pkthdr *pcapPkthdr
  57. bufptr *uint8
  58. }
  59. // Stats contains statistics on how many packets were handled by a pcap handle,
  60. // and what was done with those packets.
  61. type Stats struct {
  62. PacketsReceived int
  63. PacketsDropped int
  64. PacketsIfDropped int
  65. }
  66. // Interface describes a single network interface on a machine.
  67. type Interface struct {
  68. Name string
  69. Description string
  70. Flags uint32
  71. Addresses []InterfaceAddress
  72. }
  73. // Datalink describes the datalink
  74. type Datalink struct {
  75. Name string
  76. Description string
  77. }
  78. // InterfaceAddress describes an address associated with an Interface.
  79. // Currently, it's IPv4/6 specific.
  80. type InterfaceAddress struct {
  81. IP net.IP
  82. Netmask net.IPMask // Netmask may be nil if we were unable to retrieve it.
  83. Broadaddr net.IP // Broadcast address for this IP may be nil
  84. P2P net.IP // P2P destination address for this IP may be nil
  85. }
  86. // BPF is a compiled filter program, useful for offline packet matching.
  87. type BPF struct {
  88. orig string
  89. bpf pcapBpfProgram // takes a finalizer, not overriden by outsiders
  90. hdr pcapPkthdr // allocate on the heap to enable optimizations
  91. }
  92. // BPFInstruction is a byte encoded structure holding a BPF instruction
  93. type BPFInstruction struct {
  94. Code uint16
  95. Jt uint8
  96. Jf uint8
  97. K uint32
  98. }
  99. // BlockForever causes it to block forever waiting for packets, when passed
  100. // into SetTimeout or OpenLive, while still returning incoming packets to userland relatively
  101. // quickly.
  102. const BlockForever = -time.Millisecond * 10
  103. func timeoutMillis(timeout time.Duration) int {
  104. // Flip sign if necessary. See package docs on timeout for reasoning behind this.
  105. if timeout < 0 {
  106. timeout *= -1
  107. }
  108. // Round up
  109. if timeout != 0 && timeout < time.Millisecond {
  110. timeout = time.Millisecond
  111. }
  112. return int(timeout / time.Millisecond)
  113. }
  114. // OpenLive opens a device and returns a *Handle.
  115. // It takes as arguments the name of the device ("eth0"), the maximum size to
  116. // read for each packet (snaplen), whether to put the interface in promiscuous
  117. // mode, and a timeout. Warning: this function supports only microsecond timestamps.
  118. // For nanosecond resolution use an InactiveHandle.
  119. //
  120. // See the package documentation for important details regarding 'timeout'.
  121. func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error) {
  122. var pro int
  123. if promisc {
  124. pro = 1
  125. }
  126. p, err := pcapOpenLive(device, int(snaplen), pro, timeoutMillis(timeout))
  127. if err != nil {
  128. return nil, err
  129. }
  130. p.timeout = timeout
  131. p.device = device
  132. ifc, err := net.InterfaceByName(device)
  133. if err != nil {
  134. // The device wasn't found in the OS, but could be "any"
  135. // Set index to 0
  136. p.deviceIndex = 0
  137. } else {
  138. p.deviceIndex = ifc.Index
  139. }
  140. p.nanoSecsFactor = 1000
  141. // Only set the PCAP handle into non-blocking mode if we have a timeout
  142. // greater than zero. If the user wants to block forever, we'll let libpcap
  143. // handle that.
  144. if p.timeout > 0 {
  145. if err := p.setNonBlocking(); err != nil {
  146. p.pcapClose()
  147. return nil, err
  148. }
  149. }
  150. return p, nil
  151. }
  152. // OpenOffline opens a file and returns its contents as a *Handle. Depending on libpcap support and
  153. // on the timestamp resolution used in the file, nanosecond or microsecond resolution is used
  154. // internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used
  155. // to query the actual resolution used.
  156. func OpenOffline(file string) (handle *Handle, err error) {
  157. handle, err = openOffline(file)
  158. if err != nil {
  159. return
  160. }
  161. if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
  162. handle.nanoSecsFactor = 1
  163. } else {
  164. handle.nanoSecsFactor = 1000
  165. }
  166. return
  167. }
  168. // OpenOfflineFile returns contents of input file as a *Handle. Depending on libpcap support and
  169. // on the timestamp resolution used in the file, nanosecond or microsecond resolution is used
  170. // internally. All returned timestamps are scaled to nanosecond resolution. Resolution() can be used
  171. // to query the actual resolution used.
  172. func OpenOfflineFile(file *os.File) (handle *Handle, err error) {
  173. handle, err = openOfflineFile(file)
  174. if err != nil {
  175. return
  176. }
  177. if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
  178. handle.nanoSecsFactor = 1
  179. } else {
  180. handle.nanoSecsFactor = 1000
  181. }
  182. return
  183. }
  184. // NextError is the return code from a call to Next.
  185. type NextError int32
  186. // NextError implements the error interface.
  187. func (n NextError) Error() string {
  188. switch n {
  189. case NextErrorOk:
  190. return "OK"
  191. case NextErrorTimeoutExpired:
  192. return "Timeout Expired"
  193. case NextErrorReadError:
  194. return "Read Error"
  195. case NextErrorNoMorePackets:
  196. return "No More Packets In File"
  197. case NextErrorNotActivated:
  198. return "Not Activated"
  199. }
  200. return strconv.Itoa(int(n))
  201. }
  202. // NextError values.
  203. const (
  204. NextErrorOk NextError = 1
  205. NextErrorTimeoutExpired NextError = 0
  206. NextErrorReadError NextError = -1
  207. // NextErrorNoMorePackets is returned when reading from a file (OpenOffline) and
  208. // EOF is reached. When this happens, Next() returns io.EOF instead of this.
  209. NextErrorNoMorePackets NextError = -2
  210. NextErrorNotActivated NextError = -3
  211. )
  212. // ReadPacketData returns the next packet read from the pcap handle, along with an error
  213. // code associated with that packet. If the packet is read successfully, the
  214. // returned error is nil.
  215. func (p *Handle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
  216. p.mu.Lock()
  217. err = p.getNextBufPtrLocked(&ci)
  218. if err == nil {
  219. data = make([]byte, ci.CaptureLength)
  220. copy(data, (*(*[1 << 30]byte)(unsafe.Pointer(p.bufptr)))[:])
  221. }
  222. p.mu.Unlock()
  223. if err == NextErrorTimeoutExpired {
  224. runtime.Gosched()
  225. }
  226. return
  227. }
  228. type activateError int
  229. const (
  230. aeNoError = activateError(0)
  231. aeActivated = activateError(pcapErrorActivated)
  232. aePromisc = activateError(pcapWarningPromisc)
  233. aeNoSuchDevice = activateError(pcapErrorNoSuchDevice)
  234. aeDenied = activateError(pcapErrorDenied)
  235. aeNotUp = activateError(pcapErrorNotUp)
  236. aeWarning = activateError(pcapWarning)
  237. )
  238. func (a activateError) Error() string {
  239. switch a {
  240. case aeNoError:
  241. return "No Error"
  242. case aeActivated:
  243. return "Already Activated"
  244. case aePromisc:
  245. return "Cannot set as promisc"
  246. case aeNoSuchDevice:
  247. return "No Such Device"
  248. case aeDenied:
  249. return "Permission Denied"
  250. case aeNotUp:
  251. return "Interface Not Up"
  252. case aeWarning:
  253. return fmt.Sprintf("Warning: %v", activateErrMsg.Error())
  254. default:
  255. return fmt.Sprintf("unknown activated error: %d", a)
  256. }
  257. }
  258. // getNextBufPtrLocked is shared code for ReadPacketData and
  259. // ZeroCopyReadPacketData.
  260. func (p *Handle) getNextBufPtrLocked(ci *gopacket.CaptureInfo) error {
  261. if !p.isOpen() {
  262. return io.EOF
  263. }
  264. // set after we have call waitForPacket for the first time
  265. var waited bool
  266. for atomic.LoadUint64(&p.stop) == 0 {
  267. // try to read a packet if one is immediately available
  268. result := p.pcapNextPacketEx()
  269. switch result {
  270. case NextErrorOk:
  271. sec := p.pkthdr.getSec()
  272. // convert micros to nanos
  273. nanos := int64(p.pkthdr.getUsec()) * p.nanoSecsFactor
  274. ci.Timestamp = time.Unix(sec, nanos)
  275. ci.CaptureLength = p.pkthdr.getCaplen()
  276. ci.Length = p.pkthdr.getLen()
  277. ci.InterfaceIndex = p.deviceIndex
  278. return nil
  279. case NextErrorNoMorePackets:
  280. // no more packets, return EOF rather than libpcap-specific error
  281. return io.EOF
  282. case NextErrorTimeoutExpired:
  283. // we've already waited for a packet and we're supposed to time out
  284. //
  285. // we should never actually hit this if we were passed BlockForever
  286. // since we should block on C.pcap_next_ex until there's a packet
  287. // to read.
  288. if waited && p.timeout > 0 {
  289. return result
  290. }
  291. // wait for packet before trying again
  292. p.waitForPacket()
  293. waited = true
  294. default:
  295. return result
  296. }
  297. }
  298. // stop must be set
  299. return io.EOF
  300. }
  301. // ZeroCopyReadPacketData reads the next packet off the wire, and returns its data.
  302. // The slice returned by ZeroCopyReadPacketData points to bytes owned by the
  303. // the Handle. Each call to ZeroCopyReadPacketData invalidates any data previously
  304. // returned by ZeroCopyReadPacketData. Care must be taken not to keep pointers
  305. // to old bytes when using ZeroCopyReadPacketData... if you need to keep data past
  306. // the next time you call ZeroCopyReadPacketData, use ReadPacketData, which copies
  307. // the bytes into a new buffer for you.
  308. // data1, _, _ := handle.ZeroCopyReadPacketData()
  309. // // do everything you want with data1 here, copying bytes out of it if you'd like to keep them around.
  310. // data2, _, _ := handle.ZeroCopyReadPacketData() // invalidates bytes in data1
  311. func (p *Handle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
  312. p.mu.Lock()
  313. err = p.getNextBufPtrLocked(&ci)
  314. if err == nil {
  315. slice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
  316. slice.Data = uintptr(unsafe.Pointer(p.bufptr))
  317. slice.Len = ci.CaptureLength
  318. slice.Cap = ci.CaptureLength
  319. }
  320. p.mu.Unlock()
  321. if err == NextErrorTimeoutExpired {
  322. runtime.Gosched()
  323. }
  324. return
  325. }
  326. // Close closes the underlying pcap handle.
  327. func (p *Handle) Close() {
  328. p.closeMu.Lock()
  329. defer p.closeMu.Unlock()
  330. if !p.isOpen() {
  331. return
  332. }
  333. atomic.StoreUint64(&p.stop, 1)
  334. // wait for packet reader to stop
  335. p.mu.Lock()
  336. defer p.mu.Unlock()
  337. p.pcapClose()
  338. }
  339. // Error returns the current error associated with a pcap handle (pcap_geterr).
  340. func (p *Handle) Error() error {
  341. return p.pcapGeterr()
  342. }
  343. // Stats returns statistics on the underlying pcap handle.
  344. func (p *Handle) Stats() (stat *Stats, err error) {
  345. return p.pcapStats()
  346. }
  347. // ListDataLinks obtains a list of all possible data link types supported for an interface.
  348. func (p *Handle) ListDataLinks() (datalinks []Datalink, err error) {
  349. return p.pcapListDatalinks()
  350. }
  351. // compileBPFFilter always returns an allocated C.struct_bpf_program
  352. // It is the callers responsibility to free the memory again, e.g.
  353. //
  354. // C.pcap_freecode(&bpf)
  355. //
  356. func (p *Handle) compileBPFFilter(expr string) (pcapBpfProgram, error) {
  357. var maskp = uint32(pcapNetmaskUnknown)
  358. // Only do the lookup on network interfaces.
  359. // No device indicates we're handling a pcap file.
  360. if len(p.device) > 0 {
  361. var err error
  362. _, maskp, err = pcapLookupnet(p.device)
  363. if err != nil {
  364. // We can't lookup the network, but that could be because the interface
  365. // doesn't have an IPv4.
  366. maskp = uint32(pcapNetmaskUnknown)
  367. }
  368. }
  369. return p.pcapCompile(expr, maskp)
  370. }
  371. // CompileBPFFilter compiles and returns a BPF filter with given a link type and capture length.
  372. func CompileBPFFilter(linkType layers.LinkType, captureLength int, expr string) ([]BPFInstruction, error) {
  373. h, err := pcapOpenDead(linkType, captureLength)
  374. if err != nil {
  375. return nil, err
  376. }
  377. defer h.Close()
  378. return h.CompileBPFFilter(expr)
  379. }
  380. // CompileBPFFilter compiles and returns a BPF filter for the pcap handle.
  381. func (p *Handle) CompileBPFFilter(expr string) ([]BPFInstruction, error) {
  382. bpf, err := p.compileBPFFilter(expr)
  383. defer bpf.free()
  384. if err != nil {
  385. return nil, err
  386. }
  387. return bpf.toBPFInstruction(), nil
  388. }
  389. // SetBPFFilter compiles and sets a BPF filter for the pcap handle.
  390. func (p *Handle) SetBPFFilter(expr string) (err error) {
  391. bpf, err := p.compileBPFFilter(expr)
  392. defer bpf.free()
  393. if err != nil {
  394. return err
  395. }
  396. return p.pcapSetfilter(bpf)
  397. }
  398. // SetBPFInstructionFilter may be used to apply a filter in BPF asm byte code format.
  399. //
  400. // Simplest way to generate BPF asm byte code is with tcpdump:
  401. // tcpdump -dd 'udp'
  402. //
  403. // The output may be used directly to add a filter, e.g.:
  404. // bpfInstructions := []pcap.BpfInstruction{
  405. // {0x28, 0, 0, 0x0000000c},
  406. // {0x15, 0, 9, 0x00000800},
  407. // {0x30, 0, 0, 0x00000017},
  408. // {0x15, 0, 7, 0x00000006},
  409. // {0x28, 0, 0, 0x00000014},
  410. // {0x45, 5, 0, 0x00001fff},
  411. // {0xb1, 0, 0, 0x0000000e},
  412. // {0x50, 0, 0, 0x0000001b},
  413. // {0x54, 0, 0, 0x00000012},
  414. // {0x15, 0, 1, 0x00000012},
  415. // {0x6, 0, 0, 0x0000ffff},
  416. // {0x6, 0, 0, 0x00000000},
  417. // }
  418. //
  419. // An other posibility is to write the bpf code in bpf asm.
  420. // Documentation: https://www.kernel.org/doc/Documentation/networking/filter.txt
  421. //
  422. // To compile the code use bpf_asm from
  423. // https://github.com/torvalds/linux/tree/master/tools/net
  424. //
  425. // The following command may be used to convert bpf_asm output to c/go struct, usable for SetBPFFilterByte:
  426. // bpf_asm -c tcp.bpf
  427. func (p *Handle) SetBPFInstructionFilter(bpfInstructions []BPFInstruction) (err error) {
  428. bpf, err := bpfInstructionFilter(bpfInstructions)
  429. if err != nil {
  430. return err
  431. }
  432. defer bpf.free()
  433. return p.pcapSetfilter(bpf)
  434. }
  435. func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf pcapBpfProgram, err error) {
  436. if len(bpfInstructions) < 1 {
  437. return bpf, errors.New("bpfInstructions must not be empty")
  438. }
  439. if len(bpfInstructions) > MaxBpfInstructions {
  440. return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions)
  441. }
  442. return pcapBpfProgramFromInstructions(bpfInstructions), nil
  443. }
  444. // NewBPF compiles the given string into a new filter program.
  445. //
  446. // BPF filters need to be created from activated handles, because they need to
  447. // know the underlying link type to correctly compile their offsets.
  448. func (p *Handle) NewBPF(expr string) (*BPF, error) {
  449. bpf := &BPF{orig: expr}
  450. var err error
  451. bpf.bpf, err = p.pcapCompile(expr, pcapNetmaskUnknown)
  452. if err != nil {
  453. return nil, err
  454. }
  455. runtime.SetFinalizer(bpf, destroyBPF)
  456. return bpf, nil
  457. }
  458. // NewBPF allows to create a BPF without requiring an existing handle.
  459. // This allows to match packets obtained from a-non GoPacket capture source
  460. // to be matched.
  461. //
  462. // buf := make([]byte, MaxFrameSize)
  463. // bpfi, _ := pcap.NewBPF(layers.LinkTypeEthernet, MaxFrameSize, "icmp")
  464. // n, _ := someIO.Read(buf)
  465. // ci := gopacket.CaptureInfo{CaptureLength: n, Length: n}
  466. // if bpfi.Matches(ci, buf) {
  467. // doSomething()
  468. // }
  469. func NewBPF(linkType layers.LinkType, captureLength int, expr string) (*BPF, error) {
  470. h, err := pcapOpenDead(linkType, captureLength)
  471. if err != nil {
  472. return nil, err
  473. }
  474. defer h.Close()
  475. return h.NewBPF(expr)
  476. }
  477. // NewBPFInstructionFilter sets the given BPFInstructions as new filter program.
  478. //
  479. // More details see func SetBPFInstructionFilter
  480. //
  481. // BPF filters need to be created from activated handles, because they need to
  482. // know the underlying link type to correctly compile their offsets.
  483. func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) {
  484. var err error
  485. bpf := &BPF{orig: "BPF Instruction Filter"}
  486. bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
  487. if err != nil {
  488. return nil, err
  489. }
  490. runtime.SetFinalizer(bpf, destroyBPF)
  491. return bpf, nil
  492. }
  493. func destroyBPF(bpf *BPF) {
  494. bpf.bpf.free()
  495. }
  496. // String returns the original string this BPF filter was compiled from.
  497. func (b *BPF) String() string {
  498. return b.orig
  499. }
  500. // Matches returns true if the given packet data matches this filter.
  501. func (b *BPF) Matches(ci gopacket.CaptureInfo, data []byte) bool {
  502. return b.pcapOfflineFilter(ci, data)
  503. }
  504. // Version returns pcap_lib_version.
  505. func Version() string {
  506. return pcapLibVersion()
  507. }
  508. // LinkType returns pcap_datalink, as a layers.LinkType.
  509. func (p *Handle) LinkType() layers.LinkType {
  510. return p.pcapDatalink()
  511. }
  512. // SetLinkType calls pcap_set_datalink on the pcap handle.
  513. func (p *Handle) SetLinkType(dlt layers.LinkType) error {
  514. return p.pcapSetDatalink(dlt)
  515. }
  516. // DatalinkValToName returns pcap_datalink_val_to_name as string
  517. func DatalinkValToName(dlt int) string {
  518. return pcapDatalinkValToName(dlt)
  519. }
  520. // DatalinkValToDescription returns pcap_datalink_val_to_description as string
  521. func DatalinkValToDescription(dlt int) string {
  522. return pcapDatalinkValToDescription(dlt)
  523. }
  524. // DatalinkNameToVal returns pcap_datalink_name_to_val as int
  525. func DatalinkNameToVal(name string) int {
  526. return pcapDatalinkNameToVal(name)
  527. }
  528. // FindAllDevs attempts to enumerate all interfaces on the current machine.
  529. func FindAllDevs() (ifs []Interface, err error) {
  530. alldevsp, err := pcapFindAllDevs()
  531. if err != nil {
  532. return nil, err
  533. }
  534. defer alldevsp.free()
  535. for alldevsp.next() {
  536. var iface Interface
  537. iface.Name = alldevsp.name()
  538. iface.Description = alldevsp.description()
  539. iface.Addresses = findalladdresses(alldevsp.addresses())
  540. iface.Flags = alldevsp.flags()
  541. ifs = append(ifs, iface)
  542. }
  543. return
  544. }
  545. func findalladdresses(addresses pcapAddresses) (retval []InterfaceAddress) {
  546. // TODO - make it support more than IPv4 and IPv6?
  547. retval = make([]InterfaceAddress, 0, 1)
  548. for addresses.next() {
  549. // Strangely, it appears that in some cases, we get a pcap address back from
  550. // pcap_findalldevs with a nil .addr. It appears that we can skip over
  551. // these.
  552. if addresses.addr() == nil {
  553. continue
  554. }
  555. var a InterfaceAddress
  556. var err error
  557. if a.IP, err = sockaddrToIP(addresses.addr()); err != nil {
  558. continue
  559. }
  560. // To be safe, we'll also check for netmask.
  561. if addresses.netmask() == nil {
  562. continue
  563. }
  564. if a.Netmask, err = sockaddrToIP(addresses.netmask()); err != nil {
  565. // If we got an IP address but we can't get a netmask, just return the IP
  566. // address.
  567. a.Netmask = nil
  568. }
  569. if a.Broadaddr, err = sockaddrToIP(addresses.broadaddr()); err != nil {
  570. a.Broadaddr = nil
  571. }
  572. if a.P2P, err = sockaddrToIP(addresses.dstaddr()); err != nil {
  573. a.P2P = nil
  574. }
  575. retval = append(retval, a)
  576. }
  577. return
  578. }
  579. func sockaddrToIP(rsa *syscall.RawSockaddr) (IP []byte, err error) {
  580. if rsa == nil {
  581. err = errors.New("Value not set")
  582. return
  583. }
  584. switch rsa.Family {
  585. case syscall.AF_INET:
  586. pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
  587. IP = make([]byte, 4)
  588. for i := 0; i < len(IP); i++ {
  589. IP[i] = pp.Addr[i]
  590. }
  591. return
  592. case syscall.AF_INET6:
  593. pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
  594. IP = make([]byte, 16)
  595. for i := 0; i < len(IP); i++ {
  596. IP[i] = pp.Addr[i]
  597. }
  598. return
  599. }
  600. err = errors.New("Unsupported address type")
  601. return
  602. }
  603. // WritePacketData calls pcap_sendpacket, injecting the given data into the pcap handle.
  604. func (p *Handle) WritePacketData(data []byte) (err error) {
  605. return p.pcapSendpacket(data)
  606. }
  607. // Direction is used by Handle.SetDirection.
  608. type Direction uint8
  609. // Direction values for Handle.SetDirection.
  610. const (
  611. DirectionIn = Direction(pcapDIN)
  612. DirectionOut = Direction(pcapDOUT)
  613. DirectionInOut = Direction(pcapDINOUT)
  614. )
  615. // SetDirection sets the direction for which packets will be captured.
  616. func (p *Handle) SetDirection(direction Direction) error {
  617. if direction != DirectionIn && direction != DirectionOut && direction != DirectionInOut {
  618. return fmt.Errorf("Invalid direction: %v", direction)
  619. }
  620. return p.pcapSetdirection(direction)
  621. }
  622. // SnapLen returns the snapshot length
  623. func (p *Handle) SnapLen() int {
  624. return p.pcapSnapshot()
  625. }
  626. // Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.
  627. func (p *Handle) Resolution() gopacket.TimestampResolution {
  628. if p.nanoSecsFactor == 1 {
  629. return gopacket.TimestampResolutionMicrosecond
  630. }
  631. return gopacket.TimestampResolutionNanosecond
  632. }
  633. // TimestampSource tells PCAP which type of timestamp to use for packets.
  634. type TimestampSource int
  635. // String returns the timestamp type as a human-readable string.
  636. func (t TimestampSource) String() string {
  637. return t.pcapTstampTypeValToName()
  638. }
  639. // TimestampSourceFromString translates a string into a timestamp type, case
  640. // insensitive.
  641. func TimestampSourceFromString(s string) (TimestampSource, error) {
  642. return pcapTstampTypeNameToVal(s)
  643. }
  644. // InactiveHandle allows you to call pre-pcap_activate functions on your pcap
  645. // handle to set it up just the way you'd like.
  646. type InactiveHandle struct {
  647. // cptr is the handle for the actual pcap C object.
  648. cptr pcapTPtr
  649. device string
  650. deviceIndex int
  651. timeout time.Duration
  652. }
  653. // holds the err messoge in case activation returned a Warning
  654. var activateErrMsg error
  655. // Error returns the current error associated with a pcap handle (pcap_geterr).
  656. func (p *InactiveHandle) Error() error {
  657. return p.pcapGeterr()
  658. }
  659. // Activate activates the handle. The current InactiveHandle becomes invalid
  660. // and all future function calls on it will fail.
  661. func (p *InactiveHandle) Activate() (*Handle, error) {
  662. // ignore error with set_tstamp_precision, since the actual precision is queried later anyway
  663. pcapSetTstampPrecision(p.cptr, pcapTstampPrecisionNano)
  664. handle, err := p.pcapActivate()
  665. if err != aeNoError {
  666. if err == aeWarning {
  667. activateErrMsg = p.Error()
  668. }
  669. return nil, err
  670. }
  671. handle.timeout = p.timeout
  672. if p.timeout > 0 {
  673. if err := handle.setNonBlocking(); err != nil {
  674. handle.pcapClose()
  675. return nil, err
  676. }
  677. }
  678. handle.device = p.device
  679. handle.deviceIndex = p.deviceIndex
  680. if pcapGetTstampPrecision(handle.cptr) == pcapTstampPrecisionNano {
  681. handle.nanoSecsFactor = 1
  682. } else {
  683. handle.nanoSecsFactor = 1000
  684. }
  685. return handle, nil
  686. }
  687. // CleanUp cleans up any stuff left over from a successful or failed building
  688. // of a handle.
  689. func (p *InactiveHandle) CleanUp() {
  690. p.pcapClose()
  691. }
  692. // NewInactiveHandle creates a new InactiveHandle, which wraps an un-activated PCAP handle.
  693. // Callers of NewInactiveHandle should immediately defer 'CleanUp', as in:
  694. // inactive := NewInactiveHandle("eth0")
  695. // defer inactive.CleanUp()
  696. func NewInactiveHandle(device string) (*InactiveHandle, error) {
  697. // Try to get the interface index, but iy could be something like "any"
  698. // in which case use 0, which doesn't exist in nature
  699. deviceIndex := 0
  700. ifc, err := net.InterfaceByName(device)
  701. if err == nil {
  702. deviceIndex = ifc.Index
  703. }
  704. // This copies a bunch of the pcap_open_live implementation from pcap.c:
  705. handle, err := pcapCreate(device)
  706. if err != nil {
  707. return nil, err
  708. }
  709. handle.device = device
  710. handle.deviceIndex = deviceIndex
  711. return handle, nil
  712. }
  713. // SetSnapLen sets the snap length (max bytes per packet to capture).
  714. func (p *InactiveHandle) SetSnapLen(snaplen int) error {
  715. return p.pcapSetSnaplen(snaplen)
  716. }
  717. // SetPromisc sets the handle to either be promiscuous (capture packets
  718. // unrelated to this host) or not.
  719. func (p *InactiveHandle) SetPromisc(promisc bool) error {
  720. return p.pcapSetPromisc(promisc)
  721. }
  722. // SetTimeout sets the read timeout for the handle.
  723. //
  724. // See the package documentation for important details regarding 'timeout'.
  725. func (p *InactiveHandle) SetTimeout(timeout time.Duration) error {
  726. err := p.pcapSetTimeout(timeout)
  727. if err != nil {
  728. return err
  729. }
  730. p.timeout = timeout
  731. return nil
  732. }
  733. // SupportedTimestamps returns a list of supported timstamp types for this
  734. // handle.
  735. func (p *InactiveHandle) SupportedTimestamps() (out []TimestampSource) {
  736. return p.pcapListTstampTypes()
  737. }
  738. // SetTimestampSource sets the type of timestamp generator PCAP uses when
  739. // attaching timestamps to packets.
  740. func (p *InactiveHandle) SetTimestampSource(t TimestampSource) error {
  741. return p.pcapSetTstampType(t)
  742. }
  743. // CannotSetRFMon is returned by SetRFMon if the handle does not allow
  744. // setting RFMon because pcap_can_set_rfmon returns 0.
  745. var CannotSetRFMon = errors.New("Cannot set rfmon for this handle")
  746. // SetRFMon turns on radio monitoring mode, similar to promiscuous mode but for
  747. // wireless networks. If this mode is enabled, the interface will not need to
  748. // associate with an access point before it can receive traffic.
  749. func (p *InactiveHandle) SetRFMon(monitor bool) error {
  750. return p.pcapSetRfmon(monitor)
  751. }
  752. // SetBufferSize sets the buffer size (in bytes) of the handle.
  753. func (p *InactiveHandle) SetBufferSize(bufferSize int) error {
  754. return p.pcapSetBufferSize(bufferSize)
  755. }
  756. // SetImmediateMode sets (or unsets) the immediate mode of the
  757. // handle. In immediate mode, packets are delivered to the application
  758. // as soon as they arrive. In other words, this overrides SetTimeout.
  759. func (p *InactiveHandle) SetImmediateMode(mode bool) error {
  760. return p.pcapSetImmediateMode(mode)
  761. }