貌似是大功告成了

This commit is contained in:
chn
2020-01-13 19:42:05 +08:00
parent bf60ca2b3c
commit 24a7930091
8 changed files with 404 additions and 429 deletions

View File

@@ -143,9 +143,7 @@ flush 函数,关闭超时的流。
用比较宽松的方案去处理。当找不到需要的流的时候去新建而不是寻找三次握手的首包。当扫描到 User-Agent: 后再捕获包、分析、修改,避免不是 HTTP 流量的包被捕获。如果捕获过程中读到 psh即使没有读到 UA 末尾也要提交。UA 的长度也需要作假设;可以假定为最多两个包。
接下里需要修改的文件
debug 的计划
c
Manager
Map
Stream
打印出序列号,同时抓包
根据序列号确认需要的包的流向

View File

@@ -1,3 +1,4 @@
#pragma once
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kmod.h>
@@ -13,7 +14,9 @@
#include <linux/moduleparam.h>
#include <linux/time.h>
#include <linux/mutex.h>
#pragma once
typedef _Bool bool;
#define static_assert _Static_assert
const static unsigned char* str_uaBegin = "User-Agent: ";
const static unsigned char* str_uaEnd = "\r\n";
@@ -31,3 +34,9 @@ void rkpFree(void* p)
{
kfree(p);
}
#include "rkpSetting.h"
#include "rkpPacket.h"
#include "rkpMap.h"
#include "rkpStream.h"
#include "rkpManager.h"

View File

