Go语言使用miekg/dns包解析dns.RR类型A、CNAME资源记录求助
问题解决思路
你遇到的问题本质是dns.RR是通用接口类型,无法直接访问具体记录类型的字段,只需要通过类型断言将接口转为对应的具体结构体指针,就可以直接读取目标属性,不需要做转字符串、解包这类操作。
字段对应关系
*dns.CNAME结构体:Hdr.Name:当前CNAME记录的名称Target:CNAME指向的目标域名
*dns.A结构体:Hdr.Name:当前A记录的名称A:net.IP类型的IP地址,调用String()方法即可得到字符串格式的IP
代码修改示例
直接替换你main函数中处理dreq的逻辑即可:
if len(dreq) > 0 { fmt.Println(" [+] Forward Lookup answer") // 定义变量存储结果,按需使用 var cnameRecords []struct{Name, Target string} var aRecords []struct{Name, Ip string} // 遍历所有返回的资源记录,按类型处理 for _, rr := range dreq { switch rrType := rr.(type) { case *dns.CNAME: // 提取CNAME字段 cname := struct{Name, Target string}{ Name: rrType.Hdr.Name, Target: rrType.Target, } cnameRecords = append(cnameRecords, cname) fmt.Printf(" [+] CNAME记录:%s 指向 %s\n", cname.Name, cname.Target) case *dns.A: // 提取A记录字段 a := struct{Name, Ip string}{ Name: rrType.Hdr.Name, Ip: rrType.A.String(), } aRecords = append(aRecords, a) fmt.Printf(" [+] A记录:%s 解析到 %s\n", a.Name, a.Ip) } } // 后续可以直接使用cnameRecords、aRecords变量里的存储值 } else { fmt.Println(" [-] We Got Nothing") }
补充说明
- 这种用
switch做类型分支的写法比单独判断第一条记录类型更稳妥,哪怕返回的记录顺序变化也不会出错 - 如果你需要区分CNAME对应的A记录,只要匹配
dns.CNAME.Target和后续A记录的Hdr.Name即可
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

