我正在使用dpkt来读取pcap文件。
try: dns = dpkt.dns.DNS(udp.data)
except: continue
if dns.qr != dpkt.dns.DNS_R: continue
if dns.opcode != dpkt.dns.DNS_QUERY: continue
if dns.rcode != dpkt.dns.DNS_RCODE_NOERR: continue
if len(dns.an) < 1: continue
for answer in dns.an:
if answer.type == 5:
print "CNAME request", answer.name, "\tresponse", answer.cname
我想为每个答案读取IP地址和TTL。我做了dir(answer)
但我找不到任何似乎返回响应的IP地址/ TTL的内容,而且我在文档中找不到任何内容。
有方法吗?
答案 0 :(得分:2)
我假设您正在阅读这样的内容:
import dpkt
import sys
f=file(sys.argv[1],"rb")
pcap=dpkt.pcap.Reader(f)
从以太网开始单独解析每个层。
for ts, buf in pcap:
eth=dpkt.ethernet.Ethernet(buf)
ip=eth.data
udp=ip.data
然后从IP标头中提取相关的TTL和IP值。
TTL和IP值在IP标头中,而不是DNS答案。
答案 1 :(得分:0)
RR对象具有ttl
属性,这是您正在寻找的:
try:
dns = dpkt.dns.DNS(udp.data)
except:
continue
if dns.qr != dpkt.dns.DNS_R: continue
if dns.opcode != dpkt.dns.DNS_QUERY: continue
if dns.rcode != dpkt.dns.DNS_RCODE_NOERR: continue
if len(dns.an) < 1: continue
for answer in dns.an:
if answer.type == 5:
print "CNAME request", answer.name, "\tresponse", answer.cname, "\tttl", answer.ttl
答案 2 :(得分:0)
(这是一个可悲的迟到的答案。)Bob你要求发送回复的服务器的IP地址,或CNAME记录中名称的IP地址? DNS回复的资源记录(RR)部分中的规范名称(CNAME)数据仅具有域名和TTL。我测试过的名称服务器在不同的附加信息RR记录中返回CNAME应答的IP地址。
如果您想阅读原始章节和经文:https://www.ietf.org/rfc/rfc1035.txt
以下是使用dpkt的一些Python代码,可让您生成和探索DNS回复的内容。
import dpkt
import random
import socket
# build query
query_id = int(random.random() * 10000)
query = dpkt.dns.DNS(id=query_id)
my_q = dpkt.dns.DNS.Q(name="www.yahoo.com")
query.qd.append(my_q)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(("8.8.8.8", 53))
sock.send(str(query))
buf = sock.recv(0xffff)
# parse response
response = dpkt.dns.DNS(buf)
if query_id != response.id:
print "Expected %d but received id %d" % (query_id, response.id)
elif response.qr != dpkt.dns.DNS_R:
print "Not a response!"
elif response.opcode != dpkt.dns.DNS_QUERY:
print "Not a query op!"
elif response.rcode != dpkt.dns.DNS_RCODE_NOERR:
print "Not a successful response!"
elif len(response.an) == 0:
print"Response has no answers!"
else:
print "%d bytes received, id is %d" % (len(buf), response.id)
for rr in response.an:
print "AN: class is %d, type is %d, name is %s" % (rr.cls, rr.type, rr.name)
if hasattr(rr, 'ip'):
print "\tIP is %s" % socket.inet_ntoa(rr.ip)
for rr in response.ns:
print "NS: class is %d, type is %d, name is %s" % (rr.cls, rr.type, rr.name)
for rr in response.ar:
print "AR: class is %d, type is %d, name is %s" % (rr.cls, rr.type, rr.name)
我看到的结果(坐在东海岸):
240 bytes received, id is 5848
AN: class is 1, type is 5, name is www.yahoo.com
AN: class is 1, type is 1, name is fd-fp3.wg1.b.yahoo.com
IP is 98.139.180.149
AN: class is 1, type is 1, name is fd-fp3.wg1.b.yahoo.com
IP is 98.139.183.24
NS: class is 1, type is 2, name is wg1.b.yahoo.com
NS: class is 1, type is 2, name is wg1.b.yahoo.com
NS: class is 1, type is 2, name is wg1.b.yahoo.com
NS: class is 1, type is 2, name is wg1.b.yahoo.com
AR: class is 1, type is 1, name is yf2.yahoo.com
AR: class is 1, type is 1, name is yf1.yahoo.com
AR: class is 1, type is 1, name is yf3.a1.b.yahoo.net
AR: class is 1, type is 1, name is yf4.a1.b.yahoo.net