Skip to content

Commit

Permalink
Merge pull request #11 from exaring/fix/spoofsrc
Browse files Browse the repository at this point in the history
Implement hop specific source ranges
  • Loading branch information
takt authored May 16, 2019
2 parents 2f7f796 + bfb7fd8 commit 2ff0001
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 35 deletions.
35 changes: 17 additions & 18 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ var (
dfltPayloadSizeBytes = uint64(0)
dfltPPS = uint64(25)
dfltSrcRange = "169.254.0.0/16"
dfltSpoofReplySrc = true
dfltMetricsPath = "/metrics"
)

Expand All @@ -30,6 +29,7 @@ type Config struct {
ListenAddress *string `yaml:"listen_address"`
BasePort *uint16 `yaml:"base_port"`
Defaults *Defaults `yaml:"defaults"`
SrcRange *string `yaml:"src_range"`
Classes []Class `yaml:"classes"`
Paths []Path `yaml:"paths"`
Routers []Router `yaml:"routers"`
Expand All @@ -40,7 +40,6 @@ type Defaults struct {
MeasurementLengthMS *uint64 `yaml:"measurement_length_ms"`
PayloadSizeBytes *uint64 `yaml:"payload_size_bytes"`
PPS *uint64 `yaml:"pps"`
SpoofReplySrc *bool `yaml:"spoof_reply_src"`
SrcRange *string `yaml:"src_range"`
TimeoutMS *uint64 `yaml:"timeout"`
SrcInterface *string `yaml:"src_interface"`
Expand All @@ -59,15 +58,14 @@ type Path struct {
MeasurementLengthMS *uint64 `yaml:"measurement_length_ms"`
PayloadSizeBytes *uint64 `yaml:"payload_size_bytes"`
PPS *uint64 `yaml:"pps"`
SpoofReplySrc *bool `yaml:"spoof_reply_src"`
SrcRange *string `yaml:"src_range"`
TimeoutMS *uint64 `yaml:"timeout"`
}

// Router represents a router used a an explicit hop in a path
type Router struct {
Name string `yaml:"name"`
DstRange string `yaml:"dst_range"`
SrcRange string `yaml:"src_range"`
}

// Validate validates a configuration
Expand Down Expand Up @@ -123,6 +121,11 @@ func (c *Config) ApplyDefaults() {
if c.Defaults == nil {
c.Defaults = &Defaults{}
}
c.Defaults.applyDefaults()

if c.SrcRange == nil {
c.SrcRange = c.Defaults.SrcRange
}

if c.MetricsPath == nil {
c.MetricsPath = &dfltMetricsPath
Expand All @@ -136,19 +139,27 @@ func (c *Config) ApplyDefaults() {
c.BasePort = &dfltBasePort
}

c.Defaults.applyDefaults()

for i := range c.Paths {
c.Paths[i].applyDefaults(c.Defaults)
}

for i := range c.Routers {
c.Routers[i].applyDefaults(c.Defaults)
}

if c.Classes == nil {
c.Classes = []Class{
dfltClass,
}
}
}

func (r *Router) applyDefaults(d *Defaults) {
if r.SrcRange == "" {
r.SrcRange = *d.SrcRange
}
}

func (p *Path) applyDefaults(d *Defaults) {
if p.MeasurementLengthMS == nil {
p.MeasurementLengthMS = d.MeasurementLengthMS
Expand All @@ -162,14 +173,6 @@ func (p *Path) applyDefaults(d *Defaults) {
p.PPS = d.PPS
}

if p.SpoofReplySrc == nil {
p.SpoofReplySrc = d.SpoofReplySrc
}

if p.SrcRange == nil {
p.SrcRange = d.SrcRange
}

if p.TimeoutMS == nil {
p.TimeoutMS = d.TimeoutMS
}
Expand All @@ -188,10 +191,6 @@ func (d *Defaults) applyDefaults() {
d.PPS = &dfltPPS
}

if d.SpoofReplySrc == nil {
d.SpoofReplySrc = &dfltSpoofReplySrc
}

if d.SrcRange == nil {
d.SrcRange = &dfltSrcRange
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ func TestConfigApplyDefaults(t *testing.T) {
MetricsPath: &dfltMetricsPath,
ListenAddress: &dfltListenAddress,
BasePort: &dfltBasePort,
SrcRange: &dfltSrcRange,
Defaults: &Defaults{
MeasurementLengthMS: &dfltMeasurementLengthMS,
PayloadSizeBytes: &dfltPayloadSizeBytes,
PPS: &dfltPPS,
SpoofReplySrc: &dfltSpoofReplySrc,
SrcRange: &dfltSrcRange,
TimeoutMS: &dfltTimeoutMS,
},
Expand All @@ -50,18 +50,19 @@ func TestConfigApplyDefaults(t *testing.T) {
{
Name: "SomeRouter02.SomeMetro01",
DstRange: "192.168.0.0/24",
SrcRange: "192.168.100.0/24",
},
},
},
expected: &Config{
MetricsPath: &dfltMetricsPath,
ListenAddress: &dfltListenAddress,
BasePort: &dfltBasePort,
SrcRange: &dfltSrcRange,
Defaults: &Defaults{
MeasurementLengthMS: &dfltMeasurementLengthMS,
PayloadSizeBytes: &dfltPayloadSizeBytes,
PPS: &dfltPPS,
SpoofReplySrc: &dfltSpoofReplySrc,
SrcRange: &dfltSrcRange,
TimeoutMS: &dfltTimeoutMS,
},
Expand All @@ -74,15 +75,14 @@ func TestConfigApplyDefaults(t *testing.T) {
MeasurementLengthMS: &dfltMeasurementLengthMS,
PayloadSizeBytes: &dfltPayloadSizeBytes,
PPS: &dfltPPS,
SpoofReplySrc: &dfltSpoofReplySrc,
SrcRange: &dfltSrcRange,
TimeoutMS: &dfltTimeoutMS,
},
},
Routers: []Router{
{
Name: "SomeRouter02.SomeMetro01",
DstRange: "192.168.0.0/24",
SrcRange: "192.168.100.0/24",
},
},
Classes: []Class{
Expand Down
24 changes: 12 additions & 12 deletions pkg/prober/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package prober

import (
"fmt"
"net"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
Expand All @@ -11,9 +12,15 @@ const (
ttl = 64
)

func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
srcAddr := p.srcAddrs[pr.Seq%uint64(len(p.srcAddrs))]
func (p *Prober) getSrcAddrHop(hop int, seq uint64) net.IP {
return p.hops[hop-1].srcRange[seq%uint64(len(p.hops[hop-1].srcRange))]
}

func (p *Prober) getDstAddr(hop int, seq uint64) net.IP {
return p.hops[hop].dstRange[seq%uint64(len(p.hops[hop].dstRange))]
}

func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
probeSer, err := pr.marshal()
if err != nil {
return nil, fmt.Errorf("Unable to marshal probe: %v", err)
Expand All @@ -25,12 +32,6 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
ComputeChecksums: true,
}

innerSrc := srcAddr
if !*p.path.SpoofReplySrc {
lastHop := p.hops[len(p.hops)-1]
innerSrc = lastHop.dstRange[len(lastHop.dstRange)]
}

l := make([]gopacket.SerializableLayer, 0, (len(p.hops)-1)*2+5)
l = append(l, &layers.GRE{
Protocol: layers.EthernetTypeIPv4,
Expand All @@ -41,10 +42,9 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {
continue
}

dstAddr := p.hops[i].dstRange[pr.Seq%uint64(len(p.hops[i].dstRange))]
l = append(l, &layers.IPv4{
SrcIP: srcAddr,
DstIP: dstAddr,
SrcIP: p.getSrcAddrHop(i, pr.Seq),
DstIP: p.getDstAddr(i, pr.Seq),
Version: 4,
Protocol: layers.IPProtocolGRE,
TOS: p.tos,
Expand All @@ -58,7 +58,7 @@ func (p *Prober) craftPacket(pr *probe) ([]byte, error) {

// Create final UDP packet that will return
ip := &layers.IPv4{
SrcIP: innerSrc,
SrcIP: p.getSrcAddrHop(len(p.hops)-1, pr.Seq),
DstIP: p.localAddr,
Version: 4,
Protocol: layers.IPProtocolUDP,
Expand Down
4 changes: 3 additions & 1 deletion pkg/prober/prober.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Prober struct {
type hop struct {
name string
dstRange []net.IP
srcRange []net.IP
}

func (h *hop) getAddr(s uint64) net.IP {
Expand All @@ -58,7 +59,7 @@ func New(c *config.Config, p config.Path, tos uint8) (*Prober, error) {
mtu: mtuMax,
transitProbes: newTransitProbes(),
measurements: measurement.NewDB(),
srcAddrs: generateAddrs(*p.SrcRange),
srcAddrs: generateAddrs(*c.SrcRange),
tos: tos,
payload: make(gopacket.Payload, *p.PayloadSizeBytes),
}
Expand Down Expand Up @@ -105,6 +106,7 @@ func confHopsToHops(cfg *config.Config, pathCfg config.Path) []hop {
h := hop{
name: cfg.Routers[j].Name,
dstRange: generateAddrs(cfg.Routers[j].DstRange),
srcRange: generateAddrs(cfg.Routers[j].SrcRange),
}
res = append(res, h)
}
Expand Down

0 comments on commit 2ff0001

Please sign in to comment.