Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes #5 #7

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ all:
GOOS=windows GOARCH=amd64 go build -o binaries/cidr2ip-win64.exe cidr2ip.go
GOOS=linux GOARCH=386 go build -o binaries/cidr2ip-linux32 cidr2ip.go
GOOS=linux GOARCH=amd64 go build -o binaries/cidr2ip-linux64 cidr2ip.go
GOOS=linux GOARCH=arm64 go build -o binaries/cidr2ip-linuxarm64 cidr2ip.go
GOOS=darwin GOARCH=amd64 go build -o binaries/cidr2ip-osx64 cidr2ip.go
55 changes: 46 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,69 @@ This program converts IPv4 CIDR blocks into their constituent IP addresses.
1. Commnd line arguments
```
code@express:~$ cidr2ip 10.0.0.0/30 192.68.0.0/30
10.0.0.0
10.0.0.1
10.0.0.2
10.0.0.3
192.68.0.0
192.68.0.1
192.68.0.2
```

The `-r` flag outputs IP ranges seperated by hyphen.

```
code@express:~$ cidr2ip -r 10.0.0.0/30 192.68.0.0/30
10.0.0.1-10.0.0.2
192.68.0.1-192.68.0.2
192.68.0.3
```

2. Piped input
```
code@express:~$ cat cidrs.txt | cidr2ip
127.0.0.1
192.168.0.100
192.168.0.101
192.168.0.102
192.168.0.103
10.0.0.0
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
10.0.0.6
10.0.0.7
```

3. File input
```
code@express:~$ cidr2ip -f cidrs.txt
code@express:~$ cidr2ip -i cidrs.txt
127.0.0.1
192.168.0.100
192.168.0.101
192.168.0.102
192.168.0.103
10.0.0.0
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
10.0.0.6
10.0.0.7
```

4. File output
```
code@express:~$ cidr2ip -i cidrs.txt -o results.txt
code@express:~$ cat results.txt
127.0.0.1
192.168.0.100
192.168.0.101
192.168.0.102
192.168.0.103
10.0.0.0
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
10.0.0.6
10.0.0.7
```

### Install
Expand Down
98 changes: 39 additions & 59 deletions cidr2ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ import (
"flag"
"fmt"
"log"
"net"
"os"
"regexp"

"github.com/adedayo/cidr"
)

const (
Version = "2.0.0"
Version = "3.0.0"
IPRegex = `\b(?:\d{1,3}\.){3}\d{1,3}\b$`
)

var (
cidrFilePtr = flag.String("f", "",
"[Optional] Name of file with CIDR blocks")
printRangesPtrPtr = flag.Bool("r", false,
"[Optional] Print IP ranges instead of all IPs")
cidrFilePtr = flag.String("i", "",
"[Optional] Name of input file with CIDR blocks")
outputFilePtr = flag.String("o", "",
"[Optional] Name of output file for storing result")
outputWriterPtr *bufio.Writer
)

func main() {
Expand All @@ -32,6 +34,16 @@ func main() {
}
args := os.Args[1:]

if *outputFilePtr != "" {
f, err := os.Create(*outputFilePtr)
if err != nil {
log.Fatal(err)
} else {
defer f.Close()
outputWriterPtr = bufio.NewWriter(f)
}
}

if *cidrFilePtr != "" {
file, err := os.Open(*cidrFilePtr)
if err != nil {
Expand All @@ -53,76 +65,44 @@ func main() {
}
} else if len(args) > 0 { // look for CIDRs on cmd line
var cidrs []string
if *printRangesPtrPtr == true {
cidrs = args[1:]
} else {
cidrs = args
}
cidrs = args

for _, cidr := range cidrs {
displayIPs(cidr)
for _, cs := range cidrs {
displayIPs(cs)
}
} else { // no piped input, no file provide and no args, display usage
flag.Usage()
}

if outputWriterPtr != nil {
outputWriterPtr.Flush()
}
}

func isIPAddr(cidr string) bool {
match, _ := regexp.MatchString(IPRegex, cidr)
func isIPAddr(cs string) bool {
match, _ := regexp.MatchString(IPRegex, cs)
return match
}

func displayIPs(cidr string) {
var ips []string

// if a IP address, display the IP address and return
if isIPAddr(cidr) {
fmt.Println(cidr)
return
}
func displayIPs(cs string) {
ips := cidr.Expand(cs)

ipAddr, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
log.Print(err)
return
}

for ip := ipAddr.Mask(ipNet.Mask); ipNet.Contains(ip); increment(ip) {
ips = append(ips, ip.String())
}

// CIDR too small eg. /31
if len(ips) <= 2 {
return
}

if *printRangesPtrPtr == true {
fmt.Printf("%s-%s\n", ips[1], ips[len(ips)-2])
} else {
for _, ip := range ips[1 : len(ips)-1] {
fmt.Println(ip)
}
}
}

// The next IP address of a given ip address
// https://stackoverflow.com/a/33925954
func increment(ip net.IP) {
for i := len(ip) - 1; i >= 0; i-- {
ip[i]++
if ip[i] != 0 {
break
for _, ip := range ips {
if *outputFilePtr != "" {
outputWriterPtr.WriteString(ip + "\n")
} else {
println(ip)
}
}
}

func usage() {
fmt.Fprintf(os.Stderr, "CIDR to IPs version %s\n", Version)
fmt.Fprintf(os.Stderr, "Usage: $ cidr2ip [-r] [-f <filename>] <list of cidrs> \n")
fmt.Fprintf(os.Stderr, "Example: $ cidr2ip -f cidrs.txt\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip 10.0.0.0/24\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip -r 10.0.0.0/24\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip -r -f cidrs.txt\n")
fmt.Fprintf(os.Stderr, "Usage: $ cidr2ip [-i <filename>] [-o <filename>] [<list of cidrs>] \n")
fmt.Fprintf(os.Stderr, "Example: $ cidr2ip 10.0.0.0/27\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip -i cidrs.txt\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip -o results.txt 10.0.0.0/27\n")
fmt.Fprintf(os.Stderr, " $ cidr2ip -i cidrs.txt -o results.txt\n")
fmt.Fprintf(os.Stderr, " $ cat cidrs.txt | cidr2ip \n")
fmt.Fprintf(os.Stderr, "--------------------------\nFlags:\n")
flag.PrintDefaults()
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module cidr2ip

go 1.23.2

require github.com/adedayo/cidr v0.1.5
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
github.com/adedayo/cidr v0.1.5 h1:O6N8M2CPOT7LAy2upOHnQ4YIKHD+VXAQc8/OalCsmnU=
github.com/adedayo/cidr v0.1.5/go.mod h1:By6g82fmUcv8/Z/6JcDs1D4wO4gc/Ookb842bVCV6Io=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=