Skip to content

Instantly share code, notes, and snippets.

@bave
Last active March 18, 2020 00:46
Show Gist options
  • Save bave/6139574 to your computer and use it in GitHub Desktop.
Save bave/6139574 to your computer and use it in GitHub Desktop.
How to use {libresolv, libbind}.
/*
* # Advance preparation are required.
* # ipfw add divert 10000 udp from me to [nameserver_ip] via [IF]
* # ipfw add divert 10000 udp from [nameserver_ip] to me via [IF]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <nameser.h>
void hexdump (char *desc, void *addr, int len)
{
int i;
unsigned char buff[17];
unsigned char *pc = addr;
if (desc != NULL)
printf ("%s:\n", desc);
for (i = 0; i < len; i++) {
if ((i % 16) == 0) {
if (i != 0) {
printf (" %s\n", buff);
}
printf (" %04x ", i);
}
printf (" %02x", pc[i]);
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
buff[i % 16] = '.';
} else {
buff[i % 16] = pc[i];
}
buff[(i % 16) + 1] = '\0';
}
while ((i % 16) != 0) {
printf (" ");
i++;
}
printf (" %s\n", buff);
return;
}
int main(int argc, char** argv)
{
int i;
int sock;
struct sockaddr_in sin_divert;
ssize_t size;
char buf[4096];
struct sockaddr_in recv_addr;
socklen_t addr_size = sizeof(recv_addr);
ns_msg ns_handle;
sin_divert.sin_family = AF_INET;
sin_divert.sin_port = htons(10000);
sock = socket(AF_INET, SOCK_RAW, IPPROTO_DIVERT);
if(sock < 0){
perror("socket.");
exit(EXIT_FAILURE);
}
if(bind(sock, (struct sockaddr*)&sin_divert, sizeof(sin_divert)) < 0){
perror("bind.");
exit(EXIT_FAILURE);
}
while(1) {
memset(&recv_addr, 0, sizeof(struct sockaddr_in));
memset(&ns_handle, 0, sizeof(ns_handle));
size = recvfrom(sock, buf, sizeof(buf), 0,(struct sockaddr*)&recv_addr, &addr_size);
if (size < 0) {
exit(EXIT_FAILURE);
}
/*
* パケットのパース部分省略!!!
*/
if(ns_initparse((uint8_t*)buf+28, size-28, &ns_handle)) {
exit(EXIT_FAILURE);
}
/*
* -- identifier
*/
int name_id = ns_msg_id(ns_handle);
printf("-- identifier -\n");
printf("%d\n", name_id);
printf("---------------\n");
/*
* -- flags --
* 0 1 5 6 7 8 11 15
* +----+----------------+----+----+----+-----------+----------------+
* | QR | Operation Code | AA | TC | RA | Zero | Recode |
* +----+----------------+----+----+----+-----------+----------------+
*
* Question/Response : ns_f_qr
* Operation code : ns_f_opcode
* Authoritative Answer : ns_f_aa
* Truncation occurred : ns_f_tc
* Recursion Desired : ns_f_rd
* Recursion Available : ns_f_ra
* MBZ : ns_f_z
* Authentic Data (DNSSEC) : ns_f_ad
* Checking Disabled (DNSSEC) : ns_f_cd
* Response code : ns_f_rcode
*/
printf("-- flag -------\n");
printf("ns_f_qr : %d\n", ns_msg_getflag(ns_handle, ns_f_qr));
printf("ns_f_opcode: %d\n", ns_msg_getflag(ns_handle, ns_f_opcode));
printf("ns_f_aa : %d\n", ns_msg_getflag(ns_handle, ns_f_aa));
printf("ns_f_tc : %d\n", ns_msg_getflag(ns_handle, ns_f_tc));
printf("ns_f_rd : %d\n", ns_msg_getflag(ns_handle, ns_f_rd));
printf("ns_f_ra : %d\n", ns_msg_getflag(ns_handle, ns_f_ra));
printf("ns_f_z : %d\n", ns_msg_getflag(ns_handle, ns_f_z));
printf("ns_f_ad : %d\n", ns_msg_getflag(ns_handle, ns_f_ad));
printf("ns_f_cd : %d\n", ns_msg_getflag(ns_handle, ns_f_cd));
printf("ns_f_rcode : %d\n", ns_msg_getflag(ns_handle, ns_f_rcode));
printf("---------------\n");
/*
Question ns_s_qd
Answer ns_s_an
Name servers ns_s_ns
Add records ns_s_ar
*/
int name_count_qd = ns_msg_count(ns_handle, ns_s_qd);
int name_count_an = ns_msg_count(ns_handle, ns_s_an);
int name_count_ns = ns_msg_count(ns_handle, ns_s_ns);
int name_count_ar = ns_msg_count(ns_handle, ns_s_ar);
/*
printf("-- count ------\n");
printf("ns_s_qd : %d\n", name_count_qd);
printf("ns_s_an : %d\n", name_count_an);
printf("ns_s_ns : %d\n", name_count_ns);
printf("ns_s_ar : %d\n", name_count_ar);
printf("---------------\n");
*/
ns_rr rr;
char pbuf[0xFFFF];
// query
printf("Questionrecord\n");
for (i = 0; i < name_count_qd; i++) {
memset(&rr, 0, sizeof(rr));
if (ns_parserr(&ns_handle, ns_s_qd, i, &rr) == 0) {
printf("\t-- %d --\n", i+1);
ns_sprintrr(&ns_handle, &rr, NULL, NULL, pbuf, sizeof(pbuf));
printf("\t%s\n", pbuf);
printf("\tfqdn :%s\n", ns_rr_name(rr));
printf("\ttype :%d\n", ns_rr_type(rr));
printf("\tclass:%d\n", ns_rr_class(rr));
printf("\tttl :%d\n", ns_rr_ttl(rr));
//printf("\trdlen:%d\n", ns_rr_rdlen(rr));
//hexdump("qd", (uint8_t*)ns_rr_rdata(rr), ns_rr_rdlen(rr));
}
}
printf("AnswerRecord\n");
for (i = 0; i < name_count_an; i++) {
memset(&rr, 0, sizeof(rr));
if (ns_parserr(&ns_handle, ns_s_an, i, &rr) == 0) {
printf("\t-- %d --\n", i+1);
ns_sprintrr(&ns_handle, &rr, NULL, NULL, pbuf, sizeof(pbuf));
printf("\t%s\n", pbuf);
printf("\tfqdn :%s\n", ns_rr_name(rr));
printf("\ttype :%d\n", ns_rr_type(rr));
printf("\tclass:%d\n", ns_rr_class(rr));
printf("\tttl :%d\n", ns_rr_ttl(rr));
//printf("\trdlen:%d\n", ns_rr_rdlen(rr));
//hexdump("an", (uint8_t*)ns_rr_rdata(rr), ns_rr_rdlen(rr));
}
}
printf("NameServerRecord\n");
for (i = 0; i < name_count_ns; i++) {
memset(&rr, 0, sizeof(rr));
if (ns_parserr(&ns_handle, ns_s_ns, i, &rr) == 0) {
printf("\t-- %d --\n", i+1);
ns_sprintrr(&ns_handle, &rr, NULL, NULL, pbuf, sizeof(pbuf));
printf("\t%s\n", pbuf);
printf("\tfqdn :%s\n", ns_rr_name(rr));
printf("\ttype :%d\n", ns_rr_type(rr));
printf("\tclass:%d\n", ns_rr_class(rr));
printf("\tttl :%d\n", ns_rr_ttl(rr));
//printf("\trdata:%s\n", ns_rr_rdata(rr));
//hexdump("ns", (uint8_t*)ns_rr_rdata(rr), ns_rr_rdlen(rr));
}
}
printf("AdditionalRecord\n");
for (i = 0; i < name_count_ar; i++) {
memset(&rr, 0, sizeof(rr));
if (ns_parserr(&ns_handle, ns_s_ar, i, &rr) == 0) {
printf("\t-- %d --\n", i+1);
ns_sprintrr (&ns_handle, &rr, NULL, NULL, pbuf, sizeof(pbuf));
printf("\t%s\n", pbuf);
printf("\tfqdn :%s\n", ns_rr_name(rr));
printf("\ttype :%d\n", ns_rr_type(rr));
printf("\tclass:%d\n", ns_rr_class(rr));
printf("\tttl :%d\n", ns_rr_ttl(rr));
//printf("\trdlen:%d\n", ns_rr_rdlen(rr));
//hexdump("ar", (uint8_t*)ns_rr_rdata(rr), ns_rr_rdlen(rr));
}
}
size = sendto(sock, buf, size, 0, (struct sockaddr*)&recv_addr, addr_size);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment