ip-utils

module
v0.0.0-...-17f6e27 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2025 License: MIT

README

IP Utils

A comprehensive Go package for IP address and CIDR network calculations. This package provides utilities for working with IP addresses, CIDR blocks, subnetting, and more.

Features

  • Calculate network details (network address, broadcast address, first/last usable IP)
  • Determine total and usable IP addresses in a CIDR block
  • Subnet networks into smaller networks
  • Convert between CIDR notation and netmask format
  • Check if an IP is within a CIDR block
  • Determine if CIDRs overlap
  • Format network sizes in human-readable format
  • Manage sets of IP addresses with efficient operations (union, intersection, difference)
  • Convert between IP ranges and CIDR blocks
  • Convert wildcard notation (e.g., 192.168..) to CIDR blocks
  • Convert octet ranges (e.g., 192.168.[1-5].0) to CIDR blocks
  • Check if an IP is in a private range or bogon range
  • Advanced functionality like supernets and next/previous networks
  • Iterate through IP addresses in a CIDR block

Installation

go get -u github.com/Dontjustadream/ip-utils

Project Structure

github.com/Dontjustadream/ip-utils/
├── cidr/                  # Core CIDR operations
│   ├── cidr.go            # CIDR type and basic methods
│   ├── subnet.go          # Subnetting operations
│   └── iterate.go         # IP iteration utilities
├── ipset/                 # IP Set operations
│   ├── ipset.go           # IPSet type and basic methods
│   ├── operations.go      # Set operations (union, intersection, etc.)
│   └── io.go              # File I/O for IP sets
├── convert/               # Format conversion utilities
│   ├── netmask.go         # CIDR and netmask conversions
│   ├── range.go           # IP range conversions
│   ├── wildcard.go        # Wildcard and octet range conversions
│   └── format.go          # Human-readable formatting
├── check/                 # IP validation and classification
│   ├── private.go         # Private IP detection
│   ├── bogon.go           # Bogon IP detection
│   └── version.go         # IPv4/IPv6 detection
└── util/                  # Common utilities
    ├── ip.go              # IP manipulation (clone, increment, etc.)
    └── math.go            # Math utilities

Basic Usage

package main

import (
    "fmt"
    "github.com/Dontjustadream/ip-utils/cidr"
    "github.com/Dontjustadream/ip-utils/check"
    "github.com/Dontjustadream/ip-utils/ipset"
)

func main() {
    // Create a new CIDR object
    c, err := cidr.New("192.168.1.0/24")
    if err != nil {
        panic(err)
    }

    // Get basic information
    fmt.Printf("CIDR: %s\n", c.String())
    fmt.Printf("Network: %s\n", c.NetworkIP)
    fmt.Printf("Broadcast: %s\n", c.BroadcastIP)
    fmt.Printf("First usable IP: %s\n", c.FirstIP)
    fmt.Printf("Last usable IP: %s\n", c.LastIP)
    fmt.Printf("Total IPs: %s\n", c.TotalIPs)
    fmt.Printf("Usable IPs: %s\n", c.UsableIPs)

    // Check if an IP is in the network
    ip := "192.168.1.10"
    fmt.Printf("Is %s in the network? %v\n", ip, c.Contains(ip))

    // Check if an IP is in a private range
    if check.IsPrivateIP(ip) {
        fmt.Println("IP is in a private range")
    }

    // Check if an IP is a bogon
    if check.IsBogonIP(ip) {
        fmt.Println("IP is a bogon")
    }

    // Create a set of IPs
    set := ipset.New()
    set.Add("192.168.1.1")
    set.Add("192.168.1.2")
    set.AddCIDR("10.0.0.0/30")
    
    fmt.Printf("Set contains %d IPv4 addresses\n", set.GetIPv4Count())
}

Working with CIDRs

// Subnet a network into smaller networks
subnets, err := c.Subnet(26) // Split into /26 networks
if err != nil {
    panic(err)
}
fmt.Printf("Subnets: %d\n", len(subnets))
for _, subnet := range subnets {
    fmt.Printf("  %s (%s IPs)\n", subnet.String(), subnet.TotalIPs)
}

// Iterate through all IPs in a network (use with caution for large networks!)
fmt.Println("First 5 IPs in the network:")
count := 0
c.Each(func(ip string) bool {
    fmt.Printf("  %s\n", ip)
    count++
    return count < 5 // Only process the first 5 IPs
})

