ZBLOG

static int dns_parse_response(char *buffer, struct dns_item **domains) { int i = 0; unsigned char *ptr = buffer; ptr += 4; int querys = ntohs(*(unsigned short*)ptr); ptr += 2; int answers = ntohs(*(unsigned short*)ptr); ptr += 6; for ...

这段代码是用于解析 DNS 响应的函数。它接受一个指向包含响应数据的缓冲区的指针和一个指向 struct dns_item 类型的指针数组,该数组将保存解析出来的域名和对应的 IP 地址。以下是代码逐行的解释:

  • ptr += 4;:跳过前面4个字节,通常用于跳过DNS请求头部。
  • int querys = ntohs(*(unsigned short*)ptr);:从指针位置读取2个字节,并使用 ntohs() 函数将其转换为主机字节序,获取查询数量。
  • int answers = ntohs(*(unsigned short*)ptr);:从指针位置读取2个字节,并使用 ntohs() 函数将其转换为主机字节序,获取回答数量。
  • ptr += 6;:跳过6个字节,用于跳过DNS响应头部中不需要处理的字段。
  • 循环处理查询部分:
    • 进入循环后,通过不断读取每个标签长度(flag)并移动指针来跳过查询部分。
    • 最后再移动4个字节来跳过查询类型(Type)和查询类(Class)字段。

接下来开始处理回答部分:

  • 使用 calloc() 动态分配大小为 answers * sizeof(struct dns_item) 的内存空间,并将返回的指针赋值给变量 list。如果内存分配失败,则返回 -1。

  • 进入循环处理回答部分:

    • bzero(aname, sizeof(aname));:将 aname 数组清零。
    • 使用 dns_parse_name() 函数从 DNS 响应中解析出域名,并将结果存储在 aname 中,同时更新长度 len
    • ptr += 2;:移动指针2个字节,跳过资源记录中的Type字段。
    • type = htons(*(unsigned short*)ptr);:从指针位置读取2个字节,并使用 htons() 函数将其转换为网络字节序,获取资源记录类型。
    • ptr += 4;:移动指针4个字节,跳过资源记录中的Class和TTL字段。
    • datalen = ntohs(*(unsigned short*)ptr);:从指针位置读取2个字节,并使用 ntohs() 函数将其转换为主机字节序,获取数据长度。
    • 根据资源记录类型进行不同的处理:
      • 如果是 CNAME 类型,则通过调用 dns_parse_name() 解析出对应的域名,并移动指针到下一个资源记录。
      • 如果是 HOST 类型且数据长度为 4,则说明是 IPv4 地址。通过调用相应的函数将网络字节序的 IP 地址转换成字符串格式,并打印相关信息。然后将域名和IP地址分别复制到列表结构体中,并递增计数器cnt。
      • 最后移动指针到下一个资源记录。
  • *domains = list;:将解析出来的域名和IP地址列表赋值给传入函数的指针数组。

  • ptr += 2;:跳过最后2个字节,用于处理响应部分中不需要处理的字段。

  • 返回计数器cnt,表示解析出来的域名和IP地址的数量。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=2623

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?