This commit is contained in:
chn
2019-12-26 19:31:20 +08:00
parent bea33f420b
commit 70ca3c6bc8
6 changed files with 77 additions and 149 deletions

View File

@@ -31,26 +31,3 @@ void rkpFree(void* p)
{
kfree(p);
}
time_t now(void)
{
struct timespec* ts = rkpMalloc(sizeof(struct timespec));
time_t rtn;
getnstimeofday(ts);
rtn = ts -> tv_sec;
rkpFree(ts);
#ifdef RKP_DEBUG
printk("now %lu\n", ts -> tv_sec);
#endif
return rtn;
}
#ifdef RKP_DEBUG
void skb_print(struct sk_buff* skb)
{
printk("skb_print:\n");
printk("\tport: %u %u\n", ntohs(tcp_hdr(skb) -> source), ntohs(tcp_hdr(skb) -> dest));
printk("\tseq: %u %u\n", ntohl(tcp_hdr(skb) -> seq), ntohl(tcp_hdr(skb) -> ack_seq));
printk("\tsyn %d ack %d psh %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack, tcp_hdr(skb) -> psh);
}
#endif

View File

@@ -10,8 +10,6 @@ unsigned int hook_funcion(void *priv, struct sk_buff *skb, const struct nf_hook_
static unsigned n_skb_captured = 0, n_skb_captured_lastPrint = 1;
if(crashed)
return NF_ACCEPT;
if(!rkpSettings_capture(skb))
return NF_ACCEPT;
#ifdef RKP_DEBUG
@@ -59,9 +57,7 @@ static int __init hook_init(void)
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]);
#ifdef RKP_DEBUG
printk("str_ua_rkp: %s\n", str_ua_rkp);
#endif
return 0;
}

View File

@@ -12,8 +12,8 @@ struct rkpManager* rkpManager_new(void);
void rkpManager_delete(struct rkpManager*);
int rkpManager_execute(struct rkpManager*, struct sk_buff*); // 处理一个数据包。返回值为 rkpStream_execute 的返回值。
int __rkpManager_execute(struct rkpManager*, struct sk_buff*);
void __rkpManager_refresh(unsigned long); // 清理过时的流
int __rkpManager_execute(struct rkpManager*, struct rkpPacket*);
void __rkpManager_refresh(unsigned long); // 清理长时间不活动的流
void __rkpManager_lock(struct rkpManager*, unsigned long*);
void __rkpManager_unlock(struct rkpManager*, unsigned long);
@@ -24,13 +24,11 @@ struct rkpManager* rkpManager_new(void)
if(rkpm == 0)
return 0;
memset(rkpm -> data, 0, sizeof(struct rkpStream*) * 256);
// 初始化线程锁
spin_lock_init(&rkpm -> lock);
// 注册定时器
init_timer(&rkpm -> timer);
rkpm -> timer.function = __rkpManager_refresh;
rkpm -> timer.data = (unsigned long)rkpm;
rkpm -> timer.expires = jiffies + 600 * HZ;
rkpm -> timer.expires = jiffies + time_keepalive * HZ;
add_timer(&rkpm -> timer);
return rkpm;
}
@@ -44,7 +42,7 @@ void rkpManager_delete(struct rkpManager* rkpm)
struct rkpStream* rkps = rkpm -> data[i];
while(rkps != 0)
{
struct rkpStream *rkps2 = rkps -> next;
struct rkpStream* rkps2 = rkps -> next;
rkpStream_delete(rkps);
rkps = rkps2;
}
@@ -58,55 +56,57 @@ int rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb)
{
unsigned long flag;
int rtn;
struct rkpPacket* rkpp = rkpPacket_new(skb);
__rkpManager_lock(rkpm, &flag);
rtn = __rkpManager_execute(rkpm, skb);
rtn = __rkpManager_execute(rkpm, rkpp);
__rkpManager_unlock(rkpm, flag);
if(rtn == NF_ACCEPT || rtn == NF_DROP)
rkpPacket_delete(rkpp);
return rtn;
}
int __rkpManager_execute(struct rkpManager* rkpm, struct sk_buff* skb)
int __rkpManager_execute(struct rkpManager* rkpm, struct rkpPacket* rkpp)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpManager_execute start.\n");
printk("\tsyn %d ack %d\n", tcp_hdr(skb) -> syn, tcp_hdr(skb) -> ack);
printk("\tsport %d dport %d\n", ntohs(tcp_hdr(skb) -> source), ntohs(tcp_hdr(skb) -> dest));
printk("\tid %d\n", (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF);
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
// 不使用标志位(三次握手)来判断是否该新建一个流,而直接搜索是否有符合条件的流,有就使用,没有就新建
u_int8_t id = (ntohs(tcp_hdr(skb) -> source) + ntohs(tcp_hdr(skb) -> dest)) & 0xFF;
struct rkpStream *rkps, *rkps_new;
for(rkps = rkpm -> data[id]; rkps != 0; rkps = rkps -> next)
if(rkpStream_belongTo(rkps, skb))
// 搜索是否有符合条件的流
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, skb);
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(skb);
rkps_new = rkpStream_new(rkpp);
if(rkps_new == 0)
return NF_ACCEPT;
if(rkpm -> data[id] == 0)
if(rkpm -> data[rkpp -> sid] == 0)
{
rkpm -> data[id] = rkps_new;
#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
{
rkpm -> data[id] -> prev = rkps_new;
rkps_new -> next = rkpm -> data[id];
rkpm -> data[id] = rkps_new;
#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);
}
@@ -115,7 +115,7 @@ void __rkpManager_refresh(unsigned long param)
{
unsigned i;
unsigned long flag;
struct rkpManager* rkpm = (struct rkpManager*)param;
struct rkpManager*& rkpm = (struct rkpManager*)param;
#ifdef RKP_DEBUG
printk("__rkpManager_refresh start.\n");
#endif
@@ -142,6 +142,8 @@ void __rkpManager_refresh(unsigned long param)
rkps = rkps -> next;
}
}
rkpm -> timer.expires = jiffies + time_keepalive * HZ;
add_timer(&rkpm -> timer);
__rkpManager_unlock(rkpm, flag);
#ifdef RKP_DEBUG
printk("__rkpManager_refresh end.\n");

