mirror of
https://github.com/danderson/netboot.git
synced 2025-10-15 17:41:38 +02:00
Make pcap.Reader's API look like bufio.Scanner's.
The Next/Packet/Err structure makes read loops much cleaner, and presents a more familiar interface for people familiar with the stdlib.
This commit is contained in:
parent
6b9cba0085
commit
178a83f3e0
@ -27,6 +27,9 @@ type Reader struct {
|
||||
r io.Reader
|
||||
order binary.ByteOrder
|
||||
tmult int64
|
||||
|
||||
pkt *Packet
|
||||
err error
|
||||
}
|
||||
|
||||
// Packet is one raw packet and its metadata.
|
||||
@ -94,8 +97,26 @@ func NewReader(r io.Reader) (*Reader, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Next returns the next packet in r.
|
||||
func (r *Reader) Next() (*Packet, error) {
|
||||
// Packet returns the packet read by the last call to Next.
|
||||
func (r *Reader) Packet() *Packet {
|
||||
return r.pkt
|
||||
}
|
||||
|
||||
// Err returns the first non-EOF error encountered by the Reader.
|
||||
func (r *Reader) Err() error {
|
||||
if r.err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return r.err
|
||||
}
|
||||
|
||||
// Next advances the Reader to the next packet in the input, which
|
||||
// will then be available through the Packet method. It returns false
|
||||
// when the Reader stops, either by reaching the end of the input or
|
||||
// an error. After Next returns false, the Err method will return any
|
||||
// error that occured while reading, except that if it was io.EOF, Err
|
||||
// will return nil.
|
||||
func (r *Reader) Next() bool {
|
||||
hdr := struct {
|
||||
Sec uint32
|
||||
SubSec uint32
|
||||
@ -104,17 +125,20 @@ func (r *Reader) Next() (*Packet, error) {
|
||||
}{}
|
||||
|
||||
if err := binary.Read(r.r, r.order, &hdr); err != nil {
|
||||
return nil, err
|
||||
r.err = err
|
||||
return false
|
||||
}
|
||||
|
||||
bs := make([]byte, hdr.Len)
|
||||
if _, err := io.ReadFull(r.r, bs); err != nil {
|
||||
return nil, err
|
||||
r.err = err
|
||||
return false
|
||||
}
|
||||
|
||||
return &Packet{
|
||||
r.pkt = &Packet{
|
||||
Timestamp: time.Unix(int64(hdr.Sec), r.tmult*int64(hdr.SubSec)),
|
||||
Length: int(hdr.OrigLen),
|
||||
Bytes: bs,
|
||||
}, nil
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package pcap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
@ -23,18 +22,15 @@ func TestFiles(t *testing.T) {
|
||||
if r.LinkType != LinkEthernet {
|
||||
t.Errorf("Expected link type %d, got %d", LinkEthernet, r.LinkType)
|
||||
}
|
||||
|
||||
pkts := []*Packet{}
|
||||
ReadLoop:
|
||||
for {
|
||||
pkt, err := r.Next()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break ReadLoop
|
||||
}
|
||||
t.Fatalf("Unexpected error reading packets: %s", err)
|
||||
}
|
||||
pkts = append(pkts, pkt)
|
||||
for r.Next() {
|
||||
pkts = append(pkts, r.Packet())
|
||||
}
|
||||
if r.Err() != nil {
|
||||
t.Fatalf("Reading packets from %s.pcap: %s", fname, r.Err())
|
||||
}
|
||||
|
||||
res := pretty.Sprintf("%# v", pkts)
|
||||
expectedFile := fmt.Sprintf("testdata/%s.parsed", fname)
|
||||
expected, err := ioutil.ReadFile(expectedFile)
|
||||
|
@ -3,7 +3,6 @@ package pcap
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@ -63,16 +62,11 @@ func TestReadback(t *testing.T) {
|
||||
t.Fatalf("Wrote link type %d, read back %d", LinkEthernet, r.LinkType)
|
||||
}
|
||||
|
||||
ReadLoop:
|
||||
for {
|
||||
pkt, err := r.Next()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break ReadLoop
|
||||
}
|
||||
t.Fatalf("Unexpected error reading packets: %s", err)
|
||||
}
|
||||
readBack = append(readBack, pkt)
|
||||
for r.Next() {
|
||||
readBack = append(readBack, r.Packet())
|
||||
}
|
||||
if r.Err() != nil {
|
||||
t.Fatalf("Reading packets back: %s", r.Err())
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(pkts, readBack) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user