src/main/scala/net/tz/ip/IpNetwork.scala
author Tomas Zeman <tzeman@volny.cz>
Sat, 01 Oct 2011 15:28:45 +0200
changeset 25 6ed154cb8b32
permissions -rw-r--r--
IpAddress/Network helpers
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     1
/*
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     2
 * Copyright 2011 Tomas Zeman <tzeman@volny.cz>
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     3
 *
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     4
 * Licensed under the Apache License, Version 2.0 (the "License");
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     5
 * you may not use this file except in compliance with the License.
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     6
 * You may obtain a copy of the License at
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     7
 *
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     8
 *     http://www.apache.org/licenses/LICENSE-2.0
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
     9
 *
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    10
 * Unless required by applicable law or agreed to in writing, software
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    11
 * distributed under the License is distributed on an "AS IS" BASIS,
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    13
 * See the License for the specific language governing permissions and
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    14
 * limitations under the License.
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    15
 */
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    16
package net.tz.ip
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    17
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    18
import net.liftweb.common._
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    19
import net.liftweb.util.Helpers._
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    20
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    21
case class IpNetwork(from: IpAddress, to: IpAddress) {
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    22
  require(from.v == to.v, "IpAddresses must be of the same version")
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    23
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    24
  lazy val v = from.v
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    25
  lazy val mask = from.v.ones ^ from.toBigInt ^ to.toBigInt
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    26
  lazy val size = to.toBigInt - from.toBigInt + 1
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    27
  lazy val maskLen = mask bitCount
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    28
  lazy val maskIp = IpAddress(v, mask)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    29
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    30
  override def toString = maskIp map { _ => from + "/" + maskLen } openOr
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    31
    (from + "-" + to)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    32
}
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    33
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    34
object IpNetwork {
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    35
  def apply(net: String, maskLen: Int): Box[IpNetwork] = for {
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    36
    ip <- IpAddress(net)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    37
    n <- apply(ip, maskLen)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    38
  } yield { n }
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    39
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    40
  def apply(net: IpAddress, maskLen: Int): Box[IpNetwork] = {
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    41
    require(net.v.bits >= maskLen,
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    42
      "MaskLen must be less or equal to IP length")
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    43
    val hm = BigInt(2).pow(net.v.bits - maskLen) - 1 // host mask
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    44
    val m = net.v.ones &~ hm // net mask
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    45
    val f = net.toBigInt & m
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    46
    val t = net.toBigInt | hm
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    47
    for {
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    48
      from <- IpAddress(net.v, f)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    49
      to <- IpAddress(net.v, t)
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    50
    } yield { IpNetwork(from, to) }
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    51
  }
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    52
}
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    53
6ed154cb8b32 IpAddress/Network helpers
Tomas Zeman <tzeman@volny.cz>
parents:
diff changeset
    54
// vim: set ts=2 sw=2 et: