mod.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. pub use self::answer::DnsAnswer;
  11. pub use self::query::DnsQuery;
  12. use core::slice;
  13. use core::u16;
  14. use alloc::String;
  15. use alloc::Vec;
  16. mod answer;
  17. mod query;
  18. #[allow(non_camel_case_types)]
  19. #[derive(Copy, Clone, Debug, Default)]
  20. #[repr(packed)]
  21. pub struct n16 {
  22. inner: u16
  23. }
  24. impl n16 {
  25. pub fn as_bytes(&self) -> &[u8] {
  26. unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) }
  27. }
  28. pub fn from_bytes(bytes: &[u8]) -> Self {
  29. n16 {
  30. inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] }
  31. }
  32. }
  33. }
  34. impl From<u16> for n16 {
  35. fn from(value: u16) -> Self {
  36. n16 {
  37. inner: value.to_be()
  38. }
  39. }
  40. }
  41. impl From<n16> for u16 {
  42. fn from(value: n16) -> Self {
  43. u16::from_be(value.inner)
  44. }
  45. }
  46. #[derive(Clone, Debug)]
  47. pub struct Dns {
  48. pub transaction_id: u16,
  49. pub flags: u16,
  50. pub queries: Vec<DnsQuery>,
  51. pub answers: Vec<DnsAnswer>
  52. }
  53. impl Dns {
  54. pub fn compile(&self) -> Vec<u8> {
  55. let mut data = Vec::new();
  56. macro_rules! push_u8 {
  57. ($value:expr) => {
  58. data.push($value);
  59. };
  60. };
  61. macro_rules! push_n16 {
  62. ($value:expr) => {
  63. data.extend_from_slice(n16::from($value).as_bytes());
  64. };
  65. };
  66. push_n16!(self.transaction_id);
  67. push_n16!(self.flags);
  68. push_n16!(self.queries.len() as u16);
  69. push_n16!(self.answers.len() as u16);
  70. push_n16!(0);
  71. push_n16!(0);
  72. for query in self.queries.iter() {
  73. for part in query.name.split('.') {
  74. push_u8!(part.len() as u8);
  75. data.extend_from_slice(part.as_bytes());
  76. }
  77. push_u8!(0);
  78. push_n16!(query.q_type);
  79. push_n16!(query.q_class);
  80. }
  81. data
  82. }
  83. pub fn parse(data: &[u8]) -> Result<Self, String> {
  84. let name_ind = 0b11000000;
  85. let mut i = 0;
  86. macro_rules! pop_u8 {
  87. () => {
  88. {
  89. i += 1;
  90. if i > data.len() {
  91. return Err(format!("{}: {}: pop_u8", file!(), line!()));
  92. }
  93. data[i - 1]
  94. }
  95. };
  96. };
  97. macro_rules! pop_n16 {
  98. () => {
  99. {
  100. i += 2;
  101. if i > data.len() {
  102. return Err(format!("{}: {}: pop_n16", file!(), line!()));
  103. }
  104. u16::from(n16::from_bytes(&data[i - 2 .. i]))
  105. }
  106. };
  107. };
  108. macro_rules! pop_data {
  109. () => {
  110. {
  111. let mut data = Vec::new();
  112. let data_len = pop_n16!();
  113. for _data_i in 0..data_len {
  114. data.push(pop_u8!());
  115. }
  116. data
  117. }
  118. };
  119. };
  120. macro_rules! pop_name {
  121. () => {
  122. {
  123. let mut name = String::new();
  124. let old_i = i;
  125. loop {
  126. let name_len = pop_u8!();
  127. if name_len & name_ind == name_ind {
  128. i -= 1;
  129. i = (pop_n16!() - ((name_ind as u16) << 8)) as usize;
  130. continue;
  131. }
  132. if name_len == 0 {
  133. break;
  134. }
  135. if ! name.is_empty() {
  136. name.push('.');
  137. }
  138. for _name_i in 0..name_len {
  139. name.push(pop_u8!() as char);
  140. }
  141. }
  142. if i <= old_i {
  143. i = old_i + 2;
  144. }
  145. name
  146. }
  147. };
  148. };
  149. let transaction_id = pop_n16!();
  150. let flags = pop_n16!();
  151. let queries_len = pop_n16!();
  152. let answers_len = pop_n16!();
  153. pop_n16!();
  154. pop_n16!();
  155. let mut queries = Vec::new();
  156. for _query_i in 0..queries_len {
  157. queries.push(DnsQuery {
  158. name: pop_name!(),
  159. q_type: pop_n16!(),
  160. q_class: pop_n16!()
  161. });
  162. }
  163. let mut answers = Vec::new();
  164. for _answer_i in 0..answers_len {
  165. answers.push(DnsAnswer {
  166. name: pop_name!(),
  167. a_type: pop_n16!(),
  168. a_class: pop_n16!(),
  169. ttl_a: pop_n16!(),
  170. ttl_b: pop_n16!(),
  171. data: pop_data!()
  172. });
  173. }
  174. Ok(Dns {
  175. transaction_id: transaction_id,
  176. flags: flags,
  177. queries: queries,
  178. answers: answers,
  179. })
  180. }
  181. }