C/C++ 提取DNS请求/响应数据包之中的 Quesion 内容

它主要是提取DNS数据包之中查询问题的信息,如:问题类型、问题类别、问题内容(域/IP),我们如果想要对于某个DNS数据包需要进行遥测的时,或者进行NS缓存生命周期管理,那么就需要类似这样的函数实现了。

例子:

                uint16_t queries_type = 0;uint16_t queries_clazz = 0;ppp::string domain = ppp::net::native::dns::ExtractHostY((Byte*)packet, packet_length,[&queries_type, &queries_clazz](ppp::net::native::dns::dns_hdr* h, ppp::string& domain, uint16_t type, uint16_t clazz) noexcept -> bool {queries_type = type;queries_clazz = clazz;return true;});

源声明:

#pragma pack(push, 1)struct dns_hdr {uint16_t                                                                usTransID;         // 标识符uint16_t                                                                usFlags;           // 各种标志位uint16_t                                                                usQuestionCount;   // Question字段个数 uint16_t                                                                usAnswerCount;     // Answer字段个数uint16_t                                                                usAuthorityCount;  // Authority字段个数uint16_t                                                                usAdditionalCount; // Additional字段个数};
#pragma pack(pop)static constexpr int MAX_DOMAINNAME_LEN                                     = 255; /* MAX: 253 +. ≈ 254 BYTE or 254 CHAR+. ≈ 255 BYTE */static constexpr int DNS_PORT                                               = PPP_DNS_SYS_PORT;static constexpr int DNS_TYPE_SIZE                                          = 2;static constexpr int DNS_CLASS_SIZE                                         = 2;static constexpr int DNS_TTL_SIZE                                           = 4;static constexpr int DNS_DATALEN_SIZE                                       = 2;static constexpr int DNS_TYPE_A                                             = 0x0001; //1 a host addressstatic constexpr int DNS_TYPE_AAAA                                          = 0x001c; //1 a host addressstatic constexpr int DNS_TYPE_CNAME                                         = 0x0005; //5 the canonical name for an aliasstatic constexpr int DNS_CLASS_IN                                           = 0x0001;static constexpr int DNS_PACKET_MAX_SIZE                                    = (sizeof(struct dns_hdr) + MAX_DOMAINNAME_LEN + DNS_TYPE_SIZE + DNS_CLASS_SIZE);ppp::string                                                                 ExtractHost(const Byte*                                                             szPacketStartPos, int                                                                     nPacketLength) noexcept;ppp::string                                                                 ExtractHostX(const Byte*                                                             szPacketStartPos, int                                                                     nPacketLength, const ppp::function<bool(dns_hdr*)>&                                    fPredicateB) noexcept;ppp::string                                                                 ExtractHostY(const Byte*                                                             szPacketStartPos, int                                                                     nPacketLength, const ppp::function<bool(dns_hdr*, ppp::string&, uint16_t, uint16_t)>&  fPredicateE) noexcept;ppp::string                                                                 ExtractHostZ(const Byte*                                                             szPacketStartPos, int                                                                     nPacketLength, const ppp::function<bool(dns_hdr*)>&                                    fPredicateB, const ppp::function<bool(dns_hdr*, ppp::string&, uint16_t, uint16_t)>&  fPredicateE) noexcept;

