From 57fe77b73f43b152fc9ce4f8c888bbcb9791addd Mon Sep 17 00:00:00 2001 From: Simon Moser Date: Wed, 3 Nov 2021 16:06:36 +0100 Subject: [PATCH] Added filter for MAC/IP [Close #8] --- proxy/main.go | 158 +++++++++++++++++++++++++++++---------------- proxy/util/util.go | 2 + 2 files changed, 105 insertions(+), 55 deletions(-) diff --git a/proxy/main.go b/proxy/main.go index 039481c..29e03b7 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/binary" "flag" "fmt" @@ -11,7 +12,6 @@ import ( "net" "proxy/cmd" "proxy/util" - "strconv" "time" ) @@ -72,29 +72,19 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough // Handle Ethernet frame frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet) - if prefix == cmd.In { - log.Debug(prefix, "Incoming MAC rewritten ", frame.DstMAC, OldMac) - frame.DstMAC = OldMac - } else if prefix == cmd.Out { - log.Debug(prefix, "Outgoing MAC rewritten ", frame.SrcMAC, NewMac) - frame.SrcMAC = NewMac - } + log.Debug("Start packet") + filterMAC(prefix, &frame.DstMAC, &frame.SrcMAC, frame.LayerType()) // Handle IPv6 packet if ipv4layer := packet.Layer(layers.LayerTypeIPv4); ipv4layer != nil { ipv4Packet, _ := ipv4layer.(*layers.IPv4) - if prefix == cmd.In { - log.Debug(prefix, "Incoming IP rewritten ", ipv4Packet.DstIP, OldIP) - ipv4Packet.DstIP = OldIP - } else if prefix == cmd.Out { - log.Debug(prefix, "Outgoing IP rewritten ", ipv4Packet.SrcIP, NewIP) - ipv4Packet.SrcIP = NewIP - } + log.Debug("IP Protocol", ipv4Packet.Protocol) + filterIP(prefix, &ipv4Packet.DstIP, &ipv4Packet.SrcIP, ipv4Packet.LayerType()) // Handle ICMP packet (based on IPv4) if icmpLayer := packet.Layer(layers.LayerTypeICMPv4); icmpLayer != nil { 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 @@ -122,47 +112,13 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough // Handle ARP packet if frame.EthernetType == layers.EthernetTypeARP { arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP) - log.Debugf( - "%sARP before modification\nAddrType:\t%s\nProtocol:\t%s\nOperation:\t%s\n"+ - "SrcHwAddress:\t%s\nSrcProtAddress:\t%s\nDstHwAddress:\t%s\nDstProtAddress:\t%s\n", - 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(prefix, "ARP Type ", arpPacket.Operation) + filterIPb(prefix, &arpPacket.DstProtAddress, &arpPacket.SourceProtAddress, arpPacket.LayerType()) + filterMACb(prefix, &arpPacket.DstHwAddress, &arpPacket.SourceHwAddress, arpPacket.LayerType()) } + log.Debug("End packet") + // Forward original frame to other plug if passthrough { writer.Write(frameLength) @@ -193,3 +149,95 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough 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) + } +} diff --git a/proxy/util/util.go b/proxy/util/util.go index 4f9a270..725bc13 100644 --- a/proxy/util/util.go +++ b/proxy/util/util.go @@ -9,6 +9,7 @@ import ( "os" ) +// WritePcap writes the provided data to a given pcap file func WritePcap(file string, data []byte, ci gopacket.CaptureInfo) { f, err := os.Create(file) if err != nil { @@ -25,6 +26,7 @@ func WritePcap(file string, data []byte, ci gopacket.CaptureInfo) { err = r.WritePacket(ci, data) } +// WriteBinary writes the provided data to a given binary file func WriteBinary(file string, data []byte) { if err := ioutil.WriteFile(file, data, 0644); err != nil { log.Errorf("Error writing binary file %s", file)