blob: 3a7c4b3d80b53bbd9885e8eecdf932ff5afb66bb [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001// Copyright 2012 Google, Inc. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree.
6
7package gopacket
8
9import (
10 "bytes"
11 "encoding/hex"
12 "errors"
13 "fmt"
14 "io"
15 "net"
16 "os"
17 "reflect"
18 "runtime/debug"
19 "strings"
20 "syscall"
21 "time"
22)
23
24// CaptureInfo provides standardized information about a packet captured off
25// the wire or read from a file.
26type CaptureInfo struct {
27 // Timestamp is the time the packet was captured, if that is known.
28 Timestamp time.Time
29 // CaptureLength is the total number of bytes read off of the wire.
30 CaptureLength int
31 // Length is the size of the original packet. Should always be >=
32 // CaptureLength.
33 Length int
34 // InterfaceIndex
35 InterfaceIndex int
36 // The packet source can place ancillary data of various types here.
37 // For example, the afpacket source can report the VLAN of captured
38 // packets this way.
39 AncillaryData []interface{}
40}
41
42// PacketMetadata contains metadata for a packet.
43type PacketMetadata struct {
44 CaptureInfo
45 // Truncated is true if packet decoding logic detects that there are fewer
46 // bytes in the packet than are detailed in various headers (for example, if
47 // the number of bytes in the IPv4 contents/payload is less than IPv4.Length).
48 // This is also set automatically for packets captured off the wire if
49 // CaptureInfo.CaptureLength < CaptureInfo.Length.
50 Truncated bool
51}
52
53// Packet is the primary object used by gopacket. Packets are created by a
54// Decoder's Decode call. A packet is made up of a set of Data, which
55// is broken into a number of Layers as it is decoded.
56type Packet interface {
57 //// Functions for outputting the packet as a human-readable string:
58 //// ------------------------------------------------------------------
59 // String returns a human-readable string representation of the packet.
60 // It uses LayerString on each layer to output the layer.
61 String() string
62 // Dump returns a verbose human-readable string representation of the packet,
63 // including a hex dump of all layers. It uses LayerDump on each layer to
64 // output the layer.
65 Dump() string
66
67 //// Functions for accessing arbitrary packet layers:
68 //// ------------------------------------------------------------------
69 // Layers returns all layers in this packet, computing them as necessary
70 Layers() []Layer
71 // Layer returns the first layer in this packet of the given type, or nil
72 Layer(LayerType) Layer
73 // LayerClass returns the first layer in this packet of the given class,
74 // or nil.
75 LayerClass(LayerClass) Layer
76
77 //// Functions for accessing specific types of packet layers. These functions
78 //// return the first layer of each type found within the packet.
79 //// ------------------------------------------------------------------
80 // LinkLayer returns the first link layer in the packet
81 LinkLayer() LinkLayer
82 // NetworkLayer returns the first network layer in the packet
83 NetworkLayer() NetworkLayer
84 // TransportLayer returns the first transport layer in the packet
85 TransportLayer() TransportLayer
86 // ApplicationLayer returns the first application layer in the packet
87 ApplicationLayer() ApplicationLayer
88 // ErrorLayer is particularly useful, since it returns nil if the packet
89 // was fully decoded successfully, and non-nil if an error was encountered
90 // in decoding and the packet was only partially decoded. Thus, its output
91 // can be used to determine if the entire packet was able to be decoded.
92 ErrorLayer() ErrorLayer
93
94 //// Functions for accessing data specific to the packet:
95 //// ------------------------------------------------------------------
96 // Data returns the set of bytes that make up this entire packet.
97 Data() []byte
98 // Metadata returns packet metadata associated with this packet.
99 Metadata() *PacketMetadata
100}
101
102// packet contains all the information we need to fulfill the Packet interface,
103// and its two "subclasses" (yes, no such thing in Go, bear with me),
104// eagerPacket and lazyPacket, provide eager and lazy decoding logic around the
105// various functions needed to access this information.
106type packet struct {
107 // data contains the entire packet data for a packet
108 data []byte
109 // initialLayers is space for an initial set of layers already created inside
110 // the packet.
111 initialLayers [6]Layer
112 // layers contains each layer we've already decoded
113 layers []Layer
114 // last is the last layer added to the packet
115 last Layer
116 // metadata is the PacketMetadata for this packet
117 metadata PacketMetadata
118
119 decodeOptions DecodeOptions
120
121 // Pointers to the various important layers
122 link LinkLayer
123 network NetworkLayer
124 transport TransportLayer
125 application ApplicationLayer
126 failure ErrorLayer
127}
128
129func (p *packet) SetTruncated() {
130 p.metadata.Truncated = true
131}
132
133func (p *packet) SetLinkLayer(l LinkLayer) {
134 if p.link == nil {
135 p.link = l
136 }
137}
138
139func (p *packet) SetNetworkLayer(l NetworkLayer) {
140 if p.network == nil {
141 p.network = l
142 }
143}
144
145func (p *packet) SetTransportLayer(l TransportLayer) {
146 if p.transport == nil {
147 p.transport = l
148 }
149}
150
151func (p *packet) SetApplicationLayer(l ApplicationLayer) {
152 if p.application == nil {
153 p.application = l
154 }
155}
156
157func (p *packet) SetErrorLayer(l ErrorLayer) {
158 if p.failure == nil {
159 p.failure = l
160 }
161}
162
163func (p *packet) AddLayer(l Layer) {
164 p.layers = append(p.layers, l)
165 p.last = l
166}
167
168func (p *packet) DumpPacketData() {
169 fmt.Fprint(os.Stderr, p.packetDump())
170 os.Stderr.Sync()
171}
172
173func (p *packet) Metadata() *PacketMetadata {
174 return &p.metadata
175}
176
177func (p *packet) Data() []byte {
178 return p.data
179}
180
181func (p *packet) DecodeOptions() *DecodeOptions {
182 return &p.decodeOptions
183}
184
185func (p *packet) addFinalDecodeError(err error, stack []byte) {
186 fail := &DecodeFailure{err: err, stack: stack}
187 if p.last == nil {
188 fail.data = p.data
189 } else {
190 fail.data = p.last.LayerPayload()
191 }
192 p.AddLayer(fail)
193 p.SetErrorLayer(fail)
194}
195
196func (p *packet) recoverDecodeError() {
197 if !p.decodeOptions.SkipDecodeRecovery {
198 if r := recover(); r != nil {
199 p.addFinalDecodeError(fmt.Errorf("%v", r), debug.Stack())
200 }
201 }
202}
203
204// LayerString outputs an individual layer as a string. The layer is output
205// in a single line, with no trailing newline. This function is specifically
206// designed to do the right thing for most layers... it follows the following
207// rules:
208// * If the Layer has a String function, just output that.
209// * Otherwise, output all exported fields in the layer, recursing into
210// exported slices and structs.
211// NOTE: This is NOT THE SAME AS fmt's "%#v". %#v will output both exported
212// and unexported fields... many times packet layers contain unexported stuff
213// that would just mess up the output of the layer, see for example the
214// Payload layer and it's internal 'data' field, which contains a large byte
215// array that would really mess up formatting.
216func LayerString(l Layer) string {
217 return fmt.Sprintf("%v\t%s", l.LayerType(), layerString(reflect.ValueOf(l), false, false))
218}
219
220// Dumper dumps verbose information on a value. If a layer type implements
221// Dumper, then its LayerDump() string will include the results in its output.
222type Dumper interface {
223 Dump() string
224}
225
226// LayerDump outputs a very verbose string representation of a layer. Its
227// output is a concatenation of LayerString(l) and hex.Dump(l.LayerContents()).
228// It contains newlines and ends with a newline.
229func LayerDump(l Layer) string {
230 var b bytes.Buffer
231 b.WriteString(LayerString(l))
232 b.WriteByte('\n')
233 if d, ok := l.(Dumper); ok {
234 dump := d.Dump()
235 if dump != "" {
236 b.WriteString(dump)
237 if dump[len(dump)-1] != '\n' {
238 b.WriteByte('\n')
239 }
240 }
241 }
242 b.WriteString(hex.Dump(l.LayerContents()))
243 return b.String()
244}
245
246// layerString outputs, recursively, a layer in a "smart" way. See docs for
247// LayerString for more details.
248//
249// Params:
250// i - value to write out
251// anonymous: if we're currently recursing an anonymous member of a struct
252// writeSpace: if we've already written a value in a struct, and need to
253// write a space before writing more. This happens when we write various
254// anonymous values, and need to keep writing more.
255func layerString(v reflect.Value, anonymous bool, writeSpace bool) string {
256 // Let String() functions take precedence.
257 if v.CanInterface() {
258 if s, ok := v.Interface().(fmt.Stringer); ok {
259 return s.String()
260 }
261 }
262 // Reflect, and spit out all the exported fields as key=value.
263 switch v.Type().Kind() {
264 case reflect.Interface, reflect.Ptr:
265 if v.IsNil() {
266 return "nil"
267 }
268 r := v.Elem()
269 return layerString(r, anonymous, writeSpace)
270 case reflect.Struct:
271 var b bytes.Buffer
272 typ := v.Type()
273 if !anonymous {
274 b.WriteByte('{')
275 }
276 for i := 0; i < v.NumField(); i++ {
277 // Check if this is upper-case.
278 ftype := typ.Field(i)
279 f := v.Field(i)
280 if ftype.Anonymous {
281 anonStr := layerString(f, true, writeSpace)
282 writeSpace = writeSpace || anonStr != ""
283 b.WriteString(anonStr)
284 } else if ftype.PkgPath == "" { // exported
285 if writeSpace {
286 b.WriteByte(' ')
287 }
288 writeSpace = true
289 fmt.Fprintf(&b, "%s=%s", typ.Field(i).Name, layerString(f, false, writeSpace))
290 }
291 }
292 if !anonymous {
293 b.WriteByte('}')
294 }
295 return b.String()
296 case reflect.Slice:
297 var b bytes.Buffer
298 b.WriteByte('[')
299 if v.Len() > 4 {
300 fmt.Fprintf(&b, "..%d..", v.Len())
301 } else {
302 for j := 0; j < v.Len(); j++ {
303 if j != 0 {
304 b.WriteString(", ")
305 }
306 b.WriteString(layerString(v.Index(j), false, false))
307 }
308 }
309 b.WriteByte(']')
310 return b.String()
311 }
312 return fmt.Sprintf("%v", v.Interface())
313}
314
315const (
316 longBytesLength = 128
317)
318
319// LongBytesGoString returns a string representation of the byte slice shortened
320// using the format '<type>{<truncated slice> ... (<n> bytes)}' if it
321// exceeds a predetermined length. Can be used to avoid filling the display with
322// very long byte strings.
323func LongBytesGoString(buf []byte) string {
324 if len(buf) < longBytesLength {
325 return fmt.Sprintf("%#v", buf)
326 }
327 s := fmt.Sprintf("%#v", buf[:longBytesLength-1])
328 s = strings.TrimSuffix(s, "}")
329 return fmt.Sprintf("%s ... (%d bytes)}", s, len(buf))
330}
331
332func baseLayerString(value reflect.Value) string {
333 t := value.Type()
334 content := value.Field(0)
335 c := make([]byte, content.Len())
336 for i := range c {
337 c[i] = byte(content.Index(i).Uint())
338 }
339 payload := value.Field(1)
340 p := make([]byte, payload.Len())
341 for i := range p {
342 p[i] = byte(payload.Index(i).Uint())
343 }
344 return fmt.Sprintf("%s{Contents:%s, Payload:%s}", t.String(),
345 LongBytesGoString(c),
346 LongBytesGoString(p))
347}
348
349func layerGoString(i interface{}, b *bytes.Buffer) {
350 if s, ok := i.(fmt.GoStringer); ok {
351 b.WriteString(s.GoString())
352 return
353 }
354
355 var v reflect.Value
356 var ok bool
357 if v, ok = i.(reflect.Value); !ok {
358 v = reflect.ValueOf(i)
359 }
360 switch v.Kind() {
361 case reflect.Ptr, reflect.Interface:
362 if v.Kind() == reflect.Ptr {
363 b.WriteByte('&')
364 }
365 layerGoString(v.Elem().Interface(), b)
366 case reflect.Struct:
367 t := v.Type()
368 b.WriteString(t.String())
369 b.WriteByte('{')
370 for i := 0; i < v.NumField(); i++ {
371 if i > 0 {
372 b.WriteString(", ")
373 }
374 if t.Field(i).Name == "BaseLayer" {
375 fmt.Fprintf(b, "BaseLayer:%s", baseLayerString(v.Field(i)))
376 } else if v.Field(i).Kind() == reflect.Struct {
377 fmt.Fprintf(b, "%s:", t.Field(i).Name)
378 layerGoString(v.Field(i), b)
379 } else if v.Field(i).Kind() == reflect.Ptr {
380 b.WriteByte('&')
381 layerGoString(v.Field(i), b)
382 } else {
383 fmt.Fprintf(b, "%s:%#v", t.Field(i).Name, v.Field(i))
384 }
385 }
386 b.WriteByte('}')
387 default:
388 fmt.Fprintf(b, "%#v", i)
389 }
390}
391
392// LayerGoString returns a representation of the layer in Go syntax,
393// taking care to shorten "very long" BaseLayer byte slices
394func LayerGoString(l Layer) string {
395 b := new(bytes.Buffer)
396 layerGoString(l, b)
397 return b.String()
398}
399
400func (p *packet) packetString() string {
401 var b bytes.Buffer
402 fmt.Fprintf(&b, "PACKET: %d bytes", len(p.Data()))
403 if p.metadata.Truncated {
404 b.WriteString(", truncated")
405 }
406 if p.metadata.Length > 0 {
407 fmt.Fprintf(&b, ", wire length %d cap length %d", p.metadata.Length, p.metadata.CaptureLength)
408 }
409 if !p.metadata.Timestamp.IsZero() {
410 fmt.Fprintf(&b, " @ %v", p.metadata.Timestamp)
411 }
412 b.WriteByte('\n')
413 for i, l := range p.layers {
414 fmt.Fprintf(&b, "- Layer %d (%02d bytes) = %s\n", i+1, len(l.LayerContents()), LayerString(l))
415 }
416 return b.String()
417}
418
419func (p *packet) packetDump() string {
420 var b bytes.Buffer
421 fmt.Fprintf(&b, "-- FULL PACKET DATA (%d bytes) ------------------------------------\n%s", len(p.data), hex.Dump(p.data))
422 for i, l := range p.layers {
423 fmt.Fprintf(&b, "--- Layer %d ---\n%s", i+1, LayerDump(l))
424 }
425 return b.String()
426}
427
428// eagerPacket is a packet implementation that does eager decoding. Upon
429// initial construction, it decodes all the layers it can from packet data.
430// eagerPacket implements Packet and PacketBuilder.
431type eagerPacket struct {
432 packet
433}
434
435var errNilDecoder = errors.New("NextDecoder passed nil decoder, probably an unsupported decode type")
436
437func (p *eagerPacket) NextDecoder(next Decoder) error {
438 if next == nil {
439 return errNilDecoder
440 }
441 if p.last == nil {
442 return errors.New("NextDecoder called, but no layers added yet")
443 }
444 d := p.last.LayerPayload()
445 if len(d) == 0 {
446 return nil
447 }
448 // Since we're eager, immediately call the next decoder.
449 return next.Decode(d, p)
450}
451func (p *eagerPacket) initialDecode(dec Decoder) {
452 defer p.recoverDecodeError()
453 err := dec.Decode(p.data, p)
454 if err != nil {
455 p.addFinalDecodeError(err, nil)
456 }
457}
458func (p *eagerPacket) LinkLayer() LinkLayer {
459 return p.link
460}
461func (p *eagerPacket) NetworkLayer() NetworkLayer {
462 return p.network
463}
464func (p *eagerPacket) TransportLayer() TransportLayer {
465 return p.transport
466}
467func (p *eagerPacket) ApplicationLayer() ApplicationLayer {
468 return p.application
469}
470func (p *eagerPacket) ErrorLayer() ErrorLayer {
471 return p.failure
472}
473func (p *eagerPacket) Layers() []Layer {
474 return p.layers
475}
476func (p *eagerPacket) Layer(t LayerType) Layer {
477 for _, l := range p.layers {
478 if l.LayerType() == t {
479 return l
480 }
481 }
482 return nil
483}
484func (p *eagerPacket) LayerClass(lc LayerClass) Layer {
485 for _, l := range p.layers {
486 if lc.Contains(l.LayerType()) {
487 return l
488 }
489 }
490 return nil
491}
492func (p *eagerPacket) String() string { return p.packetString() }
493func (p *eagerPacket) Dump() string { return p.packetDump() }
494
495// lazyPacket does lazy decoding on its packet data. On construction it does
496// no initial decoding. For each function call, it decodes only as many layers
497// as are necessary to compute the return value for that function.
498// lazyPacket implements Packet and PacketBuilder.
499type lazyPacket struct {
500 packet
501 next Decoder
502}
503
504func (p *lazyPacket) NextDecoder(next Decoder) error {
505 if next == nil {
506 return errNilDecoder
507 }
508 p.next = next
509 return nil
510}
511func (p *lazyPacket) decodeNextLayer() {
512 if p.next == nil {
513 return
514 }
515 d := p.data
516 if p.last != nil {
517 d = p.last.LayerPayload()
518 }
519 next := p.next
520 p.next = nil
521 // We've just set p.next to nil, so if we see we have no data, this should be
522 // the final call we get to decodeNextLayer if we return here.
523 if len(d) == 0 {
524 return
525 }
526 defer p.recoverDecodeError()
527 err := next.Decode(d, p)
528 if err != nil {
529 p.addFinalDecodeError(err, nil)
530 }
531}
532func (p *lazyPacket) LinkLayer() LinkLayer {
533 for p.link == nil && p.next != nil {
534 p.decodeNextLayer()
535 }
536 return p.link
537}
538func (p *lazyPacket) NetworkLayer() NetworkLayer {
539 for p.network == nil && p.next != nil {
540 p.decodeNextLayer()
541 }
542 return p.network
543}
544func (p *lazyPacket) TransportLayer() TransportLayer {
545 for p.transport == nil && p.next != nil {
546 p.decodeNextLayer()
547 }
548 return p.transport
549}
550func (p *lazyPacket) ApplicationLayer() ApplicationLayer {
551 for p.application == nil && p.next != nil {
552 p.decodeNextLayer()
553 }
554 return p.application
555}
556func (p *lazyPacket) ErrorLayer() ErrorLayer {
557 for p.failure == nil && p.next != nil {
558 p.decodeNextLayer()
559 }
560 return p.failure
561}
562func (p *lazyPacket) Layers() []Layer {
563 for p.next != nil {
564 p.decodeNextLayer()
565 }
566 return p.layers
567}
568func (p *lazyPacket) Layer(t LayerType) Layer {
569 for _, l := range p.layers {
570 if l.LayerType() == t {
571 return l
572 }
573 }
574 numLayers := len(p.layers)
575 for p.next != nil {
576 p.decodeNextLayer()
577 for _, l := range p.layers[numLayers:] {
578 if l.LayerType() == t {
579 return l
580 }
581 }
582 numLayers = len(p.layers)
583 }
584 return nil
585}
586func (p *lazyPacket) LayerClass(lc LayerClass) Layer {
587 for _, l := range p.layers {
588 if lc.Contains(l.LayerType()) {
589 return l
590 }
591 }
592 numLayers := len(p.layers)
593 for p.next != nil {
594 p.decodeNextLayer()
595 for _, l := range p.layers[numLayers:] {
596 if lc.Contains(l.LayerType()) {
597 return l
598 }
599 }
600 numLayers = len(p.layers)
601 }
602 return nil
603}
604func (p *lazyPacket) String() string { p.Layers(); return p.packetString() }
605func (p *lazyPacket) Dump() string { p.Layers(); return p.packetDump() }
606
607// DecodeOptions tells gopacket how to decode a packet.
608type DecodeOptions struct {
609 // Lazy decoding decodes the minimum number of layers needed to return data
610 // for a packet at each function call. Be careful using this with concurrent
611 // packet processors, as each call to packet.* could mutate the packet, and
612 // two concurrent function calls could interact poorly.
613 Lazy bool
614 // NoCopy decoding doesn't copy its input buffer into storage that's owned by
615 // the packet. If you can guarantee that the bytes underlying the slice
616 // passed into NewPacket aren't going to be modified, this can be faster. If
617 // there's any chance that those bytes WILL be changed, this will invalidate
618 // your packets.
619 NoCopy bool
620 // SkipDecodeRecovery skips over panic recovery during packet decoding.
621 // Normally, when packets decode, if a panic occurs, that panic is captured
622 // by a recover(), and a DecodeFailure layer is added to the packet detailing
623 // the issue. If this flag is set, panics are instead allowed to continue up
624 // the stack.
625 SkipDecodeRecovery bool
626 // DecodeStreamsAsDatagrams enables routing of application-level layers in the TCP
627 // decoder. If true, we should try to decode layers after TCP in single packets.
628 // This is disabled by default because the reassembly package drives the decoding
629 // of TCP payload data after reassembly.
630 DecodeStreamsAsDatagrams bool
631}
632
633// Default decoding provides the safest (but slowest) method for decoding
634// packets. It eagerly processes all layers (so it's concurrency-safe) and it
635// copies its input buffer upon creation of the packet (so the packet remains
636// valid if the underlying slice is modified. Both of these take time,
637// though, so beware. If you can guarantee that the packet will only be used
638// by one goroutine at a time, set Lazy decoding. If you can guarantee that
639// the underlying slice won't change, set NoCopy decoding.
640var Default = DecodeOptions{}
641
642// Lazy is a DecodeOptions with just Lazy set.
643var Lazy = DecodeOptions{Lazy: true}
644
645// NoCopy is a DecodeOptions with just NoCopy set.
646var NoCopy = DecodeOptions{NoCopy: true}
647
648// DecodeStreamsAsDatagrams is a DecodeOptions with just DecodeStreamsAsDatagrams set.
649var DecodeStreamsAsDatagrams = DecodeOptions{DecodeStreamsAsDatagrams: true}
650
651// NewPacket creates a new Packet object from a set of bytes. The
652// firstLayerDecoder tells it how to interpret the first layer from the bytes,
653// future layers will be generated from that first layer automatically.
654func NewPacket(data []byte, firstLayerDecoder Decoder, options DecodeOptions) Packet {
655 if !options.NoCopy {
656 dataCopy := make([]byte, len(data))
657 copy(dataCopy, data)
658 data = dataCopy
659 }
660 if options.Lazy {
661 p := &lazyPacket{
662 packet: packet{data: data, decodeOptions: options},
663 next: firstLayerDecoder,
664 }
665 p.layers = p.initialLayers[:0]
666 // Crazy craziness:
667 // If the following return statemet is REMOVED, and Lazy is FALSE, then
668 // eager packet processing becomes 17% FASTER. No, there is no logical
669 // explanation for this. However, it's such a hacky micro-optimization that
670 // we really can't rely on it. It appears to have to do with the size the
671 // compiler guesses for this function's stack space, since one symptom is
672 // that with the return statement in place, we more than double calls to
673 // runtime.morestack/runtime.lessstack. We'll hope the compiler gets better
674 // over time and we get this optimization for free. Until then, we'll have
675 // to live with slower packet processing.
676 return p
677 }
678 p := &eagerPacket{
679 packet: packet{data: data, decodeOptions: options},
680 }
681 p.layers = p.initialLayers[:0]
682 p.initialDecode(firstLayerDecoder)
683 return p
684}
685
686// PacketDataSource is an interface for some source of packet data. Users may
687// create their own implementations, or use the existing implementations in
688// gopacket/pcap (libpcap, allows reading from live interfaces or from
689// pcap files) or gopacket/pfring (PF_RING, allows reading from live
690// interfaces).
691type PacketDataSource interface {
692 // ReadPacketData returns the next packet available from this data source.
693 // It returns:
694 // data: The bytes of an individual packet.
695 // ci: Metadata about the capture
696 // err: An error encountered while reading packet data. If err != nil,
697 // then data/ci will be ignored.
698 ReadPacketData() (data []byte, ci CaptureInfo, err error)
699}
700
701// ConcatFinitePacketDataSources returns a PacketDataSource that wraps a set
702// of internal PacketDataSources, each of which will stop with io.EOF after
703// reading a finite number of packets. The returned PacketDataSource will
704// return all packets from the first finite source, followed by all packets from
705// the second, etc. Once all finite sources have returned io.EOF, the returned
706// source will as well.
707func ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource {
708 c := concat(pds)
709 return &c
710}
711
712type concat []PacketDataSource
713
714func (c *concat) ReadPacketData() (data []byte, ci CaptureInfo, err error) {
715 for len(*c) > 0 {
716 data, ci, err = (*c)[0].ReadPacketData()
717 if err == io.EOF {
718 *c = (*c)[1:]
719 continue
720 }
721 return
722 }
723 return nil, CaptureInfo{}, io.EOF
724}
725
726// ZeroCopyPacketDataSource is an interface to pull packet data from sources
727// that allow data to be returned without copying to a user-controlled buffer.
728// It's very similar to PacketDataSource, except that the caller must be more
729// careful in how the returned buffer is handled.
730type ZeroCopyPacketDataSource interface {
731 // ZeroCopyReadPacketData returns the next packet available from this data source.
732 // It returns:
733 // data: The bytes of an individual packet. Unlike with
734 // PacketDataSource's ReadPacketData, the slice returned here points
735 // to a buffer owned by the data source. In particular, the bytes in
736 // this buffer may be changed by future calls to
737 // ZeroCopyReadPacketData. Do not use the returned buffer after
738 // subsequent ZeroCopyReadPacketData calls.
739 // ci: Metadata about the capture
740 // err: An error encountered while reading packet data. If err != nil,
741 // then data/ci will be ignored.
742 ZeroCopyReadPacketData() (data []byte, ci CaptureInfo, err error)
743}
744
745// PacketSource reads in packets from a PacketDataSource, decodes them, and
746// returns them.
747//
748// There are currently two different methods for reading packets in through
749// a PacketSource:
750//
751// Reading With Packets Function
752//
753// This method is the most convenient and easiest to code, but lacks
754// flexibility. Packets returns a 'chan Packet', then asynchronously writes
755// packets into that channel. Packets uses a blocking channel, and closes
756// it if an io.EOF is returned by the underlying PacketDataSource. All other
757// PacketDataSource errors are ignored and discarded.
758// for packet := range packetSource.Packets() {
759// ...
760// }
761//
762// Reading With NextPacket Function
763//
764// This method is the most flexible, and exposes errors that may be
765// encountered by the underlying PacketDataSource. It's also the fastest
766// in a tight loop, since it doesn't have the overhead of a channel
767// read/write. However, it requires the user to handle errors, most
768// importantly the io.EOF error in cases where packets are being read from
769// a file.
770// for {
771// packet, err := packetSource.NextPacket()
772// if err == io.EOF {
773// break
774// } else if err != nil {
775// log.Println("Error:", err)
776// continue
777// }
778// handlePacket(packet) // Do something with each packet.
779// }
780type PacketSource struct {
781 source PacketDataSource
782 decoder Decoder
783 // DecodeOptions is the set of options to use for decoding each piece
784 // of packet data. This can/should be changed by the user to reflect the
785 // way packets should be decoded.
786 DecodeOptions
787 c chan Packet
788}
789
790// NewPacketSource creates a packet data source.
791func NewPacketSource(source PacketDataSource, decoder Decoder) *PacketSource {
792 return &PacketSource{
793 source: source,
794 decoder: decoder,
795 }
796}
797
798// NextPacket returns the next decoded packet from the PacketSource. On error,
799// it returns a nil packet and a non-nil error.
800func (p *PacketSource) NextPacket() (Packet, error) {
801 data, ci, err := p.source.ReadPacketData()
802 if err != nil {
803 return nil, err
804 }
805 packet := NewPacket(data, p.decoder, p.DecodeOptions)
806 m := packet.Metadata()
807 m.CaptureInfo = ci
808 m.Truncated = m.Truncated || ci.CaptureLength < ci.Length
809 return packet, nil
810}
811
812// packetsToChannel reads in all packets from the packet source and sends them
813// to the given channel. This routine terminates when a non-temporary error
814// is returned by NextPacket().
815func (p *PacketSource) packetsToChannel() {
816 defer close(p.c)
817 for {
818 packet, err := p.NextPacket()
819 if err == nil {
820 p.c <- packet
821 continue
822 }
823
824 // Immediately retry for temporary network errors
825 if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
826 continue
827 }
828
829 // Immediately retry for EAGAIN
830 if err == syscall.EAGAIN {
831 continue
832 }
833
834 // Immediately break for known unrecoverable errors
835 if err == io.EOF || err == io.ErrUnexpectedEOF ||
836 err == io.ErrNoProgress || err == io.ErrClosedPipe || err == io.ErrShortBuffer ||
837 err == syscall.EBADF ||
838 strings.Contains(err.Error(), "use of closed file") {
839 break
840 }
841
842 // Sleep briefly and try again
843 time.Sleep(time.Millisecond * time.Duration(5))
844 }
845}
846
847// Packets returns a channel of packets, allowing easy iterating over
848// packets. Packets will be asynchronously read in from the underlying
849// PacketDataSource and written to the returned channel. If the underlying
850// PacketDataSource returns an io.EOF error, the channel will be closed.
851// If any other error is encountered, it is ignored.
852//
853// for packet := range packetSource.Packets() {
854// handlePacket(packet) // Do something with each packet.
855// }
856//
857// If called more than once, returns the same channel.
858func (p *PacketSource) Packets() chan Packet {
859 if p.c == nil {
860 p.c = make(chan Packet, 1000)
861 go p.packetsToChannel()
862 }
863 return p.c
864}