From 9b471aafae7e49ddecf9ecc3424c5e7715d192e1 Mon Sep 17 00:00:00 2001 From: chn <897331845@qq.com> Date: Mon, 4 Nov 2019 16:05:56 +0800 Subject: [PATCH] --- Makefile | 2 +- src/common.h | 20 +++- src/rkp-ua.c | 8 +- src/rkpManager.h | 20 +++- src/rkpSettings.h | 7 ++ src/rkpStream.h | 298 +++++++++++++++++++++++++++++++++------------- 6 files changed, 259 insertions(+), 96 deletions(-) diff --git a/Makefile b/Makefile index 958a846..6cc07ea 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/package.mk EXTRA_CFLAGS:= \ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \ - -DVERSION="\"\\\"$(PKG_RELEASE)\\\"\"" --verbose + -DVERSION="\"\\\"$(PKG_RELEASE)\\\"\"" --verbose -DRKP_DEBUG MAKE_OPTS:=$(KERNEL_MAKE_FLAGS) \ SUBDIRS="$(PKG_BUILD_DIR)" \ diff --git a/src/common.h b/src/common.h index 900410c..0a96d82 100644 --- a/src/common.h +++ b/src/common.h @@ -20,7 +20,23 @@ static unsigned char str_ua_rkp[7]; time_t now(void) { - struct timespec* ts; + struct timespec* ts = kmalloc(sizeof(struct timespec), GFP_KERNEL); + time_t rtn; getnstimeofday(ts); - return ts -> tv_sec; + rtn = ts -> tv_sec; + kfree(ts); +#ifdef RKP_DEBUG + printk("now %lu\n", ts -> tv_sec); +#endif + return rtn; } + +#ifdef RKP_DEBUG +void skb_print(struct sk_buff* skb) +{ + printk("skb_print:\n"); + printk("\tport: %u %u\n", ntohs(tcp_hdr(skb) -> source), ntohs(tcp_hdr(skb) -> dest)); + printk("\tseq: %u %u\n", ntohl(tcp_hdr(skb) -> seq), ntohl(tcp_hdr(skb) -> ack_seq)); + printk("\tsyn %d ack %d psh %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack, tcp_hdr(skb) -> psh); +} +#endif \ No newline at end of file diff --git a/src/rkp-ua.c b/src/rkp-ua.c index 37d5b2a..c3345ab 100644 --- a/src/rkp-ua.c +++ b/src/rkp-ua.c @@ -30,6 +30,7 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_ printk("rkp-ua: Crashed.\n"); crashed = 1; rkpManager_del(rkpm); + rkpm = 0; return NF_STOLEN; } else @@ -44,12 +45,12 @@ static int __init hook_init(void) last_flush = now(); memcpy(str_ua_rkp, "RKP/", 4); - memcpy(str_ua_rkp, VERSION, 3); + memcpy(str_ua_rkp + 4, VERSION, 3); nfho.hook = hook_funcion; nfho.pf = NFPROTO_IPV4; nfho.hooknum = NF_INET_POST_ROUTING; - nfho.priority = NF_IP_PRI_NAT_SRC; + nfho.priority = NF_IP_PRI_RAW; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) ret = nf_register_net_hook(&init_net, &nfho); @@ -70,7 +71,8 @@ static int __init hook_init(void) static void __exit hook_exit(void) { - rkpManager_del(rkpm); + if(rkpm != 0) + rkpManager_del(rkpm); #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) nf_unregister_net_hook(&init_net, &nfho); diff --git a/src/rkpManager.h b/src/rkpManager.h index f3cef40..46ec9c5 100644 --- a/src/rkpManager.h +++ b/src/rkpManager.h @@ -41,15 +41,21 @@ void rkpManager_del(struct rkpManager* rkpm) u_int8_t rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) { - printk("syn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack); - printk("sport %d dport %d\n", tcp_hdr(skb) -> source, tcp_hdr(skb) -> dest); +#ifdef RKP_DEBUG + printk("rkpManager_execute\n"); + printk("\tsyn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack); + printk("\tsport %d dport %d\n", tcp_hdr(skb) -> source, tcp_hdr(skb) -> dest); + printk("\tid %d\n", (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF); +#endif if(rkpSettings_first(skb)) // 新增加一个流或覆盖已经有的流 { u_int8_t id = (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF; struct rkpStream* rkps_new = rkpStream_new(skb); - struct rkpStream *rkps = rkpm -> data[id]; - printk("Add a stream id=%u.\n", id); + struct rkpStream* rkps = rkpm -> data[id]; +#ifdef RKP_DEBUG + printk("\nAdd a stream id=%u.\n", id); +#endif if(rkps_new == 0) { printk("rkp-ua::rkpStream::rkpStream_new: `kmalloc` failed, may caused by shortage of memory.\n"); @@ -89,8 +95,10 @@ u_int8_t rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb) // 使用已经有的流 { u_int8_t id = (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF; - struct rkpStream *rkps = rkpm -> data[id]; - printk("rkpStream_belong %d\n", rkpStream_belong(rkps, skb)); + struct rkpStream* rkps = rkpm -> data[id]; +#ifdef RKP_DEBUG + printk("rkpStream_belong %d\n", (int)rkpStream_belong(rkps, skb)); +#endif while(rkps != 0) if(rkpStream_belong(rkps, skb)) return rkpStream_execute(rkps, skb); diff --git a/src/rkpSettings.h b/src/rkpSettings.h index cccc730..4267690 100644 --- a/src/rkpSettings.h +++ b/src/rkpSettings.h @@ -27,11 +27,18 @@ bool rkpSettings_preserve(const struct sk_buff*); bool rkpSettings_capture(const struct sk_buff* skb) { +#ifdef RKP_DEBUG if(ntohl(ip_hdr(skb) -> daddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192 && ntohl(ip_hdr(skb) -> saddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192) return false; +#endif if(mode_advanced) + { +#ifdef RKP_DEBUG + printk("\tadvanced return %d", (skb -> mark & mark_capture) == mark_capture); +#endif return (skb -> mark & mark_capture) == mark_capture; + } else { if(ip_hdr(skb) -> protocol != IPPROTO_TCP) diff --git a/src/rkpStream.h b/src/rkpStream.h index 4fb81d7..b25d62f 100644 --- a/src/rkpStream.h +++ b/src/rkpStream.h @@ -8,9 +8,9 @@ struct rkpStream rkpStream_waiting } status; u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序 - struct sk_buff *buff, *buff_prev, *buff_next; - u_int32_t ack; // 下一个服务端确认收到的字节的序列号。以后所有的相对序列号都是将这个序号视为零的相对序列号。 - u_int32_t seq; // 下一个期待收到的序列号。 + struct sk_buff *buff, *buff_prev, *buff_next; // 都按照字节序排好了 + u_int32_t ack; // 服务端已经确认收到的最后一个字节的序列号。以后所有的相对序列号都是将这个序号视为零的相对序列号。 + u_int32_t seq; // 已经收到的最后一个字节的序列号。期待的序列号应该比它加1。 time_t last_active; bool scan_matched; bool preserve; @@ -22,7 +22,7 @@ void rkpStream_del(struct rkpStream*); // 析构函 bool rkpStream_belong(const struct rkpStream*, const struct sk_buff*); // 判断一个数据包是否属于一个流 unsigned rkpStream_execute(struct rkpStream*, struct sk_buff*); // 处理一个数据包(假定包属于这个流) -void __rkpStream_refresh_ack(struct rkpStream*, u_int32_t); // 刷新确认序列号。第二个参数就是ack包中的确认号(绝对值)。会自动重新计算序列号的偏移,以及释放 buff_prev 中的多余数据包 +void __rkpStream_refresh_ack(struct rkpStream*, u_int32_t); // 刷新确认序列号。第二个参数就是ack包中的确认号(绝对值)减一,表明已经确认到了哪个位置。会自动重新计算序列号的偏移,以及释放 buff_prev 中的多余数据包 unsigned char* __rkpStream_skb_appBegin(const struct sk_buff*); // 返回一个包的应用层数据起始位置 u_int16_t __rkpStream_skb_appLen(const struct sk_buff*); // 返回一个包的应用层数据长度 @@ -31,9 +31,10 @@ int32_t __rkpStream_skb_seq(u_int32_t, u_int32_t); // 返回一 void __rkpStream_skb_send(struct sk_buff*); // 发送一个数据包 struct sk_buff* __rkpStream_skb_copy(const struct sk_buff*); // 复制一个数据包 void __rkpStream_skb_del(struct sk_buff*); // 删除一个数据包 +void __rkpStream_skb_csum(struct sk_buff*); // 重新计算 tcp 和 ip 的校验和 u_int16_t __rkpStream_data_scan(const unsigned char*, u_int16_t, const unsigned char*, u_int8_t); // 在指定字符串中扫描子字符串。返回值最低位表示是否完整地找到,其余 15 位表示匹配的长度(如果没有完整地找到)或子串结束时相对于起始时的位置 -void __rkpStream_data_replace(unsigned char*, u_int16_t, const unsigned char*, u_int16_t); // 替换字符串。参数与前者类似。 +void __rkpStream_data_replace(unsigned char*, u_int16_t, const unsigned char*, u_int16_t); // 替换字符串。最后一个参数表明已经替换了多少个字节。其它参数与前者类似。 void __rkpStream_buff_retain_end(struct sk_buff**, struct sk_buff*); // 将一个数据包置入数据包链的末尾 void __rkpStream_buff_retain_auto(struct sk_buff**, struct sk_buff*); // 将一个数据包置入数据包链的合适位置 @@ -41,7 +42,7 @@ void __rkpStream_buff_rejudge(struct rkpStream*, struct sk_buff**); // struct sk_buff* __rkpStream_buff_find(const struct sk_buff*, u_int32_t); // 在一个已经按照序列号排序的数据包链中寻找序列号相符的包。如果没有相符的包,就返回最后一个序列号比要求的小的包。如果没有这样的包,就返回 0。第二个参数是要查找的序列号(绝对值,已转换字节序) -void __rkpStream_buff_execute_core(struct sk_buff**, u_int16_t, bool); // 最核心的步骤,集齐头部后被调用。搜索、替换。参数分别为:数据包链表、最后一个包中 http 头结束的位置、是否保留指定 ua +void __rkpStream_buff_execute_core(struct sk_buff**, u_int16_t, bool); // 最核心的步骤,集齐头部后被调用。搜索、替换。参数分别为:数据包链表、最后一个包中 http 头最后一个字节的位置、是否保留指定 ua struct rkpStream* rkpStream_new(const struct sk_buff* skb) { @@ -60,7 +61,7 @@ struct rkpStream* rkpStream_new(const struct sk_buff* skb) rkps -> id[2] = (((u_int32_t)ntohs(tcph -> source)) << 16) + ntohs(tcph -> dest); rkps -> buff = rkps -> buff_prev = rkps -> buff_next = 0; rkps -> ack = ntohl(tcph -> seq) - 1; - rkps -> seq = 2; + rkps -> seq = 1; rkps -> last_active = now(); rkps -> scan_matched = 0; rkps -> preserve = rkpSettings_preserve(skb); @@ -76,28 +77,47 @@ void rkpStream_del(struct rkpStream* rkps) } bool rkpStream_belong(const struct rkpStream* rkps, const struct sk_buff* skb) { - printk("rkpStream_belong\n"); - printk("syn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack); - printk("sport %d dport %d\n", tcp_hdr(skb) -> source, tcp_hdr(skb) -> dest); - printk("rkpSettings_request %d\n", rkpSettings_request(skb)); +#ifdef RKP_DEBUG + printk("rkpStream_belong:\n"); + printk("\tsyn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack); + printk("\tsport %d dport %d\n", ntohs(tcp_hdr(skb) -> source), ntohs(tcp_hdr(skb) -> dest)); + printk("\tsip %u dip %u\n", ntohl(ip_hdr(skb) -> saddr), ntohl(ip_hdr(skb) -> daddr)); + printk("\trkpSettings_request %d\n", rkpSettings_request(skb)); + printk("\tid %u %u %u", rkps -> id[0], rkps -> id[1], rkps -> id[2]); +#endif if(rkpSettings_request(skb)) { if(rkps -> id[0] != ntohl(ip_hdr(skb) -> saddr)) return false; if(rkps -> id[1] != ntohl(ip_hdr(skb) -> daddr)) return false; - if(rkps -> id[2] != ((u_int32_t)ntohs(tcp_hdr(skb) -> source) << 16) + ntohs(tcp_hdr(skb) -> dest)) + if(rkps -> id[2] != (((u_int32_t)ntohs(tcp_hdr(skb) -> source)) << 16) + ntohs(tcp_hdr(skb) -> dest)) return false; return true; } else { if(rkps -> id[0] != ntohl(ip_hdr(skb) -> daddr)) + { +#ifdef RKP_DEBUG + printk("\t 0 not match.\n"); +#endif return false; + } if(rkps -> id[1] != ntohl(ip_hdr(skb) -> saddr)) + { +#ifdef RKP_DEBUG + printk("\t 1 not match.\n"); +#endif return false; - if(rkps -> id[2] != ((u_int32_t)ntohs(tcp_hdr(skb) -> dest) << 16) + ntohs(tcp_hdr(skb) -> source)) + } + if(rkps -> id[2] != (((u_int32_t)ntohs(tcp_hdr(skb) -> dest)) << 16) + ntohs(tcp_hdr(skb) -> source)) + { +#ifdef RKP_DEBUG + printk("\t 2 not match.\n"); +#endif return false; + } return true; } } @@ -105,8 +125,9 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 不要害怕麻烦,咱们把每一种情况都慢慢写一遍。 { int32_t seq; - +#ifdef RKP_DEBUG printk("rkpStream_execute\n"); +#endif // 肯定需要更新时间 rkps -> last_active = now(); @@ -114,31 +135,42 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 服务端返回确认包的情况,更新一下确认号,返回 sccept。以后的情况,都是客户端发往服务端的了。 if(!rkpSettings_request(skb)) { +#ifdef RKP_DEBUG printk("DEBUG0\n"); - int32_t seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> ack_seq)); +#endif + int32_t seq = __rkpStream_skb_seq(rkps -> ack, ((unsigned)(ntohl(tcp_hdr(skb) -> ack_seq))) - 1); if(seq > 0) - __rkpStream_refresh_ack(rkps, ntohl(tcp_hdr(skb) -> ack_seq)); + __rkpStream_refresh_ack(rkps, ((unsigned)(ntohl(tcp_hdr(skb) -> ack_seq))) - 1); return NF_ACCEPT; } - // 不携带应用层数据的情况。直接接受即可。以后的情况,都是含有应用层数据的包了。 + // 不携带应用层数据的情况。除了首包,直接接受即可。以后的情况,都是含有应用层数据的包了。 if(__rkpStream_skb_appLen(skb) == 0) { +#ifdef RKP_DEBUG printk("DEBUG1\n"); +#endif return NF_ACCEPT; } // 检查数据包是否是将来的数据包。如果是的话,需要放到 buff_next 等待处理。 seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)); +#ifdef RKP_DEBUG printk("seq %d\n", seq); - if(seq > rkps -> seq) +#endif + if(seq > rkps -> seq + 1) { +#ifdef RKP_DEBUG printk("DEBUG2\n"); - __rkpStream_buff_retain_auto(&(rkps -> buff_next), skb); - return NF_STOLEN; +#endif + skb = __rkpStream_skb_copy(skb); + if(skb == 0) + return NF_ACCEPT; + __rkpStream_buff_retain_auto(&(rkps -> buff_next), __rkpStream_skb_copy(skb)); + return NF_DROP; } - // 检查数据包是否是已经被确认的数据包。应该不会出现这种情况。出现的话就把它丢掉吧。 + // 检查数据包是否是已经被确认的数据包。应该不会出现这种情况(除了不带数据的 keep alive,但这已经考虑过了)。出现的话就把它丢掉吧。 if(seq < 0) { printk("rkp-ua::rkpStream: Re-transmission of asked package. Drop it.\n"); @@ -146,18 +178,25 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) } // 检查数据包是否是重传数据包。如果是的话,可能需要修改数据。然后,将它发出。接下来的情况,就一定是刚好是需要的序列号的情况了 - if(seq < rkps -> seq) + if(seq < rkps -> seq + 1) { +#ifdef RKP_DEBUG printk("DEBUG3\n"); +#endif const struct sk_buff* skb_prev = __rkpStream_buff_find(rkps -> buff_prev, ntohl(tcp_hdr(skb) -> seq)); if(skb_prev != 0 && tcp_hdr(skb_prev) -> seq == tcp_hdr(skb) -> seq) // 存在相符的数据包。将数据拷贝过去。 { - if(skb_ensure_writable(skb, __rkpStream_skb_appBegin(skb) - skb -> data + __rkpStream_skb_appLen(skb))) + if(skb_ensure_writable(skb, __rkpStream_skb_appBegin(skb) + __rkpStream_skb_appLen(skb) - skb -> data)) { printk("rkp-ua::rkpStream::rkpStream_execute: Can not make skb writable, may caused by shortage of memory. Drop it.\n"); return NF_DROP; } + if(__rkpStream_skb_appLen(skb_prev) != __rkpStream_skb_appLen(skb)) + { + printk("rkp-ua::rkpStream::rkpStream_execute: Size of app data in re-transmission package and previous one not match. Drop it.\n"); + return NF_DROP; + } memcpy(__rkpStream_skb_appBegin(skb), __rkpStream_skb_appBegin(skb_prev), __rkpStream_skb_appLen(skb_prev)); } return NF_ACCEPT; @@ -166,24 +205,37 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) // 如果是在 sniffing 的情况下,那一定先扫描一下再说 if(rkps -> status == rkpStream_sniffing) { +#ifdef RKP_DEBUG printk("DEBUG4\n"); +#endif u_int16_t scan = __rkpStream_data_scan(__rkpStream_skb_appBegin(skb), __rkpStream_skb_appLen(skb), str_head_end, rkps -> scan_matched); if(scan & 0x1) // 扫描找到了 HTTP 头的结尾,那么将这个数据包补到 buff 中,更新 seq,开始查找、替换、发出,然后根据情况设置状态,再考虑 buff_next 中的包,最后返回 STOLEN { +#ifdef RKP_DEBUG printk("DEBUG5\n"); - struct sk_buff* skbp = rkps -> buff; +#endif + struct sk_buff* skbp; + + skb = __rkpStream_skb_copy(skb); + if(skb == 0) + return NF_ACCEPT; // 追加到 buff 后面,更新 seq __rkpStream_buff_retain_end(&(rkps -> buff), skb); - rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb); + rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb) - 1; // 查找、替换 - __rkpStream_buff_execute_core(&(rkps -> buff), (scan >> 1) + 1, rkps -> preserve); + __rkpStream_buff_execute_core(&(rkps -> buff), scan >> 1, rkps -> preserve); + +#ifdef RKP_DEBUG + // return NF_ACCEPT; +#endif // 循环复制一份到 buff_prev 下面,同时发出 + skbp = rkps -> buff; while(skbp != 0) { struct sk_buff* skbp2 = skbp -> next; @@ -199,12 +251,12 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) rkps -> status = rkpStream_waiting; // 考虑之前截留的数据包 - __rkpStream_buff_rejudge(rkps, &(rkps -> buff_prev)); + __rkpStream_buff_rejudge(rkps, &(rkps -> buff_next)); - return NF_STOLEN; + return NF_DROP; } else if(tcp_hdr(skb) -> psh) - // 如果没有找到却读到了 PUSH,这就比较迷了。打印一句警告,更新 seq,然后把截留的包都放行,然后考虑 buff_prev 里的数据。 + // 如果没有找到却读到了 PUSH,这就比较迷了。打印一句警告,更新 seq,然后把截留的包都放行,然后考虑 buff_next 里的数据。 { struct sk_buff* skbp = rkps -> buff; @@ -212,7 +264,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) printk("rkp-ua::rkpStream::rkpStream_execute: Find PSH before header ending found. Send without modification.\n"); // 更新 seq - rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb); + rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb) - 1; // 放行截留的包 while(skbp != 0) @@ -227,25 +279,32 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) rkps -> scan_matched = 0; // 考虑之前截留的数据包 - __rkpStream_buff_rejudge(rkps, &(rkps -> buff_prev)); + __rkpStream_buff_rejudge(rkps, &(rkps -> buff_next)); return NF_ACCEPT; } else // 没有找到结尾,也没有push。那么,将这个数据包补到 buff 中,更新 seq 和 查找状态,再考虑 buff_next 中的包,最后返回 STOLEN { +#ifdef RKP_DEBUG printk("DEBUG6\n"); +#endif + + skb = __rkpStream_skb_copy(skb); + if(skb == 0) + return NF_ACCEPT; + // 追加到 buff __rkpStream_buff_retain_end(&(rkps -> buff), skb); // 更新 seq 和查找状态 - rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb); + rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb) - 1; rkps -> scan_matched = scan >> 1; // 考虑 buff_next 中的包 - __rkpStream_buff_rejudge(rkps, &(rkps -> buff_prev)); + __rkpStream_buff_rejudge(rkps, &(rkps -> buff_next)); - return NF_STOLEN; + return NF_DROP; } } else @@ -253,12 +312,12 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) { printk("DEBUG7\n"); // 设置 seq 和状态 - rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb); + rkps -> seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(skb) -> seq)) + __rkpStream_skb_appLen(skb) - 1; if(tcp_hdr(skb) -> psh) rkps -> status = rkpStream_sniffing; // 考虑 buff_next - __rkpStream_buff_rejudge(rkps, &(rkps -> buff_prev)); + __rkpStream_buff_rejudge(rkps, &(rkps -> buff_next)); return NF_ACCEPT; } @@ -267,15 +326,14 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct sk_buff* skb) void __rkpStream_refresh_ack(struct rkpStream* rkps, u_int32_t ack) { struct sk_buff* skbp; - ack--; // 重新计算 ack 和 seq - rkps -> ack = ack; rkps -> seq -= ack - rkps -> ack; + rkps -> ack = ack; // 丢弃 buff_prev 中已经确认收到的数据包 skbp = rkps -> buff_prev; - while(skbp != 0 && __rkpStream_skb_seq(tcp_hdr(skbp) -> ack, ntohl(tcp_hdr(skbp) -> seq)) < 0) + while(skbp != 0 && __rkpStream_skb_seq(ack, ntohl(tcp_hdr(skbp) -> ack)) <= 0) { struct sk_buff* skbp2 = skbp -> next; __rkpStream_skb_del(skbp); @@ -286,7 +344,7 @@ void __rkpStream_refresh_ack(struct rkpStream* rkps, u_int32_t ack) unsigned char* __rkpStream_skb_appBegin(const struct sk_buff* skb) { - return (unsigned char*)tcp_hdr(skb) + tcp_hdr(skb) -> doff * 4; + return ((unsigned char*)tcp_hdr(skb)) + tcp_hdr(skb) -> doff * 4; } u_int16_t __rkpStream_skb_appLen(const struct sk_buff* skb) @@ -296,10 +354,7 @@ u_int16_t __rkpStream_skb_appLen(const struct sk_buff* skb) int32_t __rkpStream_skb_seq(u_int32_t ack, u_int32_t seq) { - int32_t rtn; - u_int32_t rtn2 = seq - ack; - memcpy(&rtn, &rtn2, 4); - return rtn; + return (int32_t)(seq - ack); } void __rkpStream_skb_send(struct sk_buff* skb) @@ -309,13 +364,43 @@ void __rkpStream_skb_send(struct sk_buff* skb) struct sk_buff* __rkpStream_skb_copy(const struct sk_buff* skb) { + struct sk_buff* rtn = skb_copy(skb, GFP_KERNEL); + if(rtn == 0) + printk("rkp-ua::rkpStream::__rkpStream_skb_copy: `skb_copy` failed, may caused by shortage of memory."); + +#ifdef RKP_DEBUG + printk("__rkpStream_skb_copy:\n"); + printk("\tcheck if parameter equals.\n"); + printk("\tskb -> dev %d\n", skb -> dev == rtn -> dev); + printk("\tskb -> pkt_type %d\n", skb -> pkt_type == rtn -> pkt_type); + printk("\tskb -> protocol %d\n", skb -> protocol == rtn -> protocol); + printk("\tskb -> ip_summed %d\n", skb -> ip_summed == rtn -> ip_summed); + printk("\tskb -> priority %d\n", skb -> priority == rtn -> priority); + printk("\tskb -> csum %d\n", skb -> csum == rtn -> csum); + printk("\tethh -> h_dest %d\n", eth_hdr(skb) -> h_dest == eth_hdr(rtn) -> h_dest); + printk("\tethh -> h_source %d\n", eth_hdr(skb) -> h_source == eth_hdr(rtn) -> h_source); + printk("\tethh -> h_proto %d\n", eth_hdr(skb) -> h_proto == eth_hdr(rtn) -> h_proto); +#endif + + // 链路层数据还需要手动复制一下,我也不知道这是怎么个设计 + memcpy(eth_hdr(rtn), eth_hdr(skb), sizeof(unsigned char) * 2 * ETH_ALEN + sizeof(__be16)); + return skb_copy(skb, GFP_KERNEL); } - void __rkpStream_skb_del(struct sk_buff* skb) { kfree_skb(skb); } +void __rkpStream_skb_csum(struct sk_buff* skb) +{ + struct iphdr* iph = ip_hdr(skb); + struct tcphdr* tcph = tcp_hdr(skb); + tcph -> check = 0; + iph -> check = 0; + skb -> csum = skb_checksum(skb, iph -> ihl * 4, ntohs(iph -> tot_len) - iph -> ihl * 4, 0); + iph -> check = ip_fast_csum(iph, iph -> ihl); + tcph -> check = csum_tcpudp_magic(iph -> saddr, iph -> daddr, ntohs(iph -> tot_len) - iph -> ihl * 4, IPPROTO_TCP, skb -> csum); +} u_int16_t __rkpStream_data_scan(const unsigned char* data, u_int16_t data_len, const unsigned char* target, u_int8_t matched) { @@ -327,7 +412,7 @@ u_int16_t __rkpStream_data_scan(const unsigned char* data, u_int16_t data_len, c else matched = 0; if(matched == strlen(target)) - return ((u_int16_t)(p - data) << 1) | 0x1; + return (((u_int16_t)(p - data) << 1)) | 0x1; else p++; } @@ -355,11 +440,14 @@ void __rkpStream_buff_retain_end(struct sk_buff** buff, struct sk_buff* skb) skb -> next = 0; skb -> prev = 0; } - else while(p -> next != 0) - p = p -> next; - p -> next = skb; - skb -> next = 0; - skb -> prev = p; + else + { + while(p -> next != 0) + p = p -> next; + p -> next = skb; + skb -> next = 0; + skb -> prev = p; + } } void __rkpStream_buff_retain_auto(struct sk_buff** buff, struct sk_buff* skb) { @@ -369,8 +457,10 @@ void __rkpStream_buff_retain_auto(struct sk_buff** buff, struct sk_buff* skb) skb -> prev = 0; skb -> next = *buff; *buff = skb; + if(skb -> next != 0) + skb -> next -> prev = skb; } - else if(ntohl(tcp_hdr(p) -> seq) == ntohl(tcp_hdr(p) -> seq)) + else if(ntohl(tcp_hdr(p) -> seq) == ntohl(tcp_hdr(skb) -> seq)) { if(p -> prev != 0) p -> prev -> next = skb; @@ -378,6 +468,8 @@ void __rkpStream_buff_retain_auto(struct sk_buff** buff, struct sk_buff* skb) p -> next -> prev = skb; skb -> prev = p -> prev; skb -> next = p -> next; + if(*buff == p) + *buff = skb; __rkpStream_skb_del(p); } else @@ -391,38 +483,35 @@ void __rkpStream_buff_retain_auto(struct sk_buff** buff, struct sk_buff* skb) } void __rkpStream_buff_rejudge(struct rkpStream* rkps, struct sk_buff** buff) { - u_int8_t found; - // 循环检查 buff,直到确认 buff 中没有可用的 skb - do + while(*buff != 0) { - struct sk_buff* p = *buff; - found = 0; - while(p != 0 && !found) + int32_t seq = __rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(*buff) -> seq)); + if(seq <= rkps -> seq) + // 过期的skb,虽然应该不会出现这样的情况 + { + struct sk_buff* skb2 = (*buff) -> next; + __rkpStream_skb_del(*buff); + *buff = skb2; + } + else if(seq == rkps -> seq + 1) { - // 找到了一个可用的 skb,将它应用,同时在节点中删除它 - if(__rkpStream_skb_seq(rkps -> ack, ntohl(tcp_hdr(p) -> seq)) == rkps -> seq) - { unsigned rtn; - found = 1; + struct sk_buff* skb2; // 将它从链表中取出 - if(p -> prev != 0) - p -> prev -> next = p -> next; - if(p -> next != 0) - p -> next -> prev = p -> prev; - if(p == *buff) - *buff = p -> next; + if((*buff) -> next != 0) + (*buff) -> next -> prev = 0; + skb2 = *buff; + *buff = (*buff) -> next; // 执行之 - rtn = rkpStream_execute(rkps, p); + rtn = rkpStream_execute(rkps, skb2); if(rtn == NF_ACCEPT) - __rkpStream_skb_send(p); + __rkpStream_skb_send(skb2); else if(rtn == NF_DROP) - __rkpStream_skb_del(p); - else if(rtn == NF_STOLEN); - } + __rkpStream_skb_del(skb2); } - } while (found); + } } struct sk_buff* __rkpStream_buff_find(const struct sk_buff* skb, u_int32_t seq) { @@ -436,7 +525,7 @@ struct sk_buff* __rkpStream_buff_find(const struct sk_buff* skb, u_int32_t seq) } } -void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_len, bool preserve) +void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_pos, bool preserve) // 扫描是否有 ua,然后扫描 ua 中是否有匹配的字符串,并且进行修改 { u_int16_t rtn; @@ -446,41 +535,67 @@ void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_len, bo struct sk_buff *skb_ua_begin, *skb_ua_end; u_int16_t pos_ua_begin, pos_ua_end; +#ifdef RKP_DEBUG printk("__rkpStream_buff_execute_core\n"); + printk("\tlast_pos %u\n", last_pos); + printk("\tpreserve %d\n", preserve); + printk("\tstart find ua start.\n"); +#endif // 寻找 ua 开始的位置 for(p = *buff, rtn = 0; p != 0; p = p -> next) { +#ifdef RKP_DEBUG + printk("\tfind a packet.\n"); +#endif if(p -> next == 0) - rtn = __rkpStream_data_scan(__rkpStream_skb_appBegin(p), last_len, str_ua_begin, rtn >> 1); + rtn = __rkpStream_data_scan(__rkpStream_skb_appBegin(p), last_pos + 1, str_ua_begin, rtn >> 1); else rtn = __rkpStream_data_scan(__rkpStream_skb_appBegin(p), __rkpStream_skb_appLen(p), str_ua_begin, rtn >> 1); - if(rtn & 0x1) + if(rtn & 0x1) break; } if(rtn & 0x1) // 找到了 { +#ifdef RKP_DEBUG + printk("\tfound.\n"); +#endif skb_ua_begin = p; - pos_ua_begin = rtn >> 1; + pos_ua_begin = (rtn >> 1) + 1; } else // 没找到 + { +#ifdef RKP_DEBUG + printk("\tfound.\n"); +#endif return; + } // 寻找 ua 结束的位置 for(rtn = 0; p != 0; p = p -> next) { if(p == skb_ua_begin) + { rtn = __rkpStream_data_scan(__rkpStream_skb_appBegin(p) + pos_ua_begin, __rkpStream_skb_appLen(p) - pos_ua_begin, str_ua_end, rtn >> 1); + // 这时得到的 rtn 是相对于扫描开始处的位置,因此如果确认扫描到了结尾,就需要再加上相对于应用层开始处的偏移 + if(rtn & 0x01) + rtn += pos_ua_begin << 1; + } else rtn = __rkpStream_data_scan(__rkpStream_skb_appBegin(p), __rkpStream_skb_appLen(p), str_ua_end, rtn >> 1); - if(rtn & 0x1) + if(rtn & 0x1) break; } + if(!(rtn & 0x01)) + { + printk("rkp-ua::rkpStream::__rkpStream_buff_execute_core: UA end not found. Accept without modification.\n"); + return; + } // 肯定是可以找到结束位置的。 // 如果找到的结束位置在靠近应用层数据开头的位置,那么真实的结束位置应该在上一个数据包 - if(rtn >> 1 < strlen(str_ua_end)) + if((rtn >> 1) < strlen(str_ua_end)) { skb_ua_end = p -> prev; pos_ua_end = __rkpStream_skb_appLen(skb_ua_end) - (strlen(str_ua_end) - (rtn >> 1) - 1) - 1; @@ -504,9 +619,9 @@ void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_len, bo else scan_begin = __rkpStream_skb_appBegin(p); if(p == skb_ua_end) - scan_len = __rkpStream_skb_appBegin(p) + pos_ua_end + 1 - scan_begin; + scan_len = (__rkpStream_skb_appBegin(p) + pos_ua_end) - scan_begin + 1; else - scan_len = __rkpStream_skb_appBegin(p) + __rkpStream_skb_appLen(p) - scan_begin; + scan_len = (__rkpStream_skb_appBegin(p) + __rkpStream_skb_appLen(p) - 1) - scan_begin + 1; rtn = __rkpStream_data_scan(scan_begin, scan_len, str_preserve[i], rtn >> 1); if(rtn & 0x1) return; @@ -514,6 +629,13 @@ void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_len, bo break; } } + +#ifdef RKP_DEBUG + printk("\tstr_ua_rkp %s\n", str_ua_rkp); + printk("\tskb_ua_end - skb_ua_begin %d\n", skb_ua_end - skb_ua_begin); + printk("\tpos_ua_end %d pos_ua_begin %d\n", pos_ua_end, pos_ua_begin); + // return; +#endif // 替换 ua for(p = skb_ua_begin, rtn = 0;;p = p -> next) @@ -530,10 +652,18 @@ void __rkpStream_buff_execute_core(struct sk_buff** buff, u_int16_t last_len, bo else replace_begin = __rkpStream_skb_appBegin(p); if(p == skb_ua_end) - replace_len = __rkpStream_skb_appBegin(p) + pos_ua_end + 1 - replace_begin; + replace_len = (__rkpStream_skb_appBegin(p) + pos_ua_end) - replace_begin + 1; else - replace_len = __rkpStream_skb_appBegin(p) + __rkpStream_skb_appLen(p) - replace_begin; + replace_len = (__rkpStream_skb_appBegin(p) + __rkpStream_skb_appLen(p) - 1) - replace_begin + 1; +#ifdef RKP_DEBUG + printk("\treplace_begin - appBegin %d\n", replace_begin - __rkpStream_skb_appBegin(p)); + printk("\treplace_len %d\n", replace_len); +#endif __rkpStream_data_replace(replace_begin, replace_len, str_ua_rkp, rtn); +#ifdef RKP_DEBUG + printk("\tafter replace, data is %c%c%c%c%c\n", replace_begin[0], replace_begin[1], replace_begin[2], replace_begin[3], replace_begin[4]); +#endif + __rkpStream_skb_csum(p); rtn += replace_len; if(p == skb_ua_end) break;