package main import ( "encoding/binary" "fmt" "github.com/google/gopacket" "github.com/google/gopacket/layers" _ "github.com/google/gopacket/layers" "io" "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 packet's 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)) fmt.Printf("%s Frame length: %d\n", prefix, frameLengthInt) // Read actual frame frameBytes := make([]byte, frameLengthInt) _, err = reader.Read(frameBytes) if err == io.EOF { break } // Convert frame to full stack packet packet := gopacket.NewPacket(frameBytes, layers.LayerTypeEthernet, gopacket.Default) // Handle Ethernet frame frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet) fmt.Printf("src: %s\ndst: %s\ntyp: %s\n", frame.SrcMAC, frame.DstMAC, frame.EthernetType) // Handle ARP packet if frame.EthernetType == layers.EthernetTypeARP { arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP) fmt.Printf("%sARP Packet:\n%#v\n", prefix, arpPacket) } // Handle DHCP packet if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil { dhcpPacket, _ := dhcpLayer.(*layers.DHCPv4) fmt.Printf("%sDHCP Packet:\n%#v\n", prefix, dhcpPacket) } // Forward original frame to other plug writer.Write(frameLength) writer.Write(frameBytes) } }