1---------------------------------------------------------------- 2-- IRONSIDES - DNS SERVER 3-- 4-- By: Martin C. Carlisle and Barry S. Fagin 5-- Department of Computer Science 6-- United States Air Force Academy 7-- 8-- This is free software; you can redistribute it and/or 9-- modify without restriction. We do ask that you please keep 10-- the original author information, and clearly indicate if the 11-- software has been modified. 12-- 13-- This software is distributed in the hope that it will be useful, 14-- but WITHOUT ANY WARRANTY; without even the implied warranty 15-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16---------------------------------------------------------------- 17 18with System; 19 20--# inherit System; 21package DNS_Types is 22 Packet_Size : constant := 8192; 23 Header_Bits : constant := 96; 24 25 type QNAME_PTR_RANGE is range 0..2**14-1; 26 27 type Packet_Length_Range is range 0..Packet_Size; 28 --# assert Packet_Length_Range'Base is Integer; 29 UDP_Max_Size : constant Packet_Length_Range := 512; 30 31 type Packet_Bytes_Range is range 1..(Packet_Size - Header_Bits/8); 32 --# assert Packet_Bytes_Range'Base is Integer; 33 34 type Byte is mod 256; 35 --# accept Warning, 2, "representation clause ok"; 36 for Byte'Size use 8; 37 --# end accept; 38 39 40 type Unsigned_Short is range 0 .. 2**16 - 1; 41 --# assert Unsigned_Short'Base is Integer; 42 --# accept Warning, 2, "representation clause ok"; 43 for Unsigned_Short'Size use 16; 44 --# end accept; 45 46 -- used in OPCODE field below 47 type Opcode_Type is (Query, IQuery, Status); 48 --# accept Warning, 2, "representation clause ok"; 49 for Opcode_Type'Size use 4; 50 --# end accept; 51 52 -- used in RCODE field below 53 type Response_Code is 54 (No_Error, 55 Format_Error, 56 Server_Failure, 57 Name_Error, 58 Not_Implemented, 59 Refused); 60 --# accept Warning, 2, "representation clause ok"; 61 for Response_Code'Size use 4; 62 --# end accept; 63 64 65 -- See http://www.zytrax.com/books/dns/ch15/ for a description 66 -- of these fields. 67 type Header_Type is 68 record 69 -- 16 bit message ID supplied by requester and mirrored by responder 70 MessageID : Unsigned_Short; 71 -- False for query, true for response 72 QR : Boolean; 73 -- 0 for query, 1 for inverse query, 2 for status request 74 Opcode : Opcode_Type; 75 -- Authoritative Answer (response only) 76 AA : Boolean; 77 -- Truncated (partial message, true until last portion) 78 TC : Boolean; 79 -- recursion desired (query) 80 RD : Boolean; 81 -- recursion available (response) 82 RA : Boolean; 83 -- Reserved for future use (zone transfers??) 84 Res1 : Boolean; 85 Res2 : Boolean; 86 Res3 : Boolean; 87 -- response code. 88 RCODE : Response_Code; 89 -- number of queries (echo in answer!) 90 QDCOUNT : Unsigned_Short; 91 -- number of answers 92 ANCOUNT : Unsigned_Short; 93 -- number of name server resource records 94 NSCOUNT : Unsigned_Short; 95 -- number of additional records 96 ARCOUNT : Unsigned_Short; 97 end record; 98 -- for Header use record 99 -- MessageID at 0 range 0..15; 100 -- QR at 0 range 23..23; 101 -- Opcode at 0 range 19..22; 102 -- AA at 0 range 18..18; 103 -- TC at 0 range 17..17; 104 -- RD at 0 range 16..16; 105 -- RA at 0 range 31..31; 106 -- Res1 at 0 range 30..30; 107 -- Res2 at 0 range 29..29; 108 -- Res3 at 0 range 28..28; 109 -- RCODE at 0 range 24..27; 110 -- QDCOUNT at 4 range 0..15; 111 -- ANCOUNT at 4 range 16..31; 112 -- NSCOUNT at 8 range 0..15; 113 -- ARCOUNT at 8 range 16..31; 114 -- end record; 115 -- for Header'Bit_Order use System.Low_Order_First; 116 --# accept Warning, 2, "representation clause ok"; 117 for Header_Type use record 118 MessageID at 0 range 16..31; 119 QR at 0 range 8..8; 120 Opcode at 0 range 9..12; 121 AA at 0 range 13..13; 122 TC at 0 range 14..14; 123 RD at 0 range 15..15; 124 RA at 0 range 0..0; 125 Res1 at 0 range 1..1; 126 Res2 at 0 range 2..2; 127 Res3 at 0 range 3..3; 128 RCODE at 0 range 4..7; 129 QDCOUNT at 4 range 16..31; 130 ANCOUNT at 4 range 0..15; 131 NSCOUNT at 8 range 16..31; 132 ARCOUNT at 8 range 0..15; 133 end record; 134 for Header_Type'Size use Header_Bits; 135 for Header_Type'Bit_Order use System.High_Order_First; 136 --# end accept; 137 138 Empty_Header : constant Header_Type := Header_Type'( 139 MessageID => 0, 140 QR => False, 141 Opcode => Query, 142 Rcode => No_Error, 143 AA => False, 144 TC => False, 145 RD => False, 146 RA => False, 147 Res1 => False, 148 Res2 => False, 149 Res3 => False, 150 QDCOUNT => 0, 151 ANCOUNT => 0, 152 NSCOUNT => 0, 153 ARCOUNT => 0); 154 155 function Byte_Swap_US(U : Unsigned_Short) return Unsigned_Short; 156 --# accept Warning, 3, "Inline ok"; 157 pragma Inline(Byte_Swap_US); 158 --# end accept; 159 160 -- swap bytes in Unsigned_Short fields 161 -- to switch between network and host order for little endian machines 162 procedure Byte_Swap ( 163 H : in out Header_Type); 164 --# derives H from H; 165 --# post H = H~[MessageID => Byte_Swap_US(H~.MessageID); 166 --# QDCount => Byte_Swap_US(H~.QDCount); 167 --# ANCount => Byte_Swap_US(H~.ANCount); 168 --# NSCount => Byte_Swap_US(H~.NSCount); 169 --# ARCount => Byte_Swap_US(H~.ARCount)]; 170 type Query_Class is 171 (IN_CLASS, 172 CH_CLASS, 173 HS_CLASS, 174 NONE_CLASS, 175 ANY_CLASS); 176 --# accept Warning, 2, "representation clause ok"; 177 for Query_Class use 178 ( 179 IN_CLASS => 1, 180 CH_CLASS => 3, 181 HS_CLASS => 4, 182 NONE_CLASS => 254, 183 ANY_CLASS => 255); 184 for Query_Class'Size use 16; 185 --# end accept; 186 187 type Query_Type is 188 (A, 189 NS, 190 CNAME, 191 SOA, 192 WKS, 193 PTR, 194 MX, 195 AAAA, 196 SRV, 197 A6, 198 OPT, 199 --DNSSEC 200 DS, 201 RRSIG, 202 NSEC, 203 DNSKEY, 204 -- 205 ANY, 206 CAA, 207 ERROR, 208 UNIMPLEMENTED); 209 --# accept Warning, 2, "representation clause ok"; 210 for Query_Type use 211 ( 212 A => 1, 213 NS => 2, 214 CNAME => 5, 215 SOA => 6, 216 WKS => 11, 217 PTR => 12, 218 MX => 15, 219 AAAA => 28, 220 SRV => 33, 221 A6 => 38, 222 OPT => 41, 223 DS => 43, 224 RRSIG => 46, 225 NSEC => 47, 226 DNSKEY => 48, 227 ANY => 255, 228 CAA => 257, 229 ERROR => 65280, 230 UNIMPLEMENTED => 65281); 231 for Query_Type'Size use 16; 232 --# end accept; 233 234 type EDNS_Record is record 235 Root : Character; 236 Code : Query_Type; 237 Payload_Size : Unsigned_Short; 238 RCode : Byte; 239 Version : Byte; 240 ZTop : Byte; 241 ZBottom : Byte; 242 RDLen : Unsigned_Short; 243 end record; 244 --this record won't pack b/c payload_size isn't aligned correctly. 245 --for EDNS_Record'Size use 9*8; 246 --for EDNS_Record'Bit_Order use System.High_Order_First; 247 DNSSECMASK : constant := 128; 248 249 type Bytes_Array_Type is array(Packet_Bytes_Range) of Byte; 250 251 type DNS_Packet is record 252 Header : Header_Type; 253 Bytes : Bytes_Array_Type; 254 end record; 255 type DNS_Tcp_Packet is record 256 Length : Unsigned_Short; 257 Rest : DNS_Packet; 258 END RECORD; 259end Dns_Types; 260 261