dns-proto.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. // Include ares internal file for DNS protocol details
  2. #include "ares_setup.h"
  3. #include "ares.h"
  4. #include "ares_dns.h"
  5. #include "dns-proto.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <sstream>
  9. namespace ares {
  10. std::string HexDump(std::vector<byte> data) {
  11. std::stringstream ss;
  12. for (size_t ii = 0; ii < data.size(); ii++) {
  13. char buffer[2 + 1];
  14. sprintf(buffer, "%02x", data[ii]);
  15. ss << buffer;
  16. }
  17. return ss.str();
  18. }
  19. std::string HexDump(const byte *data, int len) {
  20. return HexDump(std::vector<byte>(data, data + len));
  21. }
  22. std::string HexDump(const char *data, int len) {
  23. return HexDump(reinterpret_cast<const byte*>(data), len);
  24. }
  25. std::string StatusToString(int status) {
  26. switch (status) {
  27. case ARES_SUCCESS: return "ARES_SUCCESS";
  28. case ARES_ENODATA: return "ARES_ENODATA";
  29. case ARES_EFORMERR: return "ARES_EFORMERR";
  30. case ARES_ESERVFAIL: return "ARES_ESERVFAIL";
  31. case ARES_ENOTFOUND: return "ARES_ENOTFOUND";
  32. case ARES_ENOTIMP: return "ARES_ENOTIMP";
  33. case ARES_EREFUSED: return "ARES_EREFUSED";
  34. case ARES_EBADQUERY: return "ARES_EBADQUERY";
  35. case ARES_EBADNAME: return "ARES_EBADNAME";
  36. case ARES_EBADFAMILY: return "ARES_EBADFAMILY";
  37. case ARES_EBADRESP: return "ARES_EBADRESP";
  38. case ARES_ECONNREFUSED: return "ARES_ECONNREFUSED";
  39. case ARES_ETIMEOUT: return "ARES_ETIMEOUT";
  40. case ARES_EOF: return "ARES_EOF";
  41. case ARES_EFILE: return "ARES_EFILE";
  42. case ARES_ENOMEM: return "ARES_ENOMEM";
  43. case ARES_EDESTRUCTION: return "ARES_EDESTRUCTION";
  44. case ARES_EBADSTR: return "ARES_EBADSTR";
  45. case ARES_EBADFLAGS: return "ARES_EBADFLAGS";
  46. case ARES_ENONAME: return "ARES_ENONAME";
  47. case ARES_EBADHINTS: return "ARES_EBADHINTS";
  48. case ARES_ENOTINITIALIZED: return "ARES_ENOTINITIALIZED";
  49. case ARES_ELOADIPHLPAPI: return "ARES_ELOADIPHLPAPI";
  50. case ARES_EADDRGETNETWORKPARAMS: return "ARES_EADDRGETNETWORKPARAMS";
  51. case ARES_ECANCELLED: return "ARES_ECANCELLED";
  52. default: return "UNKNOWN";
  53. }
  54. }
  55. std::string RcodeToString(int rcode) {
  56. switch (rcode) {
  57. case NOERROR: return "NOERROR";
  58. case FORMERR: return "FORMERR";
  59. case SERVFAIL: return "SERVFAIL";
  60. case NXDOMAIN: return "NXDOMAIN";
  61. case NOTIMP: return "NOTIMP";
  62. case REFUSED: return "REFUSED";
  63. case YXDOMAIN: return "YXDOMAIN";
  64. case YXRRSET: return "YXRRSET";
  65. case NXRRSET: return "NXRRSET";
  66. case NOTAUTH: return "NOTAUTH";
  67. case NOTZONE: return "NOTZONE";
  68. case TSIG_BADSIG: return "BADSIG";
  69. case TSIG_BADKEY: return "BADKEY";
  70. case TSIG_BADTIME: return "BADTIME";
  71. default: return "UNKNOWN";
  72. }
  73. }
  74. std::string RRTypeToString(int rrtype) {
  75. switch (rrtype) {
  76. case T_A: return "A";
  77. case T_NS: return "NS";
  78. case T_MD: return "MD";
  79. case T_MF: return "MF";
  80. case T_CNAME: return "CNAME";
  81. case T_SOA: return "SOA";
  82. case T_MB: return "MB";
  83. case T_MG: return "MG";
  84. case T_MR: return "MR";
  85. case T_NULL: return "NULL";
  86. case T_WKS: return "WKS";
  87. case T_PTR: return "PTR";
  88. case T_HINFO: return "HINFO";
  89. case T_MINFO: return "MINFO";
  90. case T_MX: return "MX";
  91. case T_TXT: return "TXT";
  92. case T_RP: return "RP";
  93. case T_AFSDB: return "AFSDB";
  94. case T_X25: return "X25";
  95. case T_ISDN: return "ISDN";
  96. case T_RT: return "RT";
  97. case T_NSAP: return "NSAP";
  98. case T_NSAP_PTR: return "NSAP_PTR";
  99. case T_SIG: return "SIG";
  100. case T_KEY: return "KEY";
  101. case T_PX: return "PX";
  102. case T_GPOS: return "GPOS";
  103. case T_AAAA: return "AAAA";
  104. case T_LOC: return "LOC";
  105. case T_NXT: return "NXT";
  106. case T_EID: return "EID";
  107. case T_NIMLOC: return "NIMLOC";
  108. case T_SRV: return "SRV";
  109. case T_ATMA: return "ATMA";
  110. case T_NAPTR: return "NAPTR";
  111. case T_KX: return "KX";
  112. case T_CERT: return "CERT";
  113. case T_A6: return "A6";
  114. case T_DNAME: return "DNAME";
  115. case T_SINK: return "SINK";
  116. case T_OPT: return "OPT";
  117. case T_APL: return "APL";
  118. case T_DS: return "DS";
  119. case T_SSHFP: return "SSHFP";
  120. case T_RRSIG: return "RRSIG";
  121. case T_NSEC: return "NSEC";
  122. case T_DNSKEY: return "DNSKEY";
  123. case T_TKEY: return "TKEY";
  124. case T_TSIG: return "TSIG";
  125. case T_IXFR: return "IXFR";
  126. case T_AXFR: return "AXFR";
  127. case T_MAILB: return "MAILB";
  128. case T_MAILA: return "MAILA";
  129. case T_ANY: return "ANY";
  130. case T_URI: return "URI";
  131. case T_MAX: return "MAX";
  132. default: return "UNKNOWN";
  133. }
  134. }
  135. std::string ClassToString(int qclass) {
  136. switch (qclass) {
  137. case C_IN: return "IN";
  138. case C_CHAOS: return "CHAOS";
  139. case C_HS: return "HESIOD";
  140. case C_NONE: return "NONE";
  141. case C_ANY: return "ANY";
  142. default: return "UNKNOWN";
  143. }
  144. }
  145. std::string AddressToString(const void* vaddr, int len) {
  146. const byte* addr = reinterpret_cast<const byte*>(vaddr);
  147. std::stringstream ss;
  148. if (len == 4) {
  149. char buffer[4*4 + 3 + 1];
  150. sprintf(buffer, "%u.%u.%u.%u",
  151. (unsigned char)addr[0],
  152. (unsigned char)addr[1],
  153. (unsigned char)addr[2],
  154. (unsigned char)addr[3]);
  155. ss << buffer;
  156. } else if (len == 16) {
  157. for (int ii = 0; ii < 16; ii+=2) {
  158. if (ii > 0) ss << ':';
  159. char buffer[4 + 1];
  160. sprintf(buffer, "%02x%02x", (unsigned char)addr[ii], (unsigned char)addr[ii+1]);
  161. ss << buffer;
  162. }
  163. } else {
  164. ss << "!" << HexDump(addr, len) << "!";
  165. }
  166. return ss.str();
  167. }
  168. std::string PacketToString(const std::vector<byte>& packet) {
  169. const byte* data = packet.data();
  170. int len = packet.size();
  171. std::stringstream ss;
  172. if (len < NS_HFIXEDSZ) {
  173. ss << "(too short, len " << len << ")";
  174. return ss.str();
  175. }
  176. ss << ((DNS_HEADER_QR(data) == 0) ? "REQ " : "RSP ");
  177. switch (DNS_HEADER_OPCODE(data)) {
  178. case O_QUERY: ss << "QRY "; break;
  179. case O_IQUERY: ss << "IQRY "; break;
  180. case O_STATUS: ss << "STATUS "; break;
  181. case O_NOTIFY: ss << "NOTIFY "; break;
  182. case O_UPDATE: ss << "UPDATE "; break;
  183. default: ss << "UNKNOWN(" << DNS_HEADER_OPCODE(data) << ") "; break;
  184. }
  185. if (DNS_HEADER_AA(data)) ss << "AA ";
  186. if (DNS_HEADER_TC(data)) ss << "TC ";
  187. if (DNS_HEADER_RD(data)) ss << "RD ";
  188. if (DNS_HEADER_RA(data)) ss << "RA ";
  189. if (DNS_HEADER_Z(data)) ss << "Z ";
  190. if (DNS_HEADER_QR(data) == 1) ss << RcodeToString(DNS_HEADER_RCODE(data));
  191. int nquestions = DNS_HEADER_QDCOUNT(data);
  192. int nanswers = DNS_HEADER_ANCOUNT(data);
  193. int nauths = DNS_HEADER_NSCOUNT(data);
  194. int nadds = DNS_HEADER_ARCOUNT(data);
  195. const byte* pq = data + NS_HFIXEDSZ;
  196. len -= NS_HFIXEDSZ;
  197. for (int ii = 0; ii < nquestions; ii++) {
  198. ss << " Q:" << QuestionToString(packet, &pq, &len);
  199. }
  200. const byte* prr = pq;
  201. for (int ii = 0; ii < nanswers; ii++) {
  202. ss << " A:" << RRToString(packet, &prr, &len);
  203. }
  204. for (int ii = 0; ii < nauths; ii++) {
  205. ss << " AUTH:" << RRToString(packet, &prr, &len);
  206. }
  207. for (int ii = 0; ii < nadds; ii++) {
  208. ss << " ADD:" << RRToString(packet, &prr, &len);
  209. }
  210. return ss.str();
  211. }
  212. std::string QuestionToString(const std::vector<byte>& packet,
  213. const byte** data, int* len) {
  214. std::stringstream ss;
  215. ss << "{";
  216. if (*len < NS_QFIXEDSZ) {
  217. ss << "(too short, len " << *len << ")";
  218. return ss.str();
  219. }
  220. char *name = nullptr;
  221. long enclen;
  222. int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
  223. if (rc != ARES_SUCCESS) {
  224. ss << "(error from ares_expand_name)";
  225. return ss.str();
  226. }
  227. if (enclen > *len) {
  228. ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
  229. return ss.str();
  230. }
  231. *len -= enclen;
  232. *data += enclen;
  233. ss << "'" << name << "' ";
  234. ares_free_string(name);
  235. if (*len < NS_QFIXEDSZ) {
  236. ss << "(too short, len left " << *len << ")";
  237. return ss.str();
  238. }
  239. ss << ClassToString(DNS_QUESTION_CLASS(*data)) << " ";
  240. ss << RRTypeToString(DNS_QUESTION_TYPE(*data));
  241. *data += NS_QFIXEDSZ;
  242. *len -= NS_QFIXEDSZ;
  243. ss << "}";
  244. return ss.str();
  245. }
  246. std::string RRToString(const std::vector<byte>& packet,
  247. const byte** data, int* len) {
  248. std::stringstream ss;
  249. ss << "{";
  250. if (*len < NS_RRFIXEDSZ) {
  251. ss << "too short, len " << *len << ")";
  252. return ss.str();
  253. }
  254. char *name = nullptr;
  255. long enclen;
  256. int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
  257. if (rc != ARES_SUCCESS) {
  258. ss << "(error from ares_expand_name)";
  259. return ss.str();
  260. }
  261. if (enclen > *len) {
  262. ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
  263. return ss.str();
  264. }
  265. *len -= enclen;
  266. *data += enclen;
  267. ss << "'" << name << "' ";
  268. ares_free_string(name);
  269. name = nullptr;
  270. if (*len < NS_RRFIXEDSZ) {
  271. ss << "(too short, len left " << *len << ")";
  272. return ss.str();
  273. }
  274. int rrtype = DNS_RR_TYPE(*data);
  275. if (rrtype == T_OPT) {
  276. ss << "MAXUDP=" << DNS_RR_CLASS(*data) << " ";
  277. ss << RRTypeToString(rrtype) << " ";
  278. ss << "RCODE2=" << DNS_RR_TTL(*data);
  279. } else {
  280. ss << ClassToString(DNS_RR_CLASS(*data)) << " ";
  281. ss << RRTypeToString(rrtype) << " ";
  282. ss << "TTL=" << DNS_RR_TTL(*data);
  283. }
  284. int rdatalen = DNS_RR_LEN(*data);
  285. *data += NS_RRFIXEDSZ;
  286. *len -= NS_RRFIXEDSZ;
  287. if (*len < rdatalen) {
  288. ss << "(RR too long at " << rdatalen << ", len left " << *len << ")";
  289. } else {
  290. switch (rrtype) {
  291. case T_A:
  292. case T_AAAA:
  293. ss << " " << AddressToString(*data, rdatalen);
  294. break;
  295. case T_TXT: {
  296. const byte* p = *data;
  297. while (p < (*data + rdatalen)) {
  298. int len = *p++;
  299. if ((p + len) <= (*data + rdatalen)) {
  300. std::string txt(p, p + len);
  301. ss << " " << len << ":'" << txt << "'";
  302. } else {
  303. ss << "(string too long)";
  304. }
  305. p += len;
  306. }
  307. break;
  308. }
  309. case T_CNAME:
  310. case T_NS:
  311. case T_PTR: {
  312. int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
  313. if (rc != ARES_SUCCESS) {
  314. ss << "(error from ares_expand_name)";
  315. break;
  316. }
  317. ss << " '" << name << "'";
  318. ares_free_string(name);
  319. break;
  320. }
  321. case T_MX:
  322. if (rdatalen > 2) {
  323. int rc = ares_expand_name(*data + 2, packet.data(), packet.size(), &name, &enclen);
  324. if (rc != ARES_SUCCESS) {
  325. ss << "(error from ares_expand_name)";
  326. break;
  327. }
  328. ss << " " << DNS__16BIT(*data) << " '" << name << "'";
  329. ares_free_string(name);
  330. } else {
  331. ss << "(RR too short)";
  332. }
  333. break;
  334. case T_SRV: {
  335. if (rdatalen > 6) {
  336. const byte* p = *data;
  337. unsigned long prio = DNS__16BIT(p);
  338. unsigned long weight = DNS__16BIT(p + 2);
  339. unsigned long port = DNS__16BIT(p + 4);
  340. p += 6;
  341. int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
  342. if (rc != ARES_SUCCESS) {
  343. ss << "(error from ares_expand_name)";
  344. break;
  345. }
  346. ss << prio << " " << weight << " " << port << " '" << name << "'";
  347. ares_free_string(name);
  348. } else {
  349. ss << "(RR too short)";
  350. }
  351. break;
  352. }
  353. case T_URI: {
  354. if (rdatalen > 4) {
  355. const byte* p = *data;
  356. unsigned long prio = DNS__16BIT(p);
  357. unsigned long weight = DNS__16BIT(p + 2);
  358. p += 4;
  359. std::string uri(p, p + (rdatalen - 4));
  360. ss << prio << " " << weight << " '" << uri << "'";
  361. } else {
  362. ss << "(RR too short)";
  363. }
  364. break;
  365. }
  366. case T_SOA: {
  367. const byte* p = *data;
  368. int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
  369. if (rc != ARES_SUCCESS) {
  370. ss << "(error from ares_expand_name)";
  371. break;
  372. }
  373. ss << " '" << name << "'";
  374. ares_free_string(name);
  375. p += enclen;
  376. rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
  377. if (rc != ARES_SUCCESS) {
  378. ss << "(error from ares_expand_name)";
  379. break;
  380. }
  381. ss << " '" << name << "'";
  382. ares_free_string(name);
  383. p += enclen;
  384. if ((p + 20) <= (*data + rdatalen)) {
  385. unsigned long serial = DNS__32BIT(p);
  386. unsigned long refresh = DNS__32BIT(p + 4);
  387. unsigned long retry = DNS__32BIT(p + 8);
  388. unsigned long expire = DNS__32BIT(p + 12);
  389. unsigned long minimum = DNS__32BIT(p + 16);
  390. ss << " " << serial << " " << refresh << " " << retry << " " << expire << " " << minimum;
  391. } else {
  392. ss << "(RR too short)";
  393. }
  394. break;
  395. }
  396. case T_NAPTR: {
  397. if (rdatalen > 7) {
  398. const byte* p = *data;
  399. unsigned long order = DNS__16BIT(p);
  400. unsigned long pref = DNS__16BIT(p + 2);
  401. p += 4;
  402. ss << order << " " << pref;
  403. int len = *p++;
  404. std::string flags(p, p + len);
  405. ss << " " << flags;
  406. p += len;
  407. len = *p++;
  408. std::string service(p, p + len);
  409. ss << " '" << service << "'";
  410. p += len;
  411. len = *p++;
  412. std::string regexp(p, p + len);
  413. ss << " '" << regexp << "'";
  414. p += len;
  415. int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
  416. if (rc != ARES_SUCCESS) {
  417. ss << "(error from ares_expand_name)";
  418. break;
  419. }
  420. ss << " '" << name << "'";
  421. ares_free_string(name);
  422. } else {
  423. ss << "(RR too short)";
  424. }
  425. break;
  426. }
  427. default:
  428. ss << " " << HexDump(*data, rdatalen);
  429. break;
  430. }
  431. }
  432. *data += rdatalen;
  433. *len -= rdatalen;
  434. ss << "}";
  435. return ss.str();
  436. }
  437. void PushInt32(std::vector<byte>* data, int value) {
  438. data->push_back((value & 0xff000000) >> 24);
  439. data->push_back((value & 0x00ff0000) >> 16);
  440. data->push_back((value & 0x0000ff00) >> 8);
  441. data->push_back(value & 0x000000ff);
  442. }
  443. void PushInt16(std::vector<byte>* data, int value) {
  444. data->push_back((value & 0xff00) >> 8);
  445. data->push_back(value & 0x00ff);
  446. }
  447. std::vector<byte> EncodeString(const std::string& name) {
  448. std::vector<byte> data;
  449. std::stringstream ss(name);
  450. std::string label;
  451. // TODO: cope with escapes
  452. while (std::getline(ss, label, '.')) {
  453. data.push_back(label.length());
  454. data.insert(data.end(), label.begin(), label.end());
  455. }
  456. data.push_back(0);
  457. return data;
  458. }
  459. std::vector<byte> DNSQuestion::data() const {
  460. std::vector<byte> data;
  461. std::vector<byte> encname = EncodeString(name_);
  462. data.insert(data.end(), encname.begin(), encname.end());
  463. PushInt16(&data, rrtype_);
  464. PushInt16(&data, qclass_);
  465. return data;
  466. }
  467. std::vector<byte> DNSRR::data() const {
  468. std::vector<byte> data = DNSQuestion::data();
  469. PushInt32(&data, ttl_);
  470. return data;
  471. }
  472. std::vector<byte> DNSSingleNameRR::data() const {
  473. std::vector<byte> data = DNSRR::data();
  474. std::vector<byte> encname = EncodeString(other_);
  475. int len = encname.size();
  476. PushInt16(&data, len);
  477. data.insert(data.end(), encname.begin(), encname.end());
  478. return data;
  479. }
  480. std::vector<byte> DNSTxtRR::data() const {
  481. std::vector<byte> data = DNSRR::data();
  482. int len = 0;
  483. for (const std::string& txt : txt_) {
  484. len += (1 + txt.size());
  485. }
  486. PushInt16(&data, len);
  487. for (const std::string& txt : txt_) {
  488. data.push_back(txt.size());
  489. data.insert(data.end(), txt.begin(), txt.end());
  490. }
  491. return data;
  492. }
  493. std::vector<byte> DNSMxRR::data() const {
  494. std::vector<byte> data = DNSRR::data();
  495. std::vector<byte> encname = EncodeString(other_);
  496. int len = 2 + encname.size();
  497. PushInt16(&data, len);
  498. PushInt16(&data, pref_);
  499. data.insert(data.end(), encname.begin(), encname.end());
  500. return data;
  501. }
  502. std::vector<byte> DNSSrvRR::data() const {
  503. std::vector<byte> data = DNSRR::data();
  504. std::vector<byte> encname = EncodeString(target_);
  505. int len = 6 + encname.size();
  506. PushInt16(&data, len);
  507. PushInt16(&data, prio_);
  508. PushInt16(&data, weight_);
  509. PushInt16(&data, port_);
  510. data.insert(data.end(), encname.begin(), encname.end());
  511. return data;
  512. }
  513. std::vector<byte> DNSUriRR::data() const {
  514. std::vector<byte> data = DNSRR::data();
  515. int len = 4 + target_.size();
  516. PushInt16(&data, len);
  517. PushInt16(&data, prio_);
  518. PushInt16(&data, weight_);
  519. data.insert(data.end(), target_.begin(), target_.end());
  520. return data;
  521. }
  522. std::vector<byte> DNSAddressRR::data() const {
  523. std::vector<byte> data = DNSRR::data();
  524. int len = addr_.size();
  525. PushInt16(&data, len);
  526. data.insert(data.end(), addr_.begin(), addr_.end());
  527. return data;
  528. }
  529. std::vector<byte> DNSSoaRR::data() const {
  530. std::vector<byte> data = DNSRR::data();
  531. std::vector<byte> encname1 = EncodeString(nsname_);
  532. std::vector<byte> encname2 = EncodeString(rname_);
  533. int len = encname1.size() + encname2.size() + 5*4;
  534. PushInt16(&data, len);
  535. data.insert(data.end(), encname1.begin(), encname1.end());
  536. data.insert(data.end(), encname2.begin(), encname2.end());
  537. PushInt32(&data, serial_);
  538. PushInt32(&data, refresh_);
  539. PushInt32(&data, retry_);
  540. PushInt32(&data, expire_);
  541. PushInt32(&data, minimum_);
  542. return data;
  543. }
  544. std::vector<byte> DNSOptRR::data() const {
  545. std::vector<byte> data = DNSRR::data();
  546. int len = 0;
  547. for (const DNSOption& opt : opts_) {
  548. len += (4 + opt.data_.size());
  549. }
  550. PushInt16(&data, len);
  551. for (const DNSOption& opt : opts_) {
  552. PushInt16(&data, opt.code_);
  553. PushInt16(&data, opt.data_.size());
  554. data.insert(data.end(), opt.data_.begin(), opt.data_.end());
  555. }
  556. return data;
  557. }
  558. std::vector<byte> DNSNaptrRR::data() const {
  559. std::vector<byte> data = DNSRR::data();
  560. std::vector<byte> encname = EncodeString(replacement_);
  561. int len = (4 + 1 + flags_.size() + 1 + service_.size() + 1 + regexp_.size() + encname.size());
  562. PushInt16(&data, len);
  563. PushInt16(&data, order_);
  564. PushInt16(&data, pref_);
  565. data.push_back(flags_.size());
  566. data.insert(data.end(), flags_.begin(), flags_.end());
  567. data.push_back(service_.size());
  568. data.insert(data.end(), service_.begin(), service_.end());
  569. data.push_back(regexp_.size());
  570. data.insert(data.end(), regexp_.begin(), regexp_.end());
  571. data.insert(data.end(), encname.begin(), encname.end());
  572. return data;
  573. }
  574. std::vector<byte> DNSPacket::data() const {
  575. std::vector<byte> data;
  576. PushInt16(&data, qid_);
  577. byte b = 0x00;
  578. if (response_) b |= 0x80;
  579. b |= ((opcode_ & 0x0f) << 3);
  580. if (aa_) b |= 0x04;
  581. if (tc_) b |= 0x02;
  582. if (rd_) b |= 0x01;
  583. data.push_back(b);
  584. b = 0x00;
  585. if (ra_) b |= 0x80;
  586. if (z_) b |= 0x40;
  587. if (ad_) b |= 0x20;
  588. if (cd_) b |= 0x10;
  589. b |= (rcode_ & 0x0f);
  590. data.push_back(b);
  591. int count = questions_.size();
  592. PushInt16(&data, count);
  593. count = answers_.size();
  594. PushInt16(&data, count);
  595. count = auths_.size();
  596. PushInt16(&data, count);
  597. count = adds_.size();
  598. PushInt16(&data, count);
  599. for (const std::unique_ptr<DNSQuestion>& question : questions_) {
  600. std::vector<byte> qdata = question->data();
  601. data.insert(data.end(), qdata.begin(), qdata.end());
  602. }
  603. for (const std::unique_ptr<DNSRR>& rr : answers_) {
  604. std::vector<byte> rrdata = rr->data();
  605. data.insert(data.end(), rrdata.begin(), rrdata.end());
  606. }
  607. for (const std::unique_ptr<DNSRR>& rr : auths_) {
  608. std::vector<byte> rrdata = rr->data();
  609. data.insert(data.end(), rrdata.begin(), rrdata.end());
  610. }
  611. for (const std::unique_ptr<DNSRR>& rr : adds_) {
  612. std::vector<byte> rrdata = rr->data();
  613. data.insert(data.end(), rrdata.begin(), rrdata.end());
  614. }
  615. return data;
  616. }
  617. } // namespace ares