types.rs 4.8 KB

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