Unlike subnet masks, wildcard masks allow you to use discontiguous bits which enable you to match on a range of values. Using these within routing protocols is typically frowned upon, if not outright prohibited. Unfortunately, there are those individuals who strive to trim every line they can from their ACLs. Can you say job security through routing obscurity? The downside to using these masks is that the more complex they get, the more unintentional traffic they allow in. In all sense of reality, they should never be used in production networks.
I’ll reiterate that statement. Do not use in productions networks unless you know, and completely understand the consequences!
An Illogical Example
For our first example, lets take 3 random /24s and match them with one single statement. The first thing we have to do is come up with your network address. After we convert our networks to binary, we need to perform AND logic on them. The result will be our network address.
18.104.22.168/24 - 01001010 . 00010010 . 00010111 . 00000000 22.214.171.124/24 - 01000100 . 00100010 . 00001110 . 00000000 126.96.36.199/24 - 01010100 . 00110011 . 00010100 . 00000000 AND Result ---- 01000000 . 00000010 . 00000100 . 00000000 = 188.8.131.52
Now that we have our network address we a wildcard mask to go with it. This time, we’re going to use XOR logic to calculate it.
184.108.40.206/24 - 01001010 . 00010010 . 00010111 . 00000000 220.127.116.11/24 - 01000100 . 00100010 . 00001110 . 00000000 18.104.22.168/24 - 01010100 . 00110011 . 00010100 . 00000000 XOR Result ---- 00011110 . 00110001 . 00011011 . 00000000 = 22.214.171.124
Now, something should strike you as odd, since we’re matching subnets, and not specific IP addresses, we need to change the last octet in our wildcard mask to 255. Remember, a bit set to 0 means ‘must match’, and a 1 equals ‘don’t care’. So, when complete, our ACL should look something like this.
access-list 1 permit 126.96.36.199 188.8.131.52
This brings up the point of avoiding their use in production networks again… since our mask has 18 bits set to 1, aka ‘don’t care’, this ACL will permit a total of 2^10, or 262,144 IP addresses. This means 1 in 16,384 (2^14) randomly chosen IP addresses would be allowed in through this ACL.
A Better Example
A slightly more realistic example would be a more simple match of two /32s, or single IP addresses. First, lets build our wildcard mask.
184.108.40.206 - 00001100 . 00010010 . 00010111 . 00000101 220.127.116.11 - 00001100 . 00010010 . 00010110 . 00000110 AND Result - 00001100 . 00010010 . 00010110 . 00000100 = 18.104.22.168
Using the same methods as before, we can calculate the network address.
22.214.171.124 - 00001100 . 00010010 . 00010111 . 00000101 126.96.36.199 - 00001100 . 00010010 . 00010110 . 00000110 XOR Result - 00000000 . 00000000 . 00000001 . 00000011 = 0.0.1.3
As a result, our ACL should look just like this.
access-list 2 permit 188.8.131.52 0.0.1.3
Now, before we get too far with this, since we may be allowing more addresses than intended, we should learn how to examine what will be allowed through and what will be denied. For example, let’s say that we need to ensure that this access-list did NOT permit a specific IP address. For this example, we’ll use 184.108.40.206
To check an address against the ACL we need to build a filter that we can compare against. Basically, any bits that are 0 in the wildcard mask must match. Any bits that are set to 1, we don’t care about. I’ll mark those with an ‘x’.
Network Ad. - 00001100 . 00010010 . 00010110 . 00000100 Wildcard Mask - 00000000 . 00000000 . 00000001 . 00000011 Filter - 00001100 . 00010010 . 0001011x . 000001xx
Using this filter, we can compare it to our test IP and see if it will pass through the ACL.
220.127.116.11 - 00001100 . 00010010 . 00010110 . 00001000 Filter - 00001100 . 00010010 . 0001011x . 000001xx
As you can see, in the last octet we have a discrepancy. 18.104.22.168 will NOT pass through our ACL.
Some Random Matches
So, now that we’ve explored the concepts, lets build some totally off the wall ACLs. For our first trick, lets say you wanted an ACL that matches on all IP address with a last octet of .1 — You would end up with something like this.
access-list 20 permit 0.0.0.1 255.255.255.254 ! ! or, only match inside 10.0.0.0/8 access-list 21 permit 10.0.0.1 0.255.255.254
How about a couple ACLs that only matches IPs with all odd, or even octets?
! Even access-list 30 0.0.0.0 254.254.254.254 ! Odd access-list 31 22.214.171.124 254.254.254.254
Another trick, that will probably never come in handy is matching every n-th network, or IP address. For example, lets match every 4th, or 8th network address inside 10.1.0.0/16.
! Match any ip in every 4th /24 network access-list 40 10.1.0.0 0.0.252.255 ! Match any ip in every 8th /24 network access-list 40 10.1.0.0 0.0.248.255
The way this works is quite simple. We just mark everything left of (and including) our starting point to ignore. Since we know everything to the left of 2^4 is a factor of 4 we want to only match addresses in those bits. So, we ignore them, and insure that everything to the right is matched, and equals 0. This means, that address that is matched, must be a factor of 4.
128 64 32 16 8 4 2 1 1 1 1 1 1 1 0 0 = 252 1 1 1 1 1 0 0 0 = 248
Obviously, this can get ridiculous if left to your imagination. Wildcard masks can seem archaic at first, but once you learn how useful they can truly be you will never look back. Remember that if choose to use these in a production network, be careful. Do NOT build masks with 10+ bits set to ignore, you will not be happy with the results, nor will your boss.
As usual, if you have any questions or concerns please leave a comment below. Thanks!