aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/inet.c150
-rw-r--r--src/inet.h38
-rw-r--r--src/recon.c96
3 files changed, 171 insertions, 113 deletions
diff --git a/src/inet.c b/src/inet.c
index 5f7fb7d..bf73e2a 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -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);
+}
diff --git a/src/inet.h b/src/inet.h
index 8e593f5..b7e384b 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -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(