@@ -24,7 +24,7 @@ func loadText(path string) ([]string, error) {
2424 defer f .Close ()
2525
2626 var entries []string
27- var skipped int
27+ var skipped , cidrCount int
2828 sc := bufio .NewScanner (f )
2929 for sc .Scan () {
3030 line := strings .TrimSpace (sc .Text ())
@@ -36,6 +36,15 @@ func loadText(path string) ([]string, error) {
3636 entries = append (entries , line )
3737 continue
3838 }
39+ // Try CIDR notation (e.g. 1.2.3.0/24)
40+ if strings .Contains (line , "/" ) {
41+ ips , err := expandCIDR (line )
42+ if err == nil {
43+ cidrCount ++
44+ entries = append (entries , ips ... )
45+ continue
46+ }
47+ }
3948 ip := line
4049 // Strip optional :port suffix
4150 if host , _ , err := net .SplitHostPort (line ); err == nil {
@@ -50,12 +59,46 @@ func loadText(path string) ([]string, error) {
5059 if err := sc .Err (); err != nil {
5160 return nil , err
5261 }
62+ if cidrCount > 0 {
63+ fmt .Fprintf (os .Stderr , "input: expanded %d CIDR ranges -> %d IPs\n " , cidrCount , len (entries ))
64+ }
5365 if skipped > 0 {
5466 fmt .Fprintf (os .Stderr , "input: skipped %d invalid entries\n " , skipped )
5567 }
68+ if len (entries ) > 100000 {
69+ fmt .Fprintf (os .Stderr , "warning: %d IPs is a lot — consider using smaller CIDR ranges or filtering first\n " , len (entries ))
70+ }
5671 return entries , nil
5772}
5873
74+ func expandCIDR (cidr string ) ([]string , error ) {
75+ ip , ipnet , err := net .ParseCIDR (cidr )
76+ if err != nil {
77+ return nil , err
78+ }
79+
80+ var ips []string
81+ for ip := ip .Mask (ipnet .Mask ); ipnet .Contains (ip ); incIP (ip ) {
82+ ips = append (ips , ip .String ())
83+ }
84+
85+ // Remove network and broadcast addresses for IPv4 ranges > /31
86+ if len (ips ) > 2 {
87+ ips = ips [1 : len (ips )- 1 ]
88+ }
89+
90+ return ips , nil
91+ }
92+
93+ func incIP (ip net.IP ) {
94+ for j := len (ip ) - 1 ; j >= 0 ; j -- {
95+ ip [j ]++
96+ if ip [j ] > 0 {
97+ break
98+ }
99+ }
100+ }
101+
59102func loadJSON (path string , includeFailed bool ) ([]string , error ) {
60103 data , err := os .ReadFile (path )
61104 if err != nil {
0 commit comments