登录
首页 >  Golang >  Go问答

解析类型 dns.RR

来源:stackoverflow

时间:2024-03-07 16:36:24 215浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《解析类型 dns.RR》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我是 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 is a net.IPdns.CNAME.Target which is a string。有关更多详细信息,请参阅 the package documentation

if arec, ok := dreq[0].(*dns.A); ok {
    fmt.Println("    [+] Type is A")
    fmt.Println("    [+] Answer: ", arec.A)
}

终于介绍完啦!小伙伴们,这篇关于《解析类型 dns.RR》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>