This commit is contained in:
chn
2020-01-08 19:06:59 +08:00
parent ccd0331559
commit 1be92fbb0d
8 changed files with 623 additions and 504 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.vscode
*.log
*.log
debug

View File

@@ -15,10 +15,10 @@
#include <linux/time.h>
#include <linux/mutex.h>
const static unsigned char* str_ua_begin = "User-Agent: ";
const static unsigned char* str_ua_end = "\r\n";
const static unsigned char* str_head_end = "\r\n\r\n";
static unsigned char str_ua_rkp[16];
const static unsigned char* str_uaBegin = "User-Agent: ";
const static unsigned char* str_uaEnd = "\r\n";
const static unsigned char* str_headEnd = "\r\n\r\n";
static unsigned char str_uaRkp[16];
void* rkpMalloc(unsigned size)
{

View File

@@ -6,15 +6,11 @@ static struct rkpManager* rkpm;
unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
unsigned rtn;
static bool crashed = false;
static unsigned n_skb_captured = 0, n_skb_captured_lastPrint = 1;
if(!rkpSettings_capture(skb))
return NF_ACCEPT;
#ifdef RKP_DEBUG
printk("hook_function captured a packet.\n");
#endif
rtn = rkpManager_execute(rkpm, skb);
n_skb_captured++;
@@ -23,9 +19,6 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_
printk("rkp-ua: Captured %d packets.\n", n_skb_captured);
n_skb_captured_lastPrint *= 2;
}
#ifdef RKP_DEBUG
printk("hook_function end.\n");
#endif
return rtn;
}
@@ -35,9 +28,9 @@ static int __init hook_init(void)
rkpm = rkpManager_new();
memcpy(str_ua_rkp, "RKP/", 4);
memcpy(str_ua_rkp + 4, VERSION, 2);
memcpy(str_ua_rkp + 6, ".0", 3);
memcpy(str_uaRkp, "RKP/", 4);
memcpy(str_uaRkp + 4, VERSION, 2);
memcpy(str_uaRkp + 6, ".0", 3);
nfho.hook = hook_funcion;
nfho.pf = NFPROTO_IPV4;
@@ -52,12 +45,12 @@ static int __init hook_init(void)
printk("rkp-ua: Started, version %s\n", VERSION);
printk("rkp-ua: nf_register_hook returnd %d.\n", ret);
printk("rkp-ua: autocapture=%c, mark_capture=0x%x, mark_first=0x%x.\n",
'n' + autocapture * ('y' - 'n'), mark_capture, mark_first);
printk("rkp-ua: autocapture=%c, mark_capture=0x%x\n",
'n' + autocapture * ('y' - 'n'), mark_capture);
printk("rkp-ua: str_preserve: %d\n", n_str_preserve);
for(ret = 0; ret < n_str_preserve; ret++)
printk("\t%s\n", str_preserve[ret]);
printk("str_ua_rkp: %s\n", str_ua_rkp);
printk("str_ua_rkp: %s\n", str_uaRkp);
return 0;
}

View File

