github.com/TeaOSLab/EdgeNode@v1.3.8/internal/waf/values/ip_range.go (about) 1 // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . 2 3 package values 4 5 import ( 6 "bytes" 7 "net" 8 "strings" 9 ) 10 11 type IPRangeType = string 12 13 const ( 14 IPRangeTypeCIDR IPRangeType = "cidr" // CIDR 15 IPRangeTypeSingeIP IPRangeType = "singleIP" // 单个IP 16 IPRangeTypeRange IPRangeType = "range" // IP范围,IP1-IP2 17 ) 18 19 type IPRange struct { 20 Type IPRangeType 21 CIDR *net.IPNet 22 IPFrom net.IP 23 IPTo net.IP 24 } 25 26 func (this *IPRange) Contains(netIP net.IP) bool { 27 if netIP == nil { 28 return false 29 } 30 switch this.Type { 31 case IPRangeTypeCIDR: 32 if this.CIDR != nil { 33 return this.CIDR.Contains(netIP) 34 } 35 case IPRangeTypeSingeIP: 36 if this.IPFrom != nil { 37 return this.IPFrom.Equal(netIP) 38 } 39 case IPRangeTypeRange: 40 return bytes.Compare(this.IPFrom, netIP) <= 0 && bytes.Compare(this.IPTo, netIP) >= 0 41 } 42 return false 43 } 44 45 type IPRangeList struct { 46 Ranges []*IPRange 47 } 48 49 func NewIPRangeList() *IPRangeList { 50 return &IPRangeList{} 51 } 52 53 func ParseIPRangeList(value string) *IPRangeList { 54 var list = NewIPRangeList() 55 56 if len(value) == 0 { 57 return list 58 } 59 60 var lines = strings.Split(value, "\n") 61 for _, line := range lines { 62 line = strings.TrimSpace(line) 63 if len(line) == 0 { 64 continue 65 } 66 67 if strings.Contains(line, ",") { // IPFrom,IPTo 68 var pieces = strings.SplitN(line, ",", 2) 69 if len(pieces) == 2 { 70 var ipFromString = strings.TrimSpace(pieces[0]) 71 if len(ipFromString) == 0 { 72 ipFromString = "0.0.0.0" 73 } 74 var ipFrom = net.ParseIP(ipFromString) 75 var ipTo = net.ParseIP(strings.TrimSpace(pieces[1])) 76 if ipFrom != nil && ipTo != nil { 77 if bytes.Compare(ipFrom, ipTo) > 0 { 78 ipFrom, ipTo = ipTo, ipFrom 79 } 80 list.Ranges = append(list.Ranges, &IPRange{ 81 Type: IPRangeTypeRange, 82 IPFrom: ipFrom, 83 IPTo: ipTo, 84 }) 85 } 86 } 87 } else if strings.Contains(line, "-") { // IPFrom-IPTo 88 var pieces = strings.SplitN(line, "-", 2) 89 if len(pieces) == 2 { 90 var ipFrom = net.ParseIP(strings.TrimSpace(pieces[0])) 91 var ipTo = net.ParseIP(strings.TrimSpace(pieces[1])) 92 if ipFrom != nil && ipTo != nil { 93 if bytes.Compare(ipFrom, ipTo) > 0 { 94 ipFrom, ipTo = ipTo, ipFrom 95 } 96 list.Ranges = append(list.Ranges, &IPRange{ 97 Type: IPRangeTypeRange, 98 IPFrom: ipFrom, 99 IPTo: ipTo, 100 }) 101 } 102 } 103 } else if strings.Contains(line, "/") { // CIDR 104 _, cidr, _ := net.ParseCIDR(line) 105 if cidr != nil { 106 list.Ranges = append(list.Ranges, &IPRange{ 107 Type: IPRangeTypeCIDR, 108 CIDR: cidr, 109 }) 110 } 111 } else { // single ip 112 var netIP = net.ParseIP(line) 113 if netIP != nil { 114 list.Ranges = append(list.Ranges, &IPRange{ 115 Type: IPRangeTypeSingeIP, 116 IPFrom: netIP, 117 }) 118 } 119 } 120 } 121 122 return list 123 } 124 125 func (this *IPRangeList) Contains(ip string) bool { 126 var netIP = net.ParseIP(ip) 127 if netIP == nil { 128 return false 129 } 130 for _, r := range this.Ranges { 131 if r.Contains(netIP) { 132 return true 133 } 134 } 135 return false 136 }