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.
74.18.23.0/24 - 01001010 . 00110010 . 00010111 . 00000000 68.34.14.0/24 - 01000100 . 00100010 . 00001110 . 00000000 84.51.20.0/24 - 01010100 . 00110011 . 00010100 . 00000000 AND Result ---- 01000000 . 00100010 . 00000100 . 00000000 = 64.34.4.0
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.
74.18.23.0/24 - 01001010 . 00110010 . 00010111 . 00000000 68.34.14.0/24 - 01000100 . 00100010 . 00001110 . 00000000 84.51.20.0/24 - 01010100 . 00110011 . 00010100 . 00000000 XOR Result ---- 00011110 . 00010001 . 00011011 . 00000000 = 30.17.27.0
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 64.34.4.0 30.17.27.255
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.
12.18.23.5 - 00001100 . 00010010 . 00010111 . 00000101 12.18.22.6 - 00001100 . 00010010 . 00010110 . 00000110 AND Result - 00001100 . 00010010 . 00010110 . 00000100 = 12.18.22.4
Using the same methods as before, we can calculate the network address.
12.18.23.5 - 00001100 . 00010010 . 00010111 . 00000101 12.18.22.6 - 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 12.18.22.4 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 12.18.22.8
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.
12.18.22.8 - 00001100 . 00010010 . 00010110 . 00001000 Filter - 00001100 . 00010010 . 0001011x . 000001xx
As you can see, in the last octet we have a discrepancy. 12.18.22.8 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 1.1.1.1 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
Conclusion
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!


{ 10 comments… read them below or add one }
> Unlike subnet masks, wildcard masks allow you to use discontiguous bits which enable you to match on a range of values.
B-shit. Wildcards are just kinda idiotic inverse netmask neither less nor more. Lots of net software support netmask like 255.0.255.0 absolutely gracefully.
it is not totally a subnetmask, u can do more thing with wildcard , what the netmask cannot do.
Did someone put you up to that idiotic remark ?
I had the same argument with a Cisco Trainer. Cisco choose not to implement discontiguous netmasks even though they are supported in the RFC.
it is not cisco , this is the choice of DOD who choose the way to decide the network and host bits in this way and devided the ip address in classess
74.18.23.0/24 – 01001010 . 00110010 . 00010111 . 00000000
68.34.14.0/24 – 01000100 . 00100010 . 00001110 . 00000000
84.51.20.0/24 – 01010100 . 00110011 . 00010100 . 00000000
XOR Result —- 00011110 . 00010001 . 00011011 . 00000000
Here xor result is not right ,it should be as below:
01011010 . 00100011 . 00001101 . 00000000
The problem is that when you're dealing with multiple values, you can't treat it as a true XOR.. as a true XOR is between 2 values and the order of operations would affect the output. (101=1 110=0, if that makes sense)
In this case, you're looking at a significant, or don't care bit. Thus, if you have 101, your bit has to bet set to 1, because you don't care about this value. It changes between the 3 IPs you're checking against.
Does that make sense?
101: 1)10=1 2)11=0 → 101=0
110: 1)11=0 2)00=0 → 110=0
XOR:
00=0
01=1
10=1
11=0
Not sure what I was thinking when I said 1 xor 0 = 1 xor 1 = 1… but that is not correct. Just proves that we're all human, right?
BUT, when you're setting up a discontiguous mask for 3 or more IP addresses, you need to forget XOR, and simply use your own logic. Is the bit significant or not… in the case of comparing 1, 0, 1.. the bit is NOT significant, thus it will be set to 1…
Maybe it would be best if I rewrote this article to better explain the logic.
>Maybe it would be best if I rewrote this article to better explain the logic.
It would be very kind of you. I'll translate it into Russian. I don't understand the rules for more than two IP adresses or subnets.