Need to match IP address to Range using Business Rule

wade88761
Kilo Contributor

I am trying to create a business rule that updates a computer's location based on the IP range it was originally discovered in. I'll have it run whenever the IP of the CI changes. The problem is the first 3 octets of an IP can be the same and they still have different locations. So I have the below code which queries the ranges that have the same first 3 octets but then I need it to pick the range with the next lowest 4th octet compared to the CI's IP.

For example if the CI's IP is 192.168.1.5 and there are ranges for 192.168.1.1/27 and 192.168.1.32/27 I need it to know to pick the 192.168.1.1 range. So I have the variable "last" that grabs the last octet of the CI's IP but I am unsure of how to set it up to compare it with the queries results. Any help is appreciated or ways to do this easier.

 

var ip = current.ip_address;
var shortened = ip.substring(0,ip.lastIndexOf(".")) + ".";

var last = ip.substring(ip.lastIndexOf(".")+1);
gs.log(last);

var gr = new GlideRecord('discovery_range_item');
gr.addQuery('network_ip','STARTSWITH',shortened);
gr.addQuery('active', true);
gr.query();

while(gr.next()) {
var site = gr.parent;
current.u_discovery_site = site;
}

13 REPLIES 13

Pedro Lopez
Kilo Guru

Hi Wade,

If I understand correctly, you want to validate if the first 4 octets can be the same in your query results. If this is correct, try this:

 

You have your variable "last". You will use it to validate if your query results CONTAINS the last value.

 

while(gr.next()) {

if(gr.network_ip.indexOf(last) != -1){  //This If helps you to validate if the value is contained in the IP Address

<your code>

}
}

 

I hope this helps,

Pedro Lopez

wade88761
Kilo Contributor

No, our ranges are all setup in the system by site. So we can have multiple ip ranges that have the same first 3 octets.

If the machines IP is 192.168.1.5, my query will return the following IP networks in the "discovery_range_item" table.

 

192.168.1.1

192.168.1.32

 

the subnets are both 27 bits. Looking at these results I know 192.168.1.5 falls into the first one (192.168.1.1/27). The problem is I need the code to now look at the last octet of the query results and pick the next lowest one from the results (192.168.1.1) because that's the range it came from.

Nate Wert1
Giga Guru

This is untested but you could try something like this...

 

var ip = current.ip_address;
var shortened = ip.substring(0, ip.lastIndexOf(".")) + ".";

var last = ip.substring(ip.lastIndexOf(".") + 1);
gs.log(last);


var gr = new GlideRecord("discovery_range_item");
gr.addQuery("network_ip", "STARTSWITH", shortened);
gr.addQuery("active", true);
gr.query();
var count = gr.getRowCount();
if (count == 1) {
gr.next();
current.u_discovery_site=gr.parent.toString();
} else if (count > 1){
vararr= [];
varobjNet= {};
while (gr.next()) {
objNet.last=gr.network_ip.substring(ip.lastIndexOf(".") +1);
objNet.sys_id=gr.parent;
arr.push(objNet);
}
arr.sort(function (a, b) {
returna.last-b.last;
});
for (vari=0; i<arr.length; i++) {
if (arr[i].last==last|| (arr[i].last<last&&arr[i+1].last>last)) {
current.u_discovery_site=arr[i].sys_id;
i=arr.length;
}
}
}

Seems to be a problem here, it runs fine as long as there's only 1 row returned.

 

else if (count>1) {
var arr = [];
var obiNet = {};
while (gr.next()) {
obiNet.last = gr.network_ip.substring(ip.lastIndexOf(".")+1);
obiNet.sys_id = gr.parent;
arr.push(obiNet);

}
arr.sort(function(a, b) {
return a.last-b.last;
});
for (var i=0; i<arr.length; i++) {
if (arr[i].last==last|| (arr[i].last<last&&arr[i+1].last>last)) {
current.u_discovery_site=arr[i].sys_id;
i=arr.length;
}
}
}