diff --git a/proxy/cmd/cmd.go b/proxy/cmd/cmd.go index b7f166c..3460c0c 100644 --- a/proxy/cmd/cmd.go +++ b/proxy/cmd/cmd.go @@ -7,9 +7,9 @@ import ( "os/exec" ) -// Overloads the exec.Cmd class to save the full command +// Cmd Overloads the exec.Cmd class to save the full command // and adds custom input/output pipes -type cmd struct { +type Cmd struct { fullCommand string *exec.Cmd inReader io.Reader @@ -18,13 +18,13 @@ type cmd struct { outWriter io.Writer } -// New creates a new cmd object with given arguments and returns it -func New(name string, args string) *cmd{ +// Start creates a new cmd object with given arguments, runs and then returns it +func Start(args string) (*Cmd, io.Reader, io.Writer) { ir, iw := io.Pipe() or, ow := io.Pipe() - c := cmd { - name + " " + args, - exec.Command(name, args), + c := Cmd { + "vde_plug " + args, + exec.Command("vde_plug", args), ir, iw, or, @@ -33,19 +33,15 @@ func New(name string, args string) *cmd{ c.Stdout = c.outWriter c.Stdin = c.inReader c.Stderr = os.Stderr - return &c -} - -// Execute runs Cmd.Start() and catches the possible error -func (c *cmd) Execute() { err := c.Start() if err != nil { log.Printf("%s failed with %s\n", c.fullCommand, err) } + return &c, c.OutReader, c.InWriter } // WaitH runs Cmd.Wait() and catches the possible error -func (c *cmd) WaitH() { +func (c *Cmd) WaitH() { err := c.Wait() if err != nil { log.Printf("%s failed with %s\n", c.fullCommand, err) diff --git a/proxy/main.go b/proxy/main.go index cc722bd..6fa233e 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -16,54 +16,77 @@ import ( "time" ) -var OldMac net.HardwareAddr -var NewMac net.HardwareAddr +var OldMAC net.HardwareAddr +var NewMAC net.HardwareAddr var OldIP net.IP var NewIP net.IP +var VmReader io.Reader +var VmWriter io.Writer +var NetReader io.Reader +var NetWriter io.Writer +var Passthrough bool // Start the two plugs and run two concurrent forward methods func main() { // Get command line arguments logLvl := flag.Int("log", 4, "allowed: 5 (debug), 4 (info), 3 (warning), 2 (error), 1 (fatal)") - oldip := flag.String("oldip", "", "IP before change") - newip := flag.String("newip", "10.0.0.15", "IP after change") - oldmac := flag.String("oldmac", "", "MAC before change") - newmac := flag.String("newmac", "", "MAC after change") + oldIP := flag.String("oldip", "", "IP before change") + newIP := flag.String("newip", "10.0.0.15", "IP after change") + oldMAC := flag.String("oldmac", "", "MAC before change") + newMAC := flag.String("newmac", "", "MAC after change") passthrough := flag.Bool("passthrough", false, "Whether to pass every traffic through") - proxy := flag.String("proxy", "1", "Number of the proxy switch") - pidfile := flag.String("pidfile", "", "Location to write the pid to") - logfile := flag.String("logfile", "", "Location to write output to") + sockMain := flag.String("smain", "/run/vde/sw_main.sock", "Main switch sock path, - for stdin/out") + sockProxy := flag.String("sproxy", "/run/vde/sw_proxy1.sock", "Proxy switch sock path") + pidFile := flag.String("pidfile", "", "Location to write the pid to") + logFile := flag.String("logfile", "", "Location to write output to") flag.Parse() log.SetLevel(log.Level(*logLvl)) - OldMac, _ = net.ParseMAC(*oldmac) - NewMac = util.GenerateMac(*newmac) - OldIP = net.ParseIP(*oldip).To4() - NewIP = net.ParseIP(*newip).To4() + OldMAC, _ = net.ParseMAC(*oldMAC) + NewMAC = util.GenerateMac(*newMAC) + OldIP = net.ParseIP(*oldIP).To4() + NewIP = net.ParseIP(*newIP).To4() + Passthrough = *passthrough log.SetFormatter(&log.TextFormatter{ DisableTimestamp: true, }) - if *logfile != "" { - if f, err := os.OpenFile(*logfile, os.O_WRONLY | os.O_CREATE, 0755); err != nil { - log.Error("Error opening logfile ", *logfile) + if *logFile != "" { + if f, err := os.OpenFile(*logFile, os.O_WRONLY | os.O_CREATE, 0755); err != nil { + log.Error("Error opening logFile ", *logFile) } else { log.SetOutput(f) } } - util.WritePIDFile(*pidfile) - c1 := cmd.New("vde_plug", "/run/vde/sw_main.sock") - c2 := cmd.New("vde_plug", "/run/vde/sw_proxy"+*proxy+".sock") - c1.Execute() - c2.Execute() - go pipeForward(c1.OutReader, c2.InWriter, cmd.In, *passthrough) - go pipeForward(c2.OutReader, c1.InWriter, cmd.Out, *passthrough) - c1.WaitH() + util.WritePIDFile(*pidFile) + var c1, c2 *cmd.Cmd + if *sockMain != "-" { + c1, NetReader, NetWriter = cmd.Start(*sockMain) + } else { + NetReader = os.Stdout + NetWriter = os.Stdin + } + c2, VmReader, VmWriter = cmd.Start(*sockProxy) + go pipeForward(cmd.In) + go pipeForward(cmd.Out) + if *sockMain != "-" { + c1.WaitH() + } c2.WaitH() } // Reads from an input and writes to and output, // do things to the content in between. // Is meant to be run concurrently with "go pipeForward(...)" -func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough bool) { +func pipeForward(prefix string) { + var reader io.Reader + var writer io.Writer + if prefix == cmd.In { + reader = NetReader + writer = VmWriter + } else { + reader = VmReader + writer = NetWriter + } + for { // Read frame length frameLength := make([]byte, 2) @@ -99,7 +122,7 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough } // Handle DHCP packet (based on IPv4) - drop for now - if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil && !passthrough { + if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil && !Passthrough { //dhcpPacket, _ := dhcpLayer.(*layers.DHCPv4) log.Info(prefix, "DHCP packet dropped") continue @@ -115,7 +138,7 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough } // Drop IPv6 packets - if ipv6layer := packet.Layer(layers.LayerTypeIPv6); ipv6layer != nil && !passthrough { + if ipv6layer := packet.Layer(layers.LayerTypeIPv6); ipv6layer != nil && !Passthrough { log.Info(prefix, "IPv6 packet dropped") continue } @@ -131,7 +154,7 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough log.Debug("End packet") // Forward original frame to other plug - if passthrough { + if Passthrough { writer.Write(frameLength) writer.Write(frameBytes) continue @@ -208,14 +231,14 @@ func filterIP(prefix string, dst interface{}, src interface{}, context gopacket. // filterMAC checks whether a MAC target selected from src and dst equals a given value. If yes, it is changed func filterMAC(prefix string, dst interface{}, src interface{}, context gopacket.LayerType) { - // If no OldMac is set yet, get it from outgoing src field + // If no OldMAC is set yet, get it from outgoing src field // Has to be HardwareAddr because this is used for ethernet frames which call this method first - if OldMac == nil { + if OldMAC == nil { if prefix == cmd.In { return } else if prefix == cmd.Out { - OldMac = *src.(*net.HardwareAddr) - log.Info("OldMac set to ", OldMac) + OldMAC = *src.(*net.HardwareAddr) + log.Info("OldMAC set to ", OldMAC) } } @@ -226,13 +249,13 @@ func filterMAC(prefix string, dst interface{}, src interface{}, context gopacket if prefix == cmd.In { target = dst which = "dst" - condVal = NewMac - newVal = OldMac + condVal = NewMAC + newVal = OldMAC } else if prefix == cmd.Out { target = src which = "src" - condVal = OldMac - newVal = NewMac + condVal = OldMAC + newVal = NewMAC } mac, isMac := target.(*net.HardwareAddr) bs, isBs := target.(*[]byte) diff --git a/proxy/proxy b/proxy/proxy index 562c3d0..be759ae 100755 Binary files a/proxy/proxy and b/proxy/proxy differ diff --git a/test-env/envctl b/test-env/envctl index 9246296..9363c42 100755 --- a/test-env/envctl +++ b/test-env/envctl @@ -39,10 +39,10 @@ start) $qemu -m 1024 -nic user -nic vde,mac='52:54:00:12:34:76',sock=$RUN/sw_proxy3.sock -hda kali.qcow2 -daemonize -vnc :3 -pidfile $kali ;;& proxy2 | proxies | all) - $proxy -proxy 2 -passthrough -logfile $RUN/proxy_2.log -pidfile $proxy2 & + $proxy -sproxy $RUN/sw_proxy2.sock -passthrough -logfile $RUN/proxy_2.log -pidfile $proxy2 & ;;& proxy3 | proxies | all) - $proxy -proxy 3 -passthrough -logfile $RUN/proxy_3.log -pidfile $proxy3 & + $proxy -sproxy $RUN/sw_proxy3.sock -passthrough -logfile $RUN/proxy_3.log -pidfile $proxy3 & ;; *) echo "Usage: envctl start {all|network|vms|alpine|alpine1|alpine2|kali|proxy2|proxy3|proxies}"