tcpreader

package
v0.0.0-...-2ab8e39 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2020 License: BSD-3-Clause Imports: 3 Imported by: 8

Documentation

Overview

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 parase 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

Constants

This section is empty.

Variables

View Source
var DataLost error = errors.New("lost data")

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

Functions

func DiscardBytesToEOF

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.

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

5

func DiscardBytesToFirstError

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.

Types

type ReaderStream

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

func NewReaderStream() ReaderStream

NewReaderStream returns a new ReaderStream object.

func (*ReaderStream) Close

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

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

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

Reassembled implements tcpassembly.Stream's Reassembled function.

func (*ReaderStream) ReassemblyComplete

func (r *ReaderStream) ReassemblyComplete()

ReassemblyComplete implements tcpassembly.Stream's ReassemblyComplete function.

type ReaderStreamOptions

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
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL