types.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. //! DNS packets are traditionally implemented with both the request and
  2. //! response packets at the same type. After all, both follow the same format,
  3. //! with the request packet having zero answer fields, and the response packet
  4. //! having at least one record in its answer fields.
  5. use crate::record::{Record, OPT};
  6. use crate::strings::Labels;
  7. /// A request that gets sent out over a transport.
  8. #[derive(PartialEq, Debug)]
  9. pub struct Request {
  10. /// The transaction ID of this request. This is used to make sure
  11. /// different DNS packets don’t answer each other’s questions.
  12. pub transaction_id: u16,
  13. /// The flags that accompany every DNS packet.
  14. pub flags: Flags,
  15. /// The query that this request is making. Only one query is allowed per
  16. /// request, as traditionally, DNS servers only respond to the first query
  17. /// in a packet.
  18. pub query: Query,
  19. /// An additional record that may be sent as part of the query.
  20. pub additional: Option<OPT>,
  21. }
  22. /// A response obtained from a DNS server.
  23. #[derive(PartialEq, Debug)]
  24. pub struct Response {
  25. /// The transaction ID, which should match the ID of the request.
  26. pub transaction_id: u16,
  27. /// The flags that accompany every DNS packet.
  28. pub flags: Flags,
  29. /// The queries section.
  30. pub queries: Vec<Query>,
  31. /// The answers section.
  32. pub answers: Vec<Answer>,
  33. /// The authoritative nameservers section.
  34. pub authorities: Vec<Answer>,
  35. /// The additional records section.
  36. pub additionals: Vec<Answer>,
  37. }
  38. /// A DNS query section.
  39. #[derive(PartialEq, Debug)]
  40. pub struct Query {
  41. /// The domain name being queried, in human-readable dotted notation.
  42. pub qname: Labels,
  43. /// The class number.
  44. pub qclass: QClass,
  45. /// The type number.
  46. pub qtype: TypeInt,
  47. }
  48. /// A DNS answer section.
  49. #[derive(PartialEq, Debug)]
  50. pub enum Answer {
  51. /// This is a standard answer with every field.
  52. Standard {
  53. /// The domain name being answered for.
  54. qname: Labels,
  55. /// This answer’s class.
  56. qclass: QClass,
  57. /// The time-to-live duration, in seconds.
  58. ttl: u32,
  59. /// The record contained in this answer.
  60. record: Record,
  61. },
  62. /// This is a pseudo-record answer, so some of the fields (class and TTL)
  63. /// have different meaning.
  64. Pseudo {
  65. /// The domain name being answered for.
  66. qname: Labels,
  67. /// The OPT record contained in this answer.
  68. opt: OPT,
  69. },
  70. }
  71. /// A DNS record class. Of these, the only one that’s in regular use anymore
  72. /// is the Internet class.
  73. #[derive(PartialEq, Debug, Copy, Clone)]
  74. pub enum QClass {
  75. /// The **Internet** class.
  76. IN,
  77. /// The **Chaosnet** class.
  78. CH,
  79. /// The **Hesiod** class.
  80. HS,
  81. /// A class number that does not map to any known class.
  82. Other(u16),
  83. }
  84. /// The number representing a record type, such as `1` for an **A** record, or
  85. /// `15` for an **MX** record.
  86. pub type TypeInt = u16;
  87. /// The flags that accompany every DNS packet.
  88. #[derive(PartialEq, Debug, Copy, Clone)]
  89. pub struct Flags {
  90. /// Whether this packet is a response packet.
  91. pub response: bool,
  92. /// The operation being performed.
  93. pub opcode: Opcode,
  94. /// In a response, whether the server is providing authoritative DNS responses.
  95. pub authoritative: bool,
  96. /// In a response, whether this message has been truncated by the transport.
  97. pub truncated: bool,
  98. /// In a query, whether the server may query other nameservers recursively.
  99. /// It is up to the server whether it will actually do this.
  100. pub recursion_desired: bool,
  101. /// In a response, whether the server allows recursive query support.
  102. pub recursion_available: bool,
  103. /// In a response, whether the server is marking this data as authentic.
  104. pub authentic_data: bool,
  105. /// In a request, whether the server should disable its authenticity
  106. /// checking for the request’s queries.
  107. pub checking_disabled: bool,
  108. /// In a response, a code indicating an error if one occurred.
  109. pub error_code: Option<ErrorCode>,
  110. }
  111. /// A number representing the operation being performed.
  112. #[derive(PartialEq, Debug, Copy, Clone)]
  113. pub enum Opcode {
  114. /// This request is a standard query, or this response is answering a
  115. /// standard query.
  116. Query,
  117. /// Any other opcode. This can be from 1 to 15, as the opcode field is
  118. /// four bits wide, and 0 is taken.
  119. Other(u8),
  120. }
  121. /// A code indicating an error.
  122. ///
  123. /// # References
  124. ///
  125. /// - [RFC 6895 §2.3](https://tools.ietf.org/html/rfc6895#section-2.3) — Domain
  126. /// Name System (DNS) IANA Considerations (April 2013)
  127. #[derive(PartialEq, Debug, Copy, Clone)]
  128. pub enum ErrorCode {
  129. /// `FORMERR` — The server was unable to interpret the query.
  130. FormatError,
  131. /// `SERVFAIL` — There was a problem with the server.
  132. ServerFailure,
  133. /// `NXDOMAIN` — The domain name referenced in the query does not exist.
  134. NXDomain,
  135. /// `NotImp` — The server does not support one of the requested features.
  136. NotImplemented,
  137. /// `Refused` — The server was able to interpret the query, but refused to
  138. /// fulfil it.
  139. QueryRefused,
  140. /// `NotAuth` — The server did not accept the EDNS version, or failed to
  141. /// verify a signature.
  142. BadVersion,
  143. /// An error code we don’t know what it is.
  144. Other(u16),
  145. }
  146. impl Answer {
  147. /// Whether this Answer holds a standard record, not a pseudo record.
  148. pub fn is_standard(&self) -> bool {
  149. matches!(self, Self::Standard { .. })
  150. }
  151. }