go - 解析类型dns.RR
问题描述
我是 Go 新手,并试图让一个小型 DNS 程序能够解析返回的 A 和 CNAME 记录。这是使用 github.com/miekg/dns 包。
我无法理解如何正确解析 A 或 CNAME 返回的资源记录。对于 A 记录,我想获取 IP 地址并将其存储在变量中。对于返回多个 RR 的 CNAME,我想解析名称和地址字段并存储在变量中。
我尝试将结构转换为字符串或将其解压缩无济于事。任何人都可以提供任何见解,非常感谢。
这是下面的代码。文本文件包含一个带有“www”的单行:
package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/miekg/dns"
)
func dns_request_fwd(s string) []dns.RR {
//fmt.Println(s, " : started processing DNS request")
m1 := new(dns.Msg)
m1.Id = dns.Id()
m1.RecursionDesired = true
m1.Question = make([]dns.Question, 1)
m1.Question[0] = dns.Question{s, dns.TypeA, dns.ClassINET}
in, err := dns.Exchange(m1, "8.8.8.8:53")
if err != nil {
log.Fatal(err)
}
if len(in.Answer) > 0 {
//fmt.Println("Response greater than 0 - got something!")
//fmt.Println(in.Answer)
} else {
//fmt.Println("Empty DNS Response")
return nil
}
if _, ok := in.Answer[0].(*dns.A); ok {
//fmt.Println("Detected an 'A' record Answer. Returning RR!")
return in.Answer
} else if _, ok := in.Answer[0].(*dns.CNAME); ok {
//fmt.Println("Detected a 'CNAME' record Answer. Returning RR!")
return in.Answer
} else {
fmt.Println("Returning nil")
return nil
}
}
func main() {
f, err := os.Open("list4.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
domain := "acme.com"
domain_lookup := "." + domain + "."
scanner := bufio.NewScanner(f)
for scanner.Scan() {
a_record := scanner.Text()
lookup := a_record+domain_lookup
fmt.Println("Looking up: ", lookup)
dreq := dns_request_fwd(lookup)
if len(dreq) > 0 {
fmt.Println(" [+] Forward Lookup answer")
if _, ok := dreq[0].(*dns.CNAME); ok {
fmt.Println(" [+] Type is CNAME")
//fmt.Println(dreq[0].(*dns.CNAME))
//fmt.Println(dreq[1].(*dns.A))
fmt.Println(" [+] Alias records: ", len(dreq) -1)
// Iterate through returned alias A records
for i, s := range dreq {
if i == 0{
//Do nothing because first record is repeat of request
} else {
// Need to parse the below RR to get the Name + IP address returned
fmt.Println(" [+] Returned",i, s)
fmt.Println(s[0])
}
}
} else if _, ok := dreq[0].(*dns.A); ok {
fmt.Println(" [+] Type is A")
// Need to parse the below RR to get the IP address returned
fmt.Println(" [+] Answer: ", dreq[0])
}
} else {
fmt.Println(" [-] We Got Nothing")
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
解决方案
您不需要“解析”结构。该库已经解析了响应以便为您提供结构。只需使用结构中具有所需数据的字段,例如dns.A.A
which 是 anet.IP
或dns.CNAME.Target
which 是 astring
。有关更多详细信息,请参阅包文档。
if arec, ok := dreq[0].(*dns.A); ok {
fmt.Println(" [+] Type is A")
fmt.Println(" [+] Answer: ", arec.A)
}
推荐阅读
- r - 使用 str_replace_all() 替换为完美匹配
- reactjs - 自定义钩子返回 Promise 但在 useEffect 内部解析
- git - 如何将一个 git 存储库的一部分集成为另一个存储库的一部分?
- python - Selenium:抓取和打印类
- xml - 如何将 Access-Control-Allow-Origin 添加到在不同域中使用 xslt 的 XML
- amazon-web-services - Docker 容器不在本地运行(Flask 到 AWS ECS - 第 8 部分:Docker)
- jenkins - 等待质量门返回 401
- python - 我如何才能正确地将这个等式与这个期末成绩计算器的 GUI 联系起来?
- firebase - 如何识别请求的来源以及 Firebase 中正在访问哪些文件?
- javascript - 为什么 Bootstrap 5.0.1 中的下拉菜单和汉堡菜单无法在任何地方打开?