probe/internal/pcap/packet.go
2018-08-29 13:08:37 +09:00

107 lines
2.0 KiB
Go

package pcap
import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
type PacketType int
const (
PacketTypeUnknown PacketType = iota
PacketTypeARP
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.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 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
}
}
func handlePacketTCP(ps *pCapScan, packet gopacket.Packet) {
ipLayer := packet.Layer(layers.LayerTypeIPv4)
if nil == ipLayer {
return
}
ip := ipLayer.(*layers.IPv4).SrcIP.String()
ps.tcpListenerChanMtx.RLock()
defer ps.tcpListenerChanMtx.RUnlock()
chs, ok := ps.tcpListenerChans[ip]
if ok {
layer := packet.Layer(layers.LayerTypeTCP)
tcp, _ := layer.(*layers.TCP)
for _, ch := range chs {
ch <- tcp
}
}
}
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
}
}
}