mirror of
https://github.com/CHN-beta/xmurp-ua.git
synced 2026-01-11 01:09:25 +08:00
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
.vscode
|
||||
*.log
|
||||
*.log
|
||||
debug
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
19
src/rkp-ua.c
19
src/rkp-ua.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
15
src/rkpMap.h
Normal 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*);
|
||||
211
src/rkpPacket.h
211
src/rkpPacket.h
@@ -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;
|
||||
}
|
||||
@@ -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*);
|
||||
|
||||
|
||||
818
src/rkpStream.h
818
src/rkpStream.h
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user