|
|
@@ -25,6 +25,8 @@ var (
|
|
|
|
|
|
linkLocalMulticastIPv4Range = netip.MustParsePrefix("224.0.0.0/24")
|
|
|
linkLocalMulticastIPv6Range = netip.MustParsePrefix("ff02::/16")
|
|
|
+
|
|
|
+ limitedBroadcast = netip.MustParsePrefix("255.255.255.255/32")
|
|
|
)
|
|
|
|
|
|
type direction int
|
|
|
@@ -233,26 +235,41 @@ func (f *Firewall) UpdatePermittedRoutes(newRoutes []netip.Prefix) error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- name = "link-local multicast - " + r.String()
|
|
|
- conditions = matchLinkLocalMulticast(r, false)
|
|
|
- multicastRules, err := f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionOutbound)
|
|
|
+ multicastRules, err := f.addLinkLocalMulticastRules(p, r)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
rules = append(rules, multicastRules...)
|
|
|
|
|
|
- conditions = matchLinkLocalMulticast(r, true)
|
|
|
- multicastRules, err = f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionInbound)
|
|
|
+ broadcastRules, err := f.addLimitedBroadcastRules(p, r)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- rules = append(rules, multicastRules...)
|
|
|
+ rules = append(rules, broadcastRules...)
|
|
|
|
|
|
f.permittedRoutes[r] = rules
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+// addLinkLocalMulticastRules adds rules to allow inbound and outbound
|
|
|
+// link-local multicast traffic to or from the specified network.
|
|
|
+// It returns the added rules, or an error.
|
|
|
+func (f *Firewall) addLinkLocalMulticastRules(p protocol, r netip.Prefix) ([]*wf.Rule, error) {
|
|
|
+ name := "link-local multicast - " + r.String()
|
|
|
+ conditions := matchLinkLocalMulticast(r, false)
|
|
|
+ outboundRules, err := f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionOutbound)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ conditions = matchLinkLocalMulticast(r, true)
|
|
|
+ inboundRules, err := f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionInbound)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return append(outboundRules, inboundRules...), nil
|
|
|
+}
|
|
|
+
|
|
|
// matchLinkLocalMulticast returns a list of conditions that match
|
|
|
// outbound or inbound link-local multicast traffic to or from the
|
|
|
// specified network.
|
|
|
@@ -288,6 +305,59 @@ func matchLinkLocalMulticast(pfx netip.Prefix, inbound bool) []*wf.Match {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// addLimitedBroadcastRules adds rules to allow inbound and outbound
|
|
|
+// limited broadcast traffic to or from the specified network,
|
|
|
+// if the network is IPv4. It returns the added rules, or an error.
|
|
|
+func (f *Firewall) addLimitedBroadcastRules(p protocol, r netip.Prefix) ([]*wf.Rule, error) {
|
|
|
+ if !r.Addr().Is4() {
|
|
|
+ return nil, nil
|
|
|
+ }
|
|
|
+ name := "broadcast - " + r.String()
|
|
|
+ conditions := matchLimitedBroadcast(r, false)
|
|
|
+ outboundRules, err := f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionOutbound)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ conditions = matchLimitedBroadcast(r, true)
|
|
|
+ inboundRules, err := f.addRules(name, weightKnownTraffic, conditions, wf.ActionPermit, p, directionInbound)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return append(outboundRules, inboundRules...), nil
|
|
|
+}
|
|
|
+
|
|
|
+// matchLimitedBroadcast returns a list of conditions that match
|
|
|
+// outbound or inbound limited broadcast traffic to or from the
|
|
|
+// specified network. It panics if the pfx is not IPv4.
|
|
|
+func matchLimitedBroadcast(pfx netip.Prefix, inbound bool) []*wf.Match {
|
|
|
+ if !pfx.Addr().Is4() {
|
|
|
+ panic("limited broadcast is only applicable to IPv4")
|
|
|
+ }
|
|
|
+ var localAddr, remoteAddr netip.Prefix
|
|
|
+ if inbound {
|
|
|
+ localAddr, remoteAddr = limitedBroadcast, pfx
|
|
|
+ } else {
|
|
|
+ localAddr, remoteAddr = pfx, limitedBroadcast
|
|
|
+ }
|
|
|
+ return []*wf.Match{
|
|
|
+ {
|
|
|
+ Field: wf.FieldIPProtocol,
|
|
|
+ Op: wf.MatchTypeEqual,
|
|
|
+ Value: wf.IPProtoUDP,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Field: wf.FieldIPLocalAddress,
|
|
|
+ Op: wf.MatchTypeEqual,
|
|
|
+ Value: localAddr,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ Field: wf.FieldIPRemoteAddress,
|
|
|
+ Op: wf.MatchTypeEqual,
|
|
|
+ Value: remoteAddr,
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func (f *Firewall) newRule(name string, w weight, layer wf.LayerID, conditions []*wf.Match, action wf.Action) (*wf.Rule, error) {
|
|
|
id, err := windows.GenerateGUID()
|
|
|
if err != nil {
|