Add a pcap-split tool
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
package pcap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// SplitLimit bounds each output file of Split. Zero means no limit.
|
||||
type SplitLimit struct {
|
||||
Packets int // maximum packets per file
|
||||
Bytes int64 // maximum file size, including the file and record headers
|
||||
}
|
||||
|
||||
// SplitStats summarizes a Split.
|
||||
type SplitStats struct {
|
||||
Packets int // packets copied
|
||||
Parts int // files created
|
||||
Truncated bool // the input ended with an incomplete packet record, which was dropped
|
||||
}
|
||||
|
||||
// Split copies the pcap file read from r into consecutive parts, each starting
|
||||
// with the input's file header and holding whole packet records, so that no
|
||||
// part exceeds the limit. A packet that is bigger than the size limit on its
|
||||
// own goes into a part by itself. create is called to open part 1, 2, ...
|
||||
func Split(r io.Reader, limit SplitLimit, create func(part int) (io.Writer, error)) (SplitStats, error) {
|
||||
var st SplitStats
|
||||
pr, err := NewReader(r)
|
||||
if err != nil {
|
||||
return st, err
|
||||
}
|
||||
|
||||
var (
|
||||
w io.Writer
|
||||
nPackets int
|
||||
nBytes int64
|
||||
)
|
||||
for {
|
||||
rec, err := pr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if errors.Is(err, ErrTruncated) {
|
||||
st.Truncated = true
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return st, err
|
||||
}
|
||||
|
||||
full := limit.Packets > 0 && nPackets >= limit.Packets ||
|
||||
limit.Bytes > 0 && nPackets > 0 && nBytes+int64(len(rec)) > limit.Bytes
|
||||
if w == nil || full {
|
||||
st.Parts++
|
||||
if w, err = create(st.Parts); err != nil {
|
||||
return st, err
|
||||
}
|
||||
if _, err := w.Write(pr.Header()); err != nil {
|
||||
return st, err
|
||||
}
|
||||
nPackets, nBytes = 0, int64(len(pr.Header()))
|
||||
}
|
||||
if _, err := w.Write(rec); err != nil {
|
||||
return st, err
|
||||
}
|
||||
nPackets++
|
||||
nBytes += int64(len(rec))
|
||||
st.Packets++
|
||||
}
|
||||
if st.Packets == 0 {
|
||||
return st, errors.New("the pcap file contains no packets")
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
Reference in New Issue
Block a user