You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 21:24:03