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 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) tcpassembly.Stream {
    	r := tcpreader.NewReaderStream()
    	go printRequests(&r, a, b)
    	return &r
    }
    func printRequests(r io.Reader, a, b gopacket.Flow) {
    	// 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(a, b)
    			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 = 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
        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
                      }

                        ReaderStreamOptions provides user-resettable options for a ReaderStream.

                        Source Files