Use NextHeader as a fallback for unknown IPv6 protocols

This commit is contained in:
Patrick Pacher
2020-07-31 15:15:38 +02:00
parent 9639775ad7
commit 4d56752989
3 changed files with 17 additions and 48 deletions

View File

@@ -79,20 +79,9 @@ func interceptionPrep() (err error) {
func interceptionStart() error { func interceptionStart() error {
startAPIAuth() startAPIAuth()
interceptionModule.StartWorker("stat logger", func(ctx context.Context) error { interceptionModule.StartWorker("stat logger", statLogger)
statLogger() interceptionModule.StartWorker("packet handler", packetHandler)
return nil interceptionModule.StartWorker("ports state cleaner", portsInUseCleaner)
})
interceptionModule.StartWorker("packet handler", func(ctx context.Context) error {
run()
return nil
})
interceptionModule.StartWorker("ports state cleaner", func(ctx context.Context) error {
portsInUseCleaner()
return nil
})
return interception.Start() return interception.Start()
} }
@@ -328,22 +317,22 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
// return // return
// } // }
func run() { func packetHandler(ctx context.Context) error {
for { for {
select { select {
case <-interceptionModule.Stopping(): case <-ctx.Done():
return return nil
case pkt := <-interception.Packets: case pkt := <-interception.Packets:
handlePacket(pkt) handlePacket(pkt)
} }
} }
} }
func statLogger() { func statLogger(ctx context.Context) error {
for { for {
select { select {
case <-interceptionModule.Stopping(): case <-ctx.Done():
return return nil
case <-time.After(10 * time.Second): case <-time.After(10 * time.Second):
log.Tracef( log.Tracef(
"filter: packets accepted %d, blocked %d, dropped %d, failed %d", "filter: packets accepted %d, blocked %d, dropped %d, failed %d",

View File

@@ -1,6 +1,7 @@
package firewall package firewall
import ( import (
"context"
"sync" "sync"
"time" "time"
@@ -69,11 +70,11 @@ func GetPermittedPort() uint16 {
return 0 return 0
} }
func portsInUseCleaner() { func portsInUseCleaner(ctx context.Context) error {
for { for {
select { select {
case <-interceptionModule.Stopping(): case <-ctx.Done():
return return nil
case <-time.After(cleanerTickDuration): case <-time.After(cleanerTickDuration):
cleanPortsInUse() cleanPortsInUse()
} }

View File

@@ -6,7 +6,6 @@ import (
"github.com/google/gopacket" "github.com/google/gopacket"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/safing/portbase/log"
) )
var layerType2IPProtocol map[gopacket.LayerType]IPProtocol var layerType2IPProtocol map[gopacket.LayerType]IPProtocol
@@ -33,6 +32,10 @@ func parseIPv6(packet gopacket.Packet, info *Info) error {
info.Version = IPv6 info.Version = IPv6
info.Src = ipv6.SrcIP info.Src = ipv6.SrcIP
info.Dst = ipv6.DstIP info.Dst = ipv6.DstIP
// we set Protocol to NextHeader as a fallback. If TCP or
// UDP layers are detected (somewhere in the list of options)
// the Protocol field is adjusted correctly.
info.Protocol = IPProtocol(ipv6.NextHeader)
} }
return nil return nil
} }
@@ -96,21 +99,6 @@ func checkError(packet gopacket.Packet, _ *Info) error {
return nil return nil
} }
func tryFindIPv6TransportProtocol(packet gopacket.Packet, info *Info) {
if transport := packet.TransportLayer(); transport != nil {
proto, ok := layerType2IPProtocol[transport.LayerType()]
if ok {
info.Protocol = proto
log.Tracef("packet: unsupported IPv6 protocol %02x (%d)", proto)
} else {
log.Warningf("packet: unsupported or unknown gopacket layer type: %d", transport.LayerType())
}
return
}
log.Tracef("packet: failed to get IPv6 transport protocol number")
}
// Parse parses an IP packet and saves the information in the given packet object. // Parse parses an IP packet and saves the information in the given packet object.
func Parse(packetData []byte, pktInfo *Info) error { func Parse(packetData []byte, pktInfo *Info) error {
if len(packetData) == 0 { if len(packetData) == 0 {
@@ -129,9 +117,6 @@ func Parse(packetData []byte, pktInfo *Info) error {
return fmt.Errorf("unknown IP version or network protocol: %02x", ipVersion) return fmt.Errorf("unknown IP version or network protocol: %02x", ipVersion)
} }
// 255 is reserved by IANA so we use it as a "failed-to-detect" marker.
pktInfo.Protocol = 255
packet := gopacket.NewPacket(packetData, networkLayerType, gopacket.DecodeOptions{ packet := gopacket.NewPacket(packetData, networkLayerType, gopacket.DecodeOptions{
Lazy: true, Lazy: true,
NoCopy: true, NoCopy: true,
@@ -155,12 +140,6 @@ func Parse(packetData []byte, pktInfo *Info) error {
} }
} }
// 255 is reserved by IANA and used as a "failed-to-detect"
// marker for IPv6 (parseIPv4 always sets the protocl field)
if pktInfo.Protocol == 255 {
tryFindIPv6TransportProtocol(packet, pktInfo)
}
return nil return nil
} }