diff --git a/inc/libft_network/ipv4.h b/inc/libft_network/ipv4.h index 5e1ff4c..a249a5c 100644 --- a/inc/libft_network/ipv4.h +++ b/inc/libft_network/ipv4.h @@ -6,7 +6,7 @@ /* By: brda-sil src_port); dst_port = ft_htons(pack_udp->dst_port); - if (dst_port == DNS_SRC_PORT && src_port == DNS_DST_PORT) - { + if (dst_port != DNS_SRC_PORT || src_port != DNS_DST_PORT) return (1); - } + if (pack_dns->response_code != DNS_RCODE_NO_ERROR) + return (2); return (0); } @@ -43,19 +45,23 @@ static t_bool recv_reply(int sock, t_packet *pong_pkt) return (ret == -1); } -char *ft_i4toh_recv_packet(int sock) +char **ft_i4toh_recv_packet(int sock) { t_packet pkt; + t_uint32 retv; while (TRUE) { pkt = ft_pkt_get(); if (recv_reply(sock, &pkt)) { - return 0; + return FT_NULL; } - if (check_reply(&pkt)) + retv = check_reply(&pkt); + if (!retv) break; + else if (retv == 2) + return FT_NULL; } - return (ft_dns_get_ptr_record(&pkt)); + return (ft_dns_get_record_ptr(&pkt)); } diff --git a/src/network/packet/dns/dnsq_get.c b/src/network/packet/dns/dnsq_get.c deleted file mode 100644 index 511d053..0000000 --- a/src/network/packet/dns/dnsq_get.c +++ /dev/null @@ -1,26 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* dnsq_get.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brda-sil name); - i += 1; - dnsq->type = ft_htons(*(t_uint16 *)(data + i)); - i += 2; - dnsq->class = ft_htons(*(t_uint16 *)(data + i)); - i += 2; - return (i); -} diff --git a/src/network/packet/dns/dnsr_get.c b/src/network/packet/dns/dnsr_get.c deleted file mode 100644 index 437e347..0000000 --- a/src/network/packet/dns/dnsr_get.c +++ /dev/null @@ -1,70 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* dnsr_get.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brda-sil type == DNS_TYPE_A) - { - dnsr->value = ft_calloc(5, sizeof(t_uint8)); - ft_memcpy(dnsr->value, data, 4); - ptr = dnsr->value + 4; - *ptr = 0; - return (4); - } - else if (dnsr->type == DNS_TYPE_CNAME) - return (dnsr->rdlength); - return (1); -} - -static int get_dnsr_response_info(unsigned char *data, t_dnsr *dnsr) -{ - t_dnsr tmp; - - tmp.type = ft_htons(*(t_uint16 *)(&data[2])); - tmp.class = ft_htons(*(t_uint16 *)(&data[4])); - tmp.ttl = ft_htonl(*(t_uint32 *)(&data[6])); - tmp.rdlength = ft_htons(*(t_uint16 *)(&data[10])); - if (tmp.type == DNS_TYPE_A) - { - dnsr->type = tmp.type; - dnsr->class = tmp.class; - dnsr->ttl = tmp.ttl; - dnsr->rdlength = tmp.rdlength; - return (get_dnsr_response_info_value(data + 12, dnsr) + 12); - } - else - return (get_dnsr_response_info_value(data + 12, &tmp) + 12); - return (0); -} - -int ft_pkt_dnsr_get( - unsigned char *data, - t_uint16 rc, - t_dnsr *dnsr - ) -{ - int i; - int j; - - i = 0; - j = 0; - ft_bzero(dnsr, sizeof(t_dnsr)); - while (j < rc) - { - i += get_dnsr_response_info(data + i, dnsr); - j++; - } - return (i); -} diff --git a/src/network/packet/dns/get_a_record.c b/src/network/packet/dns/get_a_record.c deleted file mode 100644 index b48b2d3..0000000 --- a/src/network/packet/dns/get_a_record.c +++ /dev/null @@ -1,34 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* get_a_record.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brda-sil response_count), &dnsr); - if (dnsr.type == DNS_TYPE_A) - ip = ft_htonl(*(t_int4 *)dnsr.value); - free(dnsq.name); - free(dnsr.value); - return (ip); -} diff --git a/src/network/packet/dns/get_ptr_record.c b/src/network/packet/dns/get_ptr_record.c deleted file mode 100644 index 0b52c40..0000000 --- a/src/network/packet/dns/get_ptr_record.c +++ /dev/null @@ -1,29 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* get_ptr_record.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brda-sil type == type && name->rsc_type == DNS_RTYPE_ANSWER) + counter++; + name = name->next; + } + return (counter); +} + +char **ft_dns_extract_answer_ptr(t_dnsr_name *name) +{ + t_uint16 count; + char **names; + + count = get_answer_nb(name, DNS_TYPE_PTR); + names = (char **)ft_calloc(count + 1, sizeof(char *)); + names[count] = FT_NULL; + count = 0; + while (name) + { + if (name->type == DNS_TYPE_PTR && name->rsc_type == DNS_RTYPE_ANSWER) + { + names[count] = ft_strdup(name->rdata); + count++; + } + name = name->next; + } + + return (names); +} + +t_int4 ft_dns_extract_answer_a(t_dnsr_name *name) +{ + while (name) + { + if (name->type == DNS_TYPE_A && name->rsc_type == DNS_RTYPE_ANSWER) + { + return(ft_atou(name->rdata)); + } + name = name->next; + } + return (0); +} diff --git a/src/network/packet/dns/get_record/get_answer.c b/src/network/packet/dns/get_record/get_answer.c new file mode 100644 index 0000000..b57d5e1 --- /dev/null +++ b/src/network/packet/dns/get_record/get_answer.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_answer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil offset = dnsr->offset; + to_add = 8; + name_len = ft_dns_getlabel_ptr(dnsr->data, dnsr->offset, &name->name, 0); + append_name(name, &dnsr); + dnsr->offset += name_len; + name->rsc_type = DNS_RTYPE_ANSWER; + name->type = get_dnsr_type(dnsr); + name->class = get_dnsr_class(dnsr); + name->ttl = get_dnsr_ttl(dnsr); + name->rlength = get_dnsr_rlength(dnsr); + dnsr->offset += to_add + 2; + switch (name->type) + { + case DNS_TYPE_A: + ft_dns_getlabel_a(dnsr->data, dnsr->offset, &name->rdata); + break; + case DNS_TYPE_PTR: + ft_dns_getlabel_ptr(dnsr->data, dnsr->offset, &name->rdata, name->rlength); + break; + } + dnsr->offset += name->rlength; +} + +void print_dns_answer_name(t_dnsr_name *name) +{ + ft_printf("Name: %s\n", name->name); + ft_printf("Type: %d\n", name->type); + ft_printf("Class: %d\n", name->class); + ft_printf("TTL: %d\n", name->ttl); + ft_printf("Data length: %d\n", name->rlength); + ft_printf("Data: %s\n", name->rdata); + ft_printf("Offset: %d\n", name->offset); + ft_putendl_fd("", 1); +} + +t_bool get_dns_anrecord(t_dnsr_struct *dnsr, t_uint16 count) +{ + int counter = 0; + + // ft_printf("ANSWER COUNT: %d\n", count); + while (counter++ < count) + { + get_dns_answer_name(dnsr); + // print_dns_answer_name(get_last_name(dnsr)); + } + return (FALSE); +} diff --git a/src/network/packet/dns/name_get.c b/src/network/packet/dns/get_record/get_label.c similarity index 64% rename from src/network/packet/dns/name_get.c rename to src/network/packet/dns/get_record/get_label.c index 36f766a..e32b528 100644 --- a/src/network/packet/dns/name_get.c +++ b/src/network/packet/dns/get_record/get_label.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* name_get.c :+: :+: :+: */ +/* get_label.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: brda-sil = max_len)) break ; if (*name) { @@ -64,3 +76,21 @@ int ft_pkt_get_dnsr_name( *name = tmp; return (i); } + +int ft_dns_getlabel_a( + unsigned char *data, + t_uint32 offset, + char **name + ) +{ + t_int4 ip; + + ip = ft_int4_comp( + data[offset], + data[offset + 1], + data[offset + 2], + data[offset + 3] + ); + *name = ft_utoa(ip); + return (4); +} diff --git a/src/network/packet/dns/get_record/get_question.c b/src/network/packet/dns/get_record/get_question.c new file mode 100644 index 0000000..e70045d --- /dev/null +++ b/src/network/packet/dns/get_record/get_question.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_question.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil offset = dnsr->offset; + to_add = 4; + name_len = ft_dns_getlabel_ptr(dnsr->data, dnsr->offset, &name->name, 0); + append_name(name, &dnsr); + dnsr->offset += name_len + 1; + name->rsc_type = DNS_RTYPE_QUESTION; + name->type = get_dnsr_type(dnsr); + name->class = get_dnsr_class(dnsr); + dnsr->offset += to_add; +} + +void print_dns_question_name(t_dnsr_name *name) +{ + ft_printf("Name: %s\n", name->name); + ft_printf("Type: %d\n", name->type); + ft_printf("Class: %d\n", name->class); + ft_printf("Offset: %d\n", name->offset); +} + +t_bool get_dns_qdrecord(t_dnsr_struct *dnsr, t_uint16 count) +{ + int counter = 0; + + // ft_printf("QUESTION COUNT: %d\n", count); + while (counter++ < count) + { + get_dns_question_name(dnsr); + // print_dns_question_name(get_last_name(dnsr)); + } + return (FALSE); +} diff --git a/src/network/packet/dns/get_record/main.c b/src/network/packet/dns/get_record/main.c new file mode 100644 index 0000000..cf39dca --- /dev/null +++ b/src/network/packet/dns/get_record/main.c @@ -0,0 +1,161 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: brda-sil names) + { + (*dnsr)->names = name; + return ; + } + tmp = (*dnsr)->names; + while (tmp->next) + tmp = tmp->next; + tmp->next = name; +} + +t_uint16 get_dns_offset(t_dnsr_struct *dnsr) +{ + t_uint16 offset; + + offset = dnsr->data[dnsr->offset] << 8 | dnsr->data[dnsr->offset + 1]; + return (0xc000 ^ offset); +} + +char *get_name_by_offset(t_dnsr_struct *dnsr) +{ + t_dnsr_name *tmp; + t_uint16 offset; + + offset = get_dns_offset(dnsr); + tmp = dnsr->names; + while (tmp) + { + if (tmp->offset == offset) + return (ft_strdup(tmp->name)); + tmp = tmp->next; + } + return (FT_NULL); +} + +t_uint16 get_dnsr_type(t_dnsr_struct *dnsr) +{ + t_uint16 index; + + index = dnsr->offset; + return (ft_htons(dnsr->data[index] | dnsr->data[index + 1] << 8)); +} + +t_uint16 get_dnsr_class(t_dnsr_struct *dnsr) +{ + t_uint16 index; + + index = dnsr->offset + 2; + return (ft_htons(dnsr->data[index] | dnsr->data[index + 1] << 8)); +} + +t_uint16 get_dnsr_ttl(t_dnsr_struct *dnsr) +{ + t_uint16 index; + t_uint32 ttl; + + index = dnsr->offset + 4; + ttl = dnsr->data[index] << 24; + ttl |= dnsr->data[index + 1] << 16; + ttl |= dnsr->data[index + 2] << 8; + ttl |= dnsr->data[index + 3]; + return (ttl); +} + +t_uint16 get_dnsr_rlength(t_dnsr_struct *dnsr) +{ + t_uint16 index; + + index = dnsr->offset + 8; + return (ft_htons(dnsr->data[index] | dnsr->data[index + 1] << 8)); +} + +t_dnsr_name *get_last_name(t_dnsr_struct *dnsr) +{ + t_dnsr_name *tmp; + + tmp = dnsr->names; + while (tmp->next) + tmp = tmp->next; + return (tmp); + +} + +void ft_free_dnsr(t_dnsr_struct *dnsr) +{ + t_dnsr_name *tmp; + t_dnsr_name *next; + + tmp = dnsr->names; + while (tmp) + { + next = tmp->next; + if (tmp->name) + { + free(tmp->name); + tmp->name = FT_NULL; + } + if (tmp->rdata) + { + free(tmp->rdata); + tmp->rdata = FT_NULL; + } + free(tmp); + tmp = FT_NULL; + tmp = next; + } +} + +char **ft_dns_get_record_ptr(t_packet *pkt) +{ + t_dnsr_struct dnsr; + t_dnshdr *header; + char **names; + + header = ft_pkt_get_dns(pkt); + dnsr.data = (unsigned char *)header; + // ft_pkt_print_raw(1, dnsr.data, 0xff); + dnsr.names = FT_NULL; + dnsr.offset = PACK_LEN_DNS; + get_dns_qdrecord(&dnsr, ft_htons(header->question_count)); + get_dns_anrecord(&dnsr, ft_htons(header->answer_count)); + names = ft_dns_extract_answer_ptr(dnsr.names); + ft_free_dnsr(&dnsr); + return (names); +} + +t_int4 ft_dns_get_record_a(t_packet *pkt) +{ + t_dnsr_struct dnsr; + t_dnshdr *header; + t_int4 ip; + + header = ft_pkt_get_dns(pkt); + dnsr.data = (unsigned char *)header; + // ft_pkt_print_raw(1, dnsr.data, 0xff); + dnsr.names = FT_NULL; + dnsr.offset = PACK_LEN_DNS; + get_dns_qdrecord(&dnsr, ft_htons(header->question_count)); + get_dns_anrecord(&dnsr, ft_htons(header->answer_count)); + ip = ft_dns_extract_answer_a(dnsr.names); + ft_free_dnsr(&dnsr); + return (ip); +} diff --git a/src/network/packet/dns/print.c b/src/network/packet/dns/print.c deleted file mode 100644 index db7df63..0000000 --- a/src/network/packet/dns/print.c +++ /dev/null @@ -1,21 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* print.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brda-sil src_port, pkt->dst_port, -// pkt->length, pkt->checksum -// ); -// } diff --git a/test/src/htoi4.c b/test/src/htoi4.c index 9abbd49..c78e1f4 100644 --- a/test/src/htoi4.c +++ b/test/src/htoi4.c @@ -6,7 +6,7 @@ /* By: brda-sil //for inet_pton() #include // for NI_MAXHOST, getnameinfo() and gai_strerror() - #ifndef CI_TEST # define CI_TEST FALSE #endif -# define TARGET_IP 0xacd914ce - -void test_getnameinfo(char *ip); - int test_i4toh(t_int4 ip) { char *name; - char *ip_str; - ip_str = ft_getip_str(ft_htonl(ip)); - name = ft_i4toh_socket(ip); - // test_getnameinfo(ip_str); - free(ip_str); + name = ft_i4toh(ip); ft_putip_fd(ip, 1); ft_putstr_fd(" -> ", 1); if (!name) @@ -38,9 +17,7 @@ int test_i4toh(t_int4 ip) ft_putstr_fd("error\n", 1); return (1); } - ft_putstr_fd(name, 1); - ft_putstr_fd("\n", 1); - free(name); + ft_printf("%s\n", name); return (0); } @@ -49,9 +26,19 @@ int ci_test(void) int ret; ret = 0; - ret += test_i4toh(0xd83ad6ae); - ret += test_i4toh(0x4d9aed79); - ret += test_i4toh(0xd5f50030); + for (int i = 0; i < 1; i++) + { + // google.com + ret += test_i4toh(0xd83ad6ae); + // wwww.google.com + ret += test_i4toh(0xacd914c4); + // archlinux.org + ret += test_i4toh(0x5fd9a3f6); + // ret += test_i4toh(0x4d9aed79); + // ret += test_i4toh(0xd5f50030); + // ret += test_i4toh(0xc0b251f9); + // ret += test_i4toh(0xc0b26915); + } // ret += test_i4toh(0xc0a80001); // not working for local ip // ret += test_i4toh(0xc0a8000c); return (ret); @@ -66,49 +53,8 @@ int interactive(void) int main(void) { if (CI_TEST) - return (ci_test()); + ci_test(); else - return (interactive()); + interactive(); return (0); } - - -#include -#include -#include -#include - -static int convert4(struct sockaddr_in *sa, const char *name) -{ - return inet_pton(sa->sin_family = AF_INET, name, &sa->sin_addr); -} - -static int convert6(struct sockaddr_in6 *sa, const char *name) -{ - return inet_pton(sa->sin6_family = AF_INET6, name, &sa->sin6_addr); -} - - -void test_getnameinfo(char *ip) -{ - union { - struct sockaddr sa; - struct sockaddr_in s4; - struct sockaddr_in6 s6; - struct sockaddr_storage ss; - } addr; - - if (convert4(&addr.s4, ip) != 1 && convert6(&addr.s6, ip) != 1) { - ft_printf("%s: not a valid IP address.\n", ip); - return ; - } - - char node[NI_MAXHOST]; - int res = getnameinfo(&addr.sa, sizeof addr, node, sizeof node, NULL, 0, NI_NAMEREQD); - if (res) { - ft_printf("%s: %s\n", ip, gai_strerror(res)); - return ; - } - ft_printf("REAL: %s\n", node); - return ; -}