@@ -20,7 +20,7 @@ void __rkpManager_unlock(struct rkpManager*, unsigned long);
struct rkpManager* rkpManager_new(void)
{
struct rkpManager* rkpm = rkpMalloc(sizeof(struct rkpManager));
struct rkpManager* rkpm = (struct rkpManager*)rkpMalloc(sizeof(struct rkpManager));
if(rkpm == 0)
return 0;
memset(rkpm -> data, 0, sizeof(struct rkpStream*) * 256);
@@ -57,68 +57,58 @@ int 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;
}
__rkpManager_lock(rkpm, &flag);
rtn = __rkpManager_execute(rkpm, rkpp);
if(debug)
{
if(rtn == NF_ACCEPT)
printk("returned NF_ACCEPT.\n");
else if(rtn == NF_DROP)
printk("returned NF_DROP.\n");
else if(rtn == NF_STOLEN)
printk("returned NF_STOLEN.\n");
}
__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)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpManager_execute start.\n");
printk("\tsyn %d\n", rkpPacket_syn(rkpp));
printk("\tsport %d dport %d\n", rkpPacket_sport(rkpp), rkpPacket_dport(rkpp));
printk("\tid %d\n", rkpp -> sid);
#endif
struct rkpStream *rkps, *rkps_new;
// 搜索是否有符合条件的流
for(rkps = rkpm -> data[rkpp -> sid]; rkps != 0; rkps = rkps -> next)
if(rkpStream_belongTo(rkps, rkpp)) // 找到了,执行即可
{
#ifdef RKP_DEBUG
printk("__rkpManager_execute: found target stream.\n");
#endif
return rkpStream_execute(rkps, rkpp);
}
// 如果运行到这里的话,那就是没有找到了,新建一个流再执行
#ifdef RKP_DEBUG
printk("__rkpManager_execute: target stream not found, create a new one. \n");
#endif
rkps_new = rkpStream_new(rkpp);
if(rkps_new == 0)
return NF_ACCEPT;
if(rkpm -> data[rkpp -> sid] == 0)
{
#ifdef RKP_DEBUG
printk("rkpManager_execute: add a new stream %d to an empty list.\n", id);
#endif
rkpm -> data[rkpp -> sid] = rkps_new;
}
else
{
#ifdef RKP_DEBUG
printk("rkpManager_execute: add a new stream %d to an unempty list.\n", id);
#endif
rkpm -> data[rkpp -> sid] -> prev = rkps_new;
rkps_new -> next = rkpm -> data[rkpp -> sid];
rkpm -> data[rkpp -> sid] = rkps_new;
}
return rkpStream_execute(rkps_new, skb);
return rkpStream_execute(rkps_new, rkpp);
}
void __rkpManager_refresh(unsigned long param)
{
unsigned i;
unsigned long flag;
struct rkpManager*& rkpm = (struct rkpManager*)param;
#ifdef RKP_DEBUG
printk("__rkpManager_refresh start.\n");
#endif
struct rkpManager* rkpm = (struct rkpManager*)param;
__rkpManager_lock(rkpm, &flag);
for(i = 0; i < 256; i++)
{
@@ -145,9 +135,6 @@ void __rkpManager_refresh(unsigned long param)
rkpm -> timer.expires = jiffies + time_keepalive * HZ;
add_timer(&rkpm -> timer);
__rkpManager_unlock(rkpm, flag);
#ifdef RKP_DEBUG
printk("__rkpManager_refresh end.\n");
#endif
}
void __rkpManager_lock(struct rkpManager* rkpm, unsigned long* flagp)

15
src/rkpMap.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include "common.h"
#include "rkpPacket.h"
struct rkpMap
{
int32_t left, right;
struct rkpMap *prev, *next;
};
struct rkpMap* rkpMap_new(int32_t, int32_t);
void rkpMap_delete(int32_t, int32_t);
unsigned char rkpMap_map(int32_t);
void rkpMap_modify(struct rkpPacket*);

View File

@@ -15,21 +15,34 @@ void rkpPacket_send(struct rkpPacket*);
void rkpPacket_delete(struct rkpPacket*);
void rkpPacket_drop(struct rkpPacket*);
unsigned char* rkpPacket_appBegin(struct rkpPacket*);
unsigned char* rkpPacket_appEnd(struct rkpPacket*);
unsigned rkpPacket_appLen(struct rkpPacket*);
int32_t rkpPacket_seq(struct rkpPacket*);
int32_t rkpPacket_ack(struct rkpPacket*);
u_int32_t rkpPacket_sip(struct rkpPacket*);
u_int32_t rkpPacket_dip(struct rkpPacket*);
u_int32_t rkpPacket_sport(struct rkpPacket*);
u_int32_t rkpPacket_dport(struct rkpPacket*);
bool rkpPacket_psh(struct rkpPacket*);
bool rkpPacket_syn(struct rkpPacket*);
unsigned char* rkpPacket_appBegin(const struct rkpPacket*);
unsigned char* rkpPacket_appEnd(const struct rkpPacket*);
unsigned rkpPacket_appLen(const struct rkpPacket*);
int32_t rkpPacket_seq(const struct rkpPacket*, const int32_t);
int32_t rkpPacket_ack(const struct rkpPacket*, const int32_t);
u_int32_t rkpPacket_sip(const struct rkpPacket*);
u_int32_t rkpPacket_dip(const struct rkpPacket*);
u_int16_t rkpPacket_sport(const struct rkpPacket*);
u_int16_t rkpPacket_dport(const struct rkpPacket*);
bool rkpPacket_psh(const struct rkpPacket*);
bool rkpPacket_syn(const struct rkpPacket*);
void rkpPacket_csum(struct rkpPacket*);
bool __rkpPacket_makeWriteable(struct rkpPacket*);
void rkpPacket_makeOffset(const struct rkpPacket*, int32_t*);
void rkpPacket_insert_auto(struct rkpPacket**, struct rkpPacket*, int32_t offset); // 在指定链表中插入一个包,自动根据序列号确定插入的位置
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*); // 返回指定链表中包的数目
void rkpPacket_sendl(struct rkpPacket**);
void rkpPacket_deletel(struct rkpPacket**);
void rkpPacket_dropl(struct rkpPacket**);
struct rkpPacket* rkpPacket_new(struct sk_buff* skb)
{
struct rkpPacket* rkpp = rkpMalloc(sizeof(struct rkpPacket));
@@ -46,7 +59,7 @@ struct rkpPacket* rkpPacket_new(struct sk_buff* skb)
rkpFree(rkpp);
return 0;
}
return p;
return rkpp;
}
void rkpPacket_send(struct rkpPacket* p)
{
@@ -67,60 +80,60 @@ void rkpPacket_drop(struct rkpPacket* p)
rkpFree(p);
}
unsigned char* rkpPacket_appBegin(struct rkpPacket* p)
unsigned char* rkpPacket_appBegin(const struct rkpPacket* p)
{
return ((unsigned char*)tcp_hdr(p -> skb)) + tcp_hdr(p -> skb) -> doff * 4;
}
unsigned char* rkpPacket_appEnd(struct rkpPacket* p)
unsigned char* rkpPacket_appEnd(const struct rkpPacket* p)
{
return ((unsigned char*)ip_hdr(p -> skb)) + ntohs(ip_hdr(p -> skb) -> tot_len);
}
unsigned rkpPacket_appLen(struct rkpPacket* p)
unsigned rkpPacket_appLen(const struct rkpPacket* p)
{
return ntohs(ip_hdr(p -> skb) -> tot_len) - ip_hdr(p -> skb) -> ihl * 4 - tcp_hdr(p -> skb) -> doff * 4;
}
int32_t rkpPacket_seq(struct rkpPacket* p)
int32_t rkpPacket_seq(const struct rkpPacket* p, const int32_t offset)
{
return ntohl(tcp_hdr(p -> skb) -> seq);
return (int32_t)ntohl(tcp_hdr(p -> skb) -> seq) - offset;
}
int32_t rkpPacket_ack(struct rkpPacket* p)
int32_t rkpPacket_ack(const struct rkpPacket* p, const int32_t offset)
{
return ntohl(tcp_hdr(p -> skb) -> ack);
return (int32_t)ntohl(tcp_hdr(p -> skb) -> ack) - offset;
}
u_int32_t rkpPacket_sip(struct rkpPacket* rkpp)
u_int32_t rkpPacket_sip(const struct rkpPacket* rkpp)
{
return ntohl(ip_hdr(rkpp -> skb) -> saddr);
}
u_int32_t rkpPacket_dip(struct rkpPacket* rkpp)
u_int32_t rkpPacket_dip(const struct rkpPacket* rkpp)
{
return ntohl(ip_hdr(rkpp -> skb) -> daddr);
}
u_int16_t rkpPacket_sport(struct rkpPacket* rkpp)
u_int16_t rkpPacket_sport(const struct rkpPacket* rkpp)
{
return ntohs(tcp_hdr(rkpp -> skb) -> source);
}
u_int32_t rkpPacket_dport(struct rkpPacket* rkpp)
u_int16_t rkpPacket_dport(const struct rkpPacket* rkpp)
{
return ntohs(tcp_hdr(rkpp -> skb) -> dest);
}
bool rkpPacket_psh(struct rkpPacket* rkpp)
bool rkpPacket_psh(const struct rkpPacket* rkpp)
{
return tcp_hdr(rkpp -> skb) -> psh;
}
bool rkpPacket_syn(struct rkpPacket* rkpp)
bool rkpPacket_syn(const struct rkpPacket* rkpp)
{
return tcp_hdr(rkpp -> skb) -> syn;
}
void rkpPacket_csum(struct rkpPacket* p)
void rkpPacket_csum(struct rkpPacket* rkpp)
{
struct iphdr* iph = ip_hdr(p -> skb);
struct tcphdr* tcph = tcp_hdr(p -> skb);
struct iphdr* iph = ip_hdr(rkpp -> skb);
struct tcphdr* tcph = tcp_hdr(rkpp -> skb);
tcph -> check = 0;
iph -> check = 0;
iph -> check = ip_fast_csum((unsigned char*)iph, iph -> ihl);
p -> skb -> csum = skb_checksum(p -> skb, iph -> ihl * 4, ntohs(iph -> tot_len) - iph -> ihl * 4, 0);
tcph -> check = csum_tcpudp_magic(iph -> saddr, iph -> daddr, ntohs(iph -> tot_len) - iph -> ihl * 4, IPPROTO_TCP, p -> skb -> csum);
rkpp -> skb -> csum = skb_checksum(rkpp -> skb, iph -> ihl * 4, ntohs(iph -> tot_len) - iph -> ihl * 4, 0);
tcph -> check = csum_tcpudp_magic(iph -> saddr, iph -> daddr, ntohs(iph -> tot_len) - iph -> ihl * 4, IPPROTO_TCP, rkpp -> skb -> csum);
}
bool __rkpPacket_makeWriteable(struct rkpPacket* rkpp)
@@ -135,4 +148,142 @@ bool __rkpPacket_makeWriteable(struct rkpPacket* rkpp)
return false;
}
return true;
}
void rkpPacket_makeOffset(const struct rkpPacket* rkpp, int32_t* offsetp)
{
*offsetp = rkpPacket_seq(rkpp, 0) + rkpPacket_appLen(rkpp);
}
void rkpPacket_insert_auto(struct rkpPacket** buff, struct rkpPacket* rkpp, int32_t offset)
{
// 如果链表是空的,那么就直接加进去
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 的包,插入到它的后面。
else
{
struct rkpPacket* rkpp2 = *buff;
while(rkpp2 -> next != 0 && rkpPacket_seq(rkpp2 -> next, offset) < rkpPacket_seq(rkpp, offset))
rkpp2 = rkpp2 -> next;
rkpp -> next = rkpp2 -> next;
rkpp -> prev = rkpp2;
if(rkpp -> next != 0)
rkpp -> next -> prev = rkpp;
rkpp2 -> next = rkpp;
}
}
void rkpPacket_insert_begin(struct rkpPacket** buff, struct rkpPacket* rkpp)
{
if(*buff == 0)
{
*buff = rkpp;
rkpp -> next = rkpp -> prev = 0;
}
else
{
(*buff) -> prev = rkpp;
rkpp -> next = *buff;
*buff = 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;
while(rkpp2 -> next != 0)
rkpp2 = rkpp2 -> next;
rkpp2 -> next = rkpp;
rkpp -> prev = rkpp2;
rkpp -> next = 0;
}
}
struct rkpPacket* rkpPacket_pop_begin(struct rkpPacket** buff)
{
struct rkpPacket* rkpp = *buff;
if(rkpp -> next == 0)
*buff = 0;
else
{
*buff = rkpp -> next;
rkpp -> next = 0;
(*buff) -> prev = 0;
}
return rkpp;
}
struct rkpPacket* rkpPacket_pop_end(struct rkpPacket** buff)
{
struct rkpPacket* rkpp = *buff;
while(rkpp -> next != 0)
rkpp = rkpp -> next;
if(rkpp == *buff)
*buff = 0;
else
{
rkpp -> prev -> next = 0;
rkpp -> prev = 0;
}
return rkpp;
}
unsigned rkpPacket_num(const struct rkpPacket* buff)
{
unsigned n = 0;
const struct rkpPacket* rkpp = buff;
while(rkpp != 0)
{
rkpp = rkpp -> next;
n++;
}
return n;
}
void rkpPacket_sendl(struct rkpPacket** rkppl)
{
struct rkpPacket *rkpp = *rkppl, *rkpp2;
while(rkpp != 0)
{
rkpp2 = rkpp -> next;
rkpPacket_send(rkpp);
rkpp = rkpp2;
}
*rkppl = 0;
}
void rkpPacket_deletel(struct rkpPacket** rkppl)
{
struct rkpPacket *rkpp = *rkppl, *rkpp2;
while(rkpp != 0)
{
rkpp2 = rkpp -> next;
rkpPacket_delete(rkpp);
rkpp = rkpp2;
}
*rkppl = 0;
}
void rkpPacket_dropl(struct rkpPacket** rkppl)
{
struct rkpPacket *rkpp = *rkppl, *rkpp2;
while(rkpp != 0)
{
rkpp2 = rkpp -> next;
rkpPacket_drop(rkpp);
rkpp = rkpp2;
}
*rkppl = 0;
}

