Commit b455e82d authored by Yves Legrandgerard's avatar Yves Legrandgerard
Browse files

TP du 26/11/2019

parent 4df4ef6f
......@@ -73,6 +73,13 @@ typedef struct {
uint16_t ns_qtc_class;
} __attribute__((packed)) ns_qtc_t;
typedef struct {
uint16_t ns_rr_type;
uint16_t ns_rr_class;
uint32_t ns_rr_ttl;
uint16_t ns_rr_rdlen;
} __attribute__((packed)) ns_rr_t;
int ns_name_set(const char *, ns_name_t *);
size_t ns_name_print(const char *, const char *, FILE *);
int ns_make_query(const char *, ns_type_t, ns_hdr_t *, ns_name_t *, ns_qtc_t *);
......
......@@ -7,10 +7,14 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ns.h>
static int conv_type(const char *);
static void wait_for_reply(int, uint16_t, struct timeval *);
static void print_packet(const char *, size_t, FILE *);
static void print_rr_a(const char *, FILE *);
int
main(int argc, char **argv)
......@@ -24,6 +28,7 @@ main(int argc, char **argv)
const char *t = argv[2];
struct sockaddr_storage ns;
socklen_t nslen;
struct timeval timeout = {.tv_sec=5, .tv_usec=0};
if (argc < 3) {
fprintf(stderr, "usage: %s [<@ns>] <dn> <type>\n", argv[0]);
......@@ -71,6 +76,7 @@ main(int argc, char **argv)
(void) close(sock);
exit(1);
}
wait_for_reply(sock, hdr.ns_hdr_id, &timeout);
(void) close(sock);
exit(0);
}
......@@ -96,3 +102,110 @@ conv_type(const char *t)
return NS_TYPE_AAAA;
return 0;
}
static void
wait_for_reply(int sock, uint16_t id, struct timeval *to)
{
int ecode;
fd_set rfds;
ssize_t rnoc;
char pkt[512];
ns_hdr_t *hdr;
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
ecode = select(sock + 1, &rfds, NULL, NULL, to);
if (ecode < 0) {
fprintf(
stderr, "%s(): select(): [%d, %s]\n", __func__, errno,
strerror(errno)
);
exit(1);
}
if (!ecode) {
fprintf(stderr, "no answer from name server\n");
exit(1);
}
rnoc = recvfrom(sock, pkt, sizeof(pkt), 0, NULL, 0);
if (rnoc < 0) {
fprintf(
stderr, "%s(): recvfrom(): [%d, %s]\n", __func__, errno,
strerror(errno)
);
exit(1);
}
hdr = (ns_hdr_t *) pkt;
if (hdr->ns_hdr_id != id) {
fprintf(stderr, "%s(): unexpected packet\n", __func__);
exit(1);
}
print_packet(pkt, rnoc, stdout);
}
static void
print_packet(const char *pkt, size_t len, FILE *os)
{
ns_hdr_t *hdr = (ns_hdr_t *) pkt;
uint16_t qdc = ntohs(hdr->ns_hdr_qdcount);
uint16_t anc = ntohs(hdr->ns_hdr_ancount);
uint16_t nsc = ntohs(hdr->ns_hdr_nscount);
uint16_t arc = ntohs(hdr->ns_hdr_arcount);
const char *cur = pkt + sizeof(*hdr);
if (len < sizeof(ns_hdr_t)) {
fprintf(stderr, "%s(); packet too short\n", __func__);
exit(1);
}
if (hdr->ns_hdr_rcode) {
fprintf(stderr, "%s(): rcode error %d\n", __func__, hdr->ns_hdr_rcode);
exit(1);
}
if (hdr->ns_hdr_tc) {
fprintf(stderr, "%s(); packet is truncated\n", __func__);
exit(1);
}
fprintf(
os, "ID: %hu, RA: %d, RCODE: no error\n", ntohs(hdr->ns_hdr_id),
hdr->ns_hdr_ra
);
fprintf(os, ">> QUESTION <<\n");
for (int i = 0; i < qdc; i++) {
ns_qtc_t *qtc;
size_t l;
l = ns_name_print(cur, pkt, os);
qtc = (ns_qtc_t *) (cur + l);
fprintf(
os, "\tType: %hu\tClass: %hu\n", ntohs(qtc->ns_qtc_type),
ntohs(qtc->ns_qtc_class)
);
cur += l + sizeof(ns_qtc_t);
}
fprintf(os, ">> ANSWER <<\n");
for (int i = 0; i < anc; i++) {
ns_rr_t *rr;
size_t l;
l = ns_name_print(cur, pkt, os);
rr = (ns_rr_t *) (cur + l);
fprintf(
os, "\tType: %hu\tClass: %hu\tTTL: %u\t", ntohs(rr->ns_rr_type),
ntohs(rr->ns_rr_class), ntohl(rr->ns_rr_ttl)
);
switch (ntohs(rr->ns_rr_type)) {
case NS_TYPE_A:
print_rr_a(cur + l + sizeof(ns_rr_t), os);
break;
}
cur += l + sizeof(ns_rr_t) + ntohs(rr->ns_rr_rdlen);
}
}
static void
print_rr_a(const char *addr, FILE *os)
{
char buf[INET_ADDRSTRLEN];
(void) inet_ntop(AF_INET, addr, buf, sizeof(buf));
fprintf(os, "A: %s\n", buf);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment