diff -r 57624188c7f1 -r 6ed154cb8b32 src/main/scala/net/tz/ip/IpNetwork.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/net/tz/ip/IpNetwork.scala Sat Oct 01 15:28:45 2011 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright 2011 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.tz.ip + +import net.liftweb.common._ +import net.liftweb.util.Helpers._ + +case class IpNetwork(from: IpAddress, to: IpAddress) { + require(from.v == to.v, "IpAddresses must be of the same version") + + lazy val v = from.v + lazy val mask = from.v.ones ^ from.toBigInt ^ to.toBigInt + lazy val size = to.toBigInt - from.toBigInt + 1 + lazy val maskLen = mask bitCount + lazy val maskIp = IpAddress(v, mask) + + override def toString = maskIp map { _ => from + "/" + maskLen } openOr + (from + "-" + to) +} + +object IpNetwork { + def apply(net: String, maskLen: Int): Box[IpNetwork] = for { + ip <- IpAddress(net) + n <- apply(ip, maskLen) + } yield { n } + + def apply(net: IpAddress, maskLen: Int): Box[IpNetwork] = { + require(net.v.bits >= maskLen, + "MaskLen must be less or equal to IP length") + val hm = BigInt(2).pow(net.v.bits - maskLen) - 1 // host mask + val m = net.v.ones &~ hm // net mask + val f = net.toBigInt & m + val t = net.toBigInt | hm + for { + from <- IpAddress(net.v, f) + to <- IpAddress(net.v, t) + } yield { IpNetwork(from, to) } + } +} + +// vim: set ts=2 sw=2 et: