📄 dns.c
字号:
/****************************************************************************
** File: dns.c
**
** Author: Mike Borella
**
** Comments: Dump DNS header information
**
** $Log: dns.c,v $
** Revision 1.2 1998/06/12 21:00:59 mborella
** Added log tag
**
*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "config.h"
#include "dns.h"
extern u_char *packet_end;
/*----------------------------------------------------------------------------
**
** dump_dns()
**
** Parse DNS packet and dump fields
**
**----------------------------------------------------------------------------
*/
void dump_dns(u_char *bp, int length)
{
u_char *ep = bp + length;
u_char *p;
DNSHdr dns_fixed;
int i, t;
u_int16_t qt, qc;
char *dns_query_type(u_int16_t);
u_char *dump_rr(u_char *, u_char *, u_char *);
u_char *parse_labels(u_char *, u_char *, u_char *);
#ifdef DEBUG
void dump_ascii(u_char *, u_char *);
#endif
/*
* Make sure we don't run off the end of the packet
*/
if (ep > packet_end)
ep = packet_end;
/*
* Overlay the first 12 bytes, which are fixed
*/
memcpy((void *) &dns_fixed, bp, sizeof(dns_fixed));
/*
* Print it
*/
printf("-----------------------------------------------------------------\n");
printf(" DNS Packet\n");
printf("-----------------------------------------------------------------\n");
printf("Identification: %d\n", ntohs(dns_fixed.dns_id));
printf("Flags: query/response: %d ", dns_fixed.dns_fl_qr);
if (dns_fixed.dns_fl_qr == 0)
printf("(query)\n");
else
printf("(response)\n");
printf(" opcode %d ", dns_fixed.dns_fl_opcode);
switch(dns_fixed.dns_fl_opcode)
{
case 0: printf("(standard)\n");
break;
case 1: printf("(inverse)\n");
break;
case 2: printf("(server status)\n");
break;
}
printf(" auth answer %d\n", dns_fixed.dns_fl_aa);
printf(" truncated %d\n", dns_fixed.dns_fl_tc);
printf(" recursion req %d\n", dns_fixed.dns_fl_rd);
printf(" recursion avail %d\n", dns_fixed.dns_fl_ra);
printf(" zero %d\n", dns_fixed.dns_fl_zero);
printf(" return code %d ", dns_fixed.dns_fl_rcode);
switch(dns_fixed.dns_fl_rcode)
{
case 0: printf("(no error)\n");
break;
case 1: printf("(format error)\n");
break;
case 2: printf("(server error)\n");
break;
case 3: printf("(name error)\n");
break;
case 4: printf("(not implemented)\n");
break;
case 5: printf("(service refused)\n");
break;
}
printf("# of questions %d\n", ntohs(dns_fixed.dns_num_q));
printf("# of answer RRs %d\n", ntohs(dns_fixed.dns_num_ans));
printf("# of authorization RRs %d\n", ntohs(dns_fixed.dns_num_auth));
printf("# of additional RRs %d\n", ntohs(dns_fixed.dns_num_add));
/*
* Do the question part of the packet.
*/
p = bp + sizeof(DNSHdr);
i = ntohs(dns_fixed.dns_num_q);
while (i > 0)
{
printf("Question: query name ");
p = parse_labels(p, bp, ep);
memcpy((void *) &qt, p, sizeof(qt));
p = p + sizeof(qt);
memcpy((void *) &qc, p, sizeof(qc));
p = p + sizeof(qc);
printf(" query type %d %s\n", ntohs(qt),
dns_query_type(ntohs(qt)));
printf(" query class %d", ntohs(qc));
if (ntohs(qc) == 1)
printf(" (Internet)");
printf("\n");
i--;
}
/*
* dump the resource records for the answers
*/
i = ntohs(dns_fixed.dns_num_ans);
t = i;
while (i > 0)
{
printf("Answer %d: ", t-i+1);
p = dump_rr(p, bp, ep);
i--;
}
/*
* dump the resource records for the authoritative answers
*/
i = ntohs(dns_fixed.dns_num_auth);
t = i;
while (i > 0)
{
printf("Auth %d: ", t-i+1);
p = dump_rr(p, bp, ep);
i--;
}
/*
* dump the resource records for the additional info
*/
i = ntohs(dns_fixed.dns_num_add);
t = i;
while (i > 0)
{
printf("Adtnl %d: ", t-i+1);
#ifdef DEBUG
dump_ascii(p, ep);
#endif
p = dump_rr(p, bp, ep);
i--;
}
}
/*----------------------------------------------------------------------------
**
** dns_query_type()
**
** Return a string describing the numeric value of a DNS query type
**
**----------------------------------------------------------------------------
*/
char *dns_query_type(u_int16_t t)
{
static char answer[32];
switch(t)
{
case 1: strncpy(answer, "(IP address)", 32);
break;
case 2: strncpy(answer, "(name server)", 32);
break;
case 5: strncpy(answer, "(canonical name)", 32);
break;
case 12: strncpy(answer, "(pointer record)", 32);
break;
case 13: strncpy(answer, "(host info)", 32);
break;
case 15: strncpy(answer, "(MX record)", 32);
break;
case 252: strncpy(answer, "(request zone transfer)", 32);
break;
case 255: strncpy(answer, "(request all records)", 32);
break;
default: answer[0] = '\0';
break;
}
return answer;
}
/*----------------------------------------------------------------------------
**
** dump_rr()
**
** Print the contents of a resource record
**
**----------------------------------------------------------------------------
*/
u_char *dump_rr(u_char *p, u_char *bp, u_char *ep)
{
int i;
u_int16_t qt, qc;
u_int32_t ttl;
u_int16_t reslen;
struct in_addr ipaddr;
u_char *parse_labels(u_char *, u_char *, u_char *);
printf("server name ");
p = parse_labels(p, bp, ep);
/*
* Do type and class
*/
memcpy((void *) &qt, p, sizeof(qt));
p = p + sizeof(qt);
memcpy((void *) &qc, p, sizeof(qc));
p = p + sizeof(qc);
printf(" type %d %s\n", ntohs(qt),
dns_query_type(ntohs(qt)));
printf(" class %d", ntohs(qc));
if (ntohs(qc) == 1)
printf(" (Internet)");
printf("\n");
/*
* Do TTL
*/
memcpy((void *) &ttl, p, sizeof(ttl));
p = p + sizeof(ttl);
printf(" ttl %d seconds\n", ntohs(ttl));
/*
* Do resource length
*/
memcpy((void *) &reslen, p, sizeof(reslen));
p = p + sizeof(reslen);
printf(" length %d\n", ntohs(reslen));
/*
* Do resource data.
*/
switch(ntohs(qt))
{
case 1:
for (i=1; i<= ntohs(reslen); i += 4)
{
memcpy((void *) &ipaddr, p, sizeof(ipaddr));
p = p + sizeof(ipaddr);
printf(" IP address %s\n", inet_ntoa(ipaddr));
}
break;
case 2:
printf(" auth host ");
p = parse_labels(p, bp, ep);
break;
case 5:
printf(" canon host ");
p = parse_labels(p, bp, ep);
break;
default:
p = p + ntohs(reslen);
}
return p;
}
/*----------------------------------------------------------------------------
**
** parse_labels()
**
** Recursively parse a label entry in a DNS packet
**
**----------------------------------------------------------------------------
*/
u_char *parse_labels(u_char *p, u_char *bp, u_char *ep)
{
u_int8_t count;
u_int16_t offset;
while(1)
{
count = (u_int8_t) *p;
if (count >= 192)
{
/*
* There's a pointer in this label. Sigh. Let's grab the
* 14 low-order bits and run with them...
*/
p++;
offset = count - 192;
offset = offset << 8;
offset = offset + *p;
p++;
parse_labels(bp+offset, bp, ep);
return p;
}
else
p++;
if (count == 0)
break;
while (count > 0)
{
if (p <= ep)
printf("%c", *p);
else
{
printf("\nPacket length exceeded\n");
return p;
}
p++;
count--;
}
printf(".");
}
printf("\n");
return p;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -