123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // http://rust-lang.org/COPYRIGHT.
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- pub use self::{answer::DnsAnswer, query::DnsQuery};
- use alloc::{string::String, vec::Vec};
- use core::{slice, u16};
- mod answer;
- mod query;
- use core::ptr;
- use mem;
- use alloc::boxed::Box;
- #[allow(non_camel_case_types)]
- #[derive(Copy, Clone, Debug, Default)]
- #[repr(packed)]
- pub struct n16 {
- inner: u16,
- }
- impl n16 {
- pub fn as_bytes(&self) -> &[u8] {
- let left_8bits = (self.inner >> 8) as u8;
- let right_8bits = self.inner as u8;
- unsafe {
- let bytes: [u8; 2] = [left_8bits, right_8bits];
- slice::from_raw_parts(bytes.as_ptr(), 2)
- }
- }
- // pub fn as_bytes(&self) -> &[u8] {
- // unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) }
- // }
- pub fn from_bytes(bytes: &[u8]) -> Self {
- n16 {
- inner: unsafe {
- slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len() / 2)[0]
- },
- }
- }
- }
- impl From<u16> for n16 {
- fn from(value: u16) -> Self {
- n16 {
- inner: value.to_be(),
- }
- }
- }
- impl From<n16> for u16 {
- fn from(value: n16) -> Self {
- u16::from_be(value.inner)
- }
- }
- #[derive(Clone, Debug)]
- pub struct Dns {
- pub transaction_id: u16,
- pub flags: u16,
- pub queries: Vec<DnsQuery>,
- pub answers: Vec<DnsAnswer>,
- }
- impl Dns {
- pub fn compile(&self) -> Vec<u8> {
- let mut data = Vec::new();
- macro_rules! push_u8 {
- ($value:expr) => {
- data.push($value);
- };
- };
- macro_rules! push_n16 {
- ($value:expr) => {
- data.extend_from_slice(n16::from($value).as_bytes());
- };
- };
- push_n16!(self.transaction_id);
- push_n16!(self.flags);
- push_n16!(self.queries.len() as u16);
- push_n16!(self.answers.len() as u16);
- push_n16!(0);
- push_n16!(0);
- for query in self.queries.iter() {
- for part in query.name.split('.') {
- push_u8!(part.len() as u8);
- data.extend_from_slice(part.as_bytes());
- }
- push_u8!(0);
- push_n16!(query.q_type);
- push_n16!(query.q_class);
- }
- data
- }
- pub fn parse(data: &[u8]) -> Result<Self, String> {
- let name_ind = 0b1100_0000;
- let mut i = 0;
- macro_rules! pop_u8 {
- () => {{
- i += 1;
- if i > data.len() {
- return Err(format!("{}: {}: pop_u8", file!(), line!()));
- }
- data[i - 1]
- }};
- };
- macro_rules! pop_n16 {
- () => {{
- i += 2;
- if i > data.len() {
- return Err(format!("{}: {}: pop_n16", file!(), line!()));
- }
- u16::from(n16::from_bytes(&data[i - 2..i]))
- }};
- };
- macro_rules! pop_data {
- () => {{
- let mut data = Vec::new();
- let data_len = pop_n16!();
- for _data_i in 0..data_len {
- data.push(pop_u8!());
- }
- data
- }};
- };
- macro_rules! pop_name {
- () => {{
- let mut name = String::new();
- let old_i = i;
- loop {
- let name_len = pop_u8!();
- if name_len & name_ind == name_ind {
- i -= 1;
- i = (pop_n16!() - ((name_ind as u16) << 8)) as usize;
- continue;
- }
- if name_len == 0 {
- break;
- }
- if !name.is_empty() {
- name.push('.');
- }
- for _name_i in 0..name_len {
- name.push(pop_u8!() as char);
- }
- }
- if i <= old_i {
- i = old_i + 2;
- }
- name
- }};
- };
- let transaction_id = pop_n16!();
- let flags = pop_n16!();
- let queries_len = pop_n16!();
- let answers_len = pop_n16!();
- pop_n16!();
- pop_n16!();
- let mut queries = Vec::new();
- for _query_i in 0..queries_len {
- queries.push(DnsQuery {
- name: pop_name!(),
- q_type: pop_n16!(),
- q_class: pop_n16!(),
- });
- }
- let mut answers = Vec::new();
- for _answer_i in 0..answers_len {
- answers.push(DnsAnswer {
- name: pop_name!(),
- a_type: pop_n16!(),
- a_class: pop_n16!(),
- ttl_a: pop_n16!(),
- ttl_b: pop_n16!(),
- data: pop_data!(),
- });
- }
- Ok(Dns {
- transaction_id,
- flags,
- queries,
- answers,
- })
- }
- }
|