- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 08:59 PM
We have the IP Range table populated, including the starting IP and Ending IP fields. The requirement is whenever the IP Address of a computer changes, we want to update the IP Location field with the Site Name of the corresponding range. I wrote the following on change script but the glide lookup isn't working. I'm assuming it's because I don't have the correct operators for finding it. Can anyone out there help me?
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
//Get current IP address
var myIP = g_form.getValue("ip_address");
//Find IP Range where current IP is between Start IP and End IP
var gr = new GlideRecord("ip_address_range");
gr.addQuery("start_ip",">=",myIP);
gr.addQuery("end_ip","<=",myIP);
gr.query();
if (gr.next()) {
// Update IP location with Range Site name
g_form.setValue("u_ip_location",gr.u_site_name);
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 09:43 PM
Hi,
I think you cannot compare IP addresses directly using those operators
here is the script which will check whether a particular Ip address is in range; The logic would be
1) query the ip address range table
2) pass the start, end, your ip to this function
3) function will return true/false
4) if it returns true then pick up the site name
5) set the value
I would recommend using business rule i.e. before update/insert to do this; since it will take more time to query every single record and compare and then set
Avoid client script
Sample business rule script here: I assume you have configured the ip address range table properly so that it returns true only for 1 record i.e. single ip address won't be present in range for multiple records; if it is then it will pick the first
Note: the function won't validate the ip address but just check whether your ip falls in that range or not
var gr = new GlideRecord("ip_address_range");
gr.query();
while(gr.next()) {
var start = gr.start_ip;
var end = gr.end_ip;
var myIP = current.ip_address;
if(isWithinRange(myIP,start,end))
current.u_ip_location = gr.u_site_name;
}
function isWithinRange(ip, lowerBound, upperBound) {
var ips = [ip.split('.'), lowerBound.split('.'), upperBound.split('.')];
for(var i = 0; i < ips.length; i++) {
for(var j = 0; j < ips[i].length; j++) {
ips[i][j] = parseInt(ips[i][j]);
}
ips[i] =
(ips[i][0] << 24) +
(ips[i][1] << 16) +
(ips[i][2] << 8) +
(ips[i][3]);
}
if(ips[0] >= ips[1] && ips[0] <= ips[2])
return true;
else
return false;
}
Mark ✅ Correct if this solves your issue and also mark 👍 Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 09:05 PM
Hi,
Using GlideRecord on a client side script is not a best practice and it is recommended to use GlideAjax. You could try the following and see if it works for you
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
//Get current IP address
var myIP = g_form.getValue("ip_address");
//Find IP Range where current IP is between Start IP and End IP
var gr = new GlideRecord("ip_address_range");
gr.addQuery("start_ip",">=",myIP);
gr.addQuery("end_ip","<=",myIP);
gr.query(function(rec) {
if (gr.next()) {
//Update IP location with Range Site name
g_form.setValue("u_ip_location",rec.u_site_name);
}
});
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 09:43 PM
Hi,
I think you cannot compare IP addresses directly using those operators
here is the script which will check whether a particular Ip address is in range; The logic would be
1) query the ip address range table
2) pass the start, end, your ip to this function
3) function will return true/false
4) if it returns true then pick up the site name
5) set the value
I would recommend using business rule i.e. before update/insert to do this; since it will take more time to query every single record and compare and then set
Avoid client script
Sample business rule script here: I assume you have configured the ip address range table properly so that it returns true only for 1 record i.e. single ip address won't be present in range for multiple records; if it is then it will pick the first
Note: the function won't validate the ip address but just check whether your ip falls in that range or not
var gr = new GlideRecord("ip_address_range");
gr.query();
while(gr.next()) {
var start = gr.start_ip;
var end = gr.end_ip;
var myIP = current.ip_address;
if(isWithinRange(myIP,start,end))
current.u_ip_location = gr.u_site_name;
}
function isWithinRange(ip, lowerBound, upperBound) {
var ips = [ip.split('.'), lowerBound.split('.'), upperBound.split('.')];
for(var i = 0; i < ips.length; i++) {
for(var j = 0; j < ips[i].length; j++) {
ips[i][j] = parseInt(ips[i][j]);
}
ips[i] =
(ips[i][0] << 24) +
(ips[i][1] << 16) +
(ips[i][2] << 8) +
(ips[i][3]);
}
if(ips[0] >= ips[1] && ips[0] <= ips[2])
return true;
else
return false;
}
Mark ✅ Correct if this solves your issue and also mark 👍 Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 10:08 PM
Ankur, thanks for the quick and helpful reply. That business rule looks sweet and seems to work, but it's only running the glide lookup for one entry in the table and then stops. I added a couple log statements to see what was happening. I put in 10.1.0.188 and saved the record, but only got one set of log statements. If it was looping through the whole table until it found the right range then I should have gotten multiple sets, right?
gs.log("CDL: Start Script");
var gr = new GlideRecord("ip_address_range");
gr.query();
while(gr.next()) {
var start = gr.start_ip;
gs.log("CDL: Start: " + start);
var end = gr.end_ip;
gs.log("CDL: End: " + end);
var myIP = current.ip_address;
gs.log("CDL: myIP: " + myIP);
if(isWithinRange(myIP,start,end))
current.u_ip_location = gr.u_site_name;
alert("CDL: Site: " + gr.u_site_name);
}
function isWithinRange(ip, lowerBound, upperBound) {
var ips = [ip.split('.'), lowerBound.split('.'), upperBound.split('.')];
for(var i = 0; i < ips.length; i++) {
for(var j = 0; j < ips[i].length; j++) {
ips[i][j] = parseInt(ips[i][j]);
}
ips[i] =
(ips[i][0] << 24) +
(ips[i][1] << 16) +
(ips[i][2] << 8) +
(ips[i][3]);
}
if(ips[0] >= ips[1] && ips[0] <= ips[2])
return true;
else
return false;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2019 10:12 PM
The even better news is that it does populate the site name when i use an ip that falls into the only range it checks. So all we need to figure out is how to make it cycle through all the ranges until it gets the correct one.