fscan/common/ParseIP.go
2020-11-15 22:17:57 +08:00

200 lines
4.2 KiB
Go

package common
import (
"bufio"
"errors"
"fmt"
"net"
"os"
"regexp"
"strconv"
"strings"
)
var ParseIPErr =errors.New("host parsing error\n" +
"format: \n"+
"192.168.1.1\n" +
"192.168.1.1/8\n"+
"192.168.1.1/16\n"+
"192.168.1.1/24\n"+
"192.168.1.1,192.168.1.2\n" +
"192.168.1.1-255")
func ParseIP(ip string,filename string)(hosts []string,err error){
if ip != ""{
hosts,err = ParseIPs(ip)
}
if filename != ""{
var filehost []string
filehost,_ = Readipfile(filename)
hosts = append(hosts,filehost...)
}
hosts = RemoveDuplicate(hosts)
return hosts,err
}
func ParseIPs(ip string)(hosts []string,err error){
if strings.Contains(ip,","){
IPList:=strings.Split(ip,",")
var ips []string
for _,ip:=range IPList{
ips,err = ParseIPone(ip)
CheckErr(ip,err)
hosts = append(hosts,ips...)
}
return hosts,err
}else {
hosts,err = ParseIPone(ip)
CheckErr(ip,err)
return hosts,err
}
}
func ParseIPone(ip string)([]string,error){
reg:=regexp.MustCompile(`[a-zA-Z]+`)
switch {
case strings.Contains(ip[len(ip)-3:len(ip)],"/24"):
return ParseIPA(ip)
case strings.Contains(ip[len(ip)-3:len(ip)],"/16"):
return ParseIPD(ip)
case strings.Contains(ip[len(ip)-2:len(ip)],"/8"):
return ParseIPE(ip)
case strings.Count(ip,"-")==1:
return ParseIPC(ip)
case reg.MatchString(ip):
_, err := net.LookupHost(ip)
if err != nil {
return nil,err
}
return []string{ip},nil
default:
testIP:=net.ParseIP(ip)
if testIP==nil{
return nil,ParseIPErr
}
return []string{ip},nil
}
}
//Parsing CIDR IP
func ParseIPA(ip string)([]string,error){
realIP:=ip[:len(ip)-3]
testIP:=net.ParseIP(realIP)
if testIP==nil{
return nil,ParseIPErr
}
IPrange:=strings.Join(strings.Split(realIP,".")[0:3],".")
var AllIP []string
for i:=0;i<=255;i++{
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(i))
}
return AllIP,nil
}
//Resolving multiple IPS, for example: 192.168.111.1,192.168.111.2
func ParseIPB(ip string)([]string,error){
IPList:=strings.Split(ip,",")
for _,i:=range IPList{
testIP:=net.ParseIP(i)
if testIP==nil{
return nil,ParseIPErr
}
}
return IPList,nil
}
//Resolving a range of IP,for example: 192.168.111.1-255
func ParseIPC(ip string)([]string,error){
IPRange:=strings.Split(ip,"-")
testIP:=net.ParseIP(IPRange[0])
Range,err:=strconv.Atoi(IPRange[1])
if testIP==nil || Range>255 || err!=nil{
return nil,ParseIPErr
}
SplitIP:=strings.Split(IPRange[0],".")
ip1,err1:=strconv.Atoi(SplitIP[3])
ip2,err2:=strconv.Atoi(IPRange[1])
PrefixIP:=strings.Join(SplitIP[0:3],".")
var AllIP []string
if ip1>ip2 || err1!=nil || err2!=nil{
return nil,ParseIPErr
}
for i:=ip1;i<=ip2;i++{
AllIP=append(AllIP,PrefixIP+"."+strconv.Itoa(i))
}
return AllIP,nil
}
func ParseIPD(ip string)([]string,error){
realIP:=ip[:len(ip)-3]
testIP:=net.ParseIP(realIP)
if testIP==nil{
return nil,ParseIPErr
}
IPrange:=strings.Join(strings.Split(realIP,".")[0:2],".")
var AllIP []string
for a:=0;a<=255;a++{
for b:=0;b<=255;b++{
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b))
}
}
return AllIP,nil
}
func ParseIPE(ip string)([]string,error){
realIP:=ip[:len(ip)-2]
testIP:=net.ParseIP(realIP)
if testIP==nil{
return nil,ParseIPErr
}
IPrange:=strings.Join(strings.Split(realIP,".")[0:1],".")
var AllIP []string
for a:=0;a<=255;a++{
for b:=0;b<=255;b++{
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(1))
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(254))
}
}
return AllIP,nil
}
func Readipfile(filename string)([]string,error){
file, err := os.Open(filename)
if err!=nil{
fmt.Println("Open %s error, %v", filename,err)
os.Exit(0)
}
defer file.Close()
var content []string
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
host,err := ParseIPs(text)
CheckErr(text,err)
content=append(content,host...)
}
}
return content,nil
}
func RemoveDuplicate(old []string) ([]string) {
result := make([]string, 0, len(old))
temp := map[string]struct{}{}
for _, item := range old {
if _, ok := temp[item]; !ok {
temp[item] = struct{}{}
result = append(result, item)
}
}
return result
}