subnet v0.2.0
Subnet
A Crystal library for working with IPv4 and IPv6 addresses.
Subnet provides a complete set of methods to handle IP addresses for any need, from simple scripting to full network design. It features a clean OO interface, comprehensive IPv4/IPv6 support, and efficient native UInt128 operations for IPv6.
Based on the Ruby IPAddress gem.
Table of Contents
Install
Add the dependency to your shard.yml:
dependencies:
subnet:
github: watzon/subnet
version: ~> 0.2.0
Run shards install.
Usage
require "subnet"
IPv4
Create and manipulate IPv4 addresses:
# Create an IPv4 address
ip = Subnet::IPv4.new("172.16.10.1/24")
# Or use the universal parser
ip = Subnet.parse("172.16.10.1/24")
# Access properties
ip.address # => "172.16.10.1"
ip.prefix # => 24
ip.netmask # => "255.255.255.0"
ip.octets # => [172, 16, 10, 1]
ip.to_u32 # => 2886732289
# Network calculations
ip.network.to_string # => "172.16.10.0/24"
ip.broadcast.to_string # => "172.16.10.255/24"
ip.first.to_s # => "172.16.10.1"
ip.last.to_s # => "172.16.10.254"
# Check address types
ip.private? # => true
ip.loopback? # => false
ip.network? # => false
# Iterate over addresses
ip.each_host { |host| puts host }
IPv6
Full IPv6 support with native UInt128 operations:
ip6 = Subnet::IPv6.new("2001:db8::8:800:200c:417a/64")
ip6.address # => "2001:0db8:0000:0000:0008:0800:200c:417a"
ip6.compressed # => "2001:db8::8:800:200c:417a"
ip6.to_u128 # => 42540766411282592856906245548098208122 (UInt128)
# Special addresses
loopback = Subnet::IPv6::Loopback.new
loopback.to_string # => "::1/128"
# IPv4-mapped addresses
mapped = Subnet::IPv6::Mapped.new("::ffff:172.16.10.1/128")
mapped.ipv4.address # => "172.16.10.1"
Network Operations
Subnet provides powerful network manipulation:
# Subnetting - divide a network
network = Subnet::IPv4.new("172.16.10.0/24")
subnets = network.split(4)
subnets.map(&.to_string)
# => ["172.16.10.0/26", "172.16.10.64/26",
# "172.16.10.128/26", "172.16.10.192/26"]
# Supernetting - combine networks
network.supernet(23).to_string # => "172.16.10.0/23"
# Summarization - find optimal supernet
ip1 = Subnet::IPv4.new("172.16.10.0/24")
ip2 = Subnet::IPv4.new("172.16.11.0/24")
Subnet::IPv4.summarize(ip1, ip2).map(&.to_string)
# => ["172.16.10.0/23"]
# Check inclusion
network.includes?(Subnet::IPv4.new("172.16.10.50/32")) # => true
# Allocate addresses sequentially
ip = Subnet::IPv4.new("10.0.0.0/24")
ip.allocate # => "10.0.0.1/24"
ip.allocate # => "10.0.0.2/24"
API
Subnet Module
Subnet.parse(address)- Parse IPv4, IPv6, or mapped addressesSubnet.valid?(address)- Check if address is validSubnet.valid_ipv4?(address)- Check IPv4 validitySubnet.valid_ipv6?(address)- Check IPv6 validity
Subnet::IPv4
Creation:
.new(address)- Create from string (e.g., "192.168.1.1/24").parse_u32(int, prefix)- Create from 32-bit integer.parse_data(bytes, prefix)- Create from byte array.parse_classful(address)- Create with classful prefix.extract(string)- Extract IPv4 from string
Properties:
#address- Address string#prefix- Prefix object#netmask- Netmask string#octets- Array of octets#to_u32/#to_i- 32-bit integer#bits- Binary string#hexstring- Hex string
Network:
#network- Network address#broadcast- Broadcast address#first/#last- First/last host#size- Number of addresses#hosts- Array of host addresses#includes?(other)- Check if includes address#each/#each_host- Iterate addresses
Operations:
#subnet(prefix)- Subnet to new prefix#split(count)- Split into N subnets#supernet(prefix)- Create supernet#allocate(skip)- Allocate next address.summarize(*addresses)- Summarize addresses
Checks:
#private?/#loopback?/#multicast?/#link_local?#network?- Is network address#a?/#b?/#c?- Classful checks
Subnet::IPv6
Similar interface to IPv4, with additions:
#to_u128- 128-bit integer (UInt128)#compressed- Compressed string#groups/#hex_groups- 16-bit groups#unspecified?/#loopback?/#mapped?#link_local?/#unique_local?.expand(address)/.compress(address)- String utilities.parse_u128(int, prefix)- Create from UInt128.parse_hex(hex, prefix)- Create from hex string
Subclasses:
Subnet::IPv6::Loopback- Loopback address (::1)Subnet::IPv6::Unspecified- Unspecified address (::)Subnet::IPv6::Mapped- IPv4-mapped address (::ffff:x.x.x.x)
Maintainers
Contributing
- Fork it (https://github.com/watzon/subnet/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Bug reports and pull requests are welcome on GitHub.
License
MIT - Chris Watson
subnet
- 20
- 2
- 1
- 3
- 0
- 14 days ago
- June 29, 2019
MIT License
Tue, 27 Jan 2026 16:16:59 GMT