123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 |
- use std::net::{Ipv4Addr, Ipv6Addr};
- use std::net::UdpSocket;
- pub struct DnsPacket {
- pub header: DnsHeader,
- pub questions: Vec<DnsQuestion>,
- pub answers: Vec<DnsRecord>,
- pub authorities: Vec<DnsRecord>,
- pub resources: Vec<DnsRecord>
- }
- impl DnsPacket {
- pub fn new(query_type: QueryType, qname: &str) -> Self {
- let id = 6677;
- let mut header = DnsHeader::new(id);
- header.recursion_desired = true;
- let mut questions = Vec::new();
- questions.push(DnsQuestion::new(String::from(qname), query_type));
- DnsPacket {
- header,
- questions,
- answers: Vec::new(),
- authorities: Vec::new(),
- resources: Vec::new(),
- }
- }
- pub fn empty() -> Self {
- let id = 6677;
- let header = DnsHeader::new(id);
- DnsPacket {
- header,
- questions: Vec::new(),
- answers: Vec::new(),
- authorities: Vec::new(),
- resources: Vec::new(),
- }
- }
- pub fn from_bytes(buffer: &mut BytePacketBuffer) -> Self {
- let header = DnsHeader::from(buffer).unwrap();
- let mut questions = Vec::new();
- let mut answers = Vec::new();
- let mut authorities = Vec::new();
- let mut resources = Vec::new();
- for _ in 0..header.question_count {
- let question = DnsQuestion::from(buffer);
- questions.push(question)
- }
- for _ in 0..header.answer_count {
- let answer = DnsRecord::from(buffer);
- answers.push(answer)
- }
- for _ in 0..header.authority_count {
- let authority = DnsRecord::from(buffer);
- authorities.push(authority)
- }
- for _ in 0..header.authority_count {
- let rec = DnsRecord::from(buffer);
- resources.push(rec)
- }
- DnsPacket {
- header,
- questions,
- answers,
- authorities,
- resources
- }
- }
- pub fn write(&mut self, buffer: &mut BytePacketBuffer) -> Result<(), &str> {
- self.header.question_count = self.questions.len() as u16;
- self.header.answer_count = self.answers.len() as u16;
- self.header.authority_count = self.authorities.len() as u16;
- self.header.add_count = self.resources.len() as u16;
- self.header.write(buffer).unwrap();
- for question in &self.questions {
- question.write(buffer).unwrap();
- }
- for rec in &self.answers {
- rec.write(buffer).unwrap();
- }
- for rec in &self.authorities {
- rec.write(buffer).unwrap();
- }
- for rec in &self.resources {
- rec.write(buffer).unwrap();
- }
- Ok(())
- }
- pub fn send(&mut self, server: (&str, u16)) -> DnsPacket {
- let mut req_buffer = BytePacketBuffer::new();
- self.write(&mut req_buffer).unwrap();
- let socket = UdpSocket::bind(("0.0.0.0", 43210)).unwrap();
- socket.send_to(&req_buffer.buf[0..req_buffer.pos], server).unwrap();
- let mut rec_buffer = BytePacketBuffer::new();
- socket.recv_from(&mut rec_buffer.buf).unwrap();
- let response = DnsPacket::from_bytes(&mut rec_buffer);
- return response;
- }
- }
- #[derive(Copy, Clone, Debug, PartialEq, Eq)]
- pub enum ResultCode {
- NOERROR = 0,
- FORMERR = 1,
- SERVFAIL = 2,
- NXDOMAIN = 3,
- NOTIMP = 4,
- REFUSED = 5,
- }
- impl ResultCode {
- pub fn from_num(num: u8) -> Self {
- match num {
- 1 => ResultCode::FORMERR,
- 2 => ResultCode::SERVFAIL,
- 3 => ResultCode::NXDOMAIN,
- 4 => ResultCode::NOTIMP,
- 5 => ResultCode::REFUSED,
- 0 | _ => ResultCode::NOERROR,
- }
- }
- }
- #[derive(Clone, Debug)]
- pub struct DnsHeader {
- pub id: u16,
- pub query_response: bool,
- pub operation_code: u8,
- pub authoritative_answer: bool,
- pub truncated_message: bool,
- pub recursion_desired: bool,
- pub recursion_available: bool,
- pub z: u8,
- pub result_code: ResultCode,
- pub question_count: u16,
- pub answer_count: u16,
- pub authority_count: u16,
- pub add_count: u16,
- }
- impl DnsHeader {
-
- pub fn new(id: u16) -> Self {
- DnsHeader {
- id,
- query_response: false,
- operation_code: 0,
- authoritative_answer: false,
- truncated_message: false,
- recursion_desired: false,
- recursion_available: false,
- z: 0,
- result_code: ResultCode::NOERROR,
- question_count: 0,
- answer_count: 0,
- authority_count: 0,
- add_count: 0
- }
- }
- pub fn from(buffer: &mut BytePacketBuffer) -> Result<Self, &str> {
- let id = buffer.read_u16().unwrap();
- let flags = buffer.read_u16().unwrap();
- let bit1 = (flags >> 8) as u8;
- let bit2 = (flags & 0xFF) as u8;
-
- Ok(DnsHeader {
- id,
- recursion_desired: (bit1 & (1 << 0)) > 0,
- truncated_message: (bit1 & (1 << 1)) > 0,
- authoritative_answer: (bit1 & (1 << 2)) > 0,
- operation_code: (bit1 >> 3) & 0xF,
- query_response: (bit1 >> 7) > 0,
- result_code: ResultCode::from_num(bit2 & 0x0F),
- z: (bit2 >> 0x4) & 0x7,
- recursion_available: (bit2 >> 7) > 0,
- question_count: buffer.read_u16().unwrap(),
- answer_count: buffer.read_u16().unwrap(),
- authority_count: buffer.read_u16().unwrap(),
- add_count: buffer.read_u16().unwrap(),
- })
- }
- pub fn write(&self, buffer: &mut BytePacketBuffer) -> Result<(), &str> {
- buffer.write_u16(self.id).unwrap();
- buffer.write_u8(
- (self.recursion_desired as u8)
- | ((self.truncated_message as u8) << 1)
- | ((self.authoritative_answer as u8) << 2)
- | (self.operation_code << 3)
- | ((self.query_response as u8) << 7) as u8
- ).unwrap();
- buffer.write_u8(
- (self.result_code as u8)
- | ((self.z as u8) << 6)
- | ((self.recursion_available as u8) << 7)
- ).unwrap();
- buffer.write_u16(self.question_count).unwrap();
- buffer.write_u16(self.answer_count).unwrap();
- buffer.write_u16(self.authority_count).unwrap();
- buffer.write_u16(self.add_count).unwrap();
- Ok(())
- }
- }
- #[derive(Copy, Clone, PartialEq, Eq, Debug, Ord, PartialOrd, Hash)]
- pub enum QueryType {
- UNKNOWN(u16),
- A,
- NS,
- CNAME,
- MX,
- AAAA,
- TXT,
- }
- impl QueryType {
- pub fn to_num(&self) -> u16 {
- match *self {
- QueryType::UNKNOWN(x) => x,
- QueryType::A => 1,
- QueryType::NS => 2,
- QueryType::CNAME => 5,
- QueryType::MX => 15,
- QueryType::TXT => 16,
- QueryType::AAAA => 28,
- }
- }
- pub fn from_num(num: u16) -> Self {
- match num {
- 1 => QueryType::A,
- 2 => QueryType::NS,
- 5 => QueryType::CNAME,
- 15 => QueryType::MX,
- 16 => QueryType::TXT,
- 28 => QueryType::AAAA,
- _ => QueryType::UNKNOWN(num),
- }
- }
- }
- #[derive(Clone, PartialEq, Eq, Debug)]
- pub struct DnsQuestion {
- pub name: String,
- pub qtype: QueryType
- }
- impl DnsQuestion {
- pub fn new(name: String, qtype: QueryType) -> Self {
- DnsQuestion {
- name,
- qtype
- }
- }
- pub fn from(buffer: &mut BytePacketBuffer) -> Self {
- let name = buffer.read_qname().unwrap();
- let qtype = QueryType::from_num(buffer.read_u16().unwrap());
- let _ = buffer.read_u16().unwrap();
- DnsQuestion {
- name,
- qtype
- }
- }
- pub fn write(&self, buffer: &mut BytePacketBuffer) -> Result<(), &str> {
- buffer.write_qname(&self.name).unwrap();
- let qtype_num = self.qtype.to_num();
- buffer.write_u16(qtype_num).unwrap();
- buffer.write_u16(1).unwrap();
- Ok(())
- }
- }
- #[derive(Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
- pub enum DnsRecord {
- UNKNOWN {
- domain: String,
- qtype: QueryType,
- data_len: u16,
- ttl: u32
- },
- A {
- domain: String,
- addr: Ipv4Addr,
- ttl: u32
- },
- NS {
- domain: String,
- host: String,
- ttl: u32
- },
- CNAME {
- domain: String,
- host: String,
- ttl: u32
- },
- MX {
- domain: String,
- priority: u16,
- host: String,
- ttl: u32
- },
- AAAA {
- domain: String,
- addr: Ipv6Addr,
- ttl: u32
- },
- TXT {
- domain: String,
- len: u8,
- txt: String,
- ttl: u32
- },
- }
- impl DnsRecord {
- pub fn from(buffer: &mut BytePacketBuffer) -> Self {
- let domain = buffer.read_qname().unwrap();
- let qtype_num = buffer.read_u16().unwrap();
- let qtype = QueryType::from_num(qtype_num);
- let _ = buffer.read_u16().unwrap();
- let ttl = buffer.read_u32().unwrap();
- let data_len = buffer.read_u16().unwrap();
- match qtype {
- QueryType::A => {
- let raw_addr = buffer.read_u32().unwrap();
- let addr = Ipv4Addr::new(
- ((raw_addr >> 24) & 0xFF) as u8,
- ((raw_addr >> 16) & 0xFF) as u8,
- ((raw_addr >> 8) & 0xFF) as u8,
- ((raw_addr) & 0xFF) as u8);
- DnsRecord::A {
- domain,
- addr,
- ttl
- }
- },
- QueryType::UNKNOWN(_) => {
- buffer.step(data_len as usize).unwrap();
- DnsRecord::UNKNOWN {
- domain,
- qtype,
- data_len,
- ttl
- }
- },
- QueryType::AAAA => {
- let raw_addr0 = buffer.read_u32().unwrap();
- let raw_addr1 = buffer.read_u32().unwrap();
- let raw_addr2 = buffer.read_u32().unwrap();
- let raw_addr3 = buffer.read_u32().unwrap();
- let addr = Ipv6Addr::new(
- ((raw_addr0 >> 16) & 0xFF) as u16,
- ((raw_addr0 >> 0) & 0xFF) as u16,
- ((raw_addr1 >> 16) & 0xFF) as u16,
- ((raw_addr1 >> 0) & 0xFF) as u16,
- ((raw_addr2 >> 16) & 0xFF) as u16,
- ((raw_addr2 >> 0) & 0xFF) as u16,
- ((raw_addr3 >> 16) & 0xFF) as u16,
- ((raw_addr3 >> 0) & 0xFF) as u16);
- DnsRecord::AAAA {
- domain,
- addr,
- ttl
- }
- },
- QueryType::NS => {
- let ns = buffer.read_qname().unwrap();
- DnsRecord::NS {
- domain,
- host: ns,
- ttl
- }
- },
- QueryType::CNAME => {
- let cname = buffer.read_qname().unwrap();
- DnsRecord::CNAME {
- domain,
- host: cname,
- ttl
- }
- },
- QueryType::MX => {
- let priority = buffer.read_u16().unwrap();
- let mx = buffer.read_qname().unwrap();
- DnsRecord::MX {
- domain,
- priority,
- host: mx,
- ttl
- }
- },
- QueryType::TXT => {
- let txt_len = buffer.read().unwrap();
- let mut s = Vec::with_capacity(txt_len as usize);
- for _ in 0..txt_len {
- s.push(buffer.read().unwrap());
- }
- let txt = String::from_utf8_lossy(&s).to_string();
- DnsRecord::TXT {
- domain,
- len: txt_len as u8,
- txt,
- ttl
- }
- }
- }
- }
- pub fn write(&self, buffer: &mut BytePacketBuffer) -> Result<usize, &str> {
- let start_pos = buffer.pos();
- match *self {
- DnsRecord::A {
- ref domain,
- ref addr,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::A.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- buffer.write_u16(4).unwrap();
- let oct = addr.octets();
- buffer.write_u8(oct[0]).unwrap();
- buffer.write_u8(oct[1]).unwrap();
- buffer.write_u8(oct[2]).unwrap();
- buffer.write_u8(oct[3]).unwrap();
- }
- DnsRecord::AAAA {
- ref domain,
- ref addr,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::AAAA.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- buffer.write_u16(8).unwrap();
- for oct in addr.segments().iter() {
- buffer.write_u16(*oct).unwrap();
- }
- },
- DnsRecord::NS {
- ref domain,
- ref host,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::NS.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- let pos = buffer.pos();
- buffer.write_u16(0).unwrap();
- buffer.write_qname(host).unwrap();
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16).unwrap();
- },
- DnsRecord::CNAME {
- ref domain,
- ref host,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::CNAME.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- let pos = buffer.pos();
- buffer.write_u16(0).unwrap();
- buffer.write_qname(host).unwrap();
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16).unwrap();
- },
- DnsRecord::MX {
- ref domain,
- priority,
- ref host,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::MX.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- let pos = buffer.pos();
- buffer.write_u16(0).unwrap();
- buffer.write_u16(priority).unwrap();
- buffer.write_qname(host).unwrap();
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16).unwrap();
- },
- DnsRecord::TXT {
- ref domain,
- len,
- ref txt,
- ttl
- } => {
- buffer.write_qname(domain).unwrap();
- buffer.write_u16(QueryType::TXT.to_num()).unwrap();
- buffer.write_u16(1).unwrap();
- buffer.write_u32(ttl).unwrap();
- let pos = buffer.pos();
- buffer.write_u16(0).unwrap();
- buffer.write_u8(len).unwrap();
- for byte in txt.as_bytes() {
- buffer.write_u8(*byte).unwrap();
- }
- let size = buffer.pos() - (pos + 2);
- buffer.set_u16(pos, size as u16).unwrap();
- },
- DnsRecord::UNKNOWN {..} => {
- return Err("Unknown DnsRecord");
- },
- }
- Ok(buffer.pos() - start_pos)
- }
- }
- pub struct BytePacketBuffer {
- pub buf: [u8; 512],
- pub pos: usize,
- }
- impl BytePacketBuffer {
- pub fn new() -> Self {
- BytePacketBuffer { buf: [0; 512] ,pos: 0}
- }
- pub fn pos(&self) -> usize {
- self.pos
- }
- pub fn step(&mut self, steps: usize) -> Result<(), &str> {
- self.pos += steps;
- Ok(())
- }
- pub fn seek(&mut self, pos: usize) -> Result<(), &str> {
- self.pos = pos;
- Ok(())
- }
-
- pub fn read(&mut self) -> Result<u8, &str> {
- if self.pos >= 512 {
- return Err("End of Buffer");
- }
- let ret = self.buf[self.pos];
- self.pos += 1;
- Ok(ret)
- }
- pub fn get(&self, pos: usize) -> Result<u8, &str> {
- if pos >= 512 {
- return Err("End of Buffer");
- }
- Ok(self.buf[pos])
- }
- pub fn get_range(&self, start: usize, len: usize) -> Result<&[u8], &str> {
- if (start + len) >= 512 {
- return Err("End of Buffer");
- }
- Ok(&self.buf[start..start+len])
- }
- pub fn read_u16(&mut self) -> Result<u16, &str> {
- if self.pos >= 512 {
- return Err("End of Buffer");
- }
- let mut res = (self.read().unwrap() as u16) << 8;
- res |= self.read()? as u16;
- Ok(res)
- }
- pub fn read_u32(&mut self) -> Result<u32, &str> {
- if self.pos >= 512 {
- return Err("End of Buffer");
- }
-
-
- let mut res = (self.read().unwrap() as u32) << 24;
- res |= (self.read().unwrap() as u32) << 16;
- res |= (self.read().unwrap() as u32) << 8;
- res |= self.read()? as u32;
- Ok(res)
- }
-
-
-
-
- fn read_qname(&mut self) -> Result<String, &str> {
- let mut lpos = self.pos;
- let mut jumped = false;
- let mut num_jmps = 0;
- let max_jmps = 5;
-
- let mut delim = "";
- let mut outstr = String::from("");
-
- loop {
-
- if num_jmps >= max_jmps {
- return Err("too many jumps");
- }
- let len = self.get(lpos).unwrap() as usize;
- if (len & 0xC0) == 0xC0 {
- if !jumped {
- self.seek(lpos + 2).unwrap();
- }
-
-
- let sb = self.get(lpos + 1).unwrap() as u16;
- let sb = ((self.get(lpos).unwrap() as u16 ^ 0xC0) << 8) as u16 | sb;
-
- lpos = sb as usize;
- jumped = true;
- num_jmps += 1;
- continue;
- }
- else {
-
- lpos += 1;
-
-
- if len == 0 {
- break
- }
- outstr.push_str(delim);
- let domain = &String::from_utf8_lossy(self.get_range(lpos, len).unwrap()).to_lowercase();
- outstr.push_str(domain);
- delim = ".";
-
- lpos += len;
- }
- }
- if !jumped {
- self.seek(lpos).unwrap();
- }
- Ok(outstr)
- }
- fn write(&mut self, val: u8) -> Result<(), &str> {
- if self.pos >= 512 {
- return Err("End of buffer");
- }
- self.buf[self.pos] = val;
- self.pos += 1;
- Ok(())
- }
- fn write_u8(&mut self, val: u8) -> Result<(), &str> {
- self.write(val)
- }
- fn write_u16(&mut self, val: u16) -> Result<(), &str> {
- self.write_u8((val >> 8) as u8).unwrap();
- self.write_u8((val & 0xFF) as u8).unwrap();
- Ok(())
- }
- fn write_u32(&mut self, val: u32) -> Result<(), &str> {
- self.write_u8(((val >> 24) & 0xFF) as u8).unwrap();
- self.write_u8(((val >> 16) & 0xFF) as u8).unwrap();
- self.write_u8(((val >> 8) & 0xFF) as u8).unwrap();
- self.write_u8(((val >> 0) & 0xFF) as u8).unwrap();
- Ok(())
- }
- fn write_qname(&mut self, qname: &str) -> Result<(), &str> {
- for label in qname.split(".") {
- let len = label.len();
- if len > 0x3F {
- return Err("Single Label exeeds 63 characters");
- }
- self.write_u8(len as u8).unwrap();
- for b in label.as_bytes() {
- self.write_u8(*b as u8).unwrap();
- }
- }
- self.write_u8(0).unwrap();
- Ok(())
- }
- fn set(&mut self, pos: usize, val: u8) -> Result<(), &str> {
- if pos >= 512 {
- return Err("End of Buffer");
- }
- self.buf[pos] = val;
- Ok(())
- }
- fn set_u16(&mut self, pos: usize, val: u16) -> Result<(), &str> {
- if pos >= 511 {
- return Err("End of Buffer");
- }
- self.buf[pos] = ((val >> 8) & 0xFF) as u8;
- self.buf[pos+1] = (val & 0xFF) as u8;
- Ok(())
- }
- }
|