package main import ( "encoding/binary" "fmt" "github.com/mdlayher/ethernet" "io" "log" "os" "proxy/cmd" ) // Start the two plugs and run two concurrent forward methods func main() { c1 := cmd.New("vde_plug", "/run/vde/sw_main.sock") c2 := cmd.New("vde_plug", "/run/vde/sw_proxy.sock") c1.Execute() c2.Execute() go pipeForward(c1.OutReader, c2.InWriter, cmd.In) go pipeForward(c2.OutReader, c1.InWriter, cmd.Out) c1.WaitH() c2.WaitH() } // Reads from an input and writes to and output, // do things to the content in between. // For now only output the frames information // Is meant to be run concurrently with "go pipeForward(...)" func pipeForward(reader io.Reader, writer io.Writer, prefix string) { for { // Read frame length and print it frameLength := make([]byte, 2) _, err := reader.Read(frameLength) if err == io.EOF { break } frameLengthInt := int(binary.BigEndian.Uint16(frameLength)) os.Stdout.WriteString(fmt.Sprintf("%s Frame length: %d\n", prefix, frameLengthInt)) // Read actual frame frameBytes := make([]byte, frameLengthInt) _, err = reader.Read(frameBytes) if err == io.EOF { break } // Marshal frame from binary var frame ethernet.Frame if e := (&frame).UnmarshalBinary(frameBytes); e != nil { log.Printf("failed to unmarshal frame: %#v\n", e) } // Print frame information fmt.Printf( "src: %s\ndst: %s\ntyp: %s\npayload\n%x\n", frame.Source, frame.Destination, frame.EtherType, frame.Payload, ) // Forward original frame to other plug writer.Write(frameLength) writer.Write(frameBytes) } }