// Check if networks overlap
net1, _ := cidr.New("192.168.1.0/24")
net2, _ := cidr.New("192.168.0.0/16")
if net1.Overlaps(net2) {
    fmt.Println("Networks overlap")
}

Working with IP Sets

// Create a new IP set
set := ipset.New()

// Add IPs to the set
set.Add("192.168.1.1")
set.Add("192.168.1.2")
set.Add("2001:db8::1")

// Add a CIDR block
set.AddCIDR("192.168.2.0/24")

// Check if an IP is in the set
if set.Contains("192.168.1.1") {
    fmt.Println("IP found in set")
}

// Get counts
fmt.Printf("IPv4 count: %d\n", set.GetIPv4Count())
fmt.Printf("IPv6 count: %d\n", set.GetIPv6Count())
fmt.Printf("Total IPs: %d\n", set.Size())

// Convert to optimized CIDR blocks
ipv4CIDRs, ipv6CIDRs, _ := set.ToCIDRs()

fmt.Println("IPv4 CIDRs:")
for _, c := range ipv4CIDRs {
    fmt.Println(c.String())
}

// Set operations
setA := ipset.New()
setA.Add("192.168.1.1")
setA.Add("192.168.1.2")

setB := ipset.New()
setB.Add("192.168.1.2")
setB.Add("192.168.1.3")

// Union of sets
unionSet := ipset.Union(setA, setB)
fmt.Printf("Union has %d IPs\n", unionSet.Size())

// Intersection
setA.Intersection(setB)
fmt.Printf("After intersection, setA has %d IPs\n", setA.Size())

IP Checking Functions

ip := "192.168.1.1"

// Check IP version
if check.IsIPv4(ip) {
    fmt.Println("This is an IPv4 address")
} else if check.IsIPv6(ip) {
    fmt.Println("This is an IPv6 address")
}

// Check if IP is private
if check.IsPrivateIP(ip) {
    fmt.Println("This is a private IP")
}

// Check if IP is a bogon (should not appear on public internet)
if check.IsBogonIP(ip) {
    fmt.Println("This is a bogon IP")
}

// Check if IP is a loopback address
if check.IsLoopbackIP(ip) {
    fmt.Println("This is a loopback IP")
}

// Check if IP is a documentation address
if check.IsDocumentationIP(ip) {
    fmt.Println("This is a documentation IP")
}

Format Conversions

// Convert netmask to prefix length
prefixLen, _ := convert.NetmaskToPrefixLen("255.255.255.0")
fmt.Printf("Prefix length: /%d\n", prefixLen)

// Convert prefix length to netmask
netmask, _ := convert.PrefixLenToNetmask(24)
fmt.Printf("Netmask: %s\n", netmask)

// Convert IP and netmask to CIDR notation
cidrNotation, _ := convert.NetmaskToCIDR("192.168.1.0", "255.255.255.0")
fmt.Printf("CIDR notation: %s\n", cidrNotation)

// Convert IP range to CIDRs
cidrs, _ := convert.IPRangeToCIDRs("192.168.1.0", "192.168.2.255")
fmt.Println("CIDRs that cover the range:")
for _, c := range cidrs {
    fmt.Println(c.String())
}

Wildcard and Octet Range Conversions

import "github.com/Dontjustadream/ip-utils/convert"

// Convert wildcard notation to CIDR blocks
cidrs, err := convert.WildcardToCIDRs("192.168.*.*")
if err != nil {
    panic(err)
}
fmt.Printf("192.168.*.* = %s\n", cidrs[0].String()) // 192.168.0.0/16

// Convert octet range notation to CIDR blocks
cidrs, err = convert.OctetRangeToCIDRs("192.168.[1-5].0")
if err != nil {
    panic(err)
}
fmt.Printf("192.168.[1-5].0 = %d CIDR blocks\n", len(cidrs))
for _, c := range cidrs {
    fmt.Printf("  %s\n", c.String())
}

// Automatic detection of format (wildcard, range, CIDR, or single IP)
cidrs, err = convert.WildcardAndRangeToCIDRs("10.[1-2].*.*")
if err != nil {
    panic(err)
}
fmt.Printf("10.[1-2].*.* = %d CIDR blocks\n", len(cidrs))

License

This project is licensed under the MIT License - see the LICENSE file for details.

Directories

Path Synopsis
cmd
ipcalc command
examples
basic command
ipset command
subnet command
wildcard command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL