diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/inet.c | 150 | ||||
-rw-r--r-- | src/inet.h | 38 | ||||
-rw-r--r-- | src/recon.c | 96 |
3 files changed, 171 insertions, 113 deletions
@@ -1,6 +1,8 @@ #include "inet.h" #include "endian.h" +#include <string.h> + void prne_netmask_from_cidr (uint8_t *out, size_t cidr) { size_t shft = 7; @@ -19,7 +21,7 @@ void prne_netmask_from_cidr (uint8_t *out, size_t cidr) { } uint16_t prne_calc_tcp_chksum4 ( - const struct iphdr *ih, + const prne_iphdr4_t *ih, const uint8_t *th, size_t th_len, const uint8_t *data, @@ -29,18 +31,17 @@ uint16_t prne_calc_tcp_chksum4 ( // pseudo sum += prne_recmb_msb16( - ((uint8_t*)&ih->saddr)[0], - ((uint8_t*)&ih->saddr)[1]); + ih->saddr[0], + ih->saddr[1]); sum += prne_recmb_msb16( - ((uint8_t*)&ih->saddr)[2], - ((uint8_t*)&ih->saddr)[3]); - + ih->saddr[2], + ih->saddr[3]); sum += prne_recmb_msb16( - ((uint8_t*)&ih->daddr)[0], - ((uint8_t*)&ih->daddr)[1]); + ih->daddr[0], + ih->daddr[1]); sum += prne_recmb_msb16( - ((uint8_t*)&ih->daddr)[2], - ((uint8_t*)&ih->daddr)[3]); + ih->daddr[2], + ih->daddr[3]); sum += 6; // IPPROTO_TCP sum += (uint16_t)(th_len + data_len); @@ -68,7 +69,7 @@ uint16_t prne_calc_tcp_chksum4 ( } uint16_t prne_calc_tcp_chksum6 ( - const struct ipv6hdr *ih, + const prne_iphdr6_t *ih, const uint8_t *th, size_t th_len, const uint8_t *data, @@ -78,55 +79,23 @@ uint16_t prne_calc_tcp_chksum6 ( const uint_fast32_t tcp_length = (uint32_t)(th_len + data_len); // pseudo - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[0], - ((const uint8_t*)&ih->saddr)[1]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[2], - ((const uint8_t*)&ih->saddr)[3]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[4], - ((const uint8_t*)&ih->saddr)[5]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[6], - ((const uint8_t*)&ih->saddr)[7]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[8], - ((const uint8_t*)&ih->saddr)[9]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[10], - ((const uint8_t*)&ih->saddr)[11]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[12], - ((const uint8_t*)&ih->saddr)[13]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->saddr)[14], - ((const uint8_t*)&ih->saddr)[15]); - - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[0], - ((const uint8_t*)&ih->daddr)[1]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[2], - ((const uint8_t*)&ih->daddr)[3]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[4], - ((const uint8_t*)&ih->daddr)[5]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[6], - ((const uint8_t*)&ih->daddr)[7]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[8], - ((const uint8_t*)&ih->daddr)[9]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[10], - ((const uint8_t*)&ih->daddr)[11]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[12], - ((const uint8_t*)&ih->daddr)[13]); - sum += prne_recmb_msb16( - ((const uint8_t*)&ih->daddr)[14], - ((const uint8_t*)&ih->daddr)[15]); + sum += prne_recmb_msb16(ih->saddr[0], ih->saddr[1]); + sum += prne_recmb_msb16(ih->saddr[2], ih->saddr[3]); + sum += prne_recmb_msb16(ih->saddr[4], ih->saddr[5]); + sum += prne_recmb_msb16(ih->saddr[6], ih->saddr[7]); + sum += prne_recmb_msb16(ih->saddr[8], ih->saddr[9]); + sum += prne_recmb_msb16(ih->saddr[10], ih->saddr[11]); + sum += prne_recmb_msb16(ih->saddr[12], ih->saddr[13]); + sum += prne_recmb_msb16(ih->saddr[14], ih->saddr[15]); + + sum += prne_recmb_msb16(ih->daddr[0], ih->daddr[1]); + sum += prne_recmb_msb16(ih->daddr[2], ih->daddr[3]); + sum += prne_recmb_msb16(ih->daddr[4], ih->daddr[5]); + sum += prne_recmb_msb16(ih->daddr[6], ih->daddr[7]); + sum += prne_recmb_msb16(ih->daddr[8], ih->daddr[9]); + sum += prne_recmb_msb16(ih->daddr[10], ih->daddr[11]); + sum += prne_recmb_msb16(ih->daddr[12], ih->daddr[13]); + sum += prne_recmb_msb16(ih->daddr[14], ih->daddr[15]); sum += (uint16_t)((tcp_length & 0xFFFF0000) >> 16); sum += (uint16_t)(tcp_length & 0xFFFF); @@ -154,3 +123,64 @@ uint16_t prne_calc_tcp_chksum6 ( return ~((sum & 0xFFFF) + (sum >> 16)); } + +void prne_ser_iphdr4 (uint8_t *mem, const prne_iphdr4_t *in) { + mem[0] = (4 << 4) | (in->ihl & 0x0F); + mem[1] = 0; + mem[2] = prne_getmsb16(in->total_len, 0); + mem[3] = prne_getmsb16(in->total_len, 1); + mem[4] = prne_getmsb16(in->id, 0); + mem[5] = prne_getmsb16(in->id, 1); + mem[6] = 0; + mem[7] = 0; + mem[8] = in->ttl; + mem[9] = in->protocol; + mem[10] = 0; + mem[11] = 0; + mem[12] = in->saddr[0]; + mem[13] = in->saddr[1]; + mem[14] = in->saddr[2]; + mem[15] = in->saddr[3]; + mem[16] = in->daddr[0]; + mem[17] = in->daddr[1]; + mem[18] = in->daddr[2]; + mem[19] = in->daddr[3]; +} + +void prne_ser_iphdr6 (uint8_t *mem, const prne_iphdr6_t *in) { + mem[0] = (6 << 4); + mem[1] = prne_getmsb32(in->flow_label, 1) & 0xF; + mem[2] = prne_getmsb32(in->flow_label, 2); + mem[3] = prne_getmsb32(in->flow_label, 3); + mem[4] = prne_getmsb16(in->payload_len, 0); + mem[5] = prne_getmsb16(in->payload_len, 1); + mem[6] = in->next_hdr; + mem[7] = in->hop_limit; + memcpy(mem + 8, in->saddr, 16); + memcpy(mem + 24, in->daddr, 16); +} + +void prne_dser_iphdr4 (const uint8_t *data, prne_iphdr4_t *out) { + out->ihl = data[0] & 0x0F; + out->total_len = prne_recmb_msb16(data[2], data[3]); + out->id = prne_recmb_msb16(data[4], data[5]); + out->ttl = data[8]; + out->protocol = data[9]; + out->saddr[0] = data[12]; + out->saddr[1] = data[13]; + out->saddr[2] = data[14]; + out->saddr[3] = data[15]; + out->daddr[0] = data[16]; + out->daddr[1] = data[17]; + out->daddr[2] = data[18]; + out->daddr[3] = data[19]; +} + +void prne_dser_iphdr6 (const uint8_t *data, prne_iphdr6_t *out) { + out->flow_label = prne_recmb_msb32(0, data[1] & 0x0F, data[2], data[3]); + out->payload_len = prne_recmb_msb16(data[4], data[5]); + out->next_hdr = data[6]; + out->hop_limit = data[7]; + memcpy(out->saddr, data + 8, 16); + memcpy(out->daddr, data + 24, 16); +} @@ -1,22 +1,50 @@ +#pragma once #include <stdint.h> #include <stdbool.h> #include <stddef.h> -// TODO: don't use these -#include <linux/ip.h> -#include <linux/ipv6.h> +#include "protocol.h" +// Workaround for header issues in uClibc +typedef struct prne_iphdr4 prne_iphdr4_t; +typedef struct prne_iphdr6 prne_iphdr6_t; + +struct prne_iphdr4 { + uint8_t saddr[4]; + uint8_t daddr[4]; + uint16_t total_len; + uint16_t id; + uint8_t ttl; + uint8_t protocol; + uint8_t ihl; +}; + +struct prne_iphdr6 { + uint8_t saddr[16]; + uint8_t daddr[16]; + uint32_t flow_label; + uint16_t payload_len; + uint8_t next_hdr; + uint8_t hop_limit; +}; + void prne_netmask_from_cidr (uint8_t *out, size_t cidr); uint16_t prne_calc_tcp_chksum4 ( - const struct iphdr *ih, + const prne_iphdr4_t *ih, const uint8_t *th, size_t th_len, const uint8_t *data, size_t data_len); uint16_t prne_calc_tcp_chksum6 ( - const struct ipv6hdr *ih, + const prne_iphdr6_t *ih, const uint8_t *th, size_t th_len, const uint8_t *data, size_t data_len); + +void prne_ser_iphdr4 (uint8_t *mem, const prne_iphdr4_t *in); +void prne_ser_iphdr6 (uint8_t *mem, const prne_iphdr6_t *in); + +void prne_dser_iphdr4 (const uint8_t *data, prne_iphdr4_t *out); +void prne_dser_iphdr6 (const uint8_t *data, prne_iphdr6_t *out); diff --git a/src/recon.c b/src/recon.c index bd09b09..882d863 100644 --- a/src/recon.c +++ b/src/recon.c @@ -15,9 +15,6 @@ #include <ifaddrs.h> #include <linux/if_ether.h> -// TODO: Don't use these -#include <linux/ip.h> -#include <linux/ipv6.h> #include <linux/tcp.h> @@ -374,20 +371,20 @@ static bool rcn_main_chk_blist ( static void rcn_main_send_syn (prne_recon_t *ctx) { prne_ipv_t ret; uint8_t src[16], dst[16]; - uint8_t m_head[prne_op_max(sizeof(struct iphdr), sizeof(struct ipv6hdr))]; - uint8_t m_pkt[sizeof(m_head) + sizeof(struct tcphdr)]; + uint8_t m_head[prne_op_max(sizeof(prne_iphdr4_t), sizeof(prne_iphdr6_t))]; + uint8_t m_pkt[40 + sizeof(struct tcphdr)]; uint8_t m_sa[prne_op_max( sizeof(struct sockaddr_in), sizeof(struct sockaddr_in6))]; - struct iphdr *ih4; - struct ipv6hdr *ih6; + prne_iphdr4_t *ih4; + prne_iphdr6_t *ih6; struct sockaddr_in *sa4; struct sockaddr_in6 *sa6; socklen_t sl = 0; struct tcphdr th; size_t coin, pkt_len = 0; uint16_t d_port; - int snd_flags = MSG_NOSIGNAL, f_ret, fd; + int snd_flags = MSG_NOSIGNAL, f_ret, fd = -1; ret = rcn_main_gen_addr(ctx, src, dst, &snd_flags); if (ret == PRNE_IPV_NONE || rcn_main_chk_blist(ctx, ret, dst)) { @@ -409,17 +406,15 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { switch (ret) { case PRNE_IPV_4: - ih4 = (struct iphdr*)m_head; - ih4->version = 4; + ih4 = (prne_iphdr4_t*)m_head; ih4->ihl = 5; - // filled in by kernel - // ih4->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr)); + ih4->total_len = 20 + sizeof(struct tcphdr); // let kernel fill this in // prne_rnd(&ctx->rnd, &ih4->id, sizeof(ih4->id)); ih4->ttl = 64; ih4->protocol = IPPROTO_TCP; - memcpy(&ih4->saddr, src, 4); - memcpy(&ih4->daddr, dst, 4); + memcpy(ih4->saddr, src, 4); + memcpy(ih4->daddr, dst, 4); // filled in by kernel // ih4->check = htons(rcn_main_ih_chk(m_head, sizeof(struct iphdr))); @@ -434,9 +429,9 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { NULL, 0)); - memcpy(m_pkt, ih4, sizeof(struct iphdr)); - memcpy(m_pkt + sizeof(struct iphdr), &th, sizeof(struct tcphdr)); - pkt_len = sizeof(struct iphdr) + sizeof(struct tcphdr); + prne_ser_iphdr4(m_pkt, ih4); + memcpy(m_pkt + 20, &th, sizeof(struct tcphdr)); + pkt_len = 20 + sizeof(struct tcphdr); sa4 = (struct sockaddr_in*)m_sa; sa4->sin_family = AF_INET; @@ -449,8 +444,8 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { char d_str[INET_ADDRSTRLEN]; prne_assert( - inet_ntop(AF_INET, &ih4->saddr, s_str, sizeof(s_str)) && - inet_ntop(AF_INET, &ih4->daddr, d_str, sizeof(d_str))); + inet_ntop(AF_INET, ih4->saddr, s_str, sizeof(s_str)) && + inet_ntop(AF_INET, ih4->daddr, d_str, sizeof(d_str))); prne_dbgpf( "Send SYN %s:%"PRIu16 " -> %s:%"PRIu16"\n", s_str, @@ -460,14 +455,16 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { } break; case PRNE_IPV_6: - ih6 = (struct ipv6hdr*)m_head; - ih6->version = 6; - prne_rnd(&ctx->rnd, ih6->flow_lbl, 3); - ih6->payload_len = htons(sizeof(struct tcphdr)); - ih6->nexthdr = IPPROTO_TCP; + ih6 = (prne_iphdr6_t*)m_head; + prne_rnd( + &ctx->rnd, + (uint8_t*)&ih6->flow_label, + sizeof(ih6->flow_label)); + ih6->payload_len = sizeof(struct tcphdr); + ih6->next_hdr = IPPROTO_TCP; ih6->hop_limit = 64; - memcpy(&ih6->saddr, src, 16); - memcpy(&ih6->daddr, dst, 16); + memcpy(ih6->saddr, src, 16); + memcpy(ih6->daddr, dst, 16); th.seq = prne_recmb_msb32(dst[0], dst[1], dst[2], dst[3]) ^ @@ -483,9 +480,9 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { NULL, 0)); - memcpy(m_pkt, ih6, sizeof(struct ipv6hdr)); - memcpy(m_pkt + sizeof(struct ipv6hdr), &th, sizeof(struct tcphdr)); - pkt_len = sizeof(struct ipv6hdr) + sizeof(struct tcphdr); + prne_ser_iphdr6(m_pkt, ih6); + memcpy(m_pkt + 40, &th, sizeof(struct tcphdr)); + pkt_len = 40 + sizeof(struct tcphdr); sa6 = (struct sockaddr_in6*)m_sa; sa6->sin6_family = AF_INET6; @@ -498,8 +495,8 @@ static void rcn_main_send_syn (prne_recon_t *ctx) { char d_str[INET6_ADDRSTRLEN]; prne_assert( - inet_ntop(AF_INET6, &ih6->saddr, s_str, sizeof(s_str)) && - inet_ntop(AF_INET6, &ih6->daddr, d_str, sizeof(d_str))); + inet_ntop(AF_INET6, ih6->saddr, s_str, sizeof(s_str)) && + inet_ntop(AF_INET6, ih6->daddr, d_str, sizeof(d_str))); prne_dbgpf( "Send SYN [%s]:%"PRIu16 " -> [%s]:%"PRIu16"\n", s_str, @@ -539,11 +536,11 @@ static void rcn_main_recv_syn_tail ( static void rcn_main_recv_syn4 (prne_recon_t *ctx) { int f_ret; uint8_t buf[ - sizeof(struct iphdr) + + 20 + 60 + // options sizeof(struct tcphdr)]; struct tcphdr th; - struct iphdr ih; + prne_iphdr4_t ih; uint32_t exp_ack; prne_net_endpoint_t ep; @@ -563,11 +560,10 @@ static void rcn_main_recv_syn4 (prne_recon_t *ctx) { } break; } - if ((size_t)f_ret < sizeof(struct iphdr)) - { + if ((size_t)f_ret < 20) { continue; } - memcpy(&ih, buf, sizeof(struct iphdr)); + prne_dser_iphdr4(buf, &ih); if (ih.ihl * 4 + sizeof(struct tcphdr) > (size_t)f_ret) { continue; } @@ -575,9 +571,15 @@ static void rcn_main_recv_syn4 (prne_recon_t *ctx) { prne_memzero(&ep, sizeof(prne_net_endpoint_t)); ep.addr.ver = PRNE_IPV_4; - memcpy(ep.addr.addr, &ih.saddr, 4); + memcpy(ep.addr.addr, ih.saddr, 4); ep.port = ntohs(th.source); - exp_ack = (ntohl(ih.saddr) ^ ctx->seq_mask) + 1; + exp_ack = prne_recmb_msb32( + ih.saddr[0], + ih.saddr[1], + ih.saddr[2], + ih.saddr[3]) ^ + ctx->seq_mask; + exp_ack += 1; rcn_main_recv_syn_tail(ctx, &th, exp_ack, &ep); } } @@ -585,7 +587,7 @@ static void rcn_main_recv_syn4 (prne_recon_t *ctx) { static void rcn_main_recv_syn6 (prne_recon_t *ctx) { int f_ret; uint8_t buf[1024]; - struct ipv6hdr ih; + prne_iphdr6_t ih; struct tcphdr th; size_t ext_pos; uint8_t next_hdr; @@ -609,14 +611,13 @@ LOOP: } break; } - if ((size_t)f_ret < sizeof(struct ipv6hdr)) - { + if ((size_t)f_ret < 40) { continue; } - memcpy(&ih, buf, sizeof(struct ipv6hdr)); + prne_dser_iphdr6(buf, &ih); - ext_pos = sizeof(struct ipv6hdr); - next_hdr = ih.nexthdr; + ext_pos = 40; + next_hdr = ih.next_hdr; while (next_hdr != IPPROTO_TCP && ext_pos + 1 > (size_t)f_ret) { switch (next_hdr) { case 0: @@ -629,19 +630,18 @@ LOOP: ext_pos += buf[ext_pos + 1] * 8 + 8; break; case 59: // no next header - default: // can't understand this packet + default: // can't parse this packet goto LOOP; } } - if ((size_t)f_ret < ext_pos + sizeof(struct tcphdr)) - { + if ((size_t)f_ret < ext_pos + sizeof(struct tcphdr)) { continue; } memcpy(&th, buf + ext_pos, sizeof(struct tcphdr)); prne_memzero(&ep, sizeof(prne_net_endpoint_t)); ep.addr.ver = PRNE_IPV_6; - memcpy(ep.addr.addr, &ih.saddr, 16); + memcpy(ep.addr.addr, ih.saddr, 16); ep.port = ntohs(th.source); exp_ack = prne_recmb_msb32( |