make compatable with windows. improve logging
This commit is contained in:
parent
cd5b96a1ef
commit
9ad732c123
12
go/README.md
12
go/README.md
|
@ -1,12 +1,14 @@
|
||||||
`sudo apt install libpcap-dev gcc`
|
`sudo apt install libpcap-dev gcc`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wlan2eth build wlan2eth.wlan2eth
|
go mod tidy
|
||||||
sudo ./wlan2eth
|
go build wlan2eth
|
||||||
```
|
```
|
||||||
|
|
||||||
If build fails, try `CGO_ENABLED=1`
|
Run the program like this:
|
||||||
|
|
||||||
# Issues
|
```
|
||||||
|
./wlan2eth --dhcp-modify-src --eth [name of ethernet] --wlan [name of wireless interface]
|
||||||
|
```
|
||||||
|
|
||||||
- To prevent forwarding duplicates, incoming hash of in packets are cached and checked against subsequent packets. This may cause issues where duplicate packets are blocked.
|
`--dhcp-modify-src` will modify the client address in the DHCP packets.
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"wlan2eth/logger"
|
"wlan2eth/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleARPRequest(packet gopacket.Packet, srcSocket, dstSocket int, srcName, dstName string, srcMAC, dstMAC net.HardwareAddr, wlan0MAC net.HardwareAddr, eth0 string) {
|
func HandleARPRequest(packet gopacket.Packet, srcSocket, dstSocket int, srcName, dstName string, srcMAC, dstMAC net.HardwareAddr, eth0MAC, wlan0MAC net.HardwareAddr, eth0 string) {
|
||||||
log := logger.GetLogger()
|
log := logger.GetLogger()
|
||||||
|
|
||||||
arpLayer := packet.Layer(layers.LayerTypeARP).(*layers.ARP)
|
arpLayer := packet.Layer(layers.LayerTypeARP).(*layers.ARP)
|
||||||
|
@ -19,7 +19,8 @@ func HandleARPRequest(packet gopacket.Packet, srcSocket, dstSocket int, srcName,
|
||||||
// Add the client to the bridgedClients map
|
// Add the client to the bridgedClients map
|
||||||
srcIP := net.IP(arpLayer.SourceProtAddress)
|
srcIP := net.IP(arpLayer.SourceProtAddress)
|
||||||
srcHwAddr := arpLayer.SourceHwAddress
|
srcHwAddr := arpLayer.SourceHwAddress
|
||||||
AddBridgedClient(srcIP, srcHwAddr, wlan0MAC, eth0)
|
|
||||||
|
AddBridgedClient(srcIP, srcHwAddr, eth0MAC, wlan0MAC, eth0)
|
||||||
|
|
||||||
// Check if the ARP request is an ARP announcement
|
// Check if the ARP request is an ARP announcement
|
||||||
isARPAnnouncement := bytes.Equal(arpLayer.SourceProtAddress, arpLayer.DstProtAddress)
|
isARPAnnouncement := bytes.Equal(arpLayer.SourceProtAddress, arpLayer.DstProtAddress)
|
||||||
|
|
|
@ -22,11 +22,28 @@ func (c ClientInfo) StringMAC() string {
|
||||||
var bridgedClients = make(map[string]ClientInfo)
|
var bridgedClients = make(map[string]ClientInfo)
|
||||||
var bridgedClientsLock sync.Mutex
|
var bridgedClientsLock sync.Mutex
|
||||||
|
|
||||||
func AddBridgedClient(ip net.IP, mac net.HardwareAddr, wlan0MAC net.HardwareAddr, eth0 string) {
|
func AddBridgedClient(ip net.IP, mac net.HardwareAddr, eth0MAC, wlan0MAC net.HardwareAddr, eth0 string) {
|
||||||
log := logger.GetLogger()
|
log := logger.GetLogger()
|
||||||
|
|
||||||
// Ignore the wlan0 MAC address
|
// Ignore the wlan0 MAC address
|
||||||
if bytes.Equal(mac, wlan0MAC) {
|
if bytes.Equal(mac, wlan0MAC) {
|
||||||
|
log.Debugf("Not adding client IP (wlan0): %s", ip)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if bytes.Equal(mac, eth0MAC) {
|
||||||
|
log.Debugf("Not adding client IP (eth0): %s", ip)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ip.String() == "0.0.0.0" {
|
||||||
|
log.Debug("Not adding client IP: 0.0.0.0")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if isAPIPA(ip) {
|
||||||
|
log.Debugf("Not adding client IP (APIPA): %s", ip)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if isExcluded(ip) {
|
||||||
|
log.Debugf("Not adding client IP (excluded): %s", ip)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,3 +129,16 @@ func AddClientRoutes(eth0 string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isAPIPA(ip net.IP) bool {
|
||||||
|
apiStart := net.ParseIP("169.254.0.0").To4()
|
||||||
|
apiEnd := net.ParseIP("169.254.255.255").To4()
|
||||||
|
ip4 := ip.To4()
|
||||||
|
|
||||||
|
return ip4 != nil && bytes.Compare(ip4, apiStart) >= 0 && bytes.Compare(ip4, apiEnd) <= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func isExcluded(ip net.IP) bool {
|
||||||
|
ip4 := ip.To4()
|
||||||
|
return ip4 != nil && (ip4[3] == 0 || ip4[3] == 255)
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"wlan2eth/logger"
|
"wlan2eth/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleDHCPResponse(packet gopacket.Packet, srcSocket, dstSocket int, srcName, dstName string, srcMAC, dstMAC net.HardwareAddr, wlan0MAC net.HardwareAddr, modifyClientSrc bool, eth0 string) {
|
func HandleDHCPResponse(packet gopacket.Packet, srcSocket, dstSocket int, srcName, dstName string, srcMAC, dstMAC, eth0MAC, wlan0MAC net.HardwareAddr, modifyClientSrc bool, eth0 string) {
|
||||||
log := logger.GetLogger()
|
log := logger.GetLogger()
|
||||||
|
|
||||||
// Get the DHCP layer
|
// Get the DHCP layer
|
||||||
|
@ -23,7 +23,7 @@ func HandleDHCPResponse(packet gopacket.Packet, srcSocket, dstSocket int, srcNam
|
||||||
dhcp := dhcpLayer.(*layers.DHCPv4)
|
dhcp := dhcpLayer.(*layers.DHCPv4)
|
||||||
clientIP := dhcp.YourClientIP
|
clientIP := dhcp.YourClientIP
|
||||||
if !clientIP.IsUnspecified() {
|
if !clientIP.IsUnspecified() {
|
||||||
arp.AddBridgedClient(clientIP, dhcp.ClientHWAddr, wlan0MAC, eth0)
|
arp.AddBridgedClient(clientIP, dhcp.ClientHWAddr, eth0MAC, wlan0MAC, eth0)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientMAC, ok := transactionIDToClientMAC[dhcp.Xid]
|
clientMAC, ok := transactionIDToClientMAC[dhcp.Xid]
|
||||||
|
@ -40,15 +40,22 @@ func HandleDHCPResponse(packet gopacket.Packet, srcSocket, dstSocket int, srcNam
|
||||||
// Get the Ethernet layer and cast it to its type
|
// Get the Ethernet layer and cast it to its type
|
||||||
ethLayer := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
ethLayer := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
||||||
|
|
||||||
// Modify the Ethernet source MAC address of the DHCP packet to clientMAC
|
//// Modify the Ethernet source MAC address of the DHCP packet to clientMAC
|
||||||
ethLayer.SrcMAC = clientMAC
|
//ethLayer.SrcMAC = clientMAC
|
||||||
|
|
||||||
|
// Modify the Ethernet source MAC address to point it towards our bridged client
|
||||||
|
ethLayer.DstMAC = clientMAC
|
||||||
|
|
||||||
// Get the IPv4 and UDP layers and cast them to their respective types
|
// Get the IPv4 and UDP layers and cast them to their respective types
|
||||||
ipLayer := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
|
ipLayer := packet.Layer(layers.LayerTypeIPv4).(*layers.IPv4)
|
||||||
udpLayer := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
|
udpLayer := packet.Layer(layers.LayerTypeUDP).(*layers.UDP)
|
||||||
|
|
||||||
// Set the network layer for the UDP checksum computation
|
// Set the network layer for the UDP checksum computation
|
||||||
udpLayer.SetNetworkLayerForChecksum(ipLayer)
|
err := udpLayer.SetNetworkLayerForChecksum(ipLayer)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to set the network layer for the UDP checksum computation: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize the modified packet
|
// Serialize the modified packet
|
||||||
buf := gopacket.NewSerializeBuffer()
|
buf := gopacket.NewSerializeBuffer()
|
||||||
|
@ -56,7 +63,7 @@ func HandleDHCPResponse(packet gopacket.Packet, srcSocket, dstSocket int, srcNam
|
||||||
FixLengths: true,
|
FixLengths: true,
|
||||||
ComputeChecksums: true,
|
ComputeChecksums: true,
|
||||||
}
|
}
|
||||||
err := gopacket.SerializeLayers(buf, opts, ethLayer, ipLayer, udpLayer, dhcp)
|
err = gopacket.SerializeLayers(buf, opts, ethLayer, ipLayer, udpLayer, dhcp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error serializing DHCP response: %v", err)
|
log.Errorf("Error serializing DHCP response: %v", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -145,21 +145,23 @@ func forwardPackets(srcSocket, dstSocket int, srcName string, dstName string) {
|
||||||
packet := gopacket.NewPacket(readBuf[:n], layers.LayerTypeEthernet, gopacket.Default)
|
packet := gopacket.NewPacket(readBuf[:n], layers.LayerTypeEthernet, gopacket.Default)
|
||||||
|
|
||||||
if packet.ErrorLayer() != nil {
|
if packet.ErrorLayer() != nil {
|
||||||
log.Errorf("Packet is not in Ethernet format: %v", packet.ErrorLayer().Error())
|
log.Warningf("Packet is not in Ethernet format: %v\n%s", packet.ErrorLayer().Error(), packet)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ethLayer := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
ethLayer := packet.Layer(layers.LayerTypeEthernet).(*layers.Ethernet)
|
||||||
if ethLayer == nil {
|
if ethLayer == nil {
|
||||||
log.Error("Packet does not have Ethernet layer.")
|
log.Warningf("Packet does not have Ethernet layer:\n%s", packet)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipv4Layer := packet.Layer(layers.LayerTypeIPv4)
|
||||||
|
|
||||||
arpLayer := packet.Layer(layers.LayerTypeARP)
|
arpLayer := packet.Layer(layers.LayerTypeARP)
|
||||||
if arpLayer != nil {
|
if arpLayer != nil {
|
||||||
arpPacket := arpLayer.(*layers.ARP)
|
arpPacket := arpLayer.(*layers.ARP)
|
||||||
if arpPacket.Operation == layers.ARPRequest {
|
if arpPacket.Operation == layers.ARPRequest {
|
||||||
arp.HandleARPRequest(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, wlan0MAC, eth0)
|
arp.HandleARPRequest(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, eth0MAC, wlan0MAC, eth0)
|
||||||
continue
|
continue
|
||||||
} else if arpPacket.Operation == layers.ARPReply {
|
} else if arpPacket.Operation == layers.ARPReply {
|
||||||
arp.HandleARPResponse(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, eth0MAC)
|
arp.HandleARPResponse(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, eth0MAC)
|
||||||
|
@ -171,7 +173,7 @@ func forwardPackets(srcSocket, dstSocket int, srcName string, dstName string) {
|
||||||
if udpLayer != nil {
|
if udpLayer != nil {
|
||||||
udp := udpLayer.(*layers.UDP)
|
udp := udpLayer.(*layers.UDP)
|
||||||
if udp.SrcPort == layers.UDPPort(67) && udp.DstPort == layers.UDPPort(68) {
|
if udp.SrcPort == layers.UDPPort(67) && udp.DstPort == layers.UDPPort(68) {
|
||||||
dhcp.HandleDHCPResponse(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, wlan0MAC, dhcpModifyClientSrc, eth0)
|
dhcp.HandleDHCPResponse(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, eth0MAC, wlan0MAC, dhcpModifyClientSrc, eth0)
|
||||||
continue
|
continue
|
||||||
} else if udp.SrcPort == layers.UDPPort(68) && udp.DstPort == layers.UDPPort(67) {
|
} else if udp.SrcPort == layers.UDPPort(68) && udp.DstPort == layers.UDPPort(67) {
|
||||||
dhcp.HandleDHCPRequest(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, dhcpModifyClientSrc)
|
dhcp.HandleDHCPRequest(packet, srcSocket, dstSocket, srcName, dstName, srcMAC, dstMAC, dhcpModifyClientSrc)
|
||||||
|
@ -186,12 +188,10 @@ func forwardPackets(srcSocket, dstSocket int, srcName string, dstName string) {
|
||||||
rawPacket := readBuf[:n]
|
rawPacket := readBuf[:n]
|
||||||
|
|
||||||
if len(rawPacket) < 14 {
|
if len(rawPacket) < 14 {
|
||||||
fmt.Println("too short")
|
log.Warningf("Packet too short (is this a bug??):\n%s", packet)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv4Layer := packet.Layer(layers.LayerTypeIPv4)
|
|
||||||
|
|
||||||
// Check if the packet is addressed for eth0
|
// Check if the packet is addressed for eth0
|
||||||
if bytes.Equal(ethLayer.DstMAC, eth0MAC) {
|
if bytes.Equal(ethLayer.DstMAC, eth0MAC) {
|
||||||
copy(rawPacket[0:6], gatewayMAC) // Modify the destination to gatewayMAC
|
copy(rawPacket[0:6], gatewayMAC) // Modify the destination to gatewayMAC
|
||||||
|
@ -223,7 +223,7 @@ func forwardPackets(srcSocket, dstSocket int, srcName string, dstName string) {
|
||||||
|
|
||||||
// Modify the source MAC address directly in the raw packet data
|
// Modify the source MAC address directly in the raw packet data
|
||||||
copy(rawPacket[6:12], srcMAC)
|
copy(rawPacket[6:12], srcMAC)
|
||||||
} else {
|
} else if printPackets {
|
||||||
log.Debugf("Packet was not IPv4!\n%s", packet)
|
log.Debugf("Packet was not IPv4!\n%s", packet)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,30 @@ func forwardPackets(srcSocket, dstSocket int, srcName string, dstName string) {
|
||||||
if printPackets {
|
if printPackets {
|
||||||
log.Debugf("Forwarded packet from %s to %s:\n%s", srcName, dstName, packet)
|
log.Debugf("Forwarded packet from %s to %s:\n%s", srcName, dstName, packet)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Forwarded packet from %s to %s", srcName, dstName)
|
var arrow string
|
||||||
|
if srcName == wlan0 {
|
||||||
|
arrow = fmt.Sprintf("%s <- %s", eth0, wlan0)
|
||||||
|
} else {
|
||||||
|
arrow = fmt.Sprintf("%s -> %s", eth0, wlan0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipv4Layer != nil {
|
||||||
|
ipv4Packet := ipv4Layer.(*layers.IPv4)
|
||||||
|
clientMAC, found := arp.GetClientMACByIP(ipv4Packet.DstIP)
|
||||||
|
var macADDR string
|
||||||
|
if found {
|
||||||
|
macADDR = net.HardwareAddr(clientMAC).String()
|
||||||
|
} else {
|
||||||
|
macADDR = ":::::"
|
||||||
|
}
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"iface": srcName,
|
||||||
|
"IP": ipv4Packet.DstIP.String(),
|
||||||
|
"MAC": macADDR,
|
||||||
|
}).Debugf("Forwarded packet: %s", arrow)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Forwarded packet: %s", arrow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(1 * time.Millisecond)
|
time.Sleep(1 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue