172 lines
3.5 KiB
Go
172 lines
3.5 KiB
Go
package pcap
|
|
|
|
import (
|
|
"github.com/google/gopacket"
|
|
"github.com/google/gopacket/layers"
|
|
)
|
|
|
|
type PacketType int
|
|
|
|
const (
|
|
PacketTypeUnknown PacketType = iota
|
|
PacketTypeARP
|
|
PacketTypeICMPv4
|
|
PacketTypeICMPv6
|
|
PacketTypeTCP
|
|
PacketTypeUDP
|
|
)
|
|
|
|
func getPacketType(packet gopacket.Packet) PacketType {
|
|
if packet == nil {
|
|
return PacketTypeUnknown
|
|
}
|
|
layer := packet.Layer(layers.LayerTypeARP)
|
|
if layer != nil {
|
|
return PacketTypeARP
|
|
}
|
|
|
|
layer = packet.Layer(layers.LayerTypeICMPv4)
|
|
if layer != nil {
|
|
return PacketTypeICMPv4
|
|
}
|
|
|
|
layer = packet.Layer(layers.LayerTypeICMPv6)
|
|
if layer != nil {
|
|
return PacketTypeICMPv6
|
|
}
|
|
|
|
layer = packet.Layer(layers.LayerTypeTCP)
|
|
if layer != nil {
|
|
if _, ok := layer.(*layers.TCP); ok {
|
|
return PacketTypeTCP
|
|
}
|
|
}
|
|
|
|
layer = packet.Layer(layers.LayerTypeUDP)
|
|
if layer != nil {
|
|
if _, ok := layer.(*layers.UDP); ok {
|
|
return PacketTypeUDP
|
|
}
|
|
}
|
|
return PacketTypeUnknown
|
|
}
|
|
|
|
func handlePacket(ps *pCapScan, packet gopacket.Packet) {
|
|
switch getPacketType(packet) {
|
|
case PacketTypeARP:
|
|
handlePacketARP(ps, packet)
|
|
case PacketTypeICMPv4:
|
|
handlePacketICMP4(ps, packet)
|
|
case PacketTypeICMPv6:
|
|
handlePacketICMP6(ps, packet)
|
|
case PacketTypeTCP:
|
|
handlePacketTCP(ps, packet)
|
|
case PacketTypeUDP:
|
|
handlePacketUDP(ps, packet)
|
|
default:
|
|
}
|
|
}
|
|
|
|
func handlePacketARP(ps *pCapScan, packet gopacket.Packet) {
|
|
ps.arpListenerChanMtx.RLock()
|
|
defer ps.arpListenerChanMtx.RUnlock()
|
|
|
|
arpLayer := packet.Layer(layers.LayerTypeARP)
|
|
arp := arpLayer.(*layers.ARP)
|
|
|
|
for _, ch := range ps.arpListenerChans {
|
|
ch <- arp
|
|
// select {
|
|
// case ch <- arp:
|
|
// default:
|
|
// log.Print("handlePacketARP cannot send to channel")
|
|
// }
|
|
}
|
|
}
|
|
|
|
func handlePacketICMP4(ps *pCapScan, packet gopacket.Packet) {
|
|
ps.icmp4ListenerChanMtx.RLock()
|
|
defer ps.icmp4ListenerChanMtx.RUnlock()
|
|
|
|
// icmp4Layer := packet.Layer(layers.LayerTypeICMPv4)
|
|
// icmp4 := icmp4Layer.(*layers.ICMPv4)
|
|
|
|
for _, ch := range ps.icmp4ListenerChans {
|
|
ch <- packet
|
|
// select {
|
|
// case ch <- packet:
|
|
// default:
|
|
// log.Print("handlePacketICMP4 cannot send to channel")
|
|
// }
|
|
}
|
|
}
|
|
|
|
func handlePacketICMP6(ps *pCapScan, packet gopacket.Packet) {
|
|
ps.icmp6ListenerChanMtx.RLock()
|
|
defer ps.icmp6ListenerChanMtx.RUnlock()
|
|
|
|
// icmp6Layer := packet.Layer(layers.LayerTypeICMPv6)
|
|
// icmp6 := icmp6Layer.(*layers.ICMPv6)
|
|
|
|
for _, ch := range ps.icmp6ListenerChans {
|
|
ch <- packet
|
|
// select {
|
|
// case ch <- packet:
|
|
// default:
|
|
// log.Print("handlePacketICMP6 cannot send to channel")
|
|
// }
|
|
}
|
|
}
|
|
|
|
func handlePacketTCP(ps *pCapScan, packet gopacket.Packet) {
|
|
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
|
if nil == ipLayer {
|
|
return
|
|
}
|
|
|
|
ip := ipLayer.(*layers.IPv4).SrcIP.String()
|
|
layer := packet.Layer(layers.LayerTypeTCP)
|
|
tcp, _ := layer.(*layers.TCP)
|
|
|
|
ps.tcpListenerChanMtx.RLock()
|
|
defer func() {
|
|
ps.tcpListenerChanMtx.RUnlock()
|
|
}()
|
|
|
|
chs, ok := ps.tcpListenerChans[ip]
|
|
if ok {
|
|
for _, ch := range chs {
|
|
ch <- tcp
|
|
// select {
|
|
// case ch <- tcp:
|
|
// default:
|
|
// log.Print("handlePacketTCP cannot send to channel")
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
func handlePacketUDP(ps *pCapScan, packet gopacket.Packet) {
|
|
ipLayer := packet.Layer(layers.LayerTypeIPv4)
|
|
if nil == ipLayer {
|
|
return
|
|
}
|
|
|
|
ip := ipLayer.(*layers.IPv4).SrcIP.String()
|
|
|
|
ps.udpListenerChanMtx.RLock()
|
|
defer ps.udpListenerChanMtx.RUnlock()
|
|
|
|
chs, ok := ps.udpListenerChans[ip]
|
|
if ok {
|
|
for _, ch := range chs {
|
|
ch <- packet
|
|
// select {
|
|
// case ch <- packet:
|
|
// default:
|
|
// log.Print("handlePacketUDP cannot send to channel")
|
|
// }
|
|
}
|
|
}
|
|
}
|