You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gdns/ipnet.go

90 lines
1.4 KiB
Go

package main
import (
"bufio"
"fmt"
"github.com/miekg/dns"
"log"
"net"
"os"
"strings"
"unicode"
)
// parse ip range region file
// format
// ip, netmask, prefixlen
func parse_net(fn string) []*net.IPNet {
fp, err := os.Open(fn)
if err != nil {
log.Fatal(err)
return []*net.IPNet{}
}
defer fp.Close()
nets := []*net.IPNet{}
reader := bufio.NewReader(fp)
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
line = strings.Trim(line, "\r\n")
fnds := strings.FieldsFunc(line, func(c rune) bool {
if unicode.IsSpace(c) {
return true
}
if c == ',' {
return true
}
return false
})
if len(fnds) != 3 {
continue
}
if _, net1, err := net.ParseCIDR(
fmt.Sprintf("%s/%s", fnds[0], fnds[2])); err == nil {
nets = append(nets, net1)
} else {
log.Fatal(err)
}
}
return nets
}
// test ip in ip range region
func in_region(ip net.IP, nets []*net.IPNet) bool {
for _, n := range nets {
if n.Contains(ip) {
return true
}
}
return false
}
// test dns reply A or AAAA in special ip range region
func answer_in_region(m *dns.Msg, nets []*net.IPNet) bool {
// no region loaded, return true
if len(nets) == 0 {
return true
}
for _, rr := range m.Answer {
if a, ok := rr.(*dns.A); ok {
if in_region(a.A, nets) {
return true
}
}
if aaaa, ok := rr.(*dns.AAAA); ok {
if in_region(aaaa.AAAA, nets) {
return true
}
}
}
return false
}