Advertisement
Guest User

Untitled

a guest
Mar 24th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.09 KB | None | 0 0
  1. package com.kaspersky.his.common.ip
  2.  
  3. import java.net.{Inet4Address, Inet6Address, InetAddress}
  4. import java.nio.ByteBuffer
  5.  
  6. sealed trait CIDR {
  7.   def address: InetAddress
  8.   def fixedBits: Int
  9.   override def toString: String = s"${address.getHostAddress}/$fixedBits"
  10.   def isInRange(check: InetAddress): Boolean
  11.  
  12.   def minIp: InetAddress
  13.   def maxIp: InetAddress
  14. }
  15.  
  16. object CIDR {
  17.  
  18.   private[ip] val cidr4Size = 32
  19.   private[ip] val cidr6Size = 128
  20.  
  21.   def parse(str: String): CIDR = {
  22.     val Array(addr, b) = str.split('/')
  23.     val bits = b.toInt
  24.     InetAddress.getByName(addr) match {
  25.       case ia4: Inet4Address =>
  26.         val bits4 =
  27.           if (bits > cidr4Size)
  28.             bits - cidr6Size + cidr4Size
  29.           else
  30.             bits
  31.         CIDR4(ia4, bits4)
  32.       case ia6: Inet6Address => CIDR6(ia6, b.toInt)
  33.     }
  34.   }
  35. }
  36.  
  37. case class CIDR6(address: Inet6Address, fixedBits: Int) extends CIDR {
  38.  
  39.   private val size = CIDR.cidr6Size
  40.   private val bytes = size / java.lang.Byte.SIZE
  41.  
  42.   private val hmask = byteMask(fixedBits.min(size / 2))
  43.   private val lmask = byteMask((fixedBits - size / 2).max(0))
  44.   private val (hcidr, lcidr) = getBytes(address)
  45.  
  46.   def isInRange(check: InetAddress): Boolean = {
  47.     check match {
  48.       case ia: Inet6Address =>
  49.         val (h, l) = getBytes(ia)
  50.         (h & hmask) == (hcidr & hmask) && (l & lmask) == (lcidr & lmask)
  51.       case _ =>
  52.         false
  53.     }
  54.   }
  55.  
  56.   private def getBytes(address: Inet6Address): (Long, Long) = {
  57.     val bb = ByteBuffer.allocate(bytes).put(address.getAddress)
  58.     (bb.getLong(0), bb.getLong(java.lang.Long.BYTES))
  59.   }
  60.  
  61.   private def byteMask(length: Int) = {
  62.     (1 to length).map(x => 1l << (size / 2 - x)).sum
  63.   }
  64.  
  65.   def minIp: InetAddress = getBytes(address) match {
  66.     case (h, l) =>
  67.       val bb = ByteBuffer.allocate(bytes)
  68.       bb.putLong(h & hmask)
  69.       bb.putLong(l & lmask)
  70.       InetAddress.getByAddress(bb.array())
  71.   }
  72.  
  73.   def maxIp: InetAddress = getBytes(address) match {
  74.     case (h, l) =>
  75.       val bb = ByteBuffer.allocate(bytes)
  76.       bb.putLong(h | ~hmask)
  77.       bb.putLong(l | ~lmask)
  78.       InetAddress.getByAddress(bb.array())
  79.   }
  80.  
  81. }
  82.  
  83. case class CIDR4(address: Inet4Address, fixedBits: Int) extends CIDR {
  84.  
  85.   private val size = CIDR.cidr4Size
  86.   private val bytes = size / java.lang.Byte.SIZE
  87.  
  88.   private val mask = byteMask(fixedBits)
  89.   private val cidr = getBytes(address)
  90.  
  91.   def isInRange(check: InetAddress): Boolean = {
  92.     check match {
  93.       case ia: Inet4Address =>
  94.         val byteAddr = getBytes(ia)
  95.         (byteAddr & mask) == (cidr & mask)
  96.       case _ =>
  97.         false
  98.     }
  99.   }
  100.  
  101.   private def getBytes(address: Inet4Address): Int = {
  102.     val bb = ByteBuffer.allocate(bytes)
  103.     bb.put(address.getAddress)
  104.     bb.getInt(0)
  105.   }
  106.  
  107.   private def byteMask(length: Int) = {
  108.     (1 to length).map(x => 1 << (size - x)).sum
  109.   }
  110.  
  111.   def minIp: InetAddress = getBytes(address) match {
  112.     case byteAddr =>
  113.       InetAddress.getByAddress(ByteBuffer.allocate(bytes).putInt(byteAddr).array())
  114.   }
  115.  
  116.   def maxIp: InetAddress = getBytes(address) match {
  117.     case byteAddr =>
  118.       InetAddress.getByAddress(ByteBuffer.allocate(bytes).putInt(byteAddr | ~mask).array())
  119.   }
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement