gopacket: github.com/google/gopacket/tcpassembly/tcpreader Index | Examples | Files

package tcpreader

import "github.com/google/gopacket/tcpassembly/tcpreader"

Package tcpreader provides an implementation for tcpassembly.Stream which presents the caller with an io.Reader for easy processing.

The assembly package handles packet data reordering, but its output is library-specific, thus not usable by the majority of external Go libraries. The io.Reader interface, on the other hand, is used throughout much of Go code as an easy mechanism for reading in data streams and decoding them. For example, the net/http package provides the ReadRequest function, which can parse an HTTP request from a live data stream, just what we'd want when sniffing HTTP traffic. Using ReaderStream, this is relatively easy to set up:

// Create our StreamFactory
type httpStreamFactory struct {}
func (f *httpStreamFactory) New(a, b gopacket.Flow) {
	r := tcpreader.NewReaderStream(false)
	go printRequests(r)
	return &r
}
func printRequests(r io.Reader) {
  // Convert to bufio, since that's what ReadRequest wants.
	buf := bufio.NewReader(r)
	for {
		if req, err := http.ReadRequest(buf); err == io.EOF {
			return
		} else if err != nil {
			log.Println("Error parsing HTTP requests:", err)
		} else {
			fmt.Println("HTTP REQUEST:", req)
			fmt.Println("Body contains", tcpreader.DiscardBytesToEOF(req.Body), "bytes")
		}
	}
}

Using just this code, we're able to reference a powerful, built-in library for HTTP request parsing to do all the dirty-work of parsing requests from the wire in real-time. Pass this stream factory to an tcpassembly.StreamPool, start up an tcpassembly.Assembler, and you're good to go!

Index

Examples

Package Files

reader.go

Variables

var DataLost = errors.New("lost data")

DataLost is returned by the ReaderStream's Read function when it encounters a Reassembly with Skip != 0.

func DiscardBytesToEOF Uses

func DiscardBytesToEOF(r io.Reader) (discarded int)

DiscardBytesToEOF will read in all bytes from a Reader until it encounters an io.EOF, then return the number of bytes. Be careful of this... if used on a Reader that returns a non-io.EOF error consistently, this will loop forever discarding that error while it waits for an EOF.

Code:

b := bytes.NewBuffer([]byte{1, 2, 3, 4, 5})
fmt.Println(DiscardBytesToEOF(b))

Output:

5

func DiscardBytesToFirstError Uses

func DiscardBytesToFirstError(r io.Reader) (discarded int, err error)

DiscardBytesToFirstError will read in all bytes up to the first error reported by the given reader, then return the number of bytes discarded and the error encountered.

type ReaderStream Uses

type ReaderStream struct {
    ReaderStreamOptions
    // contains filtered or unexported fields
}

ReaderStream implements both tcpassembly.Stream and io.Reader. You can use it as a building block to make simple, easy stream handlers.

IMPORTANT: If you use a ReaderStream, you MUST read ALL BYTES from it, quickly. Not reading available bytes will block TCP stream reassembly. It's a common pattern to do this by starting a goroutine in the factory's New method:

type myStreamHandler struct {
	r ReaderStream
}
func (m *myStreamHandler) run() {
	// Do something here that reads all of the ReaderStream, or your assembly
	// will block.
	fmt.Println(tcpreader.DiscardBytesToEOF(&m.r))
}
func (f *myStreamFactory) New(a, b gopacket.Flow) tcpassembly.Stream {
	s := &myStreamHandler{}
	go s.run()
	// Return the ReaderStream as the stream that assembly should populate.
	return &s.r
}

func NewReaderStream Uses

func NewReaderStream() ReaderStream

NewReaderStream returns a new ReaderStream object.

func (*ReaderStream) Close Uses

func (r *ReaderStream) Close() error

Close implements io.Closer's Close function, making ReaderStream a io.ReadCloser. It discards all remaining bytes in the reassembly in a manner that's safe for the assembler (IE: it doesn't block).

func (*ReaderStream) Read Uses

func (r *ReaderStream) Read(p []byte) (int, error)

Read implements io.Reader's Read function. Given a byte slice, it will either copy a non-zero number of bytes into that slice and return the number of bytes and a nil error, or it will leave slice p as is and return 0, io.EOF.

func (*ReaderStream) Reassembled Uses

func (r *ReaderStream) Reassembled(reassembly []tcpassembly.Reassembly)

Reassembled implements tcpassembly.Stream's Reassembled function.

func (*ReaderStream) ReassemblyComplete Uses

func (r *ReaderStream) ReassemblyComplete()

ReassemblyComplete implements tcpassembly.Stream's ReassemblyComplete function.

type ReaderStreamOptions Uses

type ReaderStreamOptions struct {
    // LossErrors determines whether this stream will return
    // ReaderStreamDataLoss errors from its Read function whenever it
    // determines data has been lost.
    LossErrors bool
}

ReaderStreamOptions provides user-resettable options for a ReaderStream.

Package tcpreader imports 3 packages (graph) and is imported by 26 packages. Updated 2019-10-30. Refresh now. Tools for package owners.