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 )
}
}