View File

@@ -17,6 +17,8 @@ static unsigned len_ua = 2;
module_param(len_ua, uint, 0);
static bool verbose = false;
module_param(verbose, bool, 0);
static bool debug = false;
module_param(debug, bool, 0);
bool rkpSettings_capture(const struct sk_buff*);

View File

@@ -7,54 +7,55 @@ struct rkpStream
{
enum
{
__rkpStream_sniffing_uaBegin, // 正在寻找 http 头的结尾或者 ua 的开始,这时 buff_scan 中不应该有包
__rkpStream_sniffing_uaEnd, // 已经找到 ua正在寻找它的结尾buff_scan 中可能有包
__rkpStream_waiting // 已经找到 ua 的结尾或者 http 头的结尾并且还没有 psh接下来的包都直接放行
__rkpStream_sniffing_uaBegin, // 正在寻找 http 头的结尾或者 ua 的开始,这时 buff_scan 中不应该有包
__rkpStream_sniffing_uaEnd, // 已经找到 ua正在寻找它的结尾buff_scan 中可能有包
__rkpStream_waiting // 已经找到 ua 的结尾或者 http 头的结尾并且还没有 psh接下来的包都直接放行
} status;
u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序
u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序
struct rkpPacket *buff_scan, *buff_disordered; // 分别存储准备扫描的、因乱序而提前收到的数据包,都按照序号排好了
u_int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。
bool active; // 是否仍然活动,超过一定时间不活动的流会被销毁
unsigned scan_httpEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched; // 记录现在已经匹配了多少个字节,由 __rkpStream_scan 设置
unsigned char *scan_uaBegin_p, *scan_uaEnd_p; // 在扫描到相关信息后,将信息填写到这里
int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。
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 rkpStream *prev, *next;
};
struct rkpStream* rkpStream_new(const struct rkpPacket*); // 构造一个 rkpSteam
struct rkpStream* rkpStream_new(const struct rkpPacket*);
void rkpStream_delete(struct rkpStream*);
bool rkpStream_belongTo(const struct rkpStream*, const struct rkpPacket*); // 判断一个数据包是否属于一个流
unsigned rkpStream_execute(struct rkpStream*, struct rkpPacket*); // 已知一个数据包属于这个流后,处理这个数据包
unsigned rkpStream_execute(struct rkpStream*, struct rkpPacket*); // 已知一个数据包属于这个流后,处理这个数据包
int32_t __rkpStream_seq_scanEnd(struct rkpStream*); // 返回 buff_scan 中最后一个数据包的后继的第一个字节的序列号
int32_t __rkpStream_seq_desired(const struct rkpStream*); // 返回 buff_scan 中最后一个数据包的后继的第一个字节的相对序列号
void __rkpStream_insert_auto(struct rkpStream*, struct rkpPacket**, struct rkpPacket*); // 在指定链表中插入一个节点
void __rkpStream_insert_end(struct rkpStream*, struct rkpPacket**, struct rkpPacket*);
bool __rkpStream_scan(struct rkpStream*, struct rkpPacket*); // 对一个最新的包进行扫描
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 = rkpMalloc(sizeof(struct rkpStream));
struct rkpStream* rkps;
if(debug)
printk("rkpStream_new\n");
rkps = (struct rkpStream*)rkpMalloc(sizeof(struct rkpStream));
if(rkps == 0)
return 0;
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 = ntohl(tcp_hdr(skb) -> seq);
rkps -> seq_offset = rkpPacket_seq(rkpp, 0);
rkps -> active = true;
rkps -> scan_httpEnd_matched = rkps -> scan_uaBegin_matched = rkps -> scan_uaEnd_matched = 0;
rkps -> scan_headEnd_matched = rkps -> scan_uaBegin_matched = rkps -> scan_uaEnd_matched = 0;
rkps -> scan_uaBegin_p = rkps -> scan_uaEnd_p = 0;
rkps -> prev = rkps -> next = 0;
if(verbose)
printk("rkpStream_new\n");
return rkps;
}
void rkpStream_delete(struct rkpStream* rkps)
{
struct rkpPacket* rkpp;
for(rkpp = rkps -> buff_scan; p != 0;)
if(debug)
printk("rkpStream_delete\n");
for(rkpp = rkps -> buff_scan; rkpp != 0;)
{
struct rkpPacket* rkpp2 = rkpp;
rkpp = rkpp -> next;
@@ -67,8 +68,6 @@ void rkpStream_delete(struct rkpStream* rkps)
rkpPacket_drop(rkpp2);
}
rkpFree(rkps);
if(verbose)
printk("rkpStream_delete\n");
}
bool rkpStream_belongTo(const struct rkpStream* rkps, const struct rkpPacket* rkpp)
@@ -79,208 +78,329 @@ unsigned rkpStream_execute(struct rkpStream* rkps, struct rkpPacket* rkpp)
// 不要害怕麻烦,咱们把每一种情况都慢慢写一遍。
// 以下假定:包是客户端发到服务端的,并且带有应用层数据
{
if(verbose)
if(debug)
printk("rkp-ua: rkpStream_execute start, judging...\n");
// 肯定需要更新时间
// 肯定需要更新活动情况
rkps -> active = true;
// 接下来从小到大考虑数据包的序列号的几种情况
// 已经发出的数据包,直接忽略
if(rkpPacket_seq(rkpp) - rkps -> seq_offset < 0)
if(rkpPacket_seq(rkpp, rkps -> seq_offset) < 0)
{
if(verbose)
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");
return NF_ACCEPT;
}
// 已经放到 buff_scan 中的数据包,丢弃
if(rkpPacket_seq(rkpp) - rkps -> seq_offset < __rkpStream_seq_scanEnd(rkps))
if(rkpPacket_seq(rkpp, rkps -> seq_offset) < __rkpStream_seq_desired(rkps))
{
if(verbose)
if(debug)
printk("\tThe packet with same seq has been captured, return NF_DROP.\n");
return NF_DROP;
}
// 恰好是 buff_scan 的后继数据包,这种情况比较麻烦,写到最后
// 乱序导致还没接收到前继的数据包,放到 buff_disordered
if(rkpPacket_seq(rkpp) - rkps -> seq_offset > __rkpStream_seq_scanEnd(rkps))
if(rkpPacket_seq(rkpp, rkps -> seq_offset) > __rkpStream_seq_desired(rkps))
{
if(verbose)
if(debug)
printk("\tThe packet is disordered, return NF_STOLEN.\n");
Stream_insert_auto(rkps, &(rkps -> buff_disordered), rkpp);
__rkpStream_insert_auto(rkps, &rkps -> buff_disordered, rkpp);
return NF_STOLEN;
}
// 接下来是恰好是 buff_scan 的后继数据包的情况,先分状态讨论,再一起考虑 buff_disordered 中的包
if(rkpPacket_seq(p) - rkps -> seq_offset == __rkpStream_seq_scanEnd(rkps))
// if(rkpPacket_seq(rkpp, rkps -> seq_offset) == __rkpStream_seq_desired(rkps))
if(true)
{
// 因为一会儿可能还需要统一考虑 buff_disordered 中的包,因此不直接 return将需要的返回值写到这里最后再 return
unsigned rtn;
if(debug)
printk("\tThe packet is desired one, further judging.\n");
// 接下来分析几种情况
// * sniffing_uaBegin 状态下,先扫描这个数据包,再看情况处理,因此不再单独写出。
// * sniffing_uaBegin 状态下,先扫描这个数据包,再看情况处理
// 需要考虑的方面有:
// * 是否扫描到了 uaBgin通过 uaBegin_matched 是否与 str_uaBgin 长度相等判断
// * 在扫描到了 uaBgin 的前提下,是否扫描到了 uaEnd通过 uaEnd_matched 是否与 str_uaEnd 长度相等判断
// * 在扫描到了 uaBgin 的前提下,是否得到了 ua 开头位置。这是因为,可能一个数据包的结尾恰好是 `User-Agent: `,结果扫描到了 uaBegin 但是 ua 的开头在下一个数据包。通过 uaBegin_p 是否为非零值判断
// * 是否扫描到了 headEnd,这三个通过对比 matched 来确定,通过 headEnd_matched 是否与 str_headEnd 长度相等判断
// * 是否扫描到了 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、没有 psh。状态切换为 sniffing_uaEnd更新 seq_offset返回 NF_ACCEPT
// 3. 扫描到了 uaBegin、uaEnd没有 psh
// * sniffing 状态下,没有读到 http 头的结尾,但是有设置 psh
// * waiting 状态下
// 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。
// * waiting 状态下,如果有 psh则将状态切换为 sniffing_uaBegin否则不切换然后更新 seq_offset返回 NF_ACCEPT 即可。
#ifdef RKP_DEBUG
printk("\tdesired packet judged.\n");
rkpPacket_makeWriteable(p);
unsigned char* temp = rkpMalloc((rkpPacket_appLen(p) + 1) * sizeof(unsigned char));
memcpy(temp, rkpPacket_appBegin(p), rkpPacket_appLen(p));
temp[rkpPacket_appLen(p)] = 0;
printk("\tcontent length: %d\n", rkpPacket_appLen(p));
printk("\tpacket content: %s\n", temp);
// printk("\tpacket content in int:");
// for(rtn = 0; rtn < rkpPacket_appLen(p); rtn++)
// printk("%d\n", rkpPacket_appBegin(p)[rtn]);
rtn = NF_STOLEN;
printk("\n");
rkpFree(temp);
#endif
// 如果是在 sniffing 的情况下,那一定先丢到 buff_scan 里,然后扫描一下看结果
if(rkps -> status == __rkpStream_sniffing)
if(rkps -> status == __rkpStream_sniffing_uaBegin)
{
#ifdef RKP_DEBUG
printk("\t\tsniffing.\n");
#endif
// 作任何应用层的读取和写入之前,都需要 writeable而只有这种情况需要做。
rkpPacket_makeWriteable(p);
// 丢到 buff_scan 里,记得一会儿如果要 accept还要拿出来以及更新序列号
__rkpStream_insert_end(rkps, &rkps -> buff_scan, p);
if(__rkpStream_scan(rkps, p)) // 扫描到了 http 头的结尾
if(debug)
printk("\t\tsniffing_uaBegin\n");
__rkpStream_scan(rkps, rkpp);
if(debug)
{
#ifdef RKP_DEBUG
printk("\t\t\thttp head end matched.\n");
#endif
// 替换 ua
__rkpStream_modify(rkps);
// 发出数据包,注意最后一个不发,等会儿 accept 就好
struct rkpPacket* p2;
for(p2 = rkps -> buff_scan; p2 != 0 && p2 -> next != 0;)
{
struct rkpPacket* p3 = p2;
p2 = p2 -> next;
// rkps -> seq_offset = rkpPacket_seq(p2) + rkpPacket_appLen(p2); 不需要更新偏移,因为最后一个包等会儿 accept 的时候会更新
rkpPacket_send(p2);
}
// 如果没有 psh设定状态为等待
if(!rkpPacket_psh(p))
rkps -> status = __rkpStream_waiting;
// 将最后一个包再拿出来,将链表清空,更新偏移,以及把用不到的删掉
rkps -> buff_scan = 0;
p -> prev = 0;
rkps -> seq_offset = rkpPacket_seq(p) + rkpPacket_appLen(p);
rkpPacket_delete(p);
// accept
rtn = NF_ACCEPT;
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");
}
// 没有扫描到但是有 psh同样要全部发出并 accept
else if(rkpPacket_psh(p))
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpStream_execute: psh found before http head end.\n");
#endif
// 发出数据包,注意最后一个不发,等会儿 accept 就好
struct rkpPacket* p2;
for(p2 = rkps -> buff_scan; p2 != 0 && p2 -> next != 0;)
{
struct rkpPacket* p3 = p2;
p2 = p2 -> next;
// rkps -> seq_offset = rkpPacket_seq(p2) + rkpPacket_appLen(p2); 不需要更新偏移,因为最后一个包等会儿 accept 的时候会更新
rkpPacket_send(p2);
}
// 将最后一个包再拿出来,将链表清空,更新偏移,以及把用不到的删掉
rkps -> buff_scan = 0;
p -> prev = 0;
rkps -> seq_offset = rkpPacket_seq(p) + rkpPacket_appLen(p);
rkpPacket_delete(p);
// accept
rtn = NF_ACCEPT;
}
// 没有扫描到也没有 psh偷走就好了不需要任何操作
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)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpStream_execute: head end not found.\n");
#endif
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");
}
}
else // waiting 的状态,检查 psh、设置序列号偏移、然后放行就可以了
{
#ifdef RKP_DEBUG
printk("\t\twaiting.\n");
#endif
rkps -> seq_offset = rkpPacket_seq(p) + rkpPacket_appLen(p);
if(rkpPacket_psh(p))
rkps -> status = __rkpStream_sniffing;
rkpPacket_delete(p);
rtn = NF_ACCEPT;
}
// 考虑 buff_disordered
while(rkps -> buff_disordered != 0)
{
if(rkpPacket_seq(rkps -> buff_disordered) - rkps -> seq_offset < __rkpStream_seq_scanEnd(rkps))
// 序列号是已经发出去的,丢弃
{
if(rkps -> buff_disordered -> next == 0)
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))
{
rkpPacket_drop(rkps -> buff_disordered);
rkps -> buff_disordered = 0;
__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
{
rkps -> buff_disordered = rkps -> buff_disordered -> next;
rkpPacket_drop(rkps -> buff_disordered -> prev);
rkps -> buff_disordered -> prev = 0;
__rkpStream_insert_end(rkps, &rkps -> buff_scan, rkpp);
__rkpStream_modify(rkps);
__rkpStream_pop_end(rkps, &rkps -> buff_scan);
__rkpStream_reset(rkps);
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
}
// else if(rkps -> status == __rkpStream_waiting)
else
{
if(debug)
{
printk("\t\tsniffing_uaBegin\n");
if(rkpPacket_psh(rkpp))
printk("\t\tpsh.\n");
}
if(rkpPacket_psh(rkpp))
rkps -> status = __rkpStream_sniffing_uaBegin;
rkpPacket_makeOffset(rkpp, &rkps -> seq_offset);
rtn = NF_ACCEPT;
}
// 接下来考虑乱序的包
while(rkps -> buff_disordered != 0)
{
// 序列号是已经发出去的,丢弃
if(rkpPacket_seq(rkps -> buff_disordered, rkps -> seq_offset) < __rkpStream_seq_desired(rkps))
{
if(debug)
printk("\tdrop an disordered packet.\n");
__rkpStream_pop_begin(rkps, &rkps -> buff_disordered);
}
// 如果序列号过大,结束循环
else if(rkpPacket_seq(rkps -> buff_disordered) - rkps -> seq_offset > __rkpStream_seq_scanEnd(rkps))
else if(rkpPacket_seq(rkps -> buff_disordered, rkps -> seq_offset) > __rkpStream_seq_desired(rkps))
break;
// 如果序列号恰好,把它从链表中取出,然后像刚刚抓到的包那样去执行
else
{
// 将包从链表中取出
struct rkpPacket* p2 = rkps -> buff_disordered;
if(rkps -> buff_disordered -> next == 0)
rkps -> buff_disordered = 0;
else
struct rkpPacket* rkpp2;
unsigned rtn;
if(debug)
printk("\texecute a disordered packet.\n");
rkpp2 = __rkpStream_pop_begin(rkps, &rkps -> buff_disordered);
rtn = rkpStream_execute(rkps, rkpp2);
if(debug)
{
rkps -> buff_disordered = p2 -> next;
rkps -> buff_disordered -> prev = 0;
p2 -> next = 0;
if(rtn == NF_ACCEPT)
printk("\t\treturn NF_ACCEPT.\n");
else if(rtn == NF_DROP)
printk("\t\treturn NF_DROP.\n");
else if(rtn == NF_STOLEN)
printk("\t\treturn NF_STOLEN.\n");
}
// 执行
unsigned rtn = rkpStream_execute(rkps, p2 -> skb);
if(rtn == NF_ACCEPT)
rkpPacket_send(p2);
rkpPacket_send(rkpp2);
else if(rtn == NF_DROP)
rkpPacket_drop(p2);
else if(rtn == NF_STOLEN)
rkpPacket_delete(p2);
rkpPacket_drop(rkpp2);
else if(rtn == NF_STOLEN);
}
}
if(debug)
{
if(rtn == NF_ACCEPT)
printk("\treturn NF_ACCEPT.\n");
else if(rtn == NF_DROP)
printk("\treturn NF_DROP.\n");
else if(rtn == NF_STOLEN)
printk("\treturn NF_STOLEN.\n");
}
return rtn;
}
}
int32_t __rkpStream_seq_scanEnd(struct rkpStream* rkps)
int32_t __rkpStream_seq_desired(const struct rkpStream* rkps)
{
struct rkpPacket* rkpp = rkps -> buff_scan;
if(rkpp == 0)
@@ -288,253 +408,95 @@ int32_t __rkpStream_seq_scanEnd(struct rkpStream* rkps)
else
for(; ; rkpp = rkpp -> next)
if(rkpp -> next == 0)
return rkpPacket_seq(rkpp) - rkps -> seq_offset + rkpPacket_appLen(rkpp);
return rkpPacket_seq(rkpp, rkps -> seq_offset) + rkpPacket_appLen(rkpp);
}
void __rkpStream_insert_auto(struct rkpStream* rkps, struct rkpPacket** buff, struct rkpPacket* p)
void __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_auto start.\n");
#endif
// 如果链表是空的,那么就直接加进去
if(*buff == 0)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_auto: empty buff.\n");
#endif
*buff = p;
p -> prev = p -> next = 0;
}
// 又或者,要插入的包需要排到第一个,或者和第一个序列号重复了
else if(rkpPacket_seq(*buff) - rkps -> seq_offset >= rkpPacket_seq(p) - rkps -> seq_offset)
{
if(rkpPacket_seq(*buff) - rkps -> seq_offset == rkpPacket_seq(p) - rkps -> seq_offset)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_auto: same seq. Drop it.\n");
#endif
rkpPacket_drop(p);
}
else
{
(*buff) -> prev = p;
p -> next = *buff;
p -> prev = 0;
*buff = p;
}
}
// 接下来寻找最后一个序列号不比 p 大的包,插入到它的后面或者丢掉。
else
{
struct rkpPacket* p2 = *buff;
while(p2 -> next != 0 && rkpPacket_seq(p2 -> next) - rkps -> seq_offset <= rkpPacket_seq(p) - rkps -> seq_offset)
p2 = p2 -> next;
if(rkpPacket_seq(p2) - rkps -> seq_offset == rkpPacket_seq(p) - rkps -> seq_offset)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_auto: same seq. Drop it.\n");
#endif
rkpPacket_drop(p);
}
else
{
p -> next = p2 -> next;
p -> prev = p2;
if(p -> next != 0)
p -> next -> prev = p;
p2 -> next = p;
}
}
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_auto end.\n");
#endif
}
void __rkpStream_insert_end(struct rkpStream* rkps, struct rkpPacket** buff, struct rkpPacket* p)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_end start.\n");
#endif
if(*buff == 0)
{
*buff = p;
p -> next = p -> prev = 0;
}
else
{
struct rkpPacket* p2 = *buff;
while(p2 -> next != 0)
p2 = p2 -> next;
p2 -> next = p;
p -> prev = p2;
p -> next = 0;
}
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_end end.\n");
#endif
}
bool __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_scan start.\n");
#endif
unsigned char* p;
// 需要匹配的量包括headEnd、uaBegin、uaEnd。分为两个阶段。
// 第一个阶段是 uaBegin 没有匹配完的阶段,这时尝试匹配 uaBegin 和 headEnd。
// 如果匹配完 headEnd不进入下一阶段而结束如果匹配完 uaBegin进入下一阶段这一阶段只匹配 uaEnd
for(p = rkpPacket_appBegin(rkpp); p != rkpPacket_appEnd(rkpp); p++)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_scan matching %c.\n", *p);
#endif
if(*p == str_head_end[rkps -> scan_matched])
rkps -> scan_matched++;
else
rkps -> scan_matched = 0;
if(rkps -> scan_matched == strlen(str_head_end))
if(rkps -> scan_uaBegin_matched < strlen(str_uaBegin))
{
rkps -> scan_matched = 0;
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_scan: head end found.\n");
printk("rkp-ua: __rkpStream_scan end.\n");
#endif
return true;
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;
}
}
else
rkps -> scan_uaBegin_matched = 0;
if(*p == str_headEnd[rkps -> scan_headEnd_matched])
{
rkps -> scan_headEnd_matched++;
if(rkps -> scan_headEnd_matched == strlen(str_headEnd))
return;
}
else
rkps -> scan_headEnd_matched = 0;
}
else
{
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);
return;
}
}
else
rkps -> scan_uaEnd_matched = 0;
}
}
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_scan: head end not found.\n");
printk("rkp-ua: __rkpStream_scan end.\n");
#endif
return false;
}
void __rkpStream_reset(struct rkpStream* rkps)
{
struct rkpPacket* i;
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)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify start.\n");
#endif
unsigned ua_begin_matched = 0, ua_end_matched = 0, head_end_matched = 0, *keyword_matched, ua_relplaced = 0;
unsigned char *ua_begin_p, *ua_end_p;
struct rkpPacket *ua_begin_rkpp, *ua_end_rkpp, *rkpp = rkps -> buff_scan;
unsigned char* p;
struct rkpPacket* rkpp;
unsigned replaced;
// 匹配 "User-Agent: " 的阶段
#ifdef RKP_DEBUG
printk("matching User-Agent: \n");
#endif
for(;rkpp != 0 && ua_begin_matched != strlen(str_ua_begin); rkpp = rkpp -> next)
{
unsigned char* p;
for(p = rkpPacket_appBegin(rkpp); p != rkpPacket_appEnd(rkpp); p++)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: matching %c.\n", *p);
#endif
// 检查匹配 http 头结尾的情况
if(*p == str_head_end[head_end_matched])
{
head_end_matched++;
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: head end matched.\n");
#endif
}
else
head_end_matched = 0;
if(head_end_matched == strlen(str_head_end))
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua not found.\n");
printk("rkp-ua: __rkpStream_scan end.\n");
#endif
return;
}
// 检查匹配 "User-Agent: " 的情况
if(*p == str_ua_begin[ua_begin_matched])
{
ua_begin_matched++;
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua begin matched.\n");
#endif
}
else
ua_begin_matched = 0;
if(ua_begin_matched == strlen(str_ua_begin))
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua found.\n");
#endif
// 如果是这个包中最后一个字节了,那么跳到下一个包的第一个字节;否则,移动到下一个字节
if(p == rkpPacket_appEnd(rkpp) - 1)
{
rkpp = rkpp -> next;
p = rkpPacket_appBegin(rkpp);
}
else
p++;
// 将结果记录进去
ua_begin_rkpp = rkpp;
ua_begin_p = p;
break;
}
}
}
// 匹配 "\r\n" 和需要忽略的关键字的阶段
#ifdef RKP_DEBUG
printk("matching \\r\\n\n");
#endif
// 匹配需要保留的 ua
if(n_str_preserve > 0)
{
keyword_matched = rkpMalloc(n_str_preserve * sizeof(unsigned));
unsigned* keyword_matched = (unsigned*)rkpMalloc(n_str_preserve * sizeof(unsigned));
memset(keyword_matched, 0, n_str_preserve * sizeof(unsigned));
}
for(rkpp = ua_begin_rkpp; rkpp != 0 && ua_end_matched != strlen(str_ua_end); rkpp = rkpp -> next)
{
unsigned char* p;
if(rkpp == ua_begin_rkpp)
p = ua_begin_p;
else
p = rkpPacket_appBegin(rkpp);
for(; p != rkpPacket_appEnd(rkpp); p++)
p = rkps -> scan_uaBegin_p;
rkpp = rkps -> buff_scan;
while(p != rkps -> scan_uaEnd_p)
{
// 检查匹配 "\r\n" 的情况
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: matching %c.\n", *p);
#endif
if(*p == str_ua_end[ua_end_matched])
{
ua_end_matched++;
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua end matched.\n");
#endif
}
else
ua_end_matched = 0;
if(ua_end_matched == strlen(str_ua_end))
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua end found.\n");
#endif
// 如果在某个包的开头几个字节匹配结束(即 ua 实际上全部位于上一个包),就返回去
if(p + 1 - rkpPacket_appBegin(rkpp) <= strlen(str_ua_end))
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: move to last packet.\n");
#endif
unsigned temp = strlen(str_ua_end) - (p + 1 - rkpPacket_appBegin(rkpp)); // str_ua_end 位于上一个包中的长度
rkpp = rkpp -> prev;
p = rkpPacket_appEnd(rkpp) - temp;
}
// 否则,回退到 ua 结束的位置
else
p += 1 - strlen(str_ua_end);
// 记录结果
ua_end_rkpp = rkpp;
ua_end_p = p;
// 记得删掉不用的内存
if(n_str_preserve > 0)
rkpFree(keyword_matched);
break;
}
// 检查匹配需要忽略的关键字的情况
unsigned i;
for(i = 0; i < n_str_preserve; i++)
{
@@ -544,44 +506,52 @@ void __rkpStream_modify(struct rkpStream* rkps)
keyword_matched[i] = 0;
if(keyword_matched[i] == strlen(str_preserve[i]))
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: keyword %s matched.\n", str_preserve[i]);
printk("rkp-ua: __rkpStream_scan end.\n");
#endif
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);
}
}
// 已经获得了所需要的信息并且确认 ua 需要替换,然后替换 ua 的阶段
// 已经全部 writeable可以放心大胆地替换字符串
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: ua modify start.\n");
#endif
for(rkpp = ua_begin_rkpp; ; rkpp = rkpp -> next)
// 计算校验和
rkpp = rkps -> buff_scan;
while(rkpp != 0)
{
unsigned char* p;
if(rkpp == ua_begin_rkpp)
p = ua_begin_p;
else
p = rkpPacket_appBegin(rkpp);
for(; p != rkpPacket_appEnd(rkpp) && p != ua_end_p; p++)
{
if(ua_relplaced < strlen(str_ua_rkp))
*p = str_ua_rkp[ua_relplaced];
else
*p = ' ';
ua_relplaced++;
}
if(rkpp == ua_end_rkpp)
break;
}
// 重新计算校验和
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_modify: skb checksum start.\n");
#endif
for(rkpp = ua_begin_rkpp; rkpp != 0 && rkpp -> prev != ua_end_rkpp; rkpp = rkpp -> next)
rkpPacket_csum(rkpp);
rkpp = rkpp -> next;
}
}