(client_packet: Vec<u8>, ip: IpAddr, ttl: u32)
| 692 | } |
| 693 | |
| 694 | pub fn serve_ip_response(client_packet: Vec<u8>, ip: IpAddr, ttl: u32) -> Result<Vec<u8>, Error> { |
| 695 | ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet"); |
| 696 | ensure!(qdcount(&client_packet) == 1, "No question"); |
| 697 | ensure!( |
| 698 | !is_response(&client_packet), |
| 699 | "Question expected, but got a response instead" |
| 700 | ); |
| 701 | let offset = skip_name(&client_packet, DNS_HEADER_SIZE)?; |
| 702 | let mut packet = client_packet; |
| 703 | ensure!(packet.len() - offset >= 4, "Short packet"); |
| 704 | packet.truncate(offset + 4); |
| 705 | an_ns_ar_count_clear(&mut packet); |
| 706 | authoritative_response(&mut packet); |
| 707 | ancount_inc(&mut packet)?; |
| 708 | packet.write_u16::<BigEndian>(0xc000 + DNS_HEADER_SIZE as u16)?; |
| 709 | match ip { |
| 710 | IpAddr::V4(ip) => { |
| 711 | packet.write_u16::<BigEndian>(DNS_TYPE_A)?; |
| 712 | packet.write_u16::<BigEndian>(DNS_CLASS_INET)?; |
| 713 | packet.write_u32::<BigEndian>(ttl)?; |
| 714 | packet.write_u16::<BigEndian>(4)?; |
| 715 | packet.extend_from_slice(&ip.octets()); |
| 716 | } |
| 717 | IpAddr::V6(ip) => { |
| 718 | packet.write_u16::<BigEndian>(DNS_TYPE_AAAA)?; |
| 719 | packet.write_u16::<BigEndian>(DNS_CLASS_INET)?; |
| 720 | packet.write_u32::<BigEndian>(ttl)?; |
| 721 | packet.write_u16::<BigEndian>(16)?; |
| 722 | packet.extend_from_slice(&ip.octets()); |
| 723 | } |
| 724 | }; |
| 725 | Ok(packet) |
| 726 | } |
| 727 | |
| 728 | #[cfg(test)] |
| 729 | mod tests { |
no test coverage detected