mirror of
https://github.com/safing/portmaster
synced 2025-09-02 02:29:12 +00:00
Add ICMP listener
This commit is contained in:
parent
5d61b7b682
commit
259a0a8b22
2 changed files with 98 additions and 2 deletions
|
@ -139,15 +139,29 @@ func fastTrackedPermit(pkt packet.Packet) (handled bool) {
|
||||||
|
|
||||||
switch meta.Protocol {
|
switch meta.Protocol {
|
||||||
case packet.ICMP:
|
case packet.ICMP:
|
||||||
|
// Submit to ICMP listener.
|
||||||
|
submitted := netenv.SubmitPacketToICMPListener(pkt)
|
||||||
|
|
||||||
// Always permit ICMP.
|
// Always permit ICMP.
|
||||||
log.Debugf("filter: fast-track accepting ICMP: %s", pkt)
|
log.Debugf("filter: fast-track accepting ICMP: %s", pkt)
|
||||||
|
if submitted {
|
||||||
|
_ = pkt.Accept()
|
||||||
|
} else {
|
||||||
_ = pkt.PermanentAccept()
|
_ = pkt.PermanentAccept()
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case packet.ICMPv6:
|
case packet.ICMPv6:
|
||||||
|
// Submit to ICMP listener.
|
||||||
|
submitted := netenv.SubmitPacketToICMPListener(pkt)
|
||||||
|
|
||||||
// Always permit ICMPv6.
|
// Always permit ICMPv6.
|
||||||
log.Debugf("filter: fast-track accepting ICMPv6: %s", pkt)
|
log.Debugf("filter: fast-track accepting ICMPv6: %s", pkt)
|
||||||
|
if submitted {
|
||||||
|
_ = pkt.Accept()
|
||||||
|
} else {
|
||||||
_ = pkt.PermanentAccept()
|
_ = pkt.PermanentAccept()
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case packet.UDP, packet.TCP:
|
case packet.UDP, packet.TCP:
|
||||||
|
|
82
netenv/icmp_listener.go
Normal file
82
netenv/icmp_listener.go
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
package netenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/tevino/abool"
|
||||||
|
|
||||||
|
"github.com/safing/portbase/log"
|
||||||
|
"github.com/safing/portmaster/network/packet"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// listenICMPLock locks the ICMP listening system for one user at a time.
|
||||||
|
listenICMPLock sync.Mutex
|
||||||
|
|
||||||
|
// listenICMPEnabled defines whether or not the firewall should send ICMP
|
||||||
|
// packets through this interface.
|
||||||
|
listenICMPEnabled = abool.New()
|
||||||
|
|
||||||
|
// listenICMPInput is created for every use of the ICMP listenting system.
|
||||||
|
listenICMPInput chan packet.Packet
|
||||||
|
listenICMPInputLock sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
|
func ListenToICMP() (packets chan packet.Packet, done func()) {
|
||||||
|
// Lock for single use.
|
||||||
|
listenICMPLock.Lock()
|
||||||
|
|
||||||
|
// Create new input channel.
|
||||||
|
listenICMPInputLock.Lock()
|
||||||
|
listenICMPInput = make(chan packet.Packet, 10)
|
||||||
|
listenICMPEnabled.Set()
|
||||||
|
listenICMPInputLock.Unlock()
|
||||||
|
|
||||||
|
return listenICMPInput, func() {
|
||||||
|
// Close input channel.
|
||||||
|
listenICMPInputLock.Lock()
|
||||||
|
listenICMPEnabled.UnSet()
|
||||||
|
close(listenICMPInput)
|
||||||
|
listenICMPInputLock.Unlock()
|
||||||
|
|
||||||
|
// Release for someone else to use.
|
||||||
|
listenICMPLock.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SubmitPacketToICMPListener(pkt packet.Packet) (submitted bool) {
|
||||||
|
// Hot path.
|
||||||
|
if !listenICMPEnabled.IsSet() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path.
|
||||||
|
submitPacketToICMPListenerSlow(pkt)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func submitPacketToICMPListenerSlow(pkt packet.Packet) {
|
||||||
|
// Make sure the payload is available.
|
||||||
|
if err := pkt.LoadPacketData(); err != nil {
|
||||||
|
log.Warningf("netenv: failed to get payload for ICMP listener: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to input channel.
|
||||||
|
listenICMPInputLock.Lock()
|
||||||
|
defer listenICMPInputLock.Unlock()
|
||||||
|
|
||||||
|
// Check if still enabled.
|
||||||
|
if !listenICMPEnabled.IsSet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Criticalf("netenv: recvd ICMP packet: %s", pkt)
|
||||||
|
|
||||||
|
// Send to channel, if possible.
|
||||||
|
select {
|
||||||
|
case listenICMPInput <- pkt:
|
||||||
|
default:
|
||||||
|
log.Warning("netenv: failed to send packet payload to ICMP listener: channel full")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue