| 141 | |
| 142 | |
| 143 | class DNSFlag: |
| 144 | # qr opcode aa tc rd ra z rcode |
| 145 | # 1 0000 0 0 1 1 000 0000 |
| 146 | # accept a series of kwargs to build a proper flags segment. |
| 147 | def __init__(self, |
| 148 | qr=0b1, # query record, 1 if response |
| 149 | opcode=0b0000, # 0 = query, 1 = inverse query, 2 = status request 3-15 unused |
| 150 | aa=0b0, # authoritative answer = 1 |
| 151 | tc=0b0, # truncation - 1 if truncated |
| 152 | rd=0b1, # recursion desired? |
| 153 | ra=0b1, # recursion available |
| 154 | z=0b000, # Reserved, must be zero in queries and responsed |
| 155 | rcode=0b0000 # errcode, 0 none, 1 format, 2 server, 3 name, 4 not impl, 5 refused, 6-15 unused |
| 156 | ): |
| 157 | |
| 158 | # pack the elements into an integer |
| 159 | flag_field = qr |
| 160 | flag_field = flag_field << 4 |
| 161 | flag_field ^= opcode |
| 162 | flag_field = flag_field << 1 |
| 163 | flag_field ^= aa |
| 164 | flag_field = flag_field << 1 |
| 165 | flag_field ^= tc |
| 166 | flag_field = flag_field << 1 |
| 167 | flag_field ^= rd |
| 168 | flag_field = flag_field << 1 |
| 169 | flag_field ^= ra |
| 170 | flag_field = flag_field << 3 |
| 171 | flag_field ^= z |
| 172 | flag_field = flag_field << 4 |
| 173 | flag_field ^= rcode |
| 174 | |
| 175 | self.flag_field = flag_field |
| 176 | |
| 177 | # return char rep. |
| 178 | def pack(self): |
| 179 | return struct.pack(">H", self.flag_field) |
| 180 | |
| 181 | |
| 182 | class DNSResponse(object): |