diff options
author | Wojciech Kosior <kwojtus@protonmail.com> | 2020-04-30 21:36:58 +0200 |
---|---|---|
committer | Wojciech Kosior <kwojtus@protonmail.com> | 2020-04-30 21:36:58 +0200 |
commit | 53fe2b31383a3c77cd472c91b8c022b8240b6897 (patch) | |
tree | 478a3ea467ecd9948f9857493eb3071b6fb95f04 | |
parent | 3fee573402fbbf26e61d8df2d7c37ffe37b3b740 (diff) | |
download | 0tdns-53fe2b31383a3c77cd472c91b8c022b8240b6897.tar.gz 0tdns-53fe2b31383a3c77cd472c91b8c022b8240b6897.zip |
demonstrate DNS request receiving
-rw-r--r-- | src/receive.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/receive.c b/src/receive.c new file mode 100644 index 0000000..eb5fdb2 --- /dev/null +++ b/src/receive.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2009 - 2012 Marco Peereboom <marco@peereboom.us> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <err.h> + +#include <netinet/in.h> + +#include <arpa/inet.h> + +#include <ldns/ldns.h> + +#define INBUF_SIZE 4096 +#define PORT 53 + +struct sockaddr paddr; +socklen_t plen = (socklen_t)sizeof(paddr); + +int +udp_bind(int sock, uint16_t port) +{ + struct sockaddr_in addr; + in_addr_t maddr = INADDR_ANY; + + addr.sin_family = AF_INET; + addr.sin_port = (in_port_t) htons((uint16_t)port); + addr.sin_addr.s_addr = maddr; + return (bind(sock, (struct sockaddr*)&addr, (socklen_t) sizeof(addr))); +} + +int +socket_create(uint16_t port) { + int so = socket(AF_INET, SOCK_DGRAM, 0); + if (so == -1) + err(1, "can't open socket"); + if (udp_bind(so, port)) + err(1, "can't udp bind"); + return so; +} + +void +printpacket(ldns_pkt *pkt) +{ + char *str = ldns_pkt2str(pkt); + + if (str) { + printf("%s", str); + LDNS_FREE(str); + } else + warnx("could not convert packet to string"); +} + +void receive_and_print(int so) { + uint8_t inbuf[INBUF_SIZE]; + ssize_t nb; + ldns_status status; + ldns_pkt *query_pkt; + + nb = recvfrom(so, inbuf, INBUF_SIZE, 0, &paddr, &plen); + if (nb == -1) { + if (errno == EINTR || errno == EAGAIN) + return; + else + err(EXIT_FAILURE, "recvfrom"); + } + + status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)nb); + if (status != LDNS_STATUS_OK) { + warnx("bad packet: %s", ldns_get_errorstr_by_id(status)); + return; + } else { + puts("received packet:"); + printpacket(query_pkt); + } + + ldns_pkt_free(query_pkt); +} + +int main(int argc, char **argv) { + int so; + + if (geteuid()) + errx(1, "need root privileges"); + + so = socket_create(PORT); + + while (1) + receive_and_print(so); +} |