fdump

package module
v0.0.0-...-3bf600c Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2019 License: MIT Imports: 21 Imported by: 0

README

fdump

A framework to dump and decode network packet.

Feature

  • tui to show records.
  • replay records.
  • save records to file.
  • load records from file.
  • support tcp.
  • support udp.

Screenshots

How to

Here's the way to create your packet capture application:

  1. Make a function to decode the binary packet and return an Record.
  2. Make a function to show a brief message of the record.
  3. Make a function to show a detail message of the record.
  4. (optional)Make some hook to modify the replay worker.

example:

func decode(net, transport gopacket.Flow, buf []byte) (bodies []interface{}, n int, err error) {
	if len(buf) < 4 {
		err = fdump.ErrPkgNoEnough
		return
	}
	pkgLen := binary.BigEndian.Uint32(buf)
	if uint32(len(buf)) < pkgLen {
		err = fdump.ErrPkgNoEnough
		return
	}
	str := string(buf[4:pkgLen])
	bodies = append(bodies, str)
	n = pkgLen
	return
}

func brief(record *fdump.Record) []string {
	if record == nil || len(record.Bodies) == 0 {
		return nil
	}
	str, ok := record.Bodies[0].(string)
	if !ok {
		return nil
	}
	return []string{str[:10]}
}

func detail(record *fdump.Record) string {
	str, ok := record.Bodies[0].(string)
	if !ok {
		return ""
	}
	return str
}

func postSend(conn net.Conn, record *fdump.Record) error {
	lenBuf := make([]byte, 4)
	lenLen := 0
	for lenLen < 4 {
		err := conn.SetReadDeadline(time.Now().Add(1*time.Second))
		if err != nil {
			return err
		}
		n, err := conn.Read(headBuf[lenLen:])
		if err != nil {
			return err
		}
		lenLen += n
	}

	bodyLen := binary.BigEndian.Uint32(lenBuf) - 4
	body := make([]byte, bodyLen)
	curLen := 0
	for curLen < int(bodyLen) {
		err := conn.SetReadDeadline(time.Now().Add(t*time.Second))
		if err != nil {
			return err
		}
		n, err := conn.Read(body[curlen:])
		if err != nil {
			return err
		}
		curlen += n
	}
	return nil
}

func main() {
	logging.SetLevel(logging.INFO, "")
	fdump.Init()
	replayHook := &fdump.ReplayHook{
		PostSend: postSend,
	}
	briefAttributes := []*fdump.BriefColumnAttribute{&fdump.BriefColumnAttribute{
			Title: "Head10",
			MaxWidth: 10,
		},
	}

	a := fdump.NewApp(decode, brief, detail, replayHook, briefAttributes)
	a.Run()
}

Key

View Key Summary
all f toggle frozen scroll
all s toggle stop capture
all l/Left left
all r/Right right
all j/Down down
all k/Up up
all g/Home goto first line
all G/End goto last line
all ctrl-f/PgDn page down
all ctrl-b/PgUp page up
all ctrl-c exit
all ? help
brief enter enter detail
brief Esc clean prompt
brief C clear
brief S save selected/all to file
brief L load from file
brief M toggle multiple select mode
brief m select/unselect row, select mode only
brief r revert selected, select mode only
brief a select/unselect all, select mode only
brief c clear selected, select mode only
brief R replay current select row
detail q/Esc exit detail
help q/Esc exit help

Warnning

Please set LC_CTYPE to en_US.UTF-8:

export LC_CTYPE=en_US.UTF-8

Documentation

Overview

Package fdump is a framework to create an application to capture network packet and decode the packet. It use a tui to show the packets.

Here's the way to create your packet capture application: 1. make a function to decode the binary packet and return an Record. 2. make a function to show a brief message of the record. 3. make a function to show a detail message of the record. 4. (optional)Make some hook to modify the replay workflow.

Example:

func decode(net, transport gopacket.Flow, buf []byte) (bodies []interface{}, n int, err error) {
	if len(buf) < 4 {
		err = fdump.ErrPkgNoEnough
		return
	}
	pkgLen := binary.BigEndian.Uint32(buf)
	if uint32(len(buf)) < pkgLen {
		err = fdump.ErrPkgNoEnough
		return
	}
	str := string(buf[4:pkgLen])
	bodies = append(bodies, str)
	n = pkgLen
	return
}

func brief(record *fdump.Record) []string {
	if record == nil || len(record.Bodies) == 0 {
		return nil
	}
	str, ok := record.Bodies[0].(string)
	if !ok {
		return nil
	}
	return []string{str[:10]}
}

func detail(record *fdump.Record) string {
	str, ok := record.Bodies[0].(string)
	if !ok {
		return ""
	}
	return str
}

func postSend(conn net.Conn, record *fdump.Record) error {
	lenBuf := make([]byte, 4)
	lenLen := 0
	for lenLen < 4 {
		err := conn.SetReadDeadline(time.Now().Add(1*time.Second))
		if err != nil {
			return err
		}
		n, err := conn.Read(headBuf[lenLen:])
		if err != nil {
			return err
		}
		lenLen += n
	}

	bodyLen := binary.BigEndian.Uint32(lenBuf) - 4
	body := make([]byte, bodyLen)
	curLen := 0
	for curLen < int(bodyLen) {
		err := conn.SetReadDeadline(time.Now().Add(t*time.Second))
		if err != nil {
			return err
		}
		n, err := conn.Read(body[curlen:])
		if err != nil {
			return err
		}
		curlen += n
	}
	return nil
}

func main() {
	logging.SetLevel(logging.INFO, "")
	fdump.Init()
	replayHook := &fdump.ReplayHook{
		PostSend: postSend,
	}
	briefAttributes := []*fdump.BriefColumnAttribute{&fdump.BriefColumnAttribute{
			Title: "Head10",
			MaxWidth: 10,
		},
	}

	a := fdump.NewApp(decode, brief, detail, replayHook, briefAttributes)
	a.Run()
}

If you want to add your owner command flag, please use fdump.AppFlagSet.

The framework use github.com/op/go-logging to write log. You can get the some log : `logging.MustGetLogger(fdump.LoggerName)`.

Modify the logger level: `logging.SetLevel(logging.INFO, "")`

Index

Constants

View Source
const (
	RecordTypeTCP = iota
	RecordTypeUDP
)
View Source
const (
	// LoggerName the logger name
	LoggerName = "fdump"
)

Variables

View Source
var AppFlagSet = flag.NewFlagSet("", flag.ExitOnError)

AppFlagSet Command line flag set, use this flag set to add flags. Warning: Don't use the default flag set.

View Source
var (
	// ErrPkgNoEnough packet no enough error. return this error in decode
	// function if the packet no enough.
	ErrPkgNoEnough = errors.New("pkg no enough")
)

Functions

func Init

func Init()

Init Init the packet. Call it in main/init function before NewApp

Types

type App

type App struct {
	// contains filtered or unexported fields
}

App the application to run

func NewApp

func NewApp(
	decodeFunc DecodeFunc,
	briefFunc BriefFunc,
	detailFunc DetailFunc,
	replayHook *ReplayHook,
	briefAttributes []*BriefColumnAttribute) *App

NewApp new an App instance.

func (*App) Run

func (a *App) Run()

Run begin work. It will block the goroutine

type BriefColumnAttribute

type BriefColumnAttribute struct {
	Title    string // Will show in the top line
	MaxWidth int    // the element max width
}

BriefColumnAttribute the brief column attribute.

type BriefFunc

type BriefFunc func(record *Record) []string

BriefFunc every decoded record will call this function get the strings to show in the brief view.

type DecodeFunc

type DecodeFunc func(gopacket.Flow, gopacket.Flow, []byte) (bodies []interface{}, n int, err error)

DecodeFunc Decode the packet when receive a packet. Return the decoded bodies and used bytes. It will ignore the bodies if it's empty.

type DetailFunc

type DetailFunc func(record *Record) string

DetailFunc will called when type `Enter` to get the detail message of the record.

type PostReplayHook

type PostReplayHook func(conn net.Conn) error

PostReplayHook will call after replay

type PostSendHook

type PostSendHook func(conn net.Conn, record *Record) error

PostSendHook will call after send packet. You should implement it and receive the response packet if you capture the replay response packet. Otherwise it will close the `conn` before receive the response packet.

type PreReplayHook

type PreReplayHook func(conn net.Conn, records []*Record) error

PreReplayHook Will call before replay packet

type PreSendHook

type PreSendHook func(conn net.Conn, record *Record) error

PreSendHook will call before send packet

type Record

type Record struct {
	Type      RecordType
	Net       gopacket.Flow
	Transport gopacket.Flow
	Seen      time.Time
	Bodies    []interface{}
	Buffer    []byte
}

Record decoded object

type RecordType

type RecordType int

RecordType type of the record

type ReplayHook

type ReplayHook struct {
	PreReplay  PreReplayHook
	PreSend    PreSendHook
	PostSend   PostSendHook
	PostReplay PostReplayHook
}

ReplayHook will use in replay action.

Directories

Path Synopsis
_examples
tcp
udp

Jump to

Keyboard shortcuts

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