源实现:

                static bool ExtractName(char* szEncodedStr, uint16_t* pusEncodedStrLen, char* szDotStr, uint16_t nDotStrSize, char* szPacketStartPos, char* szPacketEndPos, char** ppDecodePos) noexcept{if (NULL == szEncodedStr || NULL == pusEncodedStrLen || NULL == szDotStr || szEncodedStr >= szPacketEndPos){return false;}char*& pDecodePos = *ppDecodePos;pDecodePos = szEncodedStr;uint16_t usPlainStrLen = 0;uint8_t nLabelDataLen = 0;*pusEncodedStrLen = 0;while ((nLabelDataLen = *pDecodePos) != 0x00){// Normal Format,LabelDataLen + Labelif ((nLabelDataLen & 0xc0) == 0) {if ((usPlainStrLen + nLabelDataLen + 1) > nDotStrSize || (pDecodePos + nLabelDataLen + 1) >= szPacketEndPos){return false;}memcpy(szDotStr + usPlainStrLen, pDecodePos + 1, nLabelDataLen);memcpy(szDotStr + usPlainStrLen + nLabelDataLen, ".", 1);pDecodePos += (nLabelDataLen + 1);usPlainStrLen += (nLabelDataLen + 1);*pusEncodedStrLen += (nLabelDataLen + 1);}else  {// Message compression format is 11000000 00000000, consisting of two bytes. // The first two bits are the jump flag, and the last 14 bits are the offset of the jump。if (NULL == szPacketStartPos){return false;}uint16_t usJumpPos = ntohs(*(uint16_t*)(pDecodePos)) & 0x3fff;uint16_t nEncodeStrLen = 0;if (!ExtractName(szPacketStartPos + usJumpPos, &nEncodeStrLen, szDotStr + usPlainStrLen, nDotStrSize - usPlainStrLen, szPacketStartPos, szPacketEndPos, ppDecodePos)){return false;}else{*pusEncodedStrLen += 2;return true;}}}++pDecodePos;szDotStr[usPlainStrLen - 1] = '\0';*pusEncodedStrLen += 1;return true;}static bool ExtractHost_DefaultPredicateB(dns_hdr* h) noexcept{uint16_t usFlags = htons(h->usFlags) & htons(DNS_TYPE_A);return usFlags != 0;}ppp::string ExtractHost(const Byte* szPacketStartPos, int nPacketLength) noexcept{ppp::function<bool(dns_hdr*)> predicate = ExtractHost_DefaultPredicateB;return ExtractHostX(szPacketStartPos, nPacketLength, predicate);}ppp::string ExtractHostX(const Byte* szPacketStartPos, int nPacketLength, const ppp::function<bool(dns_hdr*)>& fPredicateB) noexcept{ppp::function<bool(dns_hdr*, ppp::string&, uint16_t, uint16_t)> fPredicateE =[](dns_hdr* h, ppp::string& domain, uint16_t type, uint16_t clazz) noexcept -> bool{return true;};return ExtractHostZ(szPacketStartPos, nPacketLength, fPredicateB, fPredicateE);}ppp::string ExtractHostY(const Byte* szPacketStartPos, int nPacketLength, const ppp::function<bool(dns_hdr*, ppp::string&, uint16_t, uint16_t)>& fPredicateE) noexcept{ppp::function<bool(dns_hdr*)> fPredicateB = ExtractHost_DefaultPredicateB;return ExtractHostZ(szPacketStartPos, nPacketLength, fPredicateB, fPredicateE);}ppp::string ExtractHostZ(const Byte*                                        szPacketStartPos, int                                                                     nPacketLength, const ppp::function<bool(dns_hdr*)>&                                    fPredicateB, const ppp::function<bool(dns_hdr*, ppp::string&, uint16_t, uint16_t)>&  fPredicateE) noexcept{static constexpr int MAX_DOMAINNAME_LEN_STR = MAX_DOMAINNAME_LEN + 1;if (NULL == fPredicateB || NULL == fPredicateE){return ppp::string();}struct dns_hdr* pDNSHeader = (struct dns_hdr*)szPacketStartPos;if (NULL == pDNSHeader || nPacketLength < sizeof(pDNSHeader)){return ppp::string();}if (!fPredicateB(pDNSHeader)){return ppp::string();}int nQuestionCount = htons(pDNSHeader->usQuestionCount);if (nQuestionCount < 1){return ppp::string();}std::shared_ptr<Byte> pioBuffers = make_shared_alloc<Byte>(MAX_DOMAINNAME_LEN_STR);if (NULL == pioBuffers) {return ppp::string();}uint16_t pusEncodedStrLen = 0;char* pDecodePos = NULL;char* szDomainDotStr = (char*)pioBuffers.get();if (!ExtractName((char*)(pDNSHeader + 1), &pusEncodedStrLen, szDomainDotStr,(uint16_t)MAX_DOMAINNAME_LEN_STR, (char*)szPacketStartPos, (char*)szPacketStartPos + nPacketLength, &pDecodePos)){return ppp::string();}while (pusEncodedStrLen > 0 && szDomainDotStr[pusEncodedStrLen - 1] == '\x0'){pusEncodedStrLen--;}if (pusEncodedStrLen == 0){return ppp::string();}uint16_t* pusDecodePos = (uint16_t*)pDecodePos;uint16_t usQueriesType = ntohs(pusDecodePos[0]);uint16_t usQueriesClass = ntohs(pusDecodePos[1]);ppp::string strDomianStr(szDomainDotStr, pusEncodedStrLen);if (!fPredicateE(pDNSHeader, strDomianStr, usQueriesType, usQueriesClass)){return ppp::string();}return strDomianStr.data();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/30483.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中System.setProperty()用法总结

Java中System.setProperty()用法总结 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java编程中&#xff0c;System.setProperty()方法用于设置系统属性。系统…

数据结构:4.1.2二叉搜索树的插入

整个框架和FInd函数的实现是一样的&#xff0c;但是也有不同&#xff08;注意&#xff09; 35>30 向30的右子树 35<41 向41的左子树 35>33 向33的右子树&#xff0c;但33右边为空&#xff0c;所以35就挂在33的右边 因为要把35挂在33的右边&#xff0c;所以要把33的…

绘制eps格式的实验结果图

1. python 画图保存为eps python画出实验结果图之后有时想进行标记从而让读者通过看图就能明白做了什么。IEEE 一般要求实验结果是eps格式&#xff08;矢量图&#xff09;&#xff0c;如果在python画图之后不需要进行进一步的编辑&#xff0c;可以直接使用Tkagg画布在小窗口画…

Solkane 冷媒性能计算软件-管路计算

下载 制冷管道设计 制冷管路的压降会降低制冷量&#xff0c;增大功耗。但不同部分的管路允许的压降的数量级是不同的。 制冷管路的压降不是唯一的考虑因素&#xff0c;制冷剂的流速往往比压降更重要。 制冷系统中&#xff0c;压缩机、阀、汽液分离器或其他附件上的连接件的尺…

VSCode 安装NeoVim扩展(详细)

目录 1、安装NeoVim扩展 2、windows安装Neovim软件 3、优化操作相关的配置&#xff1a; 5、Neovim最好的兼容性配置 6、技巧和特点 6.1 故障排除 6.2、Neovim 插件组合键设置 6.3、跳转列表 1、安装NeoVim扩展 在扩展商店搜索NeoVim&#xff0c;安装扩展 2、windows安装…

重学java 77.JDK新特性 ③ Stream流

The road is long,it can be really hard.Whatever you do,you hold on to that foolishly hopeful smile —— 24.6.19 Stream流 stream流中的"流"不是特指"IO流",它是一种"流式编程"(编程方式),可以看做是"流水线 package S109Stream;im…

JavaScript——JavaScript对象:对象的创建方式、in关键字、遍历对象的属性和方法、内置对象

目录 JavaScript对象 对象的创建方式 利用字面量创建对象 利用new Object创建对象 利用构造函数创建对象 类 in关键字 遍历对象的属性和方法 内置对象 JavaScript对象 对象的创建方式 利用字面量创建对象 /* 面向对象的编程思想&#xff1a;写类创建对象并调用对象…

【Hive】new HiveConf()时加载的配置浅析

简单看下源码&#xff1a; org.apache.hadoop.hive.conf.HiveConf HiveConf中有静态代码块&#xff0c;内容就是调用findConfigFile方法&#xff0c;尝试读取hive-default.xml&#xff0c;hive-site.xml&#xff0c;hivemetastore-site.xml&#xff0c;hiveserver2-site.xml。…

【Python机器学习实战】 | Lasso回归和弹性网回归详细分析研究

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

react使用OpenLayers实现类似船某网在地图放大时展示具体船舶符号缩小时显示聚合小点效果

一、效果 如图所示&#xff0c;地图缩小&#xff08;即比例尺放大&#xff09;时&#xff0c;显示聚合小绿点&#xff1b; 地图放大&#xff08;比例尺缩小&#xff09;时&#xff0c;展示具体船舶符号&#xff1a; 二、思路 1&#xff09;设置2个图层&#xff0c;一个展示…

计网重点面试题-TCP三次握手四次挥手

三次握手 第一次握手(syn1) 客户端会随机初始化序号&#xff08;client_isn&#xff09;&#xff0c;将此序号置于 TCP 首部的「序列号」字段中&#xff0c;同时把 SYN 标志位置为 1&#xff0c;表示 SYN 报文。接着把第一个 SYN 报文发送给服务端&#xff0c;表示向服务端发…

Microsoft Edge 查看已保存账号的密码

1、打开更多菜单选项 打开浏览器右上角的“...”设置及其他&#xff0c;快捷键&#xff1a;ALTF。 2、打开设置选项 选择“设置”&#xff0c;快捷键&#xff1a;g 3、点击密码 在“个人资料”选项中找到密码选项 4、电子钱包 电子钱包会显示“站点和应用”所保存的账户信息…

SpringCloud和K8s的区别

服务发现与注册&#xff1a; Spring Cloud中的Eureka组件提供了服务注册与发现的功能&#xff0c;允许微服务相互查找并通信。Kubernetes中的kube-apiserver作为控制平面的一部分&#xff0c;提供了服务发现的能力&#xff0c;允许系统内部组件和外部客户端通过API发现和访问集…

科技云报道:推进工业新质生产力机器人有望成为AI下一个新引擎?

科技云报道原创。 推进工业新质生产力&#xff0c;机器人有望成为AI下一个“新引擎”&#xff1f; “人工智能的下一波浪潮是机器人技术&#xff0c;这是一个‘0亿美元市场’&#xff0c;但未来将价值数十亿美元&#xff0c;就像Nvidia刚起步时的GPU加速计算一样……”这是英…

JAVAEE之网络原理(2)_传输控制协议(TCP)的连接管理机制,三次握手、四次挥手,及常见面试题

前言 在上一节中&#xff0c;我们简单介绍了 TCP 协议的相关概念和格式&#xff0c;而且还介绍了TCP 协议原理中的 确认应答机制、超时重传机制&#xff0c;在本节中我们将会继续介绍 TCP协议原理中的其他机制。 连接管理机制&#xff08;安全机制&#xff09; 在正常情况下&…

lvgl的应用:移植MusicPlayer(基于STM32F407)

目录 概述 1 软硬件环境 1.1 UI开发版本 1.2 MCU开发环境 1.3 注意点 2 GUI Guider开发UI 2.1 使用GUI Guider创建UI 2.2 GUI Guider编译项目和测试 2.2.1 GUI Guider编译项目 2.2.2 编译 2.3 了解GUI Guider生成代码 3 移植项目 3.1 Keil中加载代码 3.2 调用G…

漏洞挖掘 | 记一次src挖掘-小程序敏感信息泄露

权当是一次漏洞挖掘的思路分享 闲言 就现在的一个web漏洞挖掘强度还是非常高的&#xff0c;所以我们不妨把我们的眼光投向一个之前可能未曾涉及到的区域———小程序 是的微信小程序&#xff0c;这玩意的防范能力和过滤能力其实对比web方向是要弱小很多的 进入正题 以下就是…

Javase.抽象类和接口

抽象类和接口 【本节目标】1.抽象类1.1抽象类的概念1.2 抽象类语法1.3 抽象类特性1.4 抽象类的作用 2. 接口2.1 接口的概念2.2 语法规则2.3 接口使用2.4 接口特性2.5 实现多个接口2.6 接口间的继承2.7 接口使用实例2.8Clonable 接口和深拷贝2.9 抽象类和接口的区别 3. Object类…

开源一套Trados Sdlxliff 对比工具

开源一套Trados Sdlxliff 对比工具 在Trados翻译过程中经常对需要进行版本控制和对比&#xff0c;例如对比不同设置下生成的sdlxliff文件&#xff0c;对比不同的机器翻译结果以及对比机器翻译和人工翻译&#xff0c;对比翻译和审校等等。 当然SDL官方也提供了对比工具 https:…

[手机Linux PostmarketOS]二,cpolar实现内外网穿透

要想你的手机linux服务器能够通过外网可以访问到&#xff0c;必须需要借助工具把内网和外网打通&#xff0c;这样才能不管你在哪里都可以访问你的linux服务器&#xff0c;否则你只能在家连接同一的wifi网络才能连接&#xff0c;其实内网穿透工具大同小异&#xff0c;对比的是哪…