DataTables filter by ip address
I had to make a custom filter for ip address which accepted cidr notation (e.g /24). While there was the function to sort by ip at the time when i was doing it, a filter by ip address that accepted cidr or subnet masks function didn’t seem to have been implemented. I couldn’t find any publicly available solution online either, so i took some time to implement it. The solution is in php but can be easily ported to javascript/html if you wish
To get it to work on your own code, you will have to modify the 2 variables
var ipColNum = 0; // column number of your ip address
var tableId = “#results”; // table id that you want to attach datatables to
<!--jquery--> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!--datatables--> <link rel='stylesheet' type='text/css' href='//cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css'/> <script type='text/javascript' src='//cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js'></script> <table id="results"> <thead> <tr> <th>Ip Address</th> <th>Name</th> <th>Country</th> </tr> </thead> <tbody> <tr> <td>192.168.0.1</td> <td>abc</td> <td>abc country</td> </tr> <tr> <td>122.20.21.133</td> <td>xyz</td> <td>xyz country</td> </tr> <tr> <td>192.168.0.10</td> <td>john</td> <td>john country</td> </tr> <tr> <td>192.168.1.1</td> <td>sally</td> <td>sally country</td> </tr> </tbody> </table> <script> var table = null; var ipColNum = 0; // set the column number for the ip address var tableId = "#results"; function getIpRangeFromAddressAndNetmask(str) { var part = str.split("/"); // part[0] = base address, part[1] = netmask var ipaddress = part[0].split('.'); var netmaskblocks = ["0","0","0","0"]; if(!/\d+\.\d+\.\d+\.\d+/.test(part[1])) { // part[1] has to be between 0 and 32 netmaskblocks = ("1".repeat(parseInt(part[1], 10)) + "0".repeat(32-parseInt(part[1], 10))).match(/.{1,8}/g); netmaskblocks = netmaskblocks.map(function(el) { return parseInt(el, 2); }); } else { // xxx.xxx.xxx.xxx netmaskblocks = part[1].split('.').map(function(el) { return parseInt(el, 10) }); } var invertedNetmaskblocks = netmaskblocks.map(function(el) { return el ^ 255; }); var baseAddress = ipaddress.map(function(block, idx) { return block & netmaskblocks[idx]; }); var broadcastaddress = ipaddress.map(function(block, idx) { return block | invertedNetmaskblocks[idx]; }); return [baseAddress.join('.'), broadcastaddress.join('.')]; } function ip2long(IP) { var i = 0; IP = IP.match( /^([1-9]\d*|0[0-7]*|0x[\da-f]+)(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?(?:\.([1-9]\d*|0[0-7]*|0x[\da-f]+))?$/i ); if (!IP) { return false; } IP[0] = 0; for (i = 1; i < 5; i += 1) { IP[0] += !!((IP[i] || '').length); IP[i] = parseInt(IP[i]) || 0; } IP.push(256, 256, 256, 256); IP[4 + IP[0]] *= Math.pow(256, 4 - IP[0]); if (IP[1] >= IP[5] || IP[2] >= IP[6] || IP[3] >= IP[7] || IP[4] >= IP[8]) { return false; } return IP[1] * (IP[0] === 1 || 16777216) + IP[2] * (IP[0] <= 2 || 65536) + IP[3] * (IP[0] <= 3 || 256) + IP[4] * 1; } //https://www.jqueryscript.net/demo/DataTables-Jquery-Table-Plugin/examples/plug-ins/range_filtering.html var ipFilter = function(searchValue) { $.fn.dataTable.ext.search.push( function( settings, data, dataIndex ) { console.log("srchValue" + searchValue); var ipRange = searchValue; var colIpAddr = data[0]; // use data for the age column var range = getIpRangeFromAddressAndNetmask(ipRange); var min = ip2long(range[0]); var max = ip2long(range[1]); //console.log(ipRange); //console.log("min : " + min + " max : " + max); //console.log("chk : " + colIpAddr); var longIpAddr = ip2long(colIpAddr); if( longIpAddr >= min && longIpAddr <= max ) { return true; } return false; } ); table.draw(); $.fn.dataTable.ext.search.pop(); }; $(document).ready( function () { table = $(tableId).DataTable({ responsive: true }); if( !table ) { console.log("Failed to initialize DataTable()"); } else { // Change filter algorithm when cidr notation detected $('.dataTables_filter input').unbind().keyup(function() { var value = $(this).val(); if (value.length==0) { table.search('').draw(); return; } // Must have the format xxx.xxx.xxx.xxx/0-32 // Does not match any string without a '/<number>' at the back. if( /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))$/.test(value) ) { // We need to reset the table first, otherwise our filter won't work // probably because it detects e.g 192.168.0.1/32 -> 192.168.0.1, 192.168.0.1/ , 192.168.0.1/3, 192.168.0.1/32. The earlier 2 has to results. table.search('').draw(); ipFilter(value); } else { table.search(value).draw(); } }); } } ); </script>
See it in action over at the JsFiddle : here or below .You can test it out by putting a search value of “192.168.0.0/23” or any others of your choice
Be First to Comment