-
Notifications
You must be signed in to change notification settings - Fork 0
/
ipinrange.go
133 lines (118 loc) · 2.87 KB
/
ipinrange.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
// ipinrange :
//
// Basic ipV4 filter based on network range
//
// checkout similar code in extractip project
//
// How it works :
// read stdin, output filtered input
// if error output to stderr
//
// Evolutions :
// 2023/07/20 : V0.1
// 2023/11/24 : Negative option
// 2023/11/29 : v1.3
// - remove reserved ip addresses
// - allow array as arg
// - know local network
// so you can extract text :
// cat logs | ipinrange -N local
//
//
import (
"bufio"
"fmt"
"net"
"os"
"regexp"
"strings"
)
func main() {
var (
negativeFlag bool
subnetA []*net.IPNet
netARg string
lenArg = len(os.Args)
re = regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`)
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
Reserved_IP_addresses = []string{
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.88.99.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"224.0.0.0/4",
"233.252.0.0/24",
"240.0.0.0/4",
"255.255.255.255/32",
}
)
switch {
case lenArg >= 2 && os.Args[1] == "-n":
negativeFlag = true
fallthrough
case lenArg > 1:
netARg = os.Args[lenArg-1]
default:
fmt.Printf("Usage: ipinrange [-n(egative)] []network/x")
os.Exit(-1)
}
if netARg == "local" { // Special Case
subnetA = parseNetStringtoCIDR(local)
} else {
subnetA = argstoCIDR(netARg)
}
Reserved_IP_addressesCIDR := parseNetStringtoCIDR(Reserved_IP_addresses)
scanner := bufio.NewScanner(os.Stdin) // Reading stdin
for scanner.Scan() {
text := scanner.Text()
submatchall := re.FindAllString(text, -1) // Finding ipv4
for _, element := range submatchall {
elementIP := net.ParseIP(element) // Real ipv4 ?
found := isIn(elementIP, subnetA) // march our network arg ?
if (found && !negativeFlag) || (negativeFlag && !found) { // print ?
if !isIn(elementIP, Reserved_IP_addressesCIDR) { // exclude bogon
fmt.Println(text)
}
}
}
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}
// argstoCIDR return CIDRparsed array from "net,net"
func argstoCIDR(arg string) []*net.IPNet {
s := strings.Split(arg, ",")
return parseNetStringtoCIDR(s)
}
// isIn check if IP is in a []blocknet
func isIn(ip net.IP, reserved []*net.IPNet) bool {
found := false
for _, v := range reserved {
if v != nil && v.Contains(ip) {
return true
}
}
return found
}
// parseNetStringtoCIDR convert []string to []*net.IPNet
func parseNetStringtoCIDR(block []string) []*net.IPNet {
netBlock := make([]*net.IPNet, len(block))
for k, v := range block {
_, net, err := net.ParseCIDR(v)
if err == nil {
netBlock[k] = net
}
}
return netBlock
}