Repository: netty/netty
Issue: IpSubnetFilterRule throws ClassCastException when non expected IP version comes
Labels: defect

### Expected behavior

No error. `IpSubnetFilterRule.match` returns false.

### Actual behavior

`IpSubnetFilterRule.match` throws `ClassCastException`.

### Steps to reproduce

```
IpSubnetFilterRule rule = new IpSubnetFilterRule("0.0.0.0", 0, IpFilterRuleType.ACCEPT);

//remoteAddress.getAddress() instanceof Inet6Address
rule.matches(remoteAddress); //throws ClassCastException
```

### Minimal yet complete reproducer code (or URL to code)

```
    @Test
    public void testIpv4SubnetMaskCorrectlyHandlesIpv6() {
        IpSubnetFilterRule rule = new IpSubnetFilterRule("0.0.0.0", 0, IpFilterRuleType.ACCEPT);
        Assert.assertFalse(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
    }
```

### Netty version

4.1.9-Final



Issue comments:
Fixed by https://github.com/netty/netty/pull/6658

Pull request review comments:

Patch that resolved the issue:
diff --git a/handler/src/main/java/io/netty/handler/ipfilter/IpSubnetFilterRule.java b/handler/src/main/java/io/netty/handler/ipfilter/IpSubnetFilterRule.java
index abcb150687f..b6c2e83ebca 100644
--- a/handler/src/main/java/io/netty/handler/ipfilter/IpSubnetFilterRule.java
+++ b/handler/src/main/java/io/netty/handler/ipfilter/IpSubnetFilterRule.java
@@ -91,9 +91,12 @@ private Ip4SubnetFilterRule(Inet4Address ipAddress, int cidrPrefix, IpFilterRule
 
         @Override
         public boolean matches(InetSocketAddress remoteAddress) {
-            int ipAddress = ipToInt((Inet4Address) remoteAddress.getAddress());
-
-            return (ipAddress & subnetMask) == networkAddress;
+            final InetAddress inetAddress = remoteAddress.getAddress();
+            if (inetAddress instanceof Inet4Address) {
+                int ipAddress = ipToInt((Inet4Address) inetAddress);
+                return (ipAddress & subnetMask) == networkAddress;
+            }
+            return false;
         }
 
         @Override
@@ -147,9 +150,12 @@ private Ip6SubnetFilterRule(Inet6Address ipAddress, int cidrPrefix, IpFilterRule
 
         @Override
         public boolean matches(InetSocketAddress remoteAddress) {
-            BigInteger ipAddress = ipToInt((Inet6Address) remoteAddress.getAddress());
-
-            return ipAddress.and(subnetMask).equals(networkAddress);
+            final InetAddress inetAddress = remoteAddress.getAddress();
+            if (inetAddress instanceof Inet6Address) {
+                BigInteger ipAddress = ipToInt((Inet6Address) inetAddress);
+                return ipAddress.and(subnetMask).equals(networkAddress);
+            }
+            return false;
         }
 
         @Override


Test patch:
diff --git a/handler/src/test/java/io/netty/handler/ipfilter/IpSubnetFilterTest.java b/handler/src/test/java/io/netty/handler/ipfilter/IpSubnetFilterTest.java
index e93908b67cf..0be4cab797d 100644
--- a/handler/src/test/java/io/netty/handler/ipfilter/IpSubnetFilterTest.java
+++ b/handler/src/test/java/io/netty/handler/ipfilter/IpSubnetFilterTest.java
@@ -38,6 +38,18 @@ public void testIpv4DefaultRoute() {
         Assert.assertTrue(rule.matches(newSockAddress("192.168.93.2")));
     }
 
+    @Test
+    public void testIpv4SubnetMaskCorrectlyHandlesIpv6() {
+        IpSubnetFilterRule rule = new IpSubnetFilterRule("0.0.0.0", 0, IpFilterRuleType.ACCEPT);
+        Assert.assertFalse(rule.matches(newSockAddress("2001:db8:abcd:0000::1")));
+    }
+
+    @Test
+    public void testIpv6SubnetMaskCorrectlyHandlesIpv4() {
+        IpSubnetFilterRule rule = new IpSubnetFilterRule("::", 0, IpFilterRuleType.ACCEPT);
+        Assert.assertFalse(rule.matches(newSockAddress("91.114.240.43")));
+    }
+
     @Test
     public void testIp4SubnetFilterRule() throws Exception {
         IpSubnetFilterRule rule = new IpSubnetFilterRule("192.168.56.1", 24, IpFilterRuleType.ACCEPT);