summaryrefslogblamecommitdiffstats
path: root/server/lib/iphelper.js
blob: 78929bc5121dc32526ff5ddce784d6a69b8a92f0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                                                         
                                                         


                                                          
                                   

                                                                                                                               

                                        

































                                                                                                                              
                                     
















                                                                                                                                    
/* global __appdir */
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
module.exports = { toDecimal, toIPv4, getGroups, isIPv4 }

// 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 } } })
  if (!fittingIpRanges.length) return []

  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)
}