for _ in range(79): data += ('\xc0\x0c' + # ptr to the name '\x00\x0c' + # type = 'PTR' '\x00\x01' + # cls = 'IN' '\x00\x00\x00\x3d' + # ttl '\x00\x02' + # size of the compressed resource record '\xc4\x40') # pointer to the second record's name data += ('\xc0\x0c' + # ptr to the name '\x00\x0c' + # type = 'PTR' '\x00\x01' + # cls = 'IN' '\x00\x00\x00\x3d' + # ttl '\x00\x11' + # size of this resource record '\x04EEEE\x09DAABBEEEE\xc4\x49') sock_udp.sendto(data, addr)
时间: 2024-04-27 08:24:09 浏览: 40
这段代码在原有 DNS 响应报文的基础上,添加了 79 个附加的回答资源记录。这些记录的格式与原有的 PTR 类型的回答记录相同,但是它们的数据部分只有 2 个字节,分别是 0xc4 和 0x40,表示该记录指向响应报文中的第 65 个字节(即第一个 PTR 记录的数据部分的第一个字节)。其中,第一个字节 0xc4 表示该记录是一个指针类型的资源记录,指向响应报文中的另一个资源记录,第二个字节 0x40 表示该指针指向的资源记录的偏移量为 64。因此,这些附加的回答资源记录都指向第一个 PTR 记录,即查询 IP 地址对应的第一个域名的反向映射结果。最后,将构造好的 DNS 响应报文通过 UDP 协议发送给客户端。
相关问题
data, addr = sock_udp.recvfrom(1024) print '[UDP] Total Data len recv ' + str(len(data)) id = struct.unpack('>H', data[0:2])[0] query = data[12:] data = dw(id) # id data += dw(0x85a0) # flags data += dw(1) # questions data += dw(0x52) # answers data += dw(0) # authoritative data += dw(0) # additional # Add the question back - we're just hardcoding it data += ('\x03125\x018\x018\x018\x07in-addr\x04arpa\x00' + '\x00\x0c' + # type = 'PTR' '\x00\x01') # cls = 'IN' # Add the first answer data += ('\xc0\x0c' + # ptr to the name '\x00\x0c' + # type = 'PTR' '\x00\x01' + # cls = 'IN' '\x00\x00\x00\x3d' + # ttl '\x04\x00' + # size of this resource record '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x3e' + 'Z'*62 + '\x0e' + 'Z'*14 + '\x00') # Add the next answer, which is written out in full data += ('\xc0\x0c' + # ptr to the name '\x00\x0c' + # type = 'PTR' '\x00\x01' + # cls = 'IN' '\x00\x00\x00\x3d' + # ttl '\x00\x26' + # size of this resource record '\x08DCBBEEEE\x04DDDD\x08CCCCCCCC\x04AAAA\x04BBBB\x03com\x00')
这段代码实现了一个 DNS 服务器的响应报文的构造过程。首先,使用 UDP 协议接收来自客户端的 DNS 查询报文(不超过 1024 字节),其中包含了查询的 domain 名称,然后解析出查询的 id 和问题部分的数据。接着,根据 DNS 协议的规定,构造 DNS 响应报文,并将其打包成二进制数据。具体来说,响应报文的格式如下:
1. 16 位的 id,与查询报文的 id 相同。
2. 16 位的 flags,表示响应报文的状态信息。
3. 16 位的 questions,表示查询的问题数,这里为 1。
4. 16 位的 answers,表示响应的回答数,这里为 1。
5. 16 位的 authoritative,表示授权回答数,这里为 0。
6. 16 位的 additional,表示附加回答数,这里为 0。
接着,构造响应报文中的 question 部分,这里是一个固定的反向 DNS 查询报文,即查询 IP 地址对应的域名。然后,构造响应报文中的 answer 部分,包含了两个 PTR 类型的回答记录,分别是查询 IP 地址对应的两个域名的反向映射结果。其中,第一个 PTR 记录的数据部分由 16 个 62 字节的字符串和一个 14 字节的字符串组成,第二个 PTR 记录的数据部分是一个完整的 PTR 记录,它将查询 IP 地址映射到一个域名。最后,将构造好的 DNS 响应报文通过 UDP 协议发送给客户端。
unsigned long datapack(void *inBuf, unsigned long len, void *outBuf) { WORD16 *hdr; BYTE *in = (BYTE *)inBuf; BYTE *out = (BYTE *)outBuf; BYTE *pscrc; BYTE *ptr = out; unsigned long i; unsigned long fcs = ~(crc32_le(~0, in, len)); *ptr++ = 0x55; *ptr++ = 0xAA; hdr = (WORD16 *)ptr; ptr += 2; *ptr++ = 0x7e; *ptr++ = 0x7e; for (i = 0; i < len; i++) { switch (in[i]) { case 0x7d: *ptr++ = 0x7d; *ptr++ = 0x5d; break; case 0x7e: *ptr++ = 0x7d; *ptr++ = 0x5e; break; default: *ptr++ = in[i]; break; } } pscrc = (BYTE *)&fcs; for (i = 0; i < 4; i++, pscrc++) { switch (*pscrc) { case 0x7d: *ptr++ = 0x7d; *ptr++ = 0x5d; break; case 0x7e: *ptr++ = 0x7d; *ptr++ = 0x5e; break; default: *ptr++ = *pscrc; break; } } *ptr++ = 0x7e; *ptr++ = 0x7e; *hdr = ptr - out - 4; return ptr - out; } 转化为python程序
Here's the Python equivalent of the given C function:
```
import struct
import binascii
def datapack(inBuf, length, outBuf):
inBytes = struct.unpack(str(length)+'B', inBuf)
fcs = binascii.crc32(bytes(inBytes)) ^ 0xffffffff
outBytes = bytearray()
outBytes.append(0x55)
outBytes.append(0xAA)
outBytes.extend(struct.pack('<H', length))
outBytes.append(0x7e)
outBytes.append(0x7e)
for b in inBytes:
if b == 0x7d:
outBytes.extend([0x7d, 0x5d])
elif b == 0x7e:
outBytes.extend([0x7d, 0x5e])
else:
outBytes.append(b)
for i in range(4):
pscrc = (fcs >> (i * 8)) & 0xff
if pscrc == 0x7d:
outBytes.extend([0x7d, 0x5d])
elif pscrc == 0x7e:
outBytes.extend([0x7d, 0x5e])
else:
outBytes.append(pscrc)
outBytes.append(0x7e)
outBytes.append(0x7e)
struct.pack_into('<H', outBytes, 2, len(outBytes) - 6)
outBuf[:len(outBytes)] = outBytes
return len(outBytes)
```
Note: This implementation assumes that `inBuf`, `len`, and `outBuf` are already byte arrays in Python. If they are not, you may need to modify the code accordingly.