Last active
March 18, 2020 00:46
-
-
Save bave/6139574 to your computer and use it in GitHub Desktop.
How to use {libresolv, libbind}.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* # 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