diff --git a/util/usermetric/metrics.go b/util/usermetric/metrics.go index 0c5511759..044b4d65f 100644 --- a/util/usermetric/metrics.go +++ b/util/usermetric/metrics.go @@ -41,6 +41,9 @@ const ( // ReasonFragment means that the packet was dropped because it was an IP fragment. ReasonFragment DropReason = "fragment" + // ReasonUnknownProtocol means that the packet was dropped because it was an unknown protocol. + ReasonUnknownProtocol DropReason = "unknown_protocol" + // ReasonError means that the packet was dropped because of an error. ReasonError DropReason = "error" ) diff --git a/wgengine/filter/filter.go b/wgengine/filter/filter.go index 6269b08eb..987fcee01 100644 --- a/wgengine/filter/filter.go +++ b/wgengine/filter/filter.go @@ -621,6 +621,11 @@ func (f *Filter) pre(q *packet.Parsed, rf RunFlags, dir direction) (Response, us return Drop, usermetric.ReasonTooShort } + if q.IPProto == ipproto.Unknown { + f.logRateLimit(rf, q, dir, Drop, "unknown proto") + return Drop, usermetric.ReasonUnknownProtocol + } + if q.Dst.Addr().IsMulticast() { f.logRateLimit(rf, q, dir, Drop, "multicast") return Drop, usermetric.ReasonMulticast diff --git a/wgengine/filter/filter_test.go b/wgengine/filter/filter_test.go index 68f206778..ae39eeb08 100644 --- a/wgengine/filter/filter_test.go +++ b/wgengine/filter/filter_test.go @@ -390,7 +390,8 @@ func TestPreFilter(t *testing.T) { }{ {"empty", Accept, "", []byte{}}, {"short", Drop, usermetric.ReasonTooShort, []byte("short")}, - {"junk", Drop, "", raw4default(ipproto.Unknown, 10)}, + {"short-junk", Drop, usermetric.ReasonTooShort, raw4default(ipproto.Unknown, 10)}, + {"long-junk", Drop, usermetric.ReasonUnknownProtocol, raw4default(ipproto.Unknown, 21)}, {"fragment", Accept, "", raw4default(ipproto.Fragment, 40)}, {"tcp", noVerdict, "", raw4default(ipproto.TCP, 0)}, {"udp", noVerdict, "", raw4default(ipproto.UDP, 0)},