|
|
@ -1,6 +1,7 @@
|
|
|
|
package main
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"encoding/binary"
|
|
|
|
"flag"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
@ -11,7 +12,6 @@ import (
|
|
|
|
"net"
|
|
|
|
"net"
|
|
|
|
"proxy/cmd"
|
|
|
|
"proxy/cmd"
|
|
|
|
"proxy/util"
|
|
|
|
"proxy/util"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
@ -72,29 +72,19 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
|
|
|
|
|
|
|
|
// Handle Ethernet frame
|
|
|
|
// Handle Ethernet frame
|
|
|
|
frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
|
|
|
frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
|
|
|
if prefix == cmd.In {
|
|
|
|
log.Debug("Start packet")
|
|
|
|
log.Debug(prefix, "Incoming MAC rewritten ", frame.DstMAC, OldMac)
|
|
|
|
filterMAC(prefix, &frame.DstMAC, &frame.SrcMAC, frame.LayerType())
|
|
|
|
frame.DstMAC = OldMac
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
log.Debug(prefix, "Outgoing MAC rewritten ", frame.SrcMAC, NewMac)
|
|
|
|
|
|
|
|
frame.SrcMAC = NewMac
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle IPv6 packet
|
|
|
|
// Handle IPv6 packet
|
|
|
|
if ipv4layer := packet.Layer(layers.LayerTypeIPv4); ipv4layer != nil {
|
|
|
|
if ipv4layer := packet.Layer(layers.LayerTypeIPv4); ipv4layer != nil {
|
|
|
|
ipv4Packet, _ := ipv4layer.(*layers.IPv4)
|
|
|
|
ipv4Packet, _ := ipv4layer.(*layers.IPv4)
|
|
|
|
if prefix == cmd.In {
|
|
|
|
log.Debug("IP Protocol", ipv4Packet.Protocol)
|
|
|
|
log.Debug(prefix, "Incoming IP rewritten ", ipv4Packet.DstIP, OldIP)
|
|
|
|
filterIP(prefix, &ipv4Packet.DstIP, &ipv4Packet.SrcIP, ipv4Packet.LayerType())
|
|
|
|
ipv4Packet.DstIP = OldIP
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
log.Debug(prefix, "Outgoing IP rewritten ", ipv4Packet.SrcIP, NewIP)
|
|
|
|
|
|
|
|
ipv4Packet.SrcIP = NewIP
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle ICMP packet (based on IPv4)
|
|
|
|
// Handle ICMP packet (based on IPv4)
|
|
|
|
if icmpLayer := packet.Layer(layers.LayerTypeICMPv4); icmpLayer != nil {
|
|
|
|
if icmpLayer := packet.Layer(layers.LayerTypeICMPv4); icmpLayer != nil {
|
|
|
|
icmpPacket, _ := icmpLayer.(*layers.ICMPv4)
|
|
|
|
icmpPacket, _ := icmpLayer.(*layers.ICMPv4)
|
|
|
|
log.Debugf("%s ICMP packet\nType/Code:\t%s\n", prefix, icmpPacket.TypeCode.String())
|
|
|
|
log.Debug(prefix, "ICMP Type ", icmpPacket.TypeCode)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Handle DHCP packet (based on IPv4) - drop for now
|
|
|
|
// Handle DHCP packet (based on IPv4) - drop for now
|
|
|
@ -122,47 +112,13 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
// Handle ARP packet
|
|
|
|
// Handle ARP packet
|
|
|
|
if frame.EthernetType == layers.EthernetTypeARP {
|
|
|
|
if frame.EthernetType == layers.EthernetTypeARP {
|
|
|
|
arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP)
|
|
|
|
arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP)
|
|
|
|
log.Debugf(
|
|
|
|
log.Debug(prefix, "ARP Type ", arpPacket.Operation)
|
|
|
|
"%sARP before modification\nAddrType:\t%s\nProtocol:\t%s\nOperation:\t%s\n"+
|
|
|
|
filterIPb(prefix, &arpPacket.DstProtAddress, &arpPacket.SourceProtAddress, arpPacket.LayerType())
|
|
|
|
"SrcHwAddress:\t%s\nSrcProtAddress:\t%s\nDstHwAddress:\t%s\nDstProtAddress:\t%s\n",
|
|
|
|
filterMACb(prefix, &arpPacket.DstHwAddress, &arpPacket.SourceHwAddress, arpPacket.LayerType())
|
|
|
|
prefix,
|
|
|
|
|
|
|
|
arpPacket.AddrType,
|
|
|
|
|
|
|
|
arpPacket.Protocol,
|
|
|
|
|
|
|
|
strconv.Itoa(int(arpPacket.Operation)),
|
|
|
|
|
|
|
|
net.HardwareAddr(arpPacket.SourceHwAddress),
|
|
|
|
|
|
|
|
net.IP(arpPacket.SourceProtAddress),
|
|
|
|
|
|
|
|
net.HardwareAddr(arpPacket.DstHwAddress),
|
|
|
|
|
|
|
|
net.IP(arpPacket.DstProtAddress),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
|
|
|
arpPacket.DstProtAddress = OldIP
|
|
|
|
|
|
|
|
log.Debugf(
|
|
|
|
|
|
|
|
"%sARP after modification\nDstProtAddress:\t%s\n",
|
|
|
|
|
|
|
|
prefix,
|
|
|
|
|
|
|
|
net.IP(arpPacket.DstProtAddress),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if arpPacket.Operation == layers.ARPReply {
|
|
|
|
|
|
|
|
isInteresting = true
|
|
|
|
|
|
|
|
arpPacket.DstHwAddress = OldMac
|
|
|
|
|
|
|
|
log.Debugf(
|
|
|
|
|
|
|
|
"%sDstHwAddress:\t%s\n",
|
|
|
|
|
|
|
|
prefix,
|
|
|
|
|
|
|
|
net.HardwareAddr(arpPacket.DstHwAddress),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
arpPacket.SourceHwAddress = NewMac
|
|
|
|
|
|
|
|
arpPacket.SourceProtAddress = NewIP
|
|
|
|
|
|
|
|
log.Debugf(
|
|
|
|
|
|
|
|
"%sARP after modification\nSrcHwAddress:\t%s\nSrcProtAddress:\t%s\n",
|
|
|
|
|
|
|
|
prefix,
|
|
|
|
|
|
|
|
net.HardwareAddr(arpPacket.SourceHwAddress),
|
|
|
|
|
|
|
|
net.IP(arpPacket.SourceProtAddress),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.Debug("End packet")
|
|
|
|
|
|
|
|
|
|
|
|
// Forward original frame to other plug
|
|
|
|
// Forward original frame to other plug
|
|
|
|
if passthrough {
|
|
|
|
if passthrough {
|
|
|
|
writer.Write(frameLength)
|
|
|
|
writer.Write(frameLength)
|
|
|
@ -193,3 +149,95 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
writer.Write(newFrameBytes)
|
|
|
|
writer.Write(newFrameBytes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filterIP checks whether an IP target in net.IP format equals a given value. If yes, it is changed
|
|
|
|
|
|
|
|
func filterIP(prefix string, dst *net.IP, src *net.IP, context gopacket.LayerType) {
|
|
|
|
|
|
|
|
var target *net.IP
|
|
|
|
|
|
|
|
var condVal net.IP
|
|
|
|
|
|
|
|
var newVal net.IP
|
|
|
|
|
|
|
|
var which string
|
|
|
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
|
|
|
target = dst
|
|
|
|
|
|
|
|
which = "dst"
|
|
|
|
|
|
|
|
condVal = NewIP
|
|
|
|
|
|
|
|
newVal = OldIP
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
target = src
|
|
|
|
|
|
|
|
which = "src"
|
|
|
|
|
|
|
|
condVal = OldIP
|
|
|
|
|
|
|
|
newVal = NewIP
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if bytes.Equal(*target, condVal) {
|
|
|
|
|
|
|
|
*target = newVal
|
|
|
|
|
|
|
|
log.Debugf("%s%s %s IP %s changed to %s", prefix, context, which, condVal, newVal)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filterIPb checks whether an IP target in []byte format equals a given value. If yes, it is changed
|
|
|
|
|
|
|
|
func filterIPb(prefix string, dst *[]byte, src *[]byte, context gopacket.LayerType) {
|
|
|
|
|
|
|
|
var target *[]byte
|
|
|
|
|
|
|
|
var condVal net.IP
|
|
|
|
|
|
|
|
var newVal net.IP
|
|
|
|
|
|
|
|
var which string
|
|
|
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
|
|
|
target = dst
|
|
|
|
|
|
|
|
which = "dst"
|
|
|
|
|
|
|
|
condVal = NewIP
|
|
|
|
|
|
|
|
newVal = OldIP
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
target = src
|
|
|
|
|
|
|
|
which = "src"
|
|
|
|
|
|
|
|
condVal = OldIP
|
|
|
|
|
|
|
|
newVal = NewIP
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if bytes.Equal(*target, condVal) {
|
|
|
|
|
|
|
|
*target = newVal
|
|
|
|
|
|
|
|
log.Debugf("%s%s %s IP %s changed to %s", prefix, context, which, condVal, newVal)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filterMAC checks whether a MAC target in net.HardwareAddr format equals a given value. If yes, it is changed
|
|
|
|
|
|
|
|
func filterMAC(prefix string, dst *net.HardwareAddr, src *net.HardwareAddr, context gopacket.LayerType) {
|
|
|
|
|
|
|
|
var target *net.HardwareAddr
|
|
|
|
|
|
|
|
var condVal net.HardwareAddr
|
|
|
|
|
|
|
|
var newVal net.HardwareAddr
|
|
|
|
|
|
|
|
var which string
|
|
|
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
|
|
|
target = dst
|
|
|
|
|
|
|
|
which = "dst"
|
|
|
|
|
|
|
|
condVal = NewMac
|
|
|
|
|
|
|
|
newVal = OldMac
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
target = src
|
|
|
|
|
|
|
|
which = "src"
|
|
|
|
|
|
|
|
condVal = OldMac
|
|
|
|
|
|
|
|
newVal = NewMac
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if bytes.Equal(*target, condVal) {
|
|
|
|
|
|
|
|
*target = newVal
|
|
|
|
|
|
|
|
log.Debugf("%s%s %s MAC %s changed to %s", prefix, context, which, condVal, newVal)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filterMACb checks whether a MAC target in []byte format equals a given value. If yes, it is changed
|
|
|
|
|
|
|
|
func filterMACb(prefix string, dst *[]byte, src *[]byte, context gopacket.LayerType) {
|
|
|
|
|
|
|
|
var target *[]byte
|
|
|
|
|
|
|
|
var condVal net.HardwareAddr
|
|
|
|
|
|
|
|
var newVal net.HardwareAddr
|
|
|
|
|
|
|
|
var which string
|
|
|
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
|
|
|
target = dst
|
|
|
|
|
|
|
|
which = "dst"
|
|
|
|
|
|
|
|
condVal = NewMac
|
|
|
|
|
|
|
|
newVal = OldMac
|
|
|
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
|
|
|
target = src
|
|
|
|
|
|
|
|
which = "src"
|
|
|
|
|
|
|
|
condVal = OldMac
|
|
|
|
|
|
|
|
newVal = NewMac
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if bytes.Equal(*target, condVal) {
|
|
|
|
|
|
|
|
*target = newVal
|
|
|
|
|
|
|
|
log.Debugf("%s%s %s MAC %s changed to %s", prefix, context, which, condVal, newVal)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|