From 0999302d99156200ff174d5ec56d6831c8afd332 Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Thu, 7 Mar 2019 19:20:25 +0000 Subject: [server] New clients are automaticly added to the groups of the fitting subranges Add conflict models Sequelize string operators depricated fix IPv4 is now saved as decimal in the database Add host to config instead of hardcoding Rename ip.js lib to iphelper.js --- server/lib/iphelper.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 server/lib/iphelper.js (limited to 'server/lib/iphelper.js') diff --git a/server/lib/iphelper.js b/server/lib/iphelper.js new file mode 100644 index 0000000..5c40313 --- /dev/null +++ b/server/lib/iphelper.js @@ -0,0 +1,62 @@ +/* global __appdir */ +var path = require('path') +var db = require(path.join(__appdir, 'lib', 'sequelize')) +module.exports = { toDecimal, toString, toIPv4, getGroups } + +// Finds the groups where the ip fits best in the subnets. +async function getGroups (ipString) { + const ipInt = toDecimal(ipString) + + let fittingIpRanges = await db.iprange.findAll({ where: { startIp: { [db.Op.lte]: ipInt }, endIp: { [db.Op.gte]: ipInt } } }) + fittingIpRanges = fittingIpRanges.map(x => x.groupId) + + // List with all groups mapped so that groups[id] = [parents] + let groups = await db.group.findAll({ include: ['parents'] }) + let parentMap = {} + groups.forEach(group => { + parentMap[group.id] = group.parents + }) + + // foreach fittingIpRanges go through groups and eliminate parents in the fittingIpRanges + let result = fittingIpRanges + fittingIpRanges.forEach(groupid => { + result = eliminateParents(groupid, parentMap, result) + }) + + return result +} + +function eliminateParents (groupId, groupMap, eliminateArray, alreadyChecked = []) { + // Check for cycles and return if there is one. + if (alreadyChecked.includes(groupId)) return eliminateArray + alreadyChecked.push(groupId) + + const parents = groupMap[groupId] + parents.forEach(parent => { + const index = eliminateArray.indexOf(parent.id) + if (index !== -1) eliminateArray.splice(index, 1) + if (groupMap[parent.id].length > 0) eliminateArray = eliminateParents(parent.id, groupMap, eliminateArray, alreadyChecked) + }) + return eliminateArray +} + +// Takes an ip address and converts it to an integer. +function toDecimal (ipString) { + if (isIPv4(ipString)) return false + const ipArray = ipString.split('.') + if (ipArray.length !== 4) return false + + let result = parseInt(ipArray[0]) * 256 ** 3 + parseInt(ipArray[1]) * 256 ** 2 + parseInt(ipArray[2]) * 256 + parseInt(ipArray[3]) + return result +} + +// Converts an integer value in a human readable typical ip address. +function toIPv4 (ipInt) { + return [(ipInt >> 24) & 0xff, (ipInt >> 16) & 0xff, (ipInt >> 8) & 0xff, ipInt & 0xff].join('.') +} + +// Sanity check for an ipv4. +function isIPv4 (ipString) { + const re = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ + return re.test(ipString) +} -- cgit v1.2.3-55-g7522