mirror of
https://github.com/danderson/netboot.git
synced 2025-10-16 10:01:20 +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
|
r io.Reader
|
||||||
order binary.ByteOrder
|
order binary.ByteOrder
|
||||||
tmult int64
|
tmult int64
|
||||||
|
|
||||||
|
pkt *Packet
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packet is one raw packet and its metadata.
|
// Packet is one raw packet and its metadata.
|
||||||
@ -94,8 +97,26 @@ func NewReader(r io.Reader) (*Reader, error) {
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next returns the next packet in r.
|
// Packet returns the packet read by the last call to Next.
|
||||||
func (r *Reader) Next() (*Packet, error) {
|
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 {
|
hdr := struct {
|
||||||
Sec uint32
|
Sec uint32
|
||||||
SubSec uint32
|
SubSec uint32
|
||||||
@ -104,17 +125,20 @@ func (r *Reader) Next() (*Packet, error) {
|
|||||||
}{}
|
}{}
|
||||||
|
|
||||||
if err := binary.Read(r.r, r.order, &hdr); err != nil {
|
if err := binary.Read(r.r, r.order, &hdr); err != nil {
|
||||||
return nil, err
|
r.err = err
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := make([]byte, hdr.Len)
|
bs := make([]byte, hdr.Len)
|
||||||
if _, err := io.ReadFull(r.r, bs); err != nil {
|
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)),
|
Timestamp: time.Unix(int64(hdr.Sec), r.tmult*int64(hdr.SubSec)),
|
||||||
Length: int(hdr.OrigLen),
|
Length: int(hdr.OrigLen),
|
||||||
Bytes: bs,
|
Bytes: bs,
|
||||||
}, nil
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package pcap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
@ -23,18 +22,15 @@ func TestFiles(t *testing.T) {
|
|||||||
if r.LinkType != LinkEthernet {
|
if r.LinkType != LinkEthernet {
|
||||||
t.Errorf("Expected link type %d, got %d", LinkEthernet, r.LinkType)
|
t.Errorf("Expected link type %d, got %d", LinkEthernet, r.LinkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
pkts := []*Packet{}
|
pkts := []*Packet{}
|
||||||
ReadLoop:
|
for r.Next() {
|
||||||
for {
|
pkts = append(pkts, r.Packet())
|
||||||
pkt, err := r.Next()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break ReadLoop
|
|
||||||
}
|
}
|
||||||
t.Fatalf("Unexpected error reading packets: %s", err)
|
if r.Err() != nil {
|
||||||
}
|
t.Fatalf("Reading packets from %s.pcap: %s", fname, r.Err())
|
||||||
pkts = append(pkts, pkt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res := pretty.Sprintf("%# v", pkts)
|
res := pretty.Sprintf("%# v", pkts)
|
||||||
expectedFile := fmt.Sprintf("testdata/%s.parsed", fname)
|
expectedFile := fmt.Sprintf("testdata/%s.parsed", fname)
|
||||||
expected, err := ioutil.ReadFile(expectedFile)
|
expected, err := ioutil.ReadFile(expectedFile)
|
||||||
|
@ -3,7 +3,6 @@ package pcap
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -63,16 +62,11 @@ func TestReadback(t *testing.T) {
|
|||||||
t.Fatalf("Wrote link type %d, read back %d", LinkEthernet, r.LinkType)
|
t.Fatalf("Wrote link type %d, read back %d", LinkEthernet, r.LinkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadLoop:
|
for r.Next() {
|
||||||
for {
|
readBack = append(readBack, r.Packet())
|
||||||
pkt, err := r.Next()
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
break ReadLoop
|
|
||||||
}
|
}
|
||||||
t.Fatalf("Unexpected error reading packets: %s", err)
|
if r.Err() != nil {
|
||||||
}
|
t.Fatalf("Reading packets back: %s", r.Err())
|
||||||
readBack = append(readBack, pkt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(pkts, readBack) {
|
if !reflect.DeepEqual(pkts, readBack) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user