@@ -1,6 +1,6 @@
#include "rkpManager.h"
#include "common.h"
static struct nf_hook_ops nfho;
static struct nf_hook_ops nfho[3]; // 需要在 INPUT、OUTPUT、FORWARD 各挂一个
static struct rkpManager* rkpm;
unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
@@ -9,14 +9,15 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_
static unsigned n_skb_captured = 0, n_skb_captured_lastPrint = 1;
if(!rkpSettings_capture(skb))
if(!rkpSetting_capture(skb))
return NF_ACCEPT;
rtn = rkpManager_execute(rkpm, skb);
n_skb_captured++;
if(n_skb_captured == n_skb_captured_lastPrint * 2)
{
printk("rkp-ua: Captured %d packets.\n", n_skb_captured);
if(verbose)
printk("rkp-ua: Captured %d packets.\n", n_skb_captured);
n_skb_captured_lastPrint *= 2;
}
return rtn;
@@ -25,6 +26,7 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_
static int __init hook_init(void)
{
int ret;
unsigned i;
rkpm = rkpManager_new();
@@ -32,15 +34,19 @@ static int __init hook_init(void)
memcpy(str_uaRkp + 4, VERSION, 2);
memcpy(str_uaRkp + 6, ".0", 3);
nfho.hook = hook_funcion;
nfho.pf = NFPROTO_IPV4;
nfho.hooknum = NF_INET_POST_ROUTING;
nfho.priority = NF_IP_PRI_RAW;
nfho[0].hooknum = NF_INET_LOCAL_IN;
nfho[1].hooknum = NF_INET_LOCAL_OUT;
nfho[2].hooknum = NF_INET_FORWARD;
for(i = 0; i < 3; i++)
{
nfho[i].hook = hook_funcion;
nfho[i].pf = NFPROTO_IPV4;
nfho[i].priority = NF_IP_PRI_MANGLE;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
ret = nf_register_net_hook(&init_net, &nfho);
ret = nf_register_net_hooks(&init_net, nfho, 3);
#else
ret = nf_register_hook(&nfho);
ret = nf_register_hooks(nfho, 3);
#endif
printk("rkp-ua: Started, version %s\n", VERSION);
@@ -58,9 +64,9 @@ static int __init hook_init(void)
static void __exit hook_exit(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
nf_unregister_net_hook(&init_net, &nfho);
nf_unregister_net_hooks(&init_net, nfho, 3);
#else
nf_unregister_hook(&nfho);
nf_unregister_hooks(nfho, 3);
#endif
if(rkpm != 0)
rkpManager_delete(rkpm);

View File

@@ -1,5 +1,5 @@
#pragma once
#include "rkpStream.h"
#include "common.h"
struct rkpManager
{
@@ -11,9 +11,9 @@ struct rkpManager
struct rkpManager* rkpManager_new(void);
void rkpManager_delete(struct rkpManager*);
int rkpManager_execute(struct rkpManager*, struct sk_buff*); // 处理一个数据包。返回值为 rkpStream_execute 的返回值。
int __rkpManager_execute(struct rkpManager*, struct rkpPacket*);
void __rkpManager_refresh(unsigned long); // 清理长时间不活动的流
unsigned rkpManager_execute(struct rkpManager*, struct sk_buff*); // 处理一个数据包。返回值为 rkpStream_execute 的返回值。
unsigned __rkpManager_execute(struct rkpManager*, struct rkpPacket*);
void __rkpManager_refresh(unsigned long); // 清理长时间不活动的流,参数实际上是 rkpm 的地址
void __rkpManager_lock(struct rkpManager*, unsigned long*);
void __rkpManager_unlock(struct rkpManager*, unsigned long);
@@ -21,6 +21,8 @@ void __rkpManager_unlock(struct rkpManager*, unsigned long);
struct rkpManager* rkpManager_new(void)
{
struct rkpManager* rkpm = (struct rkpManager*)rkpMalloc(sizeof(struct rkpManager));
if(debug)
printk("rkpManager_new\n");
if(rkpm == 0)
return 0;
memset(rkpm -> data, 0, sizeof(struct rkpStream*) * 256);
@@ -36,7 +38,10 @@ void rkpManager_delete(struct rkpManager* rkpm)
{
unsigned i;
unsigned long flag;
if(debug)
printk("rkpManager_delete\n");
__rkpManager_lock(rkpm, &flag);
del_timer(&rkpm -> timer);
for(i = 0; i < 256; i++)
{
struct rkpStream* rkps = rkpm -> data[i];
@@ -47,22 +52,19 @@ void rkpManager_delete(struct rkpManager* rkpm)
rkps = rkps2;
}
}
del_timer(&rkpm -> timer);
__rkpManager_unlock(rkpm, flag);
rkpFree(rkpm);
}
int rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb)
unsigned rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb)
{
unsigned long flag;
int rtn;
struct rkpPacket* rkpp = rkpPacket_new(skb);
if(rkpPacket_appLen(rkpp) == 0)
{
rkpPacket_delete(rkpp);
return NF_ACCEPT;
}
unsigned rtn;
struct rkpPacket* rkpp;
if(debug)
printk("rkpManager_execute\n");
__rkpManager_lock(rkpm, &flag);
rkpp = rkpPacket_new(skb, rkpSetting_ack(skb));
rtn = __rkpManager_execute(rkpm, rkpp);
if(debug)
{
@@ -76,11 +78,9 @@ int rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb)
__rkpManager_unlock(rkpm, flag);
if(rtn == NF_ACCEPT || rtn == NF_DROP)
rkpPacket_delete(rkpp);
if(debug)
skb -> mark |= 0x10;
return rtn;
}
int __rkpManager_execute(struct rkpManager* rkpm, struct rkpPacket* rkpp)
unsigned __rkpManager_execute(struct rkpManager* rkpm, struct rkpPacket* rkpp)
{
struct rkpStream *rkps, *rkps_new;
@@ -109,6 +109,8 @@ void __rkpManager_refresh(unsigned long param)
unsigned i;
unsigned long flag;
struct rkpManager* rkpm = (struct rkpManager*)param;
if(debug)
printk("rkpManager_refresh\n");
__rkpManager_lock(rkpm, &flag);
for(i = 0; i < 256; i++)
{

View File

@@ -1,20 +1,19 @@
#pragma once
#include "common.h"
#include "rkpPacket.h"
struct rkpMap
// 以相对序列号记录应用层数据中需要修改的部分的位置,提供修改的函数
{
int32_t begin, length; // begin 为绝对序列号
// int32_t &seq_offset = beign; // 需要一个差不多的数值作为偏移来计算序列号谁先谁后的问题,这个偏移取为 begin
int32_t begin, length; // begin 为绝对序列号
// int32_t &seq_offset = beign; // 需要一个差不多的数值作为偏移来计算序列号谁先谁后的问题,这个偏移取为 begin
struct rkpMap *prev, *next;
};
struct rkpMap* rkpMap_new(int32_t, int32_t); // 两个参数分别为起始和终止绝对序列号
struct rkpMap* rkpMap_new(int32_t, int32_t); // 两个参数分别为起始和终止绝对序列号
void rkpMap_delete(struct rkpMap*);
unsigned char __rkpMap_map(const struct rkpMap*, int32_t); // 返回某个序列号对应的映射后的值。假定参数是合法的。这里的参数是相对序列号
void rkpMap_modify(const struct rkpMap*, struct rkpPacket**); // 对一列序列号连续且递增的包进行修改
void rkpMap_modify(struct rkpMap**, struct rkpPacket**); // 对一列序列号连续且递增的包进行修改
void rkpMap_insert_begin(struct rkpMap**, struct rkpMap*); // 在开头位置插入一个映射
void rkpMap_insert_end(struct rkpMap**, struct rkpMap*);
@@ -42,35 +41,43 @@ unsigned char __rkpMap_map(const struct rkpMap* rkpm, int32_t seq)
else
return ' ';
}
void rkpMap_modify(const struct rkpMap* rkpm, struct rkpPacket** rkppl)
void rkpMap_modify(struct rkpMap** rkpml, struct rkpPacket** rkppl)
{
struct rkpPacket* rkpp;
unsigned char* p;
int32_t seq;
// 尝试确定第一个需要修改的包
for(rkpp = *rkppl; rkpp != 0; rkpp = rkpp -> next)
if(rkpPacket_seq(rkpp, rkpm -> begin) + rkpPacket_appLen(rkpp) > 0)
break;
if(rkpp == 0)
return;
p = rkpPacket_appBegin(rkpp) - rkpPacket_seq(rkpp, rkpm -> begin);
seq = 0;
// 开始修改
for(; rkpp != 0; rkpp = rkpp -> next)
const struct rkpMap* rkpm;
for(rkpm = *rkpml; rkpm != 0; rkpm = rkpm -> next)
{
if(seq != 0)
p = rkpPacket_appBegin(rkpp);
for(; p != rkpPacket_appEnd(rkpp) && seq < rkpm -> length; p++, seq++)
*p = __rkpMap_map(rkpm, seq);
rkpPacket_csum(rkpp);
if(seq == rkpm -> length)
struct rkpPacket* rkpp;
unsigned char* p = 0;
int32_t seq;
// 尝试确定第一个需要修改的包以及需要修改的开始处
for(rkpp = *rkppl; rkpp != 0; rkpp = rkpp -> next)
if(rkpPacket_seq(rkpp, rkpm -> begin) + rkpPacket_appLen(rkpp) > 0)
break;
if(rkpp == 0)
break;
if(rkpPacket_seq(rkpp, rkpm -> begin) <= 0)
{
p = rkpPacket_appBegin(rkpp) - rkpPacket_seq(rkpp, rkpm -> begin);
seq = 0;
}
else // p 会在稍后被设置到包的开头
seq = rkpPacket_seq(rkpp, rkpm -> begin);
// 开始修改
for(; rkpp != 0; rkpp = rkpp -> next)
{
if(seq != 0)
p = rkpPacket_appBegin(rkpp);
for(; p != rkpPacket_appEnd(rkpp) && seq < rkpm -> length; p++, seq++)
*p = __rkpMap_map(rkpm, seq);
rkpPacket_csum(rkpp);
if(seq == rkpm -> length)
break;
}
}
}
void rkpMap_insert_begin(struct rkpMap** rkpml, struct rkpMap* rkpm)
{
rkpm -> next = *rkpml;
@@ -92,9 +99,20 @@ void rkpMap_insert_end(struct rkpMap** rkpml, struct rkpMap* rkpm)
}
void rkpMap_refresh(struct rkpMap** rkpml, int32_t seq)
{
struct rkpMap* rkpm;
struct rkpMap *rkpm1, *rkpm2, *rkpm3;
// 找到第一个不用删除的映射
for(rkpm = *rkpml; rkpm != 0; rkpm = rkpm -> next)
// if(rkpm -> begin + rkpm -> length <= seq) 需要避免绝对值很大的负数小于绝对值很大的正数的情况
if((int32_t)(seq - rkpm -> begin) + rkpm -> length) - seq) <= 0)
for(rkpm1 = *rkpml; rkpm1 != 0; rkpm1 = rkpm1 -> next)
// if(rkpm -> begin + rkpm -> length > seq) 需要避免绝对值很大的负数小于绝对值很大的正数的情况
if((int32_t)(seq - rkpm1 -> begin) - rkpm1 -> length < 0)
break;
// 将这个映射之前的所有映射都删除
for(rkpm2 = *rkpml; rkpm2 != rkpm1; rkpm2 = rkpm3)
{
rkpm3 = rkpm2 -> next;
rkpMap_delete(rkpm2);
}
// 修改一些指针
if(rkpm1 != 0)
rkpm1 -> prev = 0;
*rkpml = rkpm1;
}

View File

@@ -1,5 +1,5 @@
#include "common.h"
#pragma once
#include "common.h"
struct rkpPacket
// 存储一个个数据包的类,完全被 rkpStream 和 rkpManager 包裹
@@ -39,7 +39,7 @@ void rkpPacket_insert_begin(struct rkpPacket**, struct rkpPacket*); // 在
void rkpPacket_insert_end(struct rkpPacket**, struct rkpPacket*); // 在指定链表尾部插入一个包
struct rkpPacket* rkpPacket_pop_begin(struct rkpPacket**); // 将指定链表头部的包取出
struct rkpPacket* rkpPacket_pop_end(struct rkpPacket**); // 将指定链表尾部的包取出
unsigned rkpPacket_num(const struct rkpPacket*); // 返回指定链表中包的数目
unsigned rkpPacket_num(struct rkpPacket**); // 返回指定链表中包的数目
void rkpPacket_sendl(struct rkpPacket**);
void rkpPacket_deletel(struct rkpPacket**);
@@ -73,44 +73,44 @@ struct rkpPacket* rkpPacket_new(struct sk_buff* skb, bool ack)
}
return rkpp;
}
void rkpPacket_send(struct rkpPacket* p)
void rkpPacket_send(struct rkpPacket* rkpp)
{
if(dev_queue_xmit(p -> skb))
if(dev_queue_xmit(rkpp -> skb))
{
printk("rkp-ua: rkpPacket_new: Send failed. Drop it.\n");
kfree_skb(p -> skb);
kfree_skb(rkpp -> skb);
}
rkpFree(p);
rkpFree(rkpp);
}
void rkpPacket_delete(struct rkpPacket* p)
void rkpPacket_delete(struct rkpPacket* rkpp)
{
rkpFree(p);
rkpFree(rkpp);
}
void rkpPacket_drop(struct rkpPacket* p)
void rkpPacket_drop(struct rkpPacket* rkpp)
{
kfree_skb(p -> skb);
rkpFree(p);
kfree_skb(rkpp -> skb);
rkpFree(rkpp);
}
unsigned char* rkpPacket_appBegin(const struct rkpPacket* p)
unsigned char* rkpPacket_appBegin(const struct rkpPacket* rkpp)
{
return ((unsigned char*)tcp_hdr(p -> skb)) + tcp_hdr(p -> skb) -> doff * 4;
return ((unsigned char*)tcp_hdr(rkpp -> skb)) + tcp_hdr(rkpp -> skb) -> doff * 4;
}
unsigned char* rkpPacket_appEnd(const struct rkpPacket* p)
unsigned char* rkpPacket_appEnd(const struct rkpPacket* rkpp)
{
return ((unsigned char*)ip_hdr(p -> skb)) + ntohs(ip_hdr(p -> skb) -> tot_len);
return ((unsigned char*)ip_hdr(rkpp -> skb)) + ntohs(ip_hdr(rkpp -> skb) -> tot_len);
}
unsigned rkpPacket_appLen(const struct rkpPacket* p)
unsigned rkpPacket_appLen(const struct rkpPacket* rkpp)
{
return ntohs(ip_hdr(p -> skb) -> tot_len) - ip_hdr(p -> skb) -> ihl * 4 - tcp_hdr(p -> skb) -> doff * 4;
return ntohs(ip_hdr(rkpp -> skb) -> tot_len) - ip_hdr(rkpp -> skb) -> ihl * 4 - tcp_hdr(rkpp -> skb) -> doff * 4;
}
int32_t rkpPacket_seq(const struct rkpPacket* p, const int32_t offset)
int32_t rkpPacket_seq(const struct rkpPacket* rkpp, const int32_t offset)
{
return (int32_t)ntohl(tcp_hdr(p -> skb) -> seq) - offset;
return (int32_t)ntohl(tcp_hdr(rkpp -> skb) -> seq) - offset;
}
int32_t rkpPacket_seqAck(const struct rkpPacket* p, const int32_t offset)
int32_t rkpPacket_seqAck(const struct rkpPacket* rkpp, const int32_t offset)
{
return (int32_t)ntohl(tcp_hdr(p -> skb) -> ack) - offset;
return (int32_t)ntohl(tcp_hdr(rkpp -> skb) -> ack_seq) - offset;
}
u_int32_t rkpPacket_sip(const struct rkpPacket* rkpp)
{
@@ -147,8 +147,8 @@ void rkpPacket_csum(struct rkpPacket* rkpp)
struct tcphdr* tcph = tcp_hdr(rkpp -> skb);
tcph -> check = 0;
iph -> check = 0;
iph -> check = ip_fast_csum((unsigned char*)iph, iph -> ihl);
rkpp -> skb -> csum = skb_checksum(rkpp -> skb, iph -> ihl * 4, ntohs(iph -> tot_len) - iph -> ihl * 4, 0);
iph -> check = ip_fast_csum((unsigned char*)iph, iph -> ihl);
tcph -> check = csum_tcpudp_magic(iph -> saddr, iph -> daddr, ntohs(iph -> tot_len) - iph -> ihl * 4, IPPROTO_TCP, rkpp -> skb -> csum);
}
@@ -175,16 +175,12 @@ void rkpPacket_insert_auto(struct rkpPacket** buff, struct rkpPacket* rkpp, int3
{
// 如果链表是空的,那么就直接加进去
if(*buff == 0)
{
*buff = rkpp;
rkpp -> prev = rkpp -> next = 0;
}
// 又或者,要插入的包需要排到第一个
else if(rkpPacket_seq(*buff, offset) >= rkpPacket_seq(rkpp, offset))
{
(*buff) -> prev = rkpp;
rkpp -> next = *buff;
rkpp -> prev = 0;
*buff = rkpp;
}
// 接下来寻找最后一个序列号小于 rkpp 的包,插入到它的后面。
@@ -203,10 +199,7 @@ void rkpPacket_insert_auto(struct rkpPacket** buff, struct rkpPacket* rkpp, int3
void rkpPacket_insert_begin(struct rkpPacket** buff, struct rkpPacket* rkpp)
{
if(*buff == 0)
{
*buff = rkpp;
rkpp -> next = rkpp -> prev = 0;
}
else
{
(*buff) -> prev = rkpp;
@@ -217,10 +210,7 @@ void rkpPacket_insert_begin(struct rkpPacket** buff, struct rkpPacket* rkpp)
void rkpPacket_insert_end(struct rkpPacket** buff, struct rkpPacket* rkpp)
{
if(*buff == 0)
{
*buff = rkpp;
rkpp -> next = rkpp -> prev = 0;
}
else
{
struct rkpPacket* rkpp2 = *buff;
@@ -228,7 +218,6 @@ void rkpPacket_insert_end(struct rkpPacket** buff, struct rkpPacket* rkpp)
rkpp2 = rkpp2 -> next;
rkpp2 -> next = rkpp;
rkpp -> prev = rkpp2;
rkpp -> next = 0;
}
}
struct rkpPacket* rkpPacket_pop_begin(struct rkpPacket** buff)
@@ -258,10 +247,10 @@ struct rkpPacket* rkpPacket_pop_end(struct rkpPacket** buff)
}
return rkpp;
}
unsigned rkpPacket_num(const struct rkpPacket* buff)
unsigned rkpPacket_num(struct rkpPacket** buff)
{
unsigned n = 0;
const struct rkpPacket* rkpp = buff;
const struct rkpPacket* rkpp = *buff;
while(rkpp != 0)
{
rkpp = rkpp -> next;

View File

@@ -1,8 +1,8 @@
#include "common.h"
#pragma once
#include "common.h"
_Static_assert(sizeof(int) == 4, "int is not 4 bit.");
_Static_assert(sizeof(unsigned long) >= sizeof(void*), "ulong is too short.");
static_assert(sizeof(int) == 4, "int is not 4 bit.");
static_assert(sizeof(unsigned long) >= sizeof(void*), "ulong is too short.");
static bool autocapture = true;
module_param(autocapture, bool, 0);
@@ -22,10 +22,10 @@ module_param(verbose, bool, 0);
static bool debug = false;
module_param(debug, bool, 0);
bool rkpSettings_capture(const struct sk_buff*);
bool rkpSettings_ack(const struct sk_buff*);
bool rkpSetting_capture(const struct sk_buff*);
bool rkpSetting_ack(const struct sk_buff*);
bool rkpSettings_capture(const struct sk_buff* skb)
bool rkpSetting_capture(const struct sk_buff* skb)
{
if(!autocapture)
{
@@ -33,7 +33,7 @@ bool rkpSettings_capture(const struct sk_buff* skb)
}
else
{
if(rkpSettings_ack(skb))
if(rkpSetting_ack(skb))
return true;
if(ip_hdr(skb) -> protocol != IPPROTO_TCP)
return false;
@@ -46,7 +46,7 @@ bool rkpSettings_capture(const struct sk_buff* skb)
return true;
}
}
bool rkpSettings_ack(const struct sk_buff* skb)
bool rkpSetting_ack(const struct sk_buff* skb)
{
if(!autocapture)
{
@@ -61,9 +61,7 @@ bool rkpSettings_ack(const struct sk_buff* skb)
else if((ntohl(ip_hdr(skb) -> daddr) & 0xFFFF0000) != (192 << 24) + (168 << 16)
|| (ntohl(ip_hdr(skb) -> saddr) & 0xFFFF0000) == (192 << 24) + (168 << 16))
return false;
else if(tcp_hdr(skb) -> ack)
return true;
else
return false;
return tcp_hdr(skb) -> ack;
}
}

View File

@@ -1,9 +1,8 @@
#pragma once
#include "rkpSettings.h"
#include "rkpPacket.h"
#include "common.h"
struct rkpStream
// 接管一个 TCP 流。忽略重传(一律放行)。因此,也不需要捕获来自服务端的包。
// 接管一个 TCP 流。
{
enum
{
@@ -11,13 +10,24 @@ struct rkpStream
__rkpStream_sniffing_uaEnd, // 已经找到 ua正在寻找它的结尾buff_scan 中可能有包
__rkpStream_waiting // 已经找到 ua 的结尾或者 http 头的结尾并且还没有 psh接下来的包都直接放行
} status;
enum
{
__rkpStream_scan_noFound, // 还没找到 ua 的开头
__rkpStream_scan_uaBegin, // 匹配到了 ua 开头,但是 ua 实际的开头在下个数据包
__rkpStream_scan_uaRealBegin, // 匹配到了 ua 开头ua 实际的开头在这个数据包
__rkpStream_scan_uaEnd, // 匹配到了 ua 的结尾,并且需要修改 ua
__rkpStream_scan_uaGood, // 匹配到了 ua 的结尾,但是不需要修改 ua
__rkpStream_scan_headEnd // 匹配到了 http 头部的结尾,没有发现 ua
} scan_status; // 记录扫描结果,仅由 __rkpStream_scan 和 __rkpStream_reset 设置,由 rkpStream_execute 和 __rkpStream_scan 读取
u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序
struct rkpPacket *buff_scan, *buff_disordered; // 分别存储准备扫描的、因乱序而提前收到的数据包,都按照序号排好了
int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。在 rkpStream 中,序列号基本使用相对值;但在传给下一层时,基本使用绝对值
int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。在 rkpStream 中,序列号使用相对值;但在传给下一层时,使用绝对值
bool active; // 是否仍然活动,流每次处理的时候会置为 true每隔一段时间会删除标志为 false说明它在这段时间里没有活动的流将标志为 true 的流的标志也置为 false。
unsigned scan_headEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched; // 记录现在已经匹配了多少个字节,由 __rkpStream_scan 设置,但可以由其它过程置零
unsigned char *scan_uaBegin_p, *scan_uaEnd_p; // 记录扫描的一些结果,由 __rkpStream_scan 设置,但可以由其它过程置零
struct rkpMap* map;
unsigned scan_headEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched, *scan_uaPreserve_matched;
// 记录现在已经匹配了多少个字节,仅由 __rkpStream_scan 和 __rkpStream_reset 使用
uint32_t scan_uaBegin_seq, scan_uaEnd_seq;
// 记录 ua 开头和结束的序列号,仅由 __rkpStream_scan、__rkpStream_reset 设置
struct rkpMap* map; // 记录 ua 的位置,方便修改重传数据包,仅由 __rkpStream_modify 使用
struct rkpStream *prev, *next;
};
@@ -31,59 +41,79 @@ int32_t __rkpStream_seq_desired(const struct rkpStream*); // 返
void __rkpStream_scan(struct rkpStream*, struct rkpPacket*); // 对一个最新的包进行扫描
void __rkpStream_reset(struct rkpStream*); // 重置扫描进度,包括将 buff_scan 中的包全部发出
void __rkpStream_modify(struct rkpStream*); // 在收集到完整的 ua 后,对 ua 进行修改
struct rkpStream* rkpStream_new(const struct rkpPacket* rkpp)
{
struct rkpStream* rkps;
if(debug)
printk("rkpStream_new\n");
rkps = (struct rkpStream*)rkpMalloc(sizeof(struct rkpStream));
rkps = (struct rkpStream*)rkpMalloc(sizeof(struct rkpStream) + sizeof(unsigned) * n_str_preserve);
if(rkps == 0)
return 0;
rkps -> scan_uaPreserve_matched = (unsigned*)((void*)rkps + sizeof(struct rkpStream));
rkps -> status = __rkpStream_sniffing_uaBegin;
memcpy(rkps -> id, rkpp -> lid, 3 * sizeof(u_int32_t));
rkps -> buff_scan = rkps -> buff_disordered = 0;
rkps -> seq_offset = rkpPacket_seq(rkpp, 0);
if(rkpPacket_syn(rkpp))
rkps -> seq_offset++;
rkps -> active = true;
rkps -> scan_headEnd_matched = rkps -> scan_uaBegin_matched = rkps -> scan_uaEnd_matched = 0;
rkps -> scan_uaBegin_p = rkps -> scan_uaEnd_p = 0;
rkps -> map = 0;
rkps -> prev = rkps -> next = 0;
__rkpStream_reset(rkps);
return rkps;
}
void rkpStream_delete(struct rkpStream* rkps)
{
struct rkpPacket* rkpp;
struct rkpMap* rkpm;
if(debug)
printk("rkpStream_delete\n");
rkpPacket_deletel(&rkps -> buff_scan);
rkpPacket_deletel(&rkps -> buff_disordered);
for(rkpm = rkps -> map; rkpm != 0; rkpm = rkpm -> next)
rkpMap_delete(rkpm);
rkpFree(rkps);
}
bool rkpStream_belongTo(const struct rkpStream* rkps, const struct rkpPacket* rkpp)
{
if(debug)
printk("rkpStream_belongTo\n");
return memcmp(rkps -> id, rkpp -> lid, 3 * sizeof(u_int32_t)) == 0;
}
unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
// 不要害怕麻烦,咱们把每一种情况都慢慢写一遍。
// 以下假定:包是客户端发到服务端的,并且带有应用层数据
{
if(debug)
printk("rkp-ua: rkpStream_execute start, judging...\n");
printk("rkp-ua: rkpStream_execute start, judging %u ...\n", rkpPacket_seq(rkpp, 0));
// 肯定需要更新活动情况
rkps -> active = true;
// 首先处理如果是 ack 的情况
if(rkpp -> ack)
{
if(debug)
printk("ack packet\n");
rkpMap_refresh(&rkps -> map, rkpPacket_seqAck(rkpp, 0));
return NF_ACCEPT;
}
// 其它情况,首先放掉所有没有应用层数据的包
if(rkpPacket_appLen(rkpp) == 0)
{
if(debug)
printk("empty packet\n");
return NF_ACCEPT;
}
// 接下来从小到大考虑数据包的序列号的几种情况
// 已经发出的数据包,使用已有的映射修改
if(rkpPacket_seq(rkpp, rkps -> seq_offset) < 0)
{
if(debug)
printk("\tThe packet is re-transforming or has been modified, return NF_ACCEPT.\n");
if(debug && rkpp -> skb -> mark & 0x10)
printk("\tThe packet seems has been modified.\n");
printk("\tThe packet is re-transforming or has been modified.\n");
rkpMap_modify(&rkps -> map, &rkpp);
return NF_ACCEPT;
}
// 已经放到 buff_scan 中的数据包,丢弃
@@ -99,7 +129,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
if(debug)
printk("\tThe packet is disordered, return NF_STOLEN.\n");
__rkpStream_insert_auto(rkps, &rkps -> buff_disordered, rkpp);
rkpPacket_insert_auto(&rkps -> buff_disordered, rkpp, rkps -> seq_offset);
return NF_STOLEN;
}
@@ -108,45 +138,31 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
if(true)
{
// 因为一会儿可能还需要统一考虑 buff_disordered 中的包,因此不直接 return将需要的返回值写到这里最后再 return
unsigned rtn;
unsigned rtn = NF_ACCEPT;
if(debug)
printk("\tThe packet is desired one, further judging.\n");
// 接下来分析几种情况
// * sniffing_uaBegin 状态下,先扫描这个数据包,再看情况处理
// 需要考虑的方面有
// * 是否扫描到了 uaBegin通过 uaBegin_matched 是否与 str_uaBegin 长度相等判断
// * 在扫描到了 uaBegin 的前提下,是否得到了 ua 的开头位置。这是因为,可能一个数据包的结尾恰好是 `User-Agent: `,结果扫描到了 uaBegin 但是 ua 的开头在下一个数据包。通过 uaBegin_p 是否为非零值判断
// * 在扫描到了 uaBegin 和 ua 开头位置的前提下,是否扫描到了 uaEnd通过 uaEnd_matched 是否与 str_uaEnd 长度相等判断
// * 在没有扫描到 uaBegin 的前提下,是否扫描到了 headEnd通过 headEnd_matched 是否与 str_headEnd 长度相等判断;无需区分扫描到
// uaBegin 的各种情况中,扫描到 headEnd 与没有扫描到 headEnd 的情况,因为如果扫描到 headEnd必然扫描到 ua 开头位置、uaEnd分别考虑
// 是否有 psh 的两对情况,得到的处理方法相同
// * 是否有 psh
// 这些方面可能的组合(包括一些标准的 HTTP 协议不应该出现的组合)和处理办法为:
// 1. 什么都没有扫描到,没有 psh。更新 seq_offset返回 NF_ACCEPT。
// 2. 什么都没有扫描到,有 psh。重置更新 seq_offset返回 NF_ACCEPT。
// 3. 扫描到了 headEnd其它都没有扫描到下同没有 psh。重置,状态切换为 waiting更新 seq_offset返回 NF_ACCEPT
// 4. 扫描到了 headEnd有 psh。重置更新 seq_offset,返回 NF_ACCEPT
// 5. 扫描到了 uaBegin没有 psh。状态切换为 sniffing_uaEnd,更新 seq_offset返回 NF_ACCEPT。
// 6. 扫描到了 uaBegin有 psh。发出警告重置,更新 seq_offset返回 NF_ACCEPT。
// 7. 扫描到了 uaBegin、ua 开头位置,没有 psh。保留数据包状态切换为 sniffing_uaEnd返回 NF_STOLEN。
// 8. 扫描到了 uaBegin、ua 开头位置,有 psh。发出警告重置,更新 seq_offset返回 NF_ACCEPT。
// 9. 扫描到了 uaBegin、ua 开头位置、uaEnd没有 psh。修改数据包重置状态切换为 waiting,更新 seq_offset返回 NF_ACCEPT。
// 10. 扫描到了 uaBegin、ua 开头位置、uaEnd有 psh。修改数据包重置更新 seq_offset返回 NF_ACCEPT。
// 上面的情况中,有些情况的处置方法是类似的,因此可以合并;但为了整齐,在写代码时还是一个一个写出。
// * sniffing_uaEnd 状态下,如果之前没有扫描到 ua 开头位置,需要先将这个数据包的应用层起始位置作为 ua 开头位置,再扫描数据包,然后再分情况处理。
// 需要考虑的方面有(这时 uaBegin 和 ua 开头位置一定已经扫描到,并且 headEnd 是否扫描到不影响结果):
// * 是否扫描到了 uaEnd判断方法同上
// * 在没有扫描到 uaEnd 的前提下,算上这个数据包,是否达到了预估的 ua 最大长度
// * 是否有 psh
// 可能的组合和处理办法为:
// 1. 没有扫描到 uaEnd不到最大长度没有 psh。保留数据包返回 NF_STOLEN。
// 2. 没有扫描到 uaEnd不到最大长度有 psh。发出警告重置状态切换为 sniffing_uaBegin更新 seq_offset返回 NF_ACCEPT。
// 3. 没有扫描到 uaEnd到最大长度没有 psh。发出警告ua 最大长度可能太小),重置,状态切换为 waiting更新 seq_offset返回 NF_ACCEPT。
// 4. 没有扫描到 uaEnd到最大长度有 psh。发出警告重置状态切换为 sniffing_uaBegin更新 seq_offset返回 NF_ACCEPT。
// 5. 扫描到 uaEnd没有 psh。修改数据包重置状态切换为 waiting更新 seq_offset返回 NF_ACCEPT。
// 6. 扫描到 uaEnd有 psh。修改数据包重置状态切换为 sniffing_uaBegin更新 seq_offset返回 NF_ACCEPT。
// * sniffing_uaBegin 状态下,先扫描这个数据包,再看情况处理。需要考虑 scan_status 和是否有 psh。
// * 没有 psh 的情况
// * noFound更新 seq_offset返回 NF_ACCEPT。
// * uaBegin:状态切换为 sniffing_uaEnd更新 seq_offset返回 NF_ACCEPT。
// * uaRealBegin保留数据包状态切换为 sniffing_uaEnd返回 NF_STOLEN。
// * uaEnd生成映射修改数据包重置扫描进度状态切换为 waiting更新 seq_offset返回 NF_ACCEPT。
// * uaGood 或 headEnd重置扫描进度状态切换为 waiting更新 seq_offset返回 NF_ACCEPT。
// * 有 psh 的情况:
// * noFound、uaBegin、uaRealBegin、uaGood 或 headEnd重置扫描进度更新 seq_offset返回 NF_ACCEPT。
// * uaEnd生成映射修改数据包重置扫描进度更新 seq_offset返回 NF_ACCEPT。
// * sniffing_uaEnd 状态下,同样是先扫描数据包,然后再分情况处理。需要考虑 scan_status、是否有 psh 以及是否达到最大长度
// * 没有 psh 的情况:
// * uaBegin 或 uaRealBegin如果到了最大长度就发出警告ua 最大长度可能太小),重置扫描进度,发出数据包,状态切换为 waiting更新 seq_offset返回 NF_ACCEPT
// 否则,保留数据包,返回 NF_STOLEN
// * uaEnd生成映射修改数据包重置扫描进度发出数据包状态切换为 waiting,更新 seq_offset返回 NF_ACCEPT。
// * uaGood重置扫描进度发出数据包状态切换为 waiting,更新 seq_offset返回 NF_ACCEPT。
// * 有 psh 的情况:
// * uaBegin、uaRealBegin 或 uaGood重置扫描进度发出数据包状态切换为 sniffing_uaBegin,更新 seq_offset返回 NF_ACCEPT。
// * uaEnd生成映射修改数据包重置扫描进度发出数据包状态切换为 sniffing_uaBegin,更新 seq_offset返回 NF_ACCEPT。
// * waiting 状态下,如果有 psh则将状态切换为 sniffing_uaBegin否则不切换然后更新 seq_offset返回 NF_ACCEPT 即可。
if(rkps -> status == __rkpStream_sniffing_uaBegin)
@@ -156,172 +172,161 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
__rkpStream_scan(rkps, rkpp);
if(debug)
{
if(rkps -> scan_uaBegin_matched == strlen(str_uaBegin))
printk("\t\tuaBegin_matched.\n");
if(rkps -> scan_uaBegin_p != 0)
printk("\t\tuaBegin_p matched.\n");
if(rkps -> scan_uaEnd_matched == strlen(str_uaEnd))
printk("\t\tuaEnd_matched.\n");
if(rkps -> scan_headEnd_matched == strlen(str_headEnd))
printk("\t\theadEnd_matched.\n");
if(rkps -> scan_status == __rkpStream_scan_noFound)
printk("\t\tnoFound\n");
else if(rkps -> scan_status == __rkpStream_scan_uaBegin)
printk("\t\tuaBegin\n");
else if(rkps -> scan_status == __rkpStream_scan_uaRealBegin)
printk("\t\tuaRealBegin\n");
else if(rkps -> scan_status == __rkpStream_scan_uaEnd)
printk("\t\tuaEnd\n");
else if(rkps -> scan_status == __rkpStream_scan_uaGood)
printk("\t\tuaGood\n");
else if(rkps -> scan_status == __rkpStream_scan_headEnd)
printk("\t\theadEnd\n");
if(rkpPacket_psh(rkpp))
printk("\t\tpsh.\n");
printk("\t\tpsh\n");
}
if(rkps -> scan_uaBegin_matched < strlen(str_uaBegin))
if(rkps -> scan_headEnd_matched < strlen(str_headEnd))
if(!rkpPacket_psh(rkpp))
{
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(!rkpPacket_psh(rkpp))
{
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(rkps -> scan_uaBegin_p == 0)
if(!rkpPacket_psh(rkpp))
{
rkps -> status = __rkpStream_sniffing_uaEnd;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
if(verbose)
printk("half of ua found before psh.\n");
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(rkps -> scan_uaEnd_matched < strlen(str_uaEnd))
if(!rkpPacket_psh(rkpp))
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
rkps -> status = __rkpStream_sniffing_uaEnd;
rtn = NF_STOLEN;
}
else
{
if(verbose)
printk("half of ua found before psh.\n");
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(!rkpPacket_psh(rkpp))
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
__rkpStream_modify(rkps);
__rkpStream_pop_end(rkps, &rkps -> buff_scan);
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
__rkpStream_modify(rkps);
__rkpStream_pop_end(rkps, &rkps -> buff_scan);
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
}
else if(rkps -> status == __rkpStream_sniffing_uaEnd)
{
if(debug)
printk("\t\tsniffing_uaEnd\n");
if(rkps -> scan_uaBegin_p == 0)
rkps -> scan_uaBegin_p = rkpPacket_appBegin(rkpp);
__rkpStream_scan(rkps, rkpp);
if(debug)
{
if(rkps -> scan_uaBegin_matched == strlen(str_uaBegin))
printk("\t\tuaBegin_matched.\n");
if(rkps -> scan_uaBegin_p != 0)
printk("\t\tuaBegin_p matched.\n");
if(rkps -> scan_uaEnd_matched == strlen(str_uaEnd))
printk("\t\tuaEnd_matched.\n");
if(rkps -> scan_headEnd_matched == strlen(str_headEnd))
printk("\t\theadEnd_matched.\n");
if(rkpPacket_psh(rkpp))
printk("\t\tpsh.\n");
}
if(rkps -> scan_uaEnd_matched < strlen(str_uaEnd))
if(__rkpStream_num(rkps, rkps -> buff_scan) + 1 < len_ua)
if(!rkpPacket_psh(rkpp))
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
rtn = NF_STOLEN;
}
else
{
if(verbose)
printk("half of ua found before psh.\n");
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(!rkpPacket_psh(rkpp))
{
if(verbose)
printk("len_ua=%d maybe too small.\n", len_ua);
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
if(verbose)
printk("half of ua found before psh.\n");
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
if(!rkpPacket_psh(rkpp))
if(!rkpPacket_psh(rkpp))
switch (rkps -> scan_status)
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
__rkpStream_modify(rkps);
__rkpStream_pop_end(rkps, &rkps -> buff_scan);
case __rkpStream_scan_noFound:
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaBegin:
rkps -> status = __rkpStream_sniffing_uaEnd;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaRealBegin:
rkpPacket_insert_end(&rkps -> buff_scan, rkpp);
rkps -> status = __rkpStream_sniffing_uaEnd;
rtn = NF_STOLEN;
break;
case __rkpStream_scan_uaEnd:
rkpMap_insert_end(&rkps -> map, rkpMap_new(rkps -> scan_uaBegin_seq, rkps -> scan_uaEnd_seq));
rkpMap_modify(&rkps -> map, &rkpp);
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaGood:
case __rkpStream_scan_headEnd:
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
else
switch (rkps -> scan_status)
{
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
__rkpStream_modify(rkps);
__rkpStream_pop_end(rkps, &rkps -> buff_scan);
case __rkpStream_scan_noFound:
case __rkpStream_scan_uaBegin:
case __rkpStream_scan_uaRealBegin:
case __rkpStream_scan_uaGood:
case __rkpStream_scan_headEnd:
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaEnd:
rkpMap_insert_end(&rkps -> map, rkpMap_new(rkps -> scan_uaBegin_seq, rkps -> scan_uaEnd_seq));
rkpMap_modify(&rkps -> map, &rkpp);
__rkpStream_reset(rkps);
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
}
else if(rkps -> status == __rkpStream_sniffing_uaEnd)
{
if(debug)
printk("\t\tsniffing_uaEnd\n");
__rkpStream_scan(rkps, rkpp);
if(debug)
{
if(rkps -> scan_status == __rkpStream_scan_noFound)
printk("\t\tnoFound\n");
else if(rkps -> scan_status == __rkpStream_scan_uaBegin)
printk("\t\tuaBegin\n");
else if(rkps -> scan_status == __rkpStream_scan_uaRealBegin)
printk("\t\tuaRealBegin\n");
else if(rkps -> scan_status == __rkpStream_scan_uaEnd)
printk("\t\tuaEnd\n");
else if(rkps -> scan_status == __rkpStream_scan_uaGood)
printk("\t\tuaGood\n");
else if(rkps -> scan_status == __rkpStream_scan_headEnd)
printk("\t\theadEnd\n");
if(rkpPacket_psh(rkpp))
printk("\t\tpsh\n");
}
if(!rkpPacket_psh(rkpp))
switch (rkps -> scan_status)
{
case __rkpStream_scan_uaBegin:
case __rkpStream_scan_uaRealBegin:
if(rkpPacket_num(&rkps -> buff_scan) + 1 == len_ua)
{
printk("warning: len_ua may be too short.\n");
__rkpStream_reset(rkps);
rkpPacket_sendl(&rkps -> buff_scan);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
else
{
rkpPacket_insert_end(&rkps -> buff_scan, rkpp);
rtn = NF_STOLEN;
}
break;
case __rkpStream_scan_uaEnd:
rkpMap_insert_end(&rkps -> map, rkpMap_new(rkps -> scan_uaBegin_seq, rkps -> scan_uaEnd_seq));
rkpMap_modify(&rkps -> map, &rkps -> buff_scan);
rkpMap_modify(&rkps -> map, &rkpp);
__rkpStream_reset(rkps);
rkpPacket_sendl(&rkps -> buff_scan);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaGood:
__rkpStream_reset(rkps);
rkpPacket_sendl(&rkps -> buff_scan);
rkps -> status = __rkpStream_waiting;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_noFound:
case __rkpStream_scan_headEnd:
break;
}
else
switch (rkps -> scan_status)
{
case __rkpStream_scan_uaBegin:
case __rkpStream_scan_uaRealBegin:
case __rkpStream_scan_uaGood:
__rkpStream_reset(rkps);
rkpPacket_sendl(&rkps -> buff_scan);
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_uaEnd:
rkpMap_insert_end(&rkps -> map, rkpMap_new(rkps -> scan_uaBegin_seq, rkps -> scan_uaEnd_seq));
rkpMap_modify(&rkps -> map, &rkps -> buff_scan);
rkpMap_modify(&rkps -> map, &rkpp);
__rkpStream_reset(rkps);
rkpPacket_sendl(&rkps -> buff_scan);
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
break;
case __rkpStream_scan_noFound:
case __rkpStream_scan_headEnd:
break;
}
}
// else if(rkps -> status == __rkpStream_waiting)
@@ -347,7 +352,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
if(debug)
printk("\tdrop an disordered packet.\n");
__rkpStream_pop_begin(rkps, &rkps -> buff_disordered);
rkpPacket_drop(rkpPacket_pop_begin(&rkps -> buff_disordered));
}
// 如果序列号过大,结束循环
else if(rkpPacket_seq(rkps -> buff_disordered, rkps -> seq_offset) > __rkpStream_seq_desired(rkps))
@@ -360,7 +365,7 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
unsigned rtn;
if(debug)
printk("\texecute a disordered packet.\n");
rkpp2 = __rkpStream_pop_begin(rkps, &rkps -> buff_disordered);
rkpp2 = rkpPacket_pop_begin(&rkps -> buff_disordered);
rtn = rkpStream_execute(rkps, rkpp2);
if(debug)
{
@@ -394,34 +399,50 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
int32_t __rkpStream_seq_desired(const struct rkpStream* rkps)
{
if(debug)
printk("rkpStream_seq_desired\n");
struct rkpPacket* rkpp = rkps -> buff_scan;
if(rkpp == 0)
return 0;
else
for(; ; rkpp = rkpp -> next)
if(rkpp -> next == 0)
return rkpPacket_seq(rkpp, rkps -> seq_offset) + rkpPacket_appLen(rkpp);
{
for(; rkpp -> next != 0; rkpp = rkpp -> next);
return rkpPacket_seq(rkpp, rkps -> seq_offset) + rkpPacket_appLen(rkpp);
}
}
void __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
unsigned char* p;
// 需要匹配的量包括headEnd、uaBegin、uaEnd。分为两个阶段。
// 第一个阶段是 uaBegin 没有匹配完的阶段,这时尝试匹配 uaBegin 和 headEnd。
// 如果匹配完 headEnd不进入下一阶段而结束如果匹配完 uaBegin进入下一阶段这一阶段只匹配 uaEnd
for(p = rkpPacket_appBegin(rkpp); p != rkpPacket_appEnd(rkpp); p++)
{
if(rkps -> scan_uaBegin_matched < strlen(str_uaBegin))
unsigned char* p = rkpPacket_appBegin(rkpp);
if(debug)
printk("rkpStream_scan\n");
// 需要匹配的字符串包括headEnd、uaBegin、uaEnd、uaPreserve
// 开始这个函数时scan_status 只可能是 noFound、uaBegin 或 uaRealBegin这两个可以无差别对待
// * noFound扫描 uaBegin、headEnd当匹配到其中一个时停下来开始决策
// * uaBegin如果已经到数据包末尾则将状态设置为 uaBegin写入 scan_uaBegin_seq返回否则将状态设置为 uaRealBegin写入 scan_uaBegin_seq继续下个阶段的扫描
// * headEnd将状态设置为 headEnd返回
// * uaBegin 或 uaRealBegin扫描 uaEnd、uaPreserve匹配到其中一个时停下来开始决策
// * uaEnd将状态设置为 uaEnd设置 scan_uaEnd_seq返回
// * uaPreserve将状态设置为 uaGood返回
if(rkps -> scan_status == __rkpStream_scan_noFound)
for(; p != rkpPacket_appEnd(rkpp); p++)
{
if(*p == str_uaBegin[rkps -> scan_uaBegin_matched])
{
rkps -> scan_uaBegin_matched++;
if(rkps -> scan_uaBegin_matched == strlen(str_uaBegin))
{
if(p + 1 != rkpPacket_appEnd(rkpp))
rkps -> scan_uaBegin_p = p + 1;
continue;
if(p + 1 == rkpPacket_appEnd(rkpp))
rkps -> scan_status = __rkpStream_scan_uaBegin;
else
rkps -> scan_status = __rkpStream_scan_uaRealBegin;
rkps -> scan_uaBegin_seq = rkpPacket_seq(rkpp, 0) + ((p + 1) - rkpPacket_appBegin(rkpp));
if(debug)
printk("uaBegin_seq %u\n", rkps -> scan_uaBegin_seq);
p++;
break;
}
}
else
@@ -430,120 +451,54 @@ void __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
rkps -> scan_headEnd_matched++;
if(rkps -> scan_headEnd_matched == strlen(str_headEnd))
{
rkps -> scan_status = __rkpStream_scan_headEnd;
return;
}
}
else
rkps -> scan_headEnd_matched = 0;
}
else
if(rkps -> scan_status == __rkpStream_scan_uaBegin || rkps -> scan_status == __rkpStream_scan_uaRealBegin)
for(; p != rkpPacket_appEnd(rkpp); p++)
{
unsigned i;
if(*p == str_uaEnd[rkps -> scan_uaEnd_matched])
{
rkps -> scan_uaEnd_matched++;
if(rkps -> scan_uaEnd_matched == strlen(str_uaEnd))
{
int offset = p + 1 - rkpPacket_appBegin(rkpp);
// str_uaEnd 的末尾在现在的包中的偏移。如果小于等于 str_uaEnd 的长度,说明 ua 的实际结尾在上一个数据包;否则,在这个数据包。
if(offset <= strlen(str_uaEnd))
{
struct rkpPacket* i = rkps -> buff_scan;
while(i -> next != 0)
i = i -> next;
rkps -> scan_uaEnd_p = rkpPacket_appEnd(i) - (strlen(str_uaEnd) - offset);
}
else
rkps -> scan_uaEnd_p = p + 1 - strlen(str_uaEnd);
rkps -> scan_status = __rkpStream_scan_uaEnd;
rkps -> scan_uaEnd_seq = rkpPacket_seq(rkpp, 0) + ((p + 1) - rkpPacket_appBegin(rkpp)) - strlen(str_uaEnd);
if(debug)
printk("uaEnd_seq %u\n", rkps -> scan_uaEnd_seq);
return;
}
}
else
rkps -> scan_uaEnd_matched = 0;
for(i = 0; i < n_str_preserve; i++)
{
if(*p == str_preserve[i][rkps -> scan_uaPreserve_matched[i]])
{
rkps -> scan_uaPreserve_matched[i]++;
if(rkps -> scan_uaPreserve_matched[i] == strlen(str_preserve[i]))
{
rkps -> scan_status = __rkpStream_scan_uaGood;
return;
}
}
else
rkps -> scan_uaPreserve_matched[i] = 0;
}
}
}
}
void __rkpStream_reset(struct rkpStream* rkps)
{
struct rkpPacket* i;
if(debug)
printk("rkpStream_reset\n");
rkps -> scan_status = __rkpStream_scan_noFound;
rkps -> scan_headEnd_matched = rkps -> scan_uaBegin_matched = rkps -> scan_uaEnd_matched = 0;
rkps -> scan_uaBegin_p = rkps -> scan_uaEnd_p = 0;
for(i = rkps -> buff_scan; i != 0;)
{
struct rkpPacket* j = i -> next;
rkpPacket_send(i);
i = j;
}
rkps -> buff_scan = 0;
}
void __rkpStream_modify(struct rkpStream* rkps)
{
unsigned char* p;
struct rkpPacket* rkpp;
unsigned replaced;
// 匹配需要保留的 ua
if(n_str_preserve > 0)
{
unsigned* keyword_matched = (unsigned*)rkpMalloc(n_str_preserve * sizeof(unsigned));
memset(keyword_matched, 0, n_str_preserve * sizeof(unsigned));
p = rkps -> scan_uaBegin_p;
rkpp = rkps -> buff_scan;
while(p != rkps -> scan_uaEnd_p)
{
unsigned i;
for(i = 0; i < n_str_preserve; i++)
{
if(*p == str_preserve[i][keyword_matched[i]])
keyword_matched[i]++;
else
keyword_matched[i] = 0;
if(keyword_matched[i] == strlen(str_preserve[i]))
{
rkpFree(keyword_matched);
return;
}
}
p++;
if(p == rkpPacket_appEnd(rkpp))
{
rkpp = rkpp -> next;
if(rkpp == 0)
break;
else
p = rkpPacket_appBegin(rkpp);
}
}
rkpFree(keyword_matched);
}
// 执行到这里,说明不是需要保留的 ua接下来替换字符串
p = rkps -> scan_uaBegin_p;
rkpp = rkps -> buff_scan;
replaced = 0;
while(p != rkps -> scan_uaEnd_p)
{
if(replaced < strlen(str_uaRkp))
{
*p = str_uaRkp[replaced];
replaced++;
}
else
*p = ' ';
p++;
if(p == rkpPacket_appEnd(rkpp))
{
rkpp = rkpp -> next;
if(rkpp == 0)
break;
else
p = rkpPacket_appBegin(rkpp);
}
}
// 计算校验和
rkpp = rkps -> buff_scan;
while(rkpp != 0)
{
rkpPacket_csum(rkpp);
rkpp = rkpp -> next;
}
memset(rkps -> scan_uaPreserve_matched, 0, sizeof(unsigned) * n_str_preserve);
}