This commit is contained in:
chn
2019-11-04 16:05:56 +08:00
parent 4fdb049597
commit 9b471aafae
6 changed files with 259 additions and 96 deletions

View File

@@ -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)" \

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;