|
|
|
@ -72,43 +72,57 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
|
|
|
|
|
|
// Handle Ethernet frame
|
|
|
|
|
frame := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
|
|
|
|
if !passthrough && prefix == cmd.In {
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
log.Debug(prefix, "Incoming MAC rewritten ", frame.DstMAC, OldMac)
|
|
|
|
|
frame.DstMAC = OldMac
|
|
|
|
|
} else if !passthrough && prefix == cmd.Out {
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
log.Debug(prefix, "Outgoing MAC rewritten ", frame.SrcMAC, NewMac)
|
|
|
|
|
frame.SrcMAC = NewMac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle IP packet
|
|
|
|
|
// Handle IPv6 packet
|
|
|
|
|
if ipv4layer := packet.Layer(layers.LayerTypeIPv4); ipv4layer != nil {
|
|
|
|
|
ipv4Packet, _ := ipv4layer.(*layers.IPv4)
|
|
|
|
|
if !passthrough && prefix == cmd.In {
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
log.Debug(prefix, "Incoming IP rewritten ", ipv4Packet.DstIP, OldIP)
|
|
|
|
|
ipv4Packet.DstIP = OldIP
|
|
|
|
|
} else if !passthrough && prefix == cmd.Out {
|
|
|
|
|
log.Debug(prefix, "Outgoing IP rewritten ", ipv4Packet.SrcIP, NewMac)
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
log.Debug(prefix, "Outgoing IP rewritten ", ipv4Packet.SrcIP, NewIP)
|
|
|
|
|
ipv4Packet.SrcIP = NewIP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle ICMP packet (based on IPv4)
|
|
|
|
|
if icmpLayer := packet.Layer(layers.LayerTypeICMPv4); icmpLayer != nil {
|
|
|
|
|
icmpPacket, _ := icmpLayer.(*layers.ICMPv4)
|
|
|
|
|
log.Infof("%s ICMP packet\nType/Code:\t%s\n", prefix, icmpPacket.TypeCode.String())
|
|
|
|
|
log.Debugf("%s ICMP packet\nType/Code:\t%s\n", prefix, icmpPacket.TypeCode.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle DHCP packet (based on IPv4)
|
|
|
|
|
// Handle DHCP packet (based on IPv4) - drop for now
|
|
|
|
|
if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil && !passthrough {
|
|
|
|
|
//dhcpPacket, _ := dhcpLayer.(*layers.DHCPv4)
|
|
|
|
|
log.Info(prefix, "DHCP packet dropped")
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle TCP packet
|
|
|
|
|
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
|
|
|
|
|
tcpPacket, _ := tcpLayer.(*layers.TCP)
|
|
|
|
|
if err := tcpPacket.SetNetworkLayerForChecksum(ipv4Packet); err != nil {
|
|
|
|
|
log.Error(prefix, "Error setting network layer for checksum", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Drop IPv6 packets
|
|
|
|
|
if ipv6layer := packet.Layer(layers.LayerTypeIPv6); ipv6layer != nil && !passthrough {
|
|
|
|
|
log.Info(prefix, "IPv6 packet dropped")
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle ARP packet
|
|
|
|
|
if frame.EthernetType == layers.EthernetTypeARP {
|
|
|
|
|
arpPacket := packet.Layer(layers.LayerTypeARP).(*layers.ARP)
|
|
|
|
|
log.Infof(
|
|
|
|
|
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,
|
|
|
|
@ -121,27 +135,26 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
|
net.IP(arpPacket.DstProtAddress),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if !passthrough && prefix == cmd.In {
|
|
|
|
|
log.Debug(prefix, "Incoming MAC rewritten (ARP) ", net.HardwareAddr(arpPacket.DstHwAddress), OldMac)
|
|
|
|
|
if arpPacket.Operation == layers.ARPReply {
|
|
|
|
|
arpPacket.DstHwAddress = OldMac
|
|
|
|
|
if prefix == cmd.In {
|
|
|
|
|
arpPacket.DstProtAddress = OldIP
|
|
|
|
|
log.Infof(
|
|
|
|
|
log.Debugf(
|
|
|
|
|
"%sARP after modification\nDstProtAddress:\t%s\n",
|
|
|
|
|
prefix,
|
|
|
|
|
net.IP(arpPacket.DstProtAddress),
|
|
|
|
|
)
|
|
|
|
|
log.Infof(
|
|
|
|
|
if arpPacket.Operation == layers.ARPReply {
|
|
|
|
|
isInteresting = true
|
|
|
|
|
arpPacket.DstHwAddress = OldMac
|
|
|
|
|
log.Debugf(
|
|
|
|
|
"%sDstHwAddress:\t%s\n",
|
|
|
|
|
prefix,
|
|
|
|
|
net.HardwareAddr(arpPacket.DstHwAddress),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
} else if !passthrough && prefix == cmd.Out {
|
|
|
|
|
log.Debug(prefix, "Outgoing MAC rewritten (ARP) ", net.HardwareAddr(arpPacket.SourceHwAddress), NewMac)
|
|
|
|
|
} else if prefix == cmd.Out {
|
|
|
|
|
arpPacket.SourceHwAddress = NewMac
|
|
|
|
|
arpPacket.SourceProtAddress = NewIP
|
|
|
|
|
log.Infof(
|
|
|
|
|
log.Debugf(
|
|
|
|
|
"%sARP after modification\nSrcHwAddress:\t%s\nSrcProtAddress:\t%s\n",
|
|
|
|
|
prefix,
|
|
|
|
|
net.HardwareAddr(arpPacket.SourceHwAddress),
|
|
|
|
@ -150,6 +163,13 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Forward original frame to other plug
|
|
|
|
|
if passthrough {
|
|
|
|
|
writer.Write(frameLength)
|
|
|
|
|
writer.Write(frameBytes)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Serialize packet back to binary
|
|
|
|
|
buf := gopacket.NewSerializeBuffer()
|
|
|
|
|
opts := gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true}
|
|
|
|
@ -162,13 +182,13 @@ func pipeForward(reader io.Reader, writer io.Writer, prefix string, passthrough
|
|
|
|
|
binary.BigEndian.PutUint16(newFrameLength, uint16(len(newFrameBytes)))
|
|
|
|
|
|
|
|
|
|
// Write interesting things to debug file
|
|
|
|
|
if isInteresting && !passthrough {
|
|
|
|
|
util.WriteBinary(fmt.Sprintf("/tmp/arp_%di.dat", time.Now().Unix()), frameBytes)
|
|
|
|
|
util.WriteBinary(fmt.Sprintf("/tmp/arp_%do.dat", time.Now().Unix()), newFrameBytes)
|
|
|
|
|
if isInteresting {
|
|
|
|
|
util.WriteBinary(fmt.Sprintf("/tmp/pck_%di.dat", time.Now().Unix()), frameBytes)
|
|
|
|
|
util.WriteBinary(fmt.Sprintf("/tmp/pck_%do.dat", time.Now().Unix()), newFrameBytes)
|
|
|
|
|
//util.WritePcap("xyz.pcap", packet.Data(), packet.Metadata().CaptureInfo)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Forward original frame to other plug
|
|
|
|
|
// Forward modified frame to other plug
|
|
|
|
|
writer.Write(newFrameLength)
|
|
|
|
|
writer.Write(newFrameBytes)
|
|
|
|
|
}
|
|
|
|
|