Skip to content

Commit 0781179

Browse files
author
Shivam Patel
committed
First Commit
1 parent a639db2 commit 0781179

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*.dll
55
*.so
66
*.dylib
7+
binaries/*
78

89
# Test binary, build with `go test -c`
910
*.test

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all:
2+
GOOS=windows GOARCH=386 go build -o binaries/cidr2ip-win32.exe cidr2ip.go
3+
GOOS=windows GOARCH=amd64 go build -o binaries/cidr2ip-win64.exe cidr2ip.go
4+
GOOS=linux GOARCH=386 go build -o binaries/cidr2ip-linux32 cidr2ip.go
5+
GOOS=linux GOARCH=amd64 go build -o binaries/cidr2ip-linux64 cidr2ip.go
6+
GOOS=darwin GOARCH=386 go build -o binaries/cidr2ip-osx32 cidr2ip.go
7+
GOOS=darwin GOARCH=amd64 go build -o binaries/cidr2ip-osx64 cidr2ip.go

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#cidr2ip
2+
3+
This program converts IPv4 CIDR blocks into their constituent IP addresses.
4+
5+
### Input modes
6+
7+
1. Commnd line arguments
8+
```
9+
code@express:~$ cidr2ip 10.0.0.0/30 192.68.0.0/30
10+
10.0.0.1
11+
10.0.0.2
12+
192.68.0.1
13+
192.68.0.2
14+
```
15+
16+
2. Piped input
17+
```
18+
code@express:~$ cat cidrs.txt | cidr2ip
19+
192.168.0.101
20+
192.168.0.102
21+
```
22+
23+
3. File input
24+
```
25+
code@express:~$ cidr2ip -f cidrs.txt
26+
192.168.0.101
27+
192.168.0.102
28+
```
29+
30+
### Install
31+
32+
#### Download from the releases pages
33+
34+
Download pre-built binary from the release page.
35+
```
36+
37+
```
38+
39+
#### Use `go get`
40+
41+
If you have `golang` tools installed, you can download and build the source code
42+
locally as follows:
43+
```
44+
45+
```

cidr2ip.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"fmt"
7+
"log"
8+
"net"
9+
"os"
10+
"regexp"
11+
)
12+
13+
const (
14+
Version = "1.0.0"
15+
IPRegex = `\b(?:\d{1,3}\.){3}\d{1,3}\b$`
16+
)
17+
18+
var (
19+
cidrFilePtr = flag.String("f", "",
20+
"[Optional] Name of file with CIDR blocks")
21+
)
22+
23+
func main() {
24+
flag.Usage = usage
25+
flag.Parse()
26+
27+
info, err := os.Stdin.Stat()
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
args := os.Args[1:]
32+
33+
if *cidrFilePtr != "" {
34+
file, err := os.Open(*cidrFilePtr)
35+
if err != nil {
36+
log.Fatal(err)
37+
}
38+
defer file.Close()
39+
40+
scanner := bufio.NewScanner(file)
41+
for scanner.Scan() {
42+
displayIPs(scanner.Text())
43+
if err := scanner.Err(); err != nil {
44+
log.Fatal(err)
45+
}
46+
}
47+
} else if info.Mode()&os.ModeNamedPipe != 0 { // data is piped in
48+
scanner := bufio.NewScanner(os.Stdin)
49+
for scanner.Scan() {
50+
displayIPs(scanner.Text())
51+
}
52+
} else if len(args) > 0 { // look for CIDRs on cmd line
53+
for _, ip := range args {
54+
displayIPs(ip)
55+
}
56+
} else { // no piped input, no file provide and no args, display usage
57+
flag.Usage()
58+
}
59+
}
60+
61+
func isIPAddr(cidr string) bool {
62+
match, _ := regexp.MatchString(IPRegex, cidr)
63+
return match
64+
}
65+
66+
func displayIPs(cidr string) {
67+
var ips []string
68+
69+
// if a IP address, display the IP address and return
70+
if isIPAddr(cidr) {
71+
fmt.Println(cidr)
72+
return
73+
}
74+
75+
ipAddr, ipNet, err := net.ParseCIDR(cidr)
76+
if err != nil {
77+
log.Print(err)
78+
return
79+
}
80+
81+
for ip := ipAddr.Mask(ipNet.Mask); ipNet.Contains(ip); increment(ip) {
82+
ips = append(ips, ip.String())
83+
}
84+
85+
// CIDR too small eg. /31
86+
if len(ips) <= 2 {
87+
return
88+
}
89+
90+
for _, ip := range ips[1 : len(ips)-1] {
91+
fmt.Println(ip)
92+
}
93+
}
94+
95+
// The next IP address of a given ip address
96+
// https://stackoverflow.com/a/33925954
97+
func increment(ip net.IP) {
98+
for i := len(ip) - 1; i >= 0; i-- {
99+
ip[i]++
100+
if ip[i] != 0 {
101+
break
102+
}
103+
}
104+
}
105+
106+
func usage() {
107+
fmt.Fprintf(os.Stderr, "CIDR to IPs version %s\n", Version)
108+
fmt.Fprintf(os.Stderr, "Usage: $ cidr2ip [-f <filename>] <list of cidrs> \n")
109+
fmt.Fprintf(os.Stderr, "Example: $ cidr2ip -f cidrs.txt\n")
110+
fmt.Fprintf(os.Stderr, " $ cidr2ip 10.0.0.0/24\n")
111+
fmt.Fprintf(os.Stderr, " $ cat cidrs.txt | cidr2ip \n")
112+
fmt.Fprintf(os.Stderr, "--------------------------\nFlags:\n")
113+
flag.PrintDefaults()
114+
}

cidrs.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This is sample file that can be processed by cidr2ip
2+
# Lines that do not have a CIDR block will be ignored
3+
4+
127.0.0.1
5+
192.168.0.100/30
6+
10.0.0.0/29

0 commit comments

Comments
 (0)