Created
June 17, 2024 03:35
-
-
Save Zhwt/dd29491b432d530daa2d49d57c7cb171 to your computer and use it in GitHub Desktop.
Go tool for merging CIDR ranges.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"log" | |
"net/http" | |
"net/netip" | |
"os" | |
"go4.org/netipx" | |
) | |
// readCIDRsFromURL reads CIDR ranges from a URL. | |
func readCIDRsFromURL(url string) ([]netip.Prefix, error) { | |
log.Println("Reading CIDRs from URL: ", url) | |
resp, err := http.Get(url) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
var cidrs []netip.Prefix | |
scanner := bufio.NewScanner(resp.Body) | |
for scanner.Scan() { | |
line := scanner.Text() | |
cidr, err := netip.ParsePrefix(line) | |
if err != nil { | |
return nil, err | |
} | |
cidrs = append(cidrs, cidr) | |
} | |
return cidrs, scanner.Err() | |
} | |
// readCIDRsFromFile reads CIDR ranges from a file. | |
func readCIDRsFromFile(filename string) ([]netip.Prefix, error) { | |
log.Println("Reading CIDRs from file: ", filename) | |
file, err := os.Open(filename) | |
if err != nil { | |
return nil, err | |
} | |
defer file.Close() | |
var cidrs []netip.Prefix | |
scanner := bufio.NewScanner(file) | |
for scanner.Scan() { | |
line := scanner.Text() | |
cidr, err := netip.ParsePrefix(line) | |
if err != nil { | |
return nil, err | |
} | |
cidrs = append(cidrs, cidr) | |
} | |
return cidrs, scanner.Err() | |
} | |
// writeCIDRsToFile writes CIDR ranges to a file. | |
func writeCIDRsToFile(filename string, cidrs []netip.Prefix) error { | |
log.Println("Writing CIDRs to file: ", filename) | |
file, err := os.Create(filename) | |
if err != nil { | |
return err | |
} | |
defer file.Close() | |
writer := bufio.NewWriter(file) | |
for _, cidr := range cidrs { | |
_, err := writer.WriteString(cidr.String() + "\n") | |
if err != nil { | |
return err | |
} | |
} | |
return writer.Flush() | |
} | |
// mergeCIDRs merges and returns the unified list of CIDR ranges. | |
func mergeCIDRs(cidrs []netip.Prefix) []netip.Prefix { | |
var b netipx.IPSetBuilder | |
for _, cidr := range cidrs { | |
b.AddPrefix(cidr) | |
} | |
// ignore errors on purpose to avoid errors in single cidr causing fail output, | |
// see comment for IPSetBuilder.IPSet() | |
ipset, _ := b.IPSet() | |
return ipset.Prefixes() | |
} | |
func main() { | |
// Define your sources here. | |
urlSources := []string{ | |
"https://www.ipdeny.com/ipblocks/data/aggregated/cn-aggregated.zone", | |
"https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt", | |
} | |
fileSources := []string{ | |
//"ip1.txt", | |
//"ip2.txt", | |
} | |
fileSources = os.Args[1:] | |
var allCIDRs []netip.Prefix | |
// Read CIDRs from URL sources. | |
for _, url := range urlSources { | |
cidrs, err := readCIDRsFromURL(url) | |
if err != nil { | |
fmt.Printf("Error reading CIDRs from URL %s: %v\n", url, err) | |
continue | |
} | |
allCIDRs = append(allCIDRs, cidrs...) | |
} | |
// Read CIDRs from file sources. | |
for _, file := range fileSources { | |
cidrs, err := readCIDRsFromFile(file) | |
if err != nil { | |
fmt.Printf("Error reading CIDRs from file %s: %v\n", file, err) | |
continue | |
} | |
allCIDRs = append(allCIDRs, cidrs...) | |
} | |
// Merge CIDRs. | |
log.Println("Merging CIDRs...") | |
mergedCIDRs := mergeCIDRs(allCIDRs) | |
// Output the merged CIDRs. | |
//fmt.Println("Merged CIDRs:") | |
//for _, cidr := range mergedCIDRs { | |
// fmt.Println(cidr) | |
//} | |
// Write the merged CIDRs to a file. | |
err := writeCIDRsToFile("merged_cidrs.txt", mergedCIDRs) | |
if err != nil { | |
fmt.Printf("Error writing CIDRs to file: %v\n", err) | |
return | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment