1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#include "uint16.h"
#include "uint32.h"
#include "error.h"
#include "byte.h"
#include "dns.h"
#include "printrecord.h"
#include "printpacket.h"
static char *d;
#define X(s) if (!stralloc_cats(out,s)) return 0;
#define NUM(u) if (!stralloc_catulong0(out,u,0)) return 0;
unsigned int printpacket_cat(stralloc *out,char *buf,unsigned int len)
{
uint16 numqueries;
uint16 numanswers;
uint16 numauthority;
uint16 numglue;
unsigned int pos;
char data[12];
uint16 type;
pos = dns_packet_copy(buf,len,0,data,12); if (!pos) return 0;
uint16_unpack_big(data + 4,&numqueries);
uint16_unpack_big(data + 6,&numanswers);
uint16_unpack_big(data + 8,&numauthority);
uint16_unpack_big(data + 10,&numglue);
NUM(len)
X(" bytes, ")
NUM(numqueries)
X("+")
NUM(numanswers)
X("+")
NUM(numauthority)
X("+")
NUM(numglue)
X(" records")
if (data[2] & 128) X(", response")
if (data[2] & 120) X(", weird op")
if (data[2] & 4) X(", authoritative")
if (data[2] & 2) X(", truncated")
if (data[2] & 1) X(", weird rd")
if (data[3] & 128) X(", weird ra")
switch(data[3] & 15) {
case 0: X(", noerror"); break;
case 3: X(", nxdomain"); break;
case 4: X(", notimp"); break;
case 5: X(", refused"); break;
default: X(", weird rcode");
}
if (data[3] & 112) X(", weird z")
X("\n")
while (numqueries) {
--numqueries;
X("query: ")
pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
pos = dns_packet_copy(buf,len,pos,data,4); if (!pos) return 0;
if (byte_diff(data + 2,2,DNS_C_IN)) {
X("weird class")
}
else {
uint16_unpack_big(data,&type);
NUM(type)
X(" ")
if (!dns_domain_todot_cat(out,d)) return 0;
}
X("\n")
}
for (;;) {
if (numanswers) { --numanswers; X("answer: ") }
else if (numauthority) { --numauthority; X("authority: ") }
else if (numglue) { --numglue; X("additional: ") }
else break;
pos = printrecord_cat(out,buf,len,pos,0,0);
if (!pos) return 0;
}
if (pos != len) { errno = error_proto; return 0; }
return 1;
}
|