Skip to content

Commit

Permalink
add duplicate and corrupt packet options
Browse files Browse the repository at this point in the history
  • Loading branch information
vaporeyes committed Aug 24, 2019
1 parent 2e65f8c commit 6ff3609
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 39 deletions.
60 changes: 32 additions & 28 deletions comcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,27 @@ import (
"strconv"
"strings"

"github.com/tylertreat/comcast/throttler"
"./throttler"
)

const version = "1.0.0"

func main() {
// TODO: Add support for other options like packet reordering, duplication, etc.
var (
device = flag.String("device", "", "Interface (device) to use (defaults to eth0 where applicable)")
stop = flag.Bool("stop", false, "Stop packet controls")
latency = flag.Int("latency", -1, "Latency to add in ms")
targetbw = flag.Int("target-bw", -1, "Target bandwidth limit in kbit/s (slow-lane)")
defaultbw = flag.Int("default-bw", -1, "Default bandwidth limit in kbit/s (fast-lane)")
packetLoss = flag.String("packet-loss", "0", "Packet loss percentage (e.g. 0.1%)")
targetaddr = flag.String("target-addr", "", "Target addresses, (e.g. 10.0.0.1 or 10.0.0.0/24 or 10.0.0.1,192.168.0.0/24 or 2001:db8:a::123)")
targetport = flag.String("target-port", "", "Target port(s) (e.g. 80 or 1:65535 or 22,80,443,1000:1010)")
targetproto = flag.String("target-proto", "tcp,udp,icmp", "Target protocol TCP/UDP (e.g. tcp or tcp,udp or icmp)")
dryrun = flag.Bool("dry-run", false, "Specifies whether or not to actually commit the rule changes")
//icmptype = flag.String("icmp-type", "", "icmp message type (e.g. reply or reply,request)") //TODO: Maybe later :3
device = flag.String("device", "", "Interface (device) to use (defaults to eth0 where applicable)")
stop = flag.Bool("stop", false, "Stop packet controls")
latency = flag.Int("latency", -1, "Latency to add in ms")
targetbw = flag.Int("target-bw", -1, "Target bandwidth limit in kbit/s (slow-lane)")
defaultbw = flag.Int("default-bw", -1, "Default bandwidth limit in kbit/s (fast-lane)")
packetLoss = flag.String("packet-loss", "0", "Packet loss percentage (e.g. 0.1%)")
dupePcktPcnt = flag.String("duplicate-percentage", "0", "Percentage of packets to duplicate (e.g. 1.0%)")
corruptPcktPcnt = flag.String("corruptpacket-pcnt", "0", "Percentage of packets to corrupt")
targetaddr = flag.String("target-addr", "", "Target addresses, (e.g. 10.0.0.1 or 10.0.0.0/24 or 10.0.0.1,192.168.0.0/24 or 2001:db8:a::123)")
targetport = flag.String("target-port", "", "Target port(s) (e.g. 80 or 1:65535 or 22,80,443,1000:1010)")
targetproto = flag.String("target-proto", "tcp,udp,icmp", "Target protocol TCP/UDP (e.g. tcp or tcp,udp or icmp)")
dryrun = flag.Bool("dry-run", false, "Specifies whether or not to actually commit the rule changes")
//icmptype = flag.String("icmp-type", "", "icmp message type (e.g. reply or reply,request)") //TODO: Maybe later :3
vers = flag.Bool("version", false, "Print Comcast's version")
)
flag.Parse()
Expand All @@ -39,28 +41,30 @@ func main() {
targetIPv4, targetIPv6 := parseAddrs(*targetaddr)

throttler.Run(&throttler.Config{
Device: *device,
Stop: *stop,
Latency: *latency,
TargetBandwidth: *targetbw,
DefaultBandwidth: *defaultbw,
PacketLoss: parseLoss(*packetLoss),
TargetIps: targetIPv4,
TargetIps6: targetIPv6,
TargetPorts: parsePorts(*targetport),
TargetProtos: parseProtos(*targetproto),
DryRun: *dryrun,
Device: *device,
Stop: *stop,
Latency: *latency,
TargetBandwidth: *targetbw,
DefaultBandwidth: *defaultbw,
DupePacketPcnt: parseFloat(*dupePcktPcnt),
CorruptPacketPcnt: parseFloat(*corruptPcktPcnt),
PacketLoss: parseFloat(*packetLoss),
TargetIps: targetIPv4,
TargetIps6: targetIPv6,
TargetPorts: parsePorts(*targetport),
TargetProtos: parseProtos(*targetproto),
DryRun: *dryrun,
})
}

func parseLoss(loss string) float64 {
val := loss
if strings.Contains(loss, "%") {
val = loss[:len(loss)-1]
func parseFloat(percentage string) float64 {
val := percentage
if strings.Contains(percentage, "%") {
val = percentage[:len(percentage)-1]
}
l, err := strconv.ParseFloat(val, 64)
if err != nil {
fmt.Println("Incorrectly specified packet loss:", loss)
fmt.Println("Incorrectly specified percentage:", percentage)
os.Exit(1)
}
return l
Expand Down
21 changes: 21 additions & 0 deletions throttler/tc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ const (
tcNetemRule = `dev %s parent 10:10 handle 100:`
tcRate = `rate %vkbit`
tcDelay = `delay %vms`
tcDuplicate = `duplicate %v%%`
tcCorrupt = `corrupt %v%%`
tcLoss = `loss %v%%`
tcAddClass = `sudo tc class add`
tcDelClass = `sudo tc class del`
tcAddQDisc = `sudo tc qdisc add`
tcDelQDisc = `sudo tc qdisc del`
tcChangeQDisc = `sudo tc qdisc change`
iptAddTarget = `sudo %s -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
iptDelTarget = `sudo %s -D POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
iptDestIP = `-d %s`
Expand Down Expand Up @@ -129,6 +132,24 @@ func addNetemRule(cfg *Config, c commander) error {
return c.execute(cmd)
}

func changeNetemRule(cfg *Config, c commander) error {
//Add the Network Emulator rule
net := fmt.Sprintf(tcNetemRule, cfg.Device)
strs := []string{tcChangeQDisc, net, "netem"}

if cfg.DupePacketPcnt > 0 {
strs = append(strs, fmt.Sprintf(tcDuplicate, strconv.FormatFloat(cfg.DupePacketPcnt, 'f', 2, 64)))
}

if cfg.CorruptPacketPcnt > 0 {
strs = append(strs, fmt.Sprintf(tcCorrupt, strconv.FormatFloat(cfg.CorruptPacketPcnt, 'f', 2, 64)))
}

cmd := strings.Join(strs, " ")

return c.execute(cmd)
}

func addIptablesRules(cfg *Config, c commander) error {
var err error
if len(cfg.TargetIps) == 0 && len(cfg.TargetIps6) == 0 {
Expand Down
24 changes: 13 additions & 11 deletions throttler/throttler.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@ const (

// Config specifies options for configuring packet filter rules.
type Config struct {
Device string
Stop bool
Latency int
TargetBandwidth int
DefaultBandwidth int
PacketLoss float64
TargetIps []string
TargetIps6 []string
TargetPorts []string
TargetProtos []string
DryRun bool
Device string
Stop bool
Latency int
TargetBandwidth int
DefaultBandwidth int
PacketLoss float64
DupePacketPcnt float64
CorruptPacketPcnt float64
TargetIps []string
TargetIps6 []string
TargetPorts []string
TargetProtos []string
DryRun bool
}

type throttler interface {
Expand Down

0 comments on commit 6ff3609

Please sign in to comment.