I have a solution for when the addresses are stored as strings. So if you wish to make that part of your algorithm, you can use my solution here.
It is a little tricky, especially for IPv6. In IPv6 there can optionally be compressed segments, like 1::1 which is equivalent to 1:0:0:0:0:0:0:1, which is the main reason it is tricky.
The IPAddress Java library will produce mysql SQL to search for addresses in a given subnet. The link describes this problem in more detail. Disclaimer: I am the project manager.
The basic algorithm is to take the network section of the subnet address, then take each variant of that section (for example the two strings above are variants of the full address 1::1), then count the number of segment separators, then do a mysql substring on the address being matched, but also count the total separators in the address being matched.
Here is sample code:
public static void main(String[] args) throws IPAddressStringException {
System.out.println(getSearchSQL("columnX", "1.2.3.4/16"));
System.out.println(getSearchSQL("columnX", "1:2:3:4:5:6:7:8/64"));
System.out.println(getSearchSQL("columnX", "1::8/64"));
}
static String getSearchSQL(String expression, String ipAddressStr) throws IPAddressStringException {
IPAddressString ipAddressString = new IPAddressString(ipAddressStr);
IPAddress ipAddress = ipAddressString.toAddress();
IPAddressSection networkPrefix = ipAddress.getNetworkSection(ipAddress.getNetworkPrefixLength(), false);
StringBuilder sql = new StringBuilder("Select rows from table where ");
networkPrefix.getStartsWithSQLClause(sql, expression);
return sql.toString();
}
Ouptut:
Select rows from table where (substring_index(columnX,'.',2) = '1.2')
Select rows from table where (substring_index(columnX,':',4) = '1:2:3:4')
Select rows from table where ((substring_index(columnX,':',4) = '1:0:0:0') OR ((substring_index(columnX,':',2) = '1:') AND (LENGTH (columnX) - LENGTH(REPLACE(columnX, ':', '')) <= 5)))