Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

import thunk

  • Loading branch information...
commit b439de9a6bd82ae351b6617302878f940a96d985 1 parent cb116eb
@ccp0101 ccp0101 authored
View
8 kernet.xcodeproj/project.pbxproj
@@ -264,7 +264,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = YES;
- SDKROOT = macosx;
+ SDKROOT = macosx10.6;
};
name = Debug;
};
@@ -278,7 +278,8 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
- SDKROOT = macosx;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx10.6;
};
name = Release;
};
@@ -286,6 +287,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
@@ -298,6 +300,7 @@
MODULE_STOP = kernet_stop;
MODULE_VERSION = 1.0.0d1;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx10.6;
WRAPPER_EXTENSION = kext;
};
name = Debug;
@@ -318,6 +321,7 @@
MODULE_STOP = kernet_stop;
MODULE_VERSION = 1.0.0d1;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx10.6;
WRAPPER_EXTENSION = kext;
};
name = Release;
View
284 kernet/kernet.c
@@ -37,9 +37,12 @@ static mbuf_tag_id_t gidtag;
static boolean_t gipFilterRegistered = FALSE;
static boolean_t gsfltFilterRegistered = FALSE;
-TAILQ_HEAD(, ip_range_entry) ip_range_queue;
+TAILQ_HEAD(, ip_range_entry) ip_range_queue;
+TAILQ_HEAD(, delayed_inject_entry) delayed_inject_queue;
-//static lck_mtx_t *gSwallowQueueMutex = NULL;
+static lck_mtx_t *gDelayedInjectQueueMutex = NULL;
+static lck_rw_t *gipRangeQueueMutex = NULL;
+static lck_grp_t *gMutexGroup = NULL;
ipfilter_t kn_ipf_ref;
static struct ipf_filter kn_ipf_filter = {
@@ -214,14 +217,13 @@ errno_t kn_ip_input_fn (void *cookie, mbuf_t *data, int offset, u_int8_t protoco
addr = iph->ip_src.s_addr;
kn_debug("ACK+SYN packet from %s\n", kn_inet_ntoa(addr));
if (kn_shall_apply_kernet_to_ip(addr) == TRUE) {
- retval = kn_inject_after_synack(*data);
+ // retval = kn_inject_after_synack(*data);
}
else {
}
}
}
-
return KERN_SUCCESS;
}
@@ -230,6 +232,7 @@ errno_t kn_ip_output_fn (void *cookie, mbuf_t *data, ipf_pktopts_t options)
struct ip *iph;
struct tcphdr* tcph;
char *payload;
+ u_int32_t min_len;
errno_t retval = 0;
if (mbuf_len(*data) < sizeof(struct ip) + sizeof(struct tcphdr) + MIN_HTTP_REQUEST_LEN) {
@@ -251,7 +254,9 @@ errno_t kn_ip_output_fn (void *cookie, mbuf_t *data, ipf_pktopts_t options)
}
tcph = (struct tcphdr*)((char*)iph + iph->ip_hl * 4);
- if (ntohs(iph->ip_len) < (iph->ip_hl * 4 + tcph->th_off * 4 + MIN_HTTP_REQUEST_LEN)) {
+ min_len = (iph->ip_hl * 4 + tcph->th_off * 4 + MIN_HTTP_REQUEST_LEN);
+ kn_debug("min_len %u\tip_len %u\n", min_len, ntohs(iph->ip_len));
+ if (ntohs(iph->ip_len) < min_len) {
kn_debug("to %s, data length not enough\n", kn_inet_ntoa(iph->ip_dst.s_addr));
return KERN_SUCCESS;
}
@@ -259,8 +264,9 @@ errno_t kn_ip_output_fn (void *cookie, mbuf_t *data, ipf_pktopts_t options)
payload = (char*)tcph + tcph->th_off;
if (memcmp(payload, "GET", 3) == 0 || memcmp(payload, "POST", 4)) {
- //kn_debug("GET or POST to %s\n", kn_inet_ntoa(iph->ip_dst.s_addr));
- //retval = kn_inject_after_http(*data);
+ kn_debug("GET or POST to %s\n", kn_inet_ntoa(iph->ip_dst.s_addr));
+ retval = kn_inject_after_http(*data);
+ return EJUSTRETURN;
}
}
@@ -286,7 +292,7 @@ void kn_sflt_notify_fn (void *cookie, socket_t so, sflt_event_t event, void *par
if (event == sock_evt_connected) {
kn_debug("notified that so 0x%X has connected.\n", so);
// kn_inject_kernet_from_so(so);
- // sflt_detach(so, KERNET_HANDLE); // should raise progma error, should have been already detached!
+ //sflt_detach(so, KERNET_HANDLE);
}
}
@@ -308,11 +314,7 @@ errno_t kn_sflt_connect_in_fn (void *cookie, socket_t so, const struct sockaddr
errno_t kn_sflt_connect_out_fn (void *cookie, socket_t so, const struct sockaddr *to)
{
- kn_debug("notified that so 0x%X attemps to connect to %s:%d\n", so, kn_inet_ntoa(((struct sockaddr_in*)to)->sin_addr.s_addr), htons(((struct sockaddr_in*)to)->sin_port));
-
- if (kn_shall_apply_kernet_to_ip(((struct sockaddr_in*)to)->sin_addr.s_addr) == FALSE) {
- sflt_detach(so, KERNET_HANDLE);
- }
+ sflt_detach(so, KERNET_HANDLE);
return KERN_SUCCESS;
}
@@ -320,6 +322,7 @@ boolean_t kn_shall_apply_kernet_to_ip(u_int32_t ip)
{
struct ip_range_entry *range;
+ lck_rw_lock_shared(gipRangeQueueMutex);
TAILQ_FOREACH(range, &ip_range_queue, entries) {
u_int32_t left = (ntohl(ip)) >> (32 - range->prefix);
u_int32_t right = (range->ip) >> (32 - range->prefix);
@@ -328,60 +331,193 @@ boolean_t kn_shall_apply_kernet_to_ip(u_int32_t ip)
if (range->policy == ip_range_apply_kernet) return TRUE;
}
}
-
+ lck_rw_unlock_shared(gipRangeQueueMutex);
+
return FALSE;
}
errno_t kn_append_ip_range_entry(u_int32_t ip, u_int8_t prefix, ip_range_policy policy)
{
+
struct ip_range_entry *range = (struct ip_range_entry*)OSMalloc(sizeof(struct ip_range_entry), gOSMallocTag);
- if (range == NULL) return -1;
+ if (range == NULL) return ENOMEM;
range->ip = ip;
range->prefix = prefix;
range->policy = policy;
+ lck_rw_lock_exclusive(gipRangeQueueMutex);
TAILQ_INSERT_TAIL(&ip_range_queue, range, entries);
-
+ lck_rw_unlock_exclusive(gipRangeQueueMutex);
+
return 0;
}
-void kn_fulfill_ip_ranges()
+errno_t kn_delay_pkt_inject(mbuf_t pkt, u_int32_t ms, inject_direction direction)
{
- // Google
- kn_append_ip_range_entry((67305984), 24, ip_range_apply_kernet); // 4.3.2.0/24
- kn_append_ip_range_entry((134623232), 24, ip_range_apply_kernet); // 8.6.48.0/21
- kn_append_ip_range_entry((134743040), 24, ip_range_apply_kernet); // 8.8.4.0/24
- kn_append_ip_range_entry((134744064), 24, ip_range_apply_kernet); // 8.8.8.0/24
- kn_append_ip_range_entry((1078218752), 21, ip_range_apply_kernet); // 64.68.80.0/21
- kn_append_ip_range_entry((1078220800), 21, ip_range_apply_kernet); // 64.68.88.0/21
- kn_append_ip_range_entry((1089052672), 19, ip_range_apply_kernet); // 64.233.160.0/19
- kn_append_ip_range_entry((1113980928), 20, ip_range_apply_kernet); // 66.102.0.0/20
- kn_append_ip_range_entry((1123631104), 19, ip_range_apply_kernet); // 66.249.64.0/19
- kn_append_ip_range_entry((1208926208), 18, ip_range_apply_kernet); // 72.14.192.0/18
- kn_append_ip_range_entry((1249705984), 16, ip_range_apply_kernet); // 74.125.0.0/16
- kn_append_ip_range_entry((2915172352), 16, ip_range_apply_kernet); // 173.194.0.0/16
- kn_append_ip_range_entry((3512041472), 17, ip_range_apply_kernet); // 209.85.128.0/17
- kn_append_ip_range_entry((3639549952), 19, ip_range_apply_kernet); // 216.239.32.0/19
-
- // Wikipedia
- kn_append_ip_range_entry((3494942720), 22, ip_range_apply_kernet); // 208.80.152.0/22
-
- // Pornhub
- kn_append_ip_range_entry((2454899747), 32, ip_range_apply_kernet); // 146.82.204.35/32
-
- // Just-Ping
- kn_append_ip_range_entry((1161540560), 32, ip_range_apply_kernet); // 69.59.179.208/32
-
- // Dropbox
- kn_append_ip_range_entry((3492530741), 32, ip_range_apply_kernet); // 208.43.202.53/32
- kn_append_ip_range_entry((2921607977), 32, ip_range_apply_kernet); // 174.36.51.41/32
-
- // Twitter
- kn_append_ip_range_entry((2163406116), 32, ip_range_apply_kernet); // 128.242.245.36/32
+ struct delayed_inject_entry* entry;
+ errno_t retval = 0;
+ struct timespec ts;
+
+ entry = (struct delayed_inject_entry*)OSMalloc(sizeof(struct delayed_inject_entry), gOSMallocTag);
+ if (entry == NULL) {
+ return ENOMEM;
+ }
+
+ entry->pkt = pkt;
+ entry->timeout = ms;
+ entry->direction = direction;
+ microtime(&entry->timestamp);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000 * ms;
+ lck_mtx_lock(gDelayedInjectQueueMutex);
+ TAILQ_INSERT_TAIL(&delayed_inject_queue, entry, entries);
+ lck_mtx_unlock(gDelayedInjectQueueMutex);
- kn_append_ip_range_entry((2916408726), 32, ip_range_apply_kernet); // 173.212.221.150
+ bsd_timeout(kn_delayed_inject_timeout, (void*)entry, &ts);
+
+ kn_debug("kn_delay_pkt_inject put packet in queue.\n");
+
+ return retval;
+
+FAILTURE:
+ OSFree(entry, sizeof(struct delayed_inject_entry), gOSMallocTag);
+
+ return retval;
+}
+boolean_t kn_delayed_inject_entry_in_queue(struct delayed_inject_entry* entry)
+{
+ struct delayed_inject_entry* enum_entry;
+ boolean_t ret = FALSE;
+
+ TAILQ_FOREACH(enum_entry, &delayed_inject_queue, entries) {
+ if (enum_entry == entry) {
+ ret = TRUE;
+ goto END;
+ }
+ }
+
+END:
+ return ret;
+}
+void kn_delayed_inject_timeout(void* param)
+{
+ struct delayed_inject_entry* entry = param;
+ mbuf_t pkt;
+ struct timeval tv_now, tv_diff;
+ int ms_diff;
+ errno_t retval = 0;
+
+ kn_debug("kn_delayed_inject_timeout\n");
+
+ lck_mtx_lock(gDelayedInjectQueueMutex);
+
+ if (kn_delayed_inject_entry_in_queue(entry) == FALSE) {
+ goto END;
+ }
+
+ pkt = entry->pkt;
+ microtime(&tv_now);
+
+ timersub(&tv_now, &entry->timestamp, &tv_diff);
+ ms_diff = tv_diff.tv_sec * 1000 + tv_diff.tv_usec / 1000;
+ kn_debug("tv_diff.tv_usec %d\n", tv_diff.tv_usec);
+
+ if (entry->direction == outgoing_direction) {
+ retval = ipf_inject_output(pkt, kn_ipf_ref, NULL);
+ }
+ else if (entry->direction == incoming_direction) {
+ retval = ipf_inject_input(pkt, kn_ipf_ref);
+ }
+ else {
+ mbuf_free(pkt);
+ kn_debug("unknown delayed inject direction\n");
+ goto FREE_AND_END;
+ }
+ if (retval != 0) {
+ kn_debug("%ums delayed ipf_inject_output returned error %d\n", ms_diff, retval);
+ goto FREE_AND_END;
+ }
+ else {
+ kn_debug("injected tcp packet after %dms\n", ms_diff);
+ goto FREE_AND_END;
+ }
+FREE_AND_END:
+ OSFree(entry, sizeof(struct delayed_inject_entry), gOSMallocTag);
+ goto END;
+
+END:
+ lck_mtx_unlock(gDelayedInjectQueueMutex);
+ return;
+}
+
+errno_t kn_alloc_locks()
+{
+ errno_t result = 0;
+
+ gMutexGroup = lck_grp_alloc_init(KERNET_BUNDLEID, LCK_GRP_ATTR_NULL);
+ if (gMutexGroup == NULL)
+ {
+ kn_debug("lck_grp_alloc_init returned error\n");
+ result = ENOMEM;
+ }
+
+ if (result == 0)
+ {
+ gipRangeQueueMutex = lck_rw_alloc_init(gMutexGroup, LCK_ATTR_NULL);
+ if (gipRangeQueueMutex == NULL)
+ {
+ kn_debug("lck_mtx_alloc_init returned error\n");
+ result = ENOMEM;
+ }
+ if (result == 0)
+ {
+ gDelayedInjectQueueMutex = lck_mtx_alloc_init(gMutexGroup, LCK_ATTR_NULL);
+ if (gDelayedInjectQueueMutex == NULL)
+ {
+ kn_debug("lck_mtx_alloc_init returned error\n");
+ result = ENOMEM;
+ }
+ }
+ }
+
+ return result; // if we make it here, return success
+}
+errno_t kn_free_locks()
+{
+ if (gipRangeQueueMutex)
+ {
+ lck_rw_free(gipRangeQueueMutex, gMutexGroup);
+ gipRangeQueueMutex = NULL;
+ }
+ if (gDelayedInjectQueueMutex)
+ {
+ lck_mtx_free(gDelayedInjectQueueMutex, gMutexGroup);
+ gDelayedInjectQueueMutex = NULL;
+ }
+ if (gMutexGroup) {
+ lck_grp_free(gMutexGroup);
+ gMutexGroup = NULL;
+ }
+ return 0;
+}
+errno_t kn_alloc_queues()
+{
+ TAILQ_INIT(&ip_range_queue);
+ TAILQ_INIT(&delayed_inject_queue);
+ kn_fulfill_ip_ranges();
+ return 0;
+}
+errno_t kn_free_queues()
+{
+ void *entry = NULL;
+ while ((entry = TAILQ_FIRST(&ip_range_queue))) {
+ TAILQ_REMOVE(&ip_range_queue, (struct ip_range_entry*)entry, entries);
+ OSFree(entry, sizeof(struct ip_range_entry), gOSMallocTag);
+ }
+ return 0;
}
kern_return_t com_ccp0101_kext_kernet_start (kmod_info_t * ki, void * d) {
@@ -391,11 +527,23 @@ kern_return_t com_ccp0101_kext_kernet_start (kmod_info_t * ki, void * d) {
gOSMallocTag = OSMalloc_Tagalloc(KERNET_BUNDLEID, OSMT_DEFAULT); // don't want the flag set to OSMT_PAGEABLE since
// it would indicate that the memory was pageable.
if (gOSMallocTag == NULL)
- goto WTF;
-
- TAILQ_INIT(&ip_range_queue);
- kn_fulfill_ip_ranges();
+ goto WTF;
+ if (kn_alloc_locks() != 0) {
+ goto WTF;
+ }
+
+ if (kn_alloc_queues() != 0) {
+ goto WTF;
+ }
+
+ retval = kn_alloc_locks();
+ if (retval != 0)
+ {
+ kn_debug("kn_alloc_locks returned error %d\n", retval);
+ goto WTF;
+ }
+
retval = mbuf_tag_id_find(KERNET_BUNDLEID , &gidtag);
if (retval != 0)
{
@@ -436,6 +584,14 @@ kern_return_t com_ccp0101_kext_kernet_start (kmod_info_t * ki, void * d) {
ipf_remove(kn_ipf_ref);
gipFilterRegistered = FALSE;
}
+
+ kn_free_locks();
+
+ if (gOSMallocTag)
+ {
+ OSMalloc_Tagfree(gOSMallocTag);
+ gOSMallocTag = NULL;
+ }
kn_debug("extension failed to start.\n");
return KERN_FAILURE;
@@ -445,14 +601,8 @@ kern_return_t com_ccp0101_kext_kernet_start (kmod_info_t * ki, void * d) {
kern_return_t com_ccp0101_kext_kernet_stop (kmod_info_t * ki, void * d) {
int retval = 0;
- struct ip_range_entry *range;
-
- while ((range = TAILQ_FIRST(&ip_range_queue))) {
- TAILQ_REMOVE(&ip_range_queue, range, entries);
- OSFree(range, sizeof(struct ip_range_entry), gOSMallocTag);
- }
-
- if (gsfltFilterRegistered == TRUE) {
+
+ if (gsfltFilterRegistered == TRUE) {
retval = sflt_unregister(KERNET_HANDLE);
if (retval != 0) {
kn_debug("sflt_unreturned error %d\n", retval);
@@ -467,7 +617,16 @@ kern_return_t com_ccp0101_kext_kernet_stop (kmod_info_t * ki, void * d) {
goto WTF;
}
}
-
+
+ kn_free_queues();
+ kn_free_locks();
+
+ if (gOSMallocTag)
+ {
+ OSMalloc_Tagfree(gOSMallocTag);
+ gOSMallocTag = NULL;
+ }
+
kn_debug("extension has been unloaded.\n");
return KERN_SUCCESS;
@@ -475,4 +634,3 @@ kern_return_t com_ccp0101_kext_kernet_stop (kmod_info_t * ki, void * d) {
kn_debug("extension failed to stop.\n");
return KERN_FAILURE;
}
-
View
21 kernet/kernet.h
@@ -21,6 +21,11 @@ typedef enum _ip_range_policy {
ip_range_stay_away,
} ip_range_policy;
+typedef enum _inject_direction {
+ outgoing_direction,
+ incoming_direction,
+} inject_direction;
+
struct ip_range_entry {
u_int32_t ip;
u_int8_t prefix;
@@ -29,6 +34,14 @@ struct ip_range_entry {
TAILQ_ENTRY(ip_range_entry) entries;
};
+struct delayed_inject_entry {
+ mbuf_t pkt;
+ struct timeval timestamp;
+ u_int32_t timeout;
+ inject_direction direction;
+ TAILQ_ENTRY(delayed_inject_entry) entries;
+};
+
extern ipfilter_t kn_ipf_ref;
// utils:
@@ -61,10 +74,16 @@ extern errno_t kn_inject_after_http (mbuf_t otgn_data);
// injection:
extern errno_t kn_tcp_pkt_from_params(mbuf_t *data, u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len);
-extern errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len);
+extern errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len, inject_direction direction);
extern errno_t kn_alloc_locks();
extern errno_t kn_free_locks();
extern errno_t kn_alloc_queues();
extern errno_t kn_free_queues();
+
+// delayed packet injection:
+extern errno_t kn_delay_pkt_inject(mbuf_t pkt, u_int32_t ms, inject_direction direction);
+extern boolean_t kn_delayed_inject_entry_in_queue(struct delayed_inject_entry* entry);
+extern void kn_delayed_inject_timeout(void* param);
+
#endif /* KERNET_H */
View
328 kernet/manipulator.c
@@ -25,6 +25,7 @@
#include <kern/locks.h>
#include <kern/assert.h>
#include <kern/debug.h>
+#include <kern/locks.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
@@ -40,6 +41,133 @@
#include "kernet.h"
+/* data_offset = offset of the fragmented second packet without IP header counted in */
+static errno_t kn_fragment_pkt_to_two_pieces(mbuf_t orgn_pkt, mbuf_t *pkt1, mbuf_t *pkt2, u_int16_t data_offset)
+{
+ struct ip* iph;
+ u_int16_t tot_len;
+ u_int16_t pkt1_len;
+ u_int16_t pkt2_len;
+ boolean_t pkt1_allocated = FALSE;
+ boolean_t pkt2_allocated = FALSE;
+ errno_t retval = 0;
+ char *pkt1_buf, *pkt2_buf, *orgn_buf;
+ mbuf_csum_request_flags_t csum_flags = 0;
+ int orgn_ip_hl = iph->ip_hl * 4;
+ u_int16_t ip_id = 0x2912;
+
+ if (data_offset % 8 != 0) {
+ kn_debug("data_offset % 8 != 0\n");
+ goto FAILURE;
+ }
+
+ iph = (struct ip*)mbuf_data(orgn_pkt);
+ tot_len = ntohs(iph->ip_len);
+ pkt1_len = orgn_ip_hl + data_offset;
+ pkt2_len = tot_len - orgn_ip_hl - data_offset + sizeof(struct ip);
+
+ if (data_offset < tot_len - orgn_ip_hl) {
+ kn_debug("unable to fragment a packet because offset too small\n");
+ goto FAILURE;
+ }
+ retval = mbuf_allocpacket(MBUF_DONTWAIT, pkt1_len, NULL, pkt1);
+ if (retval != 0) {
+ kn_debug("mbuf_allocpacket returned error %d\n", retval);
+ goto FAILURE;
+ }
+ else {
+ pkt1_allocated = TRUE;
+ }
+
+ retval = mbuf_allocpacket(MBUF_DONTWAIT, pkt2_len, NULL, pkt2);
+ if (retval != 0) {
+ kn_debug("mbuf_allocpacket returned error %d\n", retval);
+ goto FAILURE;
+ }
+ else {
+ pkt2_allocated = TRUE;
+ }
+
+ mbuf_pkthdr_setlen(*pkt1, pkt1_len);
+ retval = mbuf_pkthdr_setrcvif(*pkt1, NULL);
+ if (retval != 0) {
+ kn_debug("mbuf_pkthdr_setrcvif returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ mbuf_setlen(*pkt1, pkt1_len);
+
+ retval = mbuf_setdata(*pkt1, (mbuf_datastart(*pkt1)), pkt1_len);
+ if (retval != 0) {
+ kn_debug("mbuf_setdata returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ mbuf_pkthdr_setheader(*pkt1, mbuf_data(*pkt1));
+
+ mbuf_pkthdr_setlen(*pkt2, pkt2_len);
+ retval = mbuf_pkthdr_setrcvif(*pkt2, NULL);
+ if (retval != 0) {
+ kn_debug("mbuf_pkthdr_setrcvif returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ mbuf_setlen(*pkt2, pkt2_len);
+
+ retval = mbuf_setdata(*pkt2, (mbuf_datastart(*pkt2)), pkt2_len);
+ if (retval != 0) {
+ kn_debug("mbuf_setdata returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ mbuf_pkthdr_setheader(*pkt2, mbuf_data(*pkt2));
+
+ pkt1_buf = mbuf_data(*pkt1);
+ pkt2_buf = mbuf_data(*pkt2);
+ memcpy(pkt1_buf, orgn_buf, data_offset + orgn_ip_hl);
+ memcpy(pkt2_buf, orgn_buf, sizeof(struct ip));
+ memcpy(pkt2_buf + sizeof(struct ip), orgn_buf + orgn_ip_hl + data_offset, pkt2_len - sizeof(struct ip));
+
+ iph = (struct ip*)pkt1_buf;
+ iph->ip_off = 0;
+ iph->ip_off = iph->ip_off | IP_MF;
+ iph->ip_len = htons(pkt1_len);
+ iph->ip_id = htons(ip_id);
+
+ mbuf_clear_csum_performed(*pkt1);
+
+ csum_flags |= MBUF_CSUM_REQ_IP;
+ retval = mbuf_get_csum_requested(*pkt1, &csum_flags, NULL);
+ if (retval != 0) {
+ kn_debug("mbuf_get_csum_requested returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ iph = (struct ip*)pkt2_buf;
+ iph->ip_off = data_offset / 8;
+ iph->ip_len = htons(pkt2_len);
+ iph->ip_id = htons(ip_id);
+
+ mbuf_clear_csum_performed(*pkt2);
+
+ csum_flags = 0;
+ csum_flags |= MBUF_CSUM_REQ_IP;
+ retval = mbuf_get_csum_requested(*pkt2, &csum_flags, NULL);
+ if (retval != 0) {
+ kn_debug("mbuf_get_csum_requested returned error %d\n", retval);
+ goto FAILURE;
+ }
+
+ return 0;
+
+FAILURE:
+ if (pkt1_allocated == TRUE)
+ mbuf_free(*pkt1);
+ if (pkt2_allocated == TRUE)
+ mbuf_free(*pkt2);
+ return retval;
+}
+
errno_t kn_inject_after_synack (mbuf_t incm_data)
{
errno_t retval = 0;
@@ -73,7 +201,7 @@ errno_t kn_inject_after_synack (mbuf_t incm_data)
seq = htonl(ntohl(tcph->th_ack) - 1);
ack = tcph->th_seq;
- retval = kn_inject_tcp_from_params(TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0);
+ retval = kn_inject_tcp_from_params(TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0, outgoing_direction);
if (retval != 0) {
return retval;
}
@@ -90,7 +218,7 @@ errno_t kn_inject_after_synack (mbuf_t incm_data)
seq = tcph->th_ack;
ack = tcph->th_seq;
- retval = kn_inject_tcp_from_params(TH_ACK, saddr, daddr, sport, dport, seq, ack, NULL, 0);
+ retval = kn_inject_tcp_from_params(TH_ACK, saddr, daddr, sport, dport, seq, ack, NULL, 0, outgoing_direction);
if (retval != 0) {
return retval;
}
@@ -108,7 +236,7 @@ errno_t kn_inject_after_synack (mbuf_t incm_data)
seq = htonl(ntohl(tcph->th_ack) + 0);
ack = htonl(ntohl(tcph->th_seq) + 0);
- retval = kn_inject_tcp_from_params(TH_ACK | TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0);
+ retval = kn_inject_tcp_from_params(TH_ACK | TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0, outgoing_direction);
if (retval != 0) {
return retval;
}
@@ -126,7 +254,7 @@ errno_t kn_inject_after_synack (mbuf_t incm_data)
seq = htonl(ntohl(tcph->th_ack) + 2);
ack = htonl(ntohl(tcph->th_seq) + 2);
- retval = kn_inject_tcp_from_params(TH_ACK | TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0);
+ retval = kn_inject_tcp_from_params(TH_ACK | TH_RST, saddr, daddr, sport, dport, seq, ack, NULL, 0, outgoing_direction);
if (retval != 0) {
return retval;
}
@@ -137,32 +265,65 @@ errno_t kn_inject_after_synack (mbuf_t incm_data)
errno_t kn_inject_after_http (mbuf_t otgn_data)
{
errno_t retval = 0;
- u_int32_t saddr;
- u_int32_t daddr;
- u_int16_t sport;
- u_int16_t dport;
- u_int32_t ack;
- u_int32_t seq;
+ // u_int32_t saddr;
+ // u_int32_t daddr;
+ // u_int16_t sport;
+ // u_int16_t dport;
+ // u_int32_t ack;
+ // u_int32_t seq;
struct ip* iph;
struct tcphdr* tcph;
- static const char* fake_message = "220 Microsoft FTP Service\r\n";
-
- iph = (struct ip*)mbuf_data(otgn_data);
- saddr = iph->ip_src.s_addr;
- daddr = iph->ip_dst.s_addr;
-
- seq = htonl(ntohl(tcph->th_seq) + 3);
- ack = tcph->th_ack;
-
- tcph = (struct tcphdr*)((char*)iph + iph->ip_hl * 4);
- sport = tcph->th_sport;
- dport = tcph->th_dport;
-
- retval = kn_inject_tcp_from_params(TH_ACK | TH_PUSH, saddr, daddr, sport, dport, seq, ack, fake_message, strlen(fake_message));
- if (retval != 0) {
+ // static const char* fake_message = "220 Microsoft FTP Service\r\n";
+ // mbuf_t otgn_data_dup;
+
+ // iph = (struct ip*)mbuf_data(otgn_data);
+ // saddr = iph->ip_src.s_addr;
+ // daddr = iph->ip_dst.s_addr;
+ //
+ // tcph = (struct tcphdr*)((char*)iph + iph->ip_hl * 4);
+ //
+ // //seq = htonl(ntohl(tcph->th_seq) - 1000);
+ // //ack = htonl(ntohl(tcph->th_ack) - 1000);
+ //
+ // seq = 0;
+ // ack = 0;
+ //
+ // sport = tcph->th_sport;
+ // dport = tcph->th_dport;
+ //
+ // retval = kn_inject_tcp_from_params(TH_ACK | TH_PUSH, saddr, daddr, sport, dport, seq, ack, fake_message, strlen(fake_message), outgoing_direction);
+ // if (retval != 0) {
+ // return retval;
+ // }
+
+ mbuf_t frag1;
+ mbuf_t frag2;
+
+ iph = (struct ip*)mbuf_data(otgn_data);
+ tcph = (struct tcphdr*)((char*)iph + iph->ip_hl * 4);
+
+ retval = kn_fragment_pkt_to_two_pieces(otgn_data, &frag1, &frag2, tcph->th_off * 4);
+ if (retval != 0) {
+ kn_debug("mbuf_dup returned error %d\n", retval);
return retval;
}
-
+
+ // retval = mbuf_dup(otgn_data, MBUF_DONTWAIT, &otgn_data_dup);
+ // if (retval != 0) {
+ // kn_debug("mbuf_dup returned error %d\n", retval);
+ // return retval;
+ // }
+
+ retval = ipf_inject_output(frag1, kn_ipf_ref, NULL);
+ if (retval != 0) {
+ kn_debug("kn_delay_pkt_inject returned error %d\n", retval);
+ return retval;
+ }
+ retval = ipf_inject_output(frag2, kn_ipf_ref, NULL);
+ if (retval != 0) {
+ kn_debug("kn_delay_pkt_inject returned error %d\n", retval);
+ return retval;
+ }
return KERN_SUCCESS;
}
@@ -174,6 +335,41 @@ errno_t kn_inject_after_http (mbuf_t otgn_data)
+void kn_fulfill_ip_ranges()
+{
+ // Google
+ kn_append_ip_range_entry((67305984), 24, ip_range_apply_kernet); // 4.3.2.0/24
+ kn_append_ip_range_entry((134623232), 24, ip_range_apply_kernet); // 8.6.48.0/21
+ kn_append_ip_range_entry((134743040), 24, ip_range_apply_kernet); // 8.8.4.0/24
+ kn_append_ip_range_entry((134744064), 24, ip_range_apply_kernet); // 8.8.8.0/24
+ kn_append_ip_range_entry((1078218752), 21, ip_range_apply_kernet); // 64.68.80.0/21
+ kn_append_ip_range_entry((1078220800), 21, ip_range_apply_kernet); // 64.68.88.0/21
+ kn_append_ip_range_entry((1089052672), 19, ip_range_apply_kernet); // 64.233.160.0/19
+ kn_append_ip_range_entry((1113980928), 20, ip_range_apply_kernet); // 66.102.0.0/20
+ kn_append_ip_range_entry((1123631104), 19, ip_range_apply_kernet); // 66.249.64.0/19
+ kn_append_ip_range_entry((1208926208), 18, ip_range_apply_kernet); // 72.14.192.0/18
+ kn_append_ip_range_entry((1249705984), 16, ip_range_apply_kernet); // 74.125.0.0/16
+ kn_append_ip_range_entry((2915172352), 16, ip_range_apply_kernet); // 173.194.0.0/16
+ kn_append_ip_range_entry((3512041472), 17, ip_range_apply_kernet); // 209.85.128.0/17
+ kn_append_ip_range_entry((3639549952), 19, ip_range_apply_kernet); // 216.239.32.0/19
+
+ // Wikipedia
+ kn_append_ip_range_entry((3494942720), 22, ip_range_apply_kernet); // 208.80.152.0/22
+
+ // Pornhub
+ kn_append_ip_range_entry((2454899747), 32, ip_range_apply_kernet); // 146.82.204.35/32
+
+ // Just-Ping
+ kn_append_ip_range_entry((1161540560), 32, ip_range_apply_kernet); // 69.59.179.208/32
+
+ // Dropbox
+ kn_append_ip_range_entry((3492530741), 32, ip_range_apply_kernet); // 208.43.202.53/32
+ kn_append_ip_range_entry((2921607977), 32, ip_range_apply_kernet); // 174.36.51.41/32
+
+ // Twitter
+ kn_append_ip_range_entry((2163406116), 32, ip_range_apply_kernet); // 128.242.245.36/32
+
+}
@@ -185,14 +381,12 @@ errno_t kn_inject_after_http (mbuf_t otgn_data)
-
-errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len)
+errno_t kn_tcp_pkt_from_params(mbuf_t *data, u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len)
{
- int retval = 0;
+ int retval = 0;
size_t tot_data_len, tot_buf_len, max_len; // mac osx thing.. to be safe, leave out 14 bytes for ethernet header.
void *buf = NULL;
- mbuf_t pkt;
- struct ip* o_iph;
+ struct ip* o_iph;
struct tcphdr* o_tcph;
u_int16_t csum;
mbuf_csum_request_flags_t csum_flags = 0;
@@ -202,7 +396,7 @@ errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_in
tot_buf_len = tot_data_len + ETHHDR_LEN;
// allocate the packet
- retval = mbuf_allocpacket(MBUF_WAITOK, tot_buf_len, NULL, &pkt);
+ retval = mbuf_allocpacket(MBUF_DONTWAIT, tot_buf_len, NULL, data);
if (retval != 0) {
kn_debug("mbuf_allocpacket returned error %d\n", retval);
goto FAILURE;
@@ -211,33 +405,33 @@ errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_in
pkt_allocated = TRUE;
}
- max_len = mbuf_maxlen(pkt);
+ max_len = mbuf_maxlen(*data);
if (max_len < tot_buf_len) {
kn_debug("no enough buffer space, try to request more.\n");
- retval = mbuf_prepend(&pkt, tot_buf_len - max_len, MBUF_WAITOK);
+ retval = mbuf_prepend(data, tot_buf_len - max_len, MBUF_DONTWAIT);
if (retval != 0) {
kn_debug("mbuf_prepend returned error %d\n", retval);
goto FAILURE;
}
}
- mbuf_pkthdr_setlen(pkt, tot_data_len);
- retval = mbuf_pkthdr_setrcvif(pkt, NULL);
+ mbuf_pkthdr_setlen(*data, tot_data_len);
+ retval = mbuf_pkthdr_setrcvif(*data, NULL);
if (retval != 0) {
kn_debug("mbuf_pkthdr_setrcvif returned error %d\n", retval);
goto FAILURE;
}
- mbuf_setlen(pkt, tot_data_len);
+ mbuf_setlen(*data, tot_data_len);
- retval = mbuf_setdata(pkt, (mbuf_datastart(pkt) + ETHHDR_LEN), tot_data_len);
+ retval = mbuf_setdata(*data, (mbuf_datastart(*data) + ETHHDR_LEN), tot_data_len);
if (retval != 0) {
kn_debug("mbuf_setdata returned error %d\n", retval);
goto FAILURE;
}
- buf = mbuf_data(pkt);
- mbuf_pkthdr_setheader(pkt, buf);
+ buf = mbuf_data(*data);
+ mbuf_pkthdr_setheader(*data, buf);
o_iph = (struct ip*)buf;
@@ -274,10 +468,10 @@ errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_in
memcpy((char*)o_tcph + sizeof(struct tcphdr), payload, payload_len);
}
- mbuf_clear_csum_performed(pkt);
+ mbuf_clear_csum_performed(*data);
csum_flags |= MBUF_CSUM_REQ_IP;
- retval = mbuf_get_csum_requested(pkt, &csum_flags, NULL);
+ retval = mbuf_get_csum_requested(*data, &csum_flags, NULL);
if (retval != 0) {
kn_debug("mbuf_get_csum_requested returned error %d\n", retval);
goto FAILURE;
@@ -287,23 +481,49 @@ errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_in
csum = kn_tcp_sum_calc(sizeof(struct tcphdr) + payload_len, (u_int16_t*)&o_iph->ip_src.s_addr, (u_int16_t*)&o_iph->ip_dst.s_addr, (u_int16_t*)o_tcph);
o_tcph->th_sum = csum;
-
- retval = ipf_inject_output(pkt, kn_ipf_ref, NULL);
- if (retval != 0) {
- kn_debug("ipf_inject_output returned error %d\n", retval);
- goto FAILURE;
- }
- else {
- kn_debug("injected tcp packet, flags: 0x%X, saddr: %s, daddr: %s, ack: %d, seq: %d\n", tcph_flags, kn_inet_ntoa(iph_saddr), kn_inet_ntoa(iph_daddr), tcph_ack, tcph_seq);
- }
- return KERN_SUCCESS;
-
+ return 0;
+
FAILURE:
if (pkt_allocated == TRUE) {
- mbuf_free(pkt);
+ mbuf_free(*data);
}
return retval;
+
}
+errno_t kn_inject_tcp_from_params(u_int8_t tcph_flags, u_int32_t iph_saddr, u_int32_t iph_daddr, u_int16_t tcph_sport, u_int16_t tcph_dport, u_int32_t tcph_seq, u_int32_t tcph_ack, const char* payload, size_t payload_len, inject_direction direction)
+{
+ mbuf_t pkt;
+ errno_t retval = 0;
+
+ retval = kn_tcp_pkt_from_params(&pkt, tcph_flags, iph_saddr, iph_daddr, tcph_sport, tcph_dport, tcph_seq, tcph_ack, payload, payload_len);
+ if (retval != 0) {
+ kn_debug("kn_tcp_pkt_from_params returned error %d\n", retval);
+ return retval;
+ }
+
+ if (direction == outgoing_direction) {
+ retval = ipf_inject_output(pkt, kn_ipf_ref, NULL);
+ }
+ else if (direction == incoming_direction) {
+ retval = ipf_inject_input(pkt, kn_ipf_ref);
+ }
+ else {
+ retval = EINVAL;
+ kn_debug("unknown inject direction\n");
+ mbuf_free(pkt);
+ return retval;
+ }
+ if (retval != 0) {
+ kn_debug("ipf_inject_output returned error %d\n", retval);
+ return retval;
+ }
+ else {
+ kn_debug("injected tcp packet, flags: 0x%X, saddr: %s, daddr: %s, ack: %u, seq: %u\n", tcph_flags, kn_inet_ntoa(iph_saddr), kn_inet_ntoa(iph_daddr), tcph_ack, tcph_seq);
+ }
+
+ return 0;
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.