View File

@@ -6,6 +6,8 @@ struct rkpPacket
{
struct rkpPacket *prev, *next;
struct sk_buff* skb;
u_int8_t sid;
u_int32_t lid[3];
};
struct rkpPacket* rkpPacket_new(struct sk_buff*);
@@ -18,64 +20,46 @@ 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*);
void rkpPacket_csum(struct rkpPacket*);
bool rkpPacket_makeWriteable(struct rkpPacket*);
struct rkpPacket* rkpPacket_new(struct sk_buff* skb)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_new start.\n");
#endif
struct rkpPacket* p = rkpMalloc(sizeof(struct rkpPacket));
if(p != 0)
{
p -> prev = p -> next = 0;
p -> skb = skb;
}
else
printk("rkp-ua: rkpPacket_new: malloc failed.\n");
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_new end.\n");
#endif
struct rkpPacket* rkpp = rkpMalloc(sizeof(struct rkpPacket));
if(rkpp == 0)
return 0;
rkpp -> prev = rkpp -> next = 0;
rkpp -> skb = skb;
rkpp -> sid = (rkpPacket_sport(rkpp) + rkpPacket_dport(rkpp)) & 0xFF;
rkpp -> lid[0] = rkpPacket_sip(rkpp);
rkpp -> lid[1] = rkpPacket_dip(rkpp);
rkpp -> lid[2] = (rkpPacket_sport(rkpp) << 16) + rkpPacket_dport(rkpp);
return p;
}
void rkpPacket_send(struct rkpPacket* p)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_send start.\n");
#endif
if(dev_queue_xmit(p -> skb))
{
printk("rkp-ua: rkpPacket_new: Send failed. Drop it.\n");
kfree_skb(p -> skb);
}
rkpFree(p);
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_send end.\n");
#endif
}
void rkpPacket_delete(struct rkpPacket* p)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_delete start.\n");
#endif
rkpFree(p);
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_delete end.\n");
#endif
}
void rkpPacket_drop(struct rkpPacket* p)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_drop start.\n");
#endif
kfree_skb(p -> skb);
rkpFree(p);
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_drop end.\n");
#endif
}
unsigned char* rkpPacket_appBegin(struct rkpPacket* p)
@@ -98,16 +82,33 @@ int32_t rkpPacket_ack(struct rkpPacket* p)
{
return ntohl(tcp_hdr(p -> skb) -> ack);
}
u_int32_t rkpPacket_sip(struct rkpPacket* rkpp)
{
return ntohl(ip_hdr(rkpp -> skb) -> saddr);
}
u_int32_t rkpPacket_dip(struct rkpPacket* rkpp)
{
return ntohl(ip_hdr(rkpp -> skb) -> daddr);
}
u_int16_t rkpPacket_sport(struct rkpPacket* rkpp)
{
return ntohs(tcp_hdr(rkpp -> skb) -> source);
}
u_int32_t rkpPacket_dport(struct rkpPacket* rkpp)
{
return ntohs(tcp_hdr(rkpp -> skb) -> dest);
}
bool rkpPacket_psh(struct rkpPacket* rkpp)
{
return tcp_hdr(rkpp -> skb) -> psh;
}
bool rkpPacket_syn(struct rkpPacket* rkpp)
{
return tcp_hdr(rkpp -> skb) -> syn;
}
void rkpPacket_csum(struct rkpPacket* p)
{
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_csum start.\n");
#endif
struct iphdr* iph = ip_hdr(p -> skb);
struct tcphdr* tcph = tcp_hdr(p -> skb);
tcph -> check = 0;
@@ -115,9 +116,6 @@ void rkpPacket_csum(struct rkpPacket* p)
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);
#ifdef RKP_DEBUG
printk("rkp-ua: rkpPacket_csum end.\n");
#endif
}
bool rkpPacket_makeWriteable(struct rkpPacket* rkpp)

View File

@@ -1,6 +1,9 @@
#pragma once
#include "common.h"
_Static_assert(sizeof(int) == 4, "int is not 4 bit.");
_Static_assert(sizeof(unsigned long) >= sizeof(void*), "ulong is too short.");
static bool autocapture = true;
module_param(autocapture, bool, 0);
@@ -8,31 +11,18 @@ static char* str_preserve[128];
static unsigned n_str_preserve = 0;
module_param_array(str_preserve, charp, &n_str_preserve, 0);
_Static_assert(sizeof(int) == 4, "int is not 4 bit.");
static unsigned mark_capture = 0x100;
module_param(mark_capture, uint, 0);
static unsigned mark_first = 0x200;
module_param(mark_first, uint, 0);
static unsigned time_keepalive = 1200;
module_param(time_keepalive, uint, 0);
bool rkpSettings_capture(const struct sk_buff*);
bool rkpSettings_first(const struct sk_buff*);
bool rkpSettings_capture(const struct sk_buff* skb)
{
#ifdef RKP_DEBUG
// if(ntohl(ip_hdr(skb) -> daddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192 && ntohl(ip_hdr(skb) -> saddr) != (216 << 24) + (24 << 16) + (178 << 8) + 192)
// return false;
#endif
if(!autocapture)
{
#ifdef RKP_DEBUG
printk("\tadvanced return %d", (skb -> mark & mark_capture) == mark_capture);
#endif
return (skb -> mark & mark_capture) == mark_capture;
}
else
@@ -47,11 +37,4 @@ bool rkpSettings_capture(const struct sk_buff* skb)
else
return true;
}
}
bool rkpSettings_first(const struct sk_buff* skb)
{
if(!autocapture)
return (skb -> mark & mark_first) == mark_first;
else
return tcp_hdr(skb) -> syn && !tcp_hdr(skb) -> ack;
}

View File

@@ -7,18 +7,20 @@ struct rkpStream
{
enum
{
__rkpStream_sniffing,
__rkpStream_waiting
__rkpStream_sniffing_end, // 正在寻找 http 头的结尾或者 ua 的开始,这时 buff_scan 中不应该有包
__rkpStream_sniffing_ua, // 已经找到 ua正在寻找它的结尾buff_scan 中可能有包
__rkpStream_waiting // 已经找到 ua 的结尾或者 http 头的结尾并且还没有 psh接下来的包都直接放行
} status;
u_int32_t id[3]; // 按顺序存储客户地址、服务地址、客户端口、服务端口,已经转换字节序
struct rkpPacket *buff_scan, *buff_disordered; // 分别存储准备扫描的、因乱序而提前收到的数据包,都按照字节序排好了
struct rkpPacket *buff_scan, *buff_disordered; // 分别存储准备扫描的、因乱序而提前收到的数据包,都按照序排好了
u_int32_t seq_offset; // 序列号的偏移。使得 buff_scan 中第一个字节的编号为零。
bool active; // 是否仍然活动,超过一定时间不活动的流会被销毁
unsigned scan_matched; // 记录现在已经匹配了多少个字节
unsigned scan_httpEnd_matched, scan_uaBegin_matched, scan_uaEnd_matched; // 记录现在已经匹配了多少个字节
unsigned char *scan_uaBegin_p, *scan_uaEnd_p; // 在扫描到相关信息后,将信息填写到这里
struct rkpStream *prev, *next;
};
struct rkpStream* rkpStream_new(const struct sk_buff*); // 由三次握手的第一个包构造一个 rkpSteam
struct rkpStream* rkpStream_new(const struct sk_buff*); // 构造一个 rkpSteam
void rkpStream_delete(struct rkpStream*);
bool rkpStream_belongTo(const struct rkpStream*, const struct sk_buff*); // 判断一个数据包是否属于一个流
@@ -28,10 +30,9 @@ int32_t __rkpStream_seq_scanEnd(struct rkpStream*); // 返回 buff_scan
void __rkpStream_insert_auto(struct rkpStream*, struct rkpPacket**, struct rkpPacket*); // 在指定链表中插入一个节点
void __rkpStream_insert_end(struct rkpStream*, struct rkpPacket**, struct rkpPacket*);
struct rkpPacket* __rkpStream_pop_end(struct rkpStream*, struct rkpPacket**);
bool __rkpStream_scan(struct rkpStream*, struct rkpPacket*); // 在包的应用层搜索 ua 头的结尾
void __rkpStream_modify(struct rkpStream*); // 在已经收集到完整的 HTTP 头后,调用去按规则修改 buff_scan 中的包
bool __rkpStream_scan(struct rkpStream*, struct rkpPacket*); // 对一个最新的包进行扫描
void __rkpStream_modify(struct rkpStream*); // 在收集到完整的 ua 后,对 ua 进行修改
struct rkpStream* rkpStream_new(const struct sk_buff* skb)
{
@@ -39,19 +40,15 @@ struct rkpStream* rkpStream_new(const struct sk_buff* skb)
printk("rkp-ua: rkpStream_new start.\n");
#endif
struct rkpStream* rkps = rkpMalloc(sizeof(struct rkpStream));
const struct iphdr* iph = ip_hdr(skb);
const struct tcphdr* tcph = tcp_hdr(skb);
struct rkpPacket* rkpp = rkpPacket_new(skb);
if(rkps == 0)
{
printk("rkp-ua: rkpStream_new: malloc failed, may caused by shortage of memory.\n");
return 0;
}
rkps -> status = __rkpStream_sniffing;
rkps -> status = __rkpStream_sniffing_end;
rkps -> id[0] = ntohl(iph -> saddr);
rkps -> id[1] = ntohl(iph -> daddr);
rkps -> id[2] = (((u_int32_t)ntohs(tcph -> source)) << 16) + ntohs(tcph -> dest);
rkps -> buff_scan = rkps -> buff_disordered = 0;
rkps -> seq_offset = ntohl(tcp_hdr(skb) -> seq) + 1;
rkps -> seq_offset = ntohl(tcp_hdr(skb) -> seq);
rkps -> active = true;
rkps -> scan_matched = 0;
rkps -> prev = rkps -> next = 0;
@@ -398,31 +395,6 @@ void __rkpStream_insert_end(struct rkpStream* rkps, struct rkpPacket** buff, str
printk("rkp-ua: __rkpStream_insert_end end.\n");
#endif
}
struct rkpPacket* __rkpStream_pop_end(struct rkpStream* rkps, struct rkpPacket** buff)
{
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_pop_end start.\n");
#endif
if(*buff == 0)
{
printk("__rkpStream_pop_end: pop from an empty list.\n");
return 0;
}
else
{
struct rkpPacket* rkpp;
for(rkpp = *buff; rkpp -> next != 0; rkpp = rkpp -> next);
if(rkpp -> prev == 0)
*buff = 0;
else
rkpp -> prev = rkpp -> prev -> next = 0;
return rkpp;
}
#ifdef RKP_DEBUG
printk("rkp-ua: __rkpStream_insert_end end.\n");
#endif
}
bool __rkpStream_scan(struct rkpStream* rkps, struct rkpPacket* rkpp)
{