-
void
-
process_tcp(u_char * data, int skblen)
-
{
-
-
struct ip *this_iphdr = (struct ip *)data;
-
/*tcphdr 的头*/
-
struct tcphdr *this_tcphdr = (struct tcphdr *)(data + 4 * this_iphdr->ip_hl);
-
int datalen, iplen;
-
int from_client = 1; /*客户发送数据*/
-
unsigned int tmp_ts;
-
-
/*流分为客户端服务端*/
-
struct tcp_stream *a_tcp;
-
struct half_stream *snd, *rcv;
-
-
ugly_iphdr = this_iphdr;
-
iplen = ntohs(this_iphdr->ip_len);
-
-
if ((unsigned)iplen < 4 * this_iphdr->ip_hl + sizeof(struct tcphdr)) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
} // ktos sie bawi
-
-
-
/*tcp 数据长度*/
-
datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->th_off;
-
-
if (datalen < 0) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
} // ktos sie bawi
-
-
-
-
/*源和目的地址都存在*/
-
-
if ((this_iphdr->ip_src.s_addr | this_iphdr->ip_dst.s_addr) == 0) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
}
-
-
/*如果没有th_ack 包,则进行扫描是否有攻击包*/
-
if (!(this_tcphdr->th_flags & TH_ACK))
-
detect_scan(this_iphdr);
-
/*
-
-
/* 表示有扫描攻击发生 */
-
-
if (!nids_params.n_tcp_streams) return;
-
-
/*tcp 头的长度,iplen -4*this_iphdr->ip_hl, 进行包头的校验*/
-
if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl,
-
this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
-
}
-
-
#if 0
-
check_flags(this_iphdr, this_tcphdr);
-
//ECN
-
-
#endif
-
-
/*查找添加流*/
-
-
/*
-
-
************* 三次握手的第一次握手*****************************************
-
-
*/
-
-
if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) {
-
-
/*是三次握手的第一个包*/
-
/*tcp里流不存在时:且tcp数据包里的(syn=1 && ack==0 && rst==0)时,添加一条tcp流*/
-
/*tcp第一次握手*/
-
if ((this_tcphdr->th_flags & TH_SYN) &&
-
!(this_tcphdr->th_flags & TH_ACK) &&
-
!(this_tcphdr->th_flags & TH_RST))
-
/*并且没有收到th_rest 包*/
-
add_new_tcp(this_tcphdr, this_iphdr);/*节点加入链表中*/
-
-
/*第一次握手完毕返回*/
-
return;
-
}
-
-
-
if (from_client) { /*从client
--> server的包*/
-
snd = &a_tcp->client;
-
rcv = &a_tcp->server;
-
}
-
else {/* server --> client的包 */
-
rcv = &a_tcp->client;
-
snd = &a_tcp->server;
-
}
-
-
-
/**********************************************************************
-
-
三次握手的第二次握手
-
-
************************************************************************/
-
-
/*tcp 三次握手, SYN ==1,ACK==1,tcp第二次握手(server -> client的同步响应)*/
-
if ((this_tcphdr->th_flags & TH_SYN)) {
-
if (from_client || a_tcp->client.state != TCP_SYN_SENT ||
-
a_tcp->server.state != TCP_CLOSE || !(this_tcphdr->th_flags & TH_ACK))
-
return;
-
-
-
/*第二次回应包的ACK 值为第一个包的序列号+1,在初始化的时候已经加一*/
-
if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack))
-
return;
-
-
-
/*第二个包服务端赋值*/
-
/*a_tcp 中服务端赋值,*/
-
-
a_tcp->server.state = TCP_SYN_RECV;
-
a_tcp->server.seq = ntohl(this_tcphdr->th_seq) + 1;
-
a_tcp->server.first_data_seq = a_tcp->server.seq;
-
a_tcp->server.ack_seq = ntohl(this_tcphdr->th_ack);
-
a_tcp->server.window = ntohs(this_tcphdr->th_win);
-
-
-
/*对于tcp 选项的赋值*/
-
//初始化客户端和服务器的时间截
-
-
if (a_tcp->client.ts_on) {
-
a_tcp->server.ts_on = get_ts(this_tcphdr, &a_tcp->server.curr_ts);
-
if (!a_tcp->server.ts_on)
-
a_tcp->client.ts_on = 0;
-
} else a_tcp->server.ts_on = 0;
-
-
-
//初始化窗口大小
-
-
if (a_tcp->client.wscale_on) {
-
a_tcp->server.wscale_on = get_wscale(this_tcphdr, &a_tcp->server.wscale);
-
if (!a_tcp->server.wscale_on) {
-
a_tcp->client.wscale_on = 0;
-
a_tcp->client.wscale = 1;
-
a_tcp->server.wscale = 1;
-
}
-
} else {
-
a_tcp->server.wscale_on = 0;
-
a_tcp->server.wscale = 1;
-
}
-
/*第二次握手完毕,返回*/
-
-
return;
-
}
-
-
-
-
-
-
/*
-
(如果有数据存在或者修列号不等于确认号的)并且
-
-
序列号在窗口之外
-
已经确认过的序号
-
-
*/
-
-
if (
-
! ( !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq )
-
&&
-
-
/*th_seq - (ack_seq+ wscale) > 0 或者th_seq+datalen - ack_sql < 0*/
-
( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) ||
-
before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq)
-
)
-
)
-
return;
-
-
-
-
/*发送th_rst 重新开启一个连接*/
-
if ((this_tcphdr->th_flags & TH_RST)) {
-
/*是tcp 数据*/
-
if (a_tcp->nids_state == NIDS_DATA) {
-
struct lurker_node *i;
-
a_tcp->nids_state = NIDS_RESET;
-
for (i = a_tcp->listeners; i; i = i->next)
-
(i->item) (a_tcp, &i->data);
-
}
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
-
-
-
-
/* PAWS check */
-
if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) &&
-
before(tmp_ts, snd->curr_ts))
-
return;
-
-
-
-
-
-
-
/*
-
**********************************************************************
-
第三次握手包
-
-
**********************************************************************
-
*/
-
-
/*
-
-
-
从client --> server的包
-
-
是从三次握手的第三个包分析开始的,进行一部分数据分析,和初始化
-
连接状态
-
-
*/
-
-
if ((this_tcphdr->th_flags & TH_ACK)) {
-
if (from_client && a_tcp->client.state == TCP_SYN_SENT &&
-
a_tcp->server.state == TCP_SYN_RECV) {
-
if (ntohl(this_tcphdr->th_ack) == a_tcp->server.seq) {
-
a_tcp->client.state = TCP_ESTABLISHED;
-
a_tcp->client.ack_seq = ntohl(this_tcphdr->th_ack);
-
{
-
struct proc_node *i;
-
struct lurker_node *j;
-
void *data;
-
-
a_tcp->server.state = TCP_ESTABLISHED;
-
a_tcp->nids_state = NIDS_JUST_EST;
-
/*开始全双工传输,client server 连接已经建立起来了*/
-
-
/*三次握手tcp ip 连接建立*/
-
for (i = tcp_procs; i; i = i->next) {
-
char whatto = 0;
-
-
char cc = a_tcp->client.collect;
-
char sc = a_tcp->server.collect;
-
char ccu = a_tcp->client.collect_urg;
-
char scu = a_tcp->server.collect_urg;
-
-
/*进入回调函数处理*/
-
-
/*
-
-
如果在相应端口出现
-
-
client.collect ++ ;
-
-
测审计次数据
-
对应用来说tcp 连接已经建立
-
-
*/
-
-
-
(i->item) (a_tcp, &data);
-
-
/**/
-
if (cc < a_tcp->client.collect)
-
whatto |= COLLECT_cc;
-
if (ccu < a_tcp->client.collect_urg)
-
whatto |= COLLECT_ccu;
-
if (sc < a_tcp->server.collect)
-
whatto |= COLLECT_sc;
-
if (scu < a_tcp->server.collect_urg)
-
whatto |= COLLECT_scu;
-
if (nids_params.one_loop_less) {
-
if (a_tcp->client.collect >=2) {
-
a_tcp->client.collect=cc;
-
whatto&=~COLLECT_cc;
-
}
-
if (a_tcp->server.collect >=2 ) {
-
a_tcp->server.collect=sc;
-
whatto&=~COLLECT_sc;
-
}
-
}
-
-
/*加入监听队列,开始数据接收*/
-
if (whatto) {
-
j = mknew(struct lurker_node);
-
j->item = i->item;/*放入监听队列*/
-
j->data = data;
-
j->whatto = whatto;
-
-
j->next = a_tcp->listeners;
-
a_tcp->listeners = j;
-
}
-
-
}
-
-
-
/*不存在监听着*/{
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
if (!a_tcp->listeners)
-
-
a_tcp->nids_state = NIDS_DATA;
-
}
-
}
-
// return;
-
-
}
-
}
-
-
-
-
/*
-
************************************************************
-
-
挥手过程
-
-
*************************************************************
-
-
*/
-
-
/*数据结束的包的判断*/
-
-
if ((this_tcphdr->th_flags & TH_ACK)) {
-
-
-
/* 从数据传输过程不断更新服务器客户端的ack_seq
-
一直到接收到fin 包,数据传输结束
-
-
*/
-
handle_ack(snd, ntohl(this_tcphdr->th_ack));
-
-
if (rcv->state == FIN_SENT)
-
rcv->state = FIN_CONFIRMED;
-
if (rcv->state == FIN_CONFIRMED && snd->state == FIN_CONFIRMED) {
-
struct lurker_node *i;
-
-
a_tcp->nids_state = NIDS_CLOSE;
-
for (i = a_tcp->listeners; i; i = i->next)
-
(i->item) (a_tcp, &i->data);
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
}
-
-
-
/*
-
-
*************************************************************
-
数据处理过程
-
*************************************************************
-
-
*/
-
-
-
-
-
if (datalen + (this_tcphdr->th_flags & TH_FIN) > 0)
-
-
/*
-
-
a_tcp -----a_tcp 客户端连接包
-
this_tcphdr tcp 包头
-
snd-----发送包
-
rcv -----接收包
-
-
(char *) (this_tcphdr) + 4 * this_tcphdr->th_off -----数据包内容
-
datalen---------数据包长度
-
-
-
*/
-
-
tcp_queue(a_tcp, this_tcphdr, snd, rcv,
-
(char *) (this_tcphdr) + 4 * this_tcphdr->th_off,
-
datalen, skblen);
-
-
snd->window = ntohs(this_tcphdr->th_win);
-
-
if (rcv->rmem_alloc > 65535)
-
-
prune_queue(rcv, this_tcphdr);
-
-
if (!a_tcp->listeners)
-
nids_free_tcp_stream(a_tcp);
-
-
-
}
-
void
-
process_tcp(u_char * data, int skblen)
-
{
-
struct ip *this_iphdr = (struct ip *)data;
-
/*tcphdr 的头*/
-
struct tcphdr *this_tcphdr = (struct tcphdr *)(data + 4 * this_iphdr->ip_hl);
-
int datalen, iplen;
-
int from_client = 1; /*客户发送数据*/
-
unsigned int tmp_ts;
-
-
/*流分为客户端服务端*/
-
struct tcp_stream *a_tcp;
-
struct half_stream *snd, *rcv;
-
ugly_iphdr = this_iphdr;
-
iplen = ntohs(this_iphdr->ip_len);
-
-
if ((unsigned)iplen < 4 * this_iphdr->ip_hl + sizeof(struct tcphdr)) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
} // ktos sie bawi
-
-
/*tcp 数据长度*/
-
datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->th_off;
-
-
if (datalen < 0) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
} // ktos sie bawi
-
-
-
/*源和目的地址都存在*/
-
if ((this_iphdr->ip_src.s_addr | this_iphdr->ip_dst.s_addr) == 0) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
}
-
/*如果没有th_ack 包,则进行扫描是否有攻击包*/
-
if (!(this_tcphdr->th_flags & TH_ACK))
-
detect_scan(this_iphdr);
-
/*
-
/* 表示有扫描攻击发生 */
-
-
if (!nids_params.n_tcp_streams) return;
-
-
/*tcp 头的长度,iplen -4*this_iphdr->ip_hl, 进行包头的校验*/
-
if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl,
-
this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) {
-
nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr,
-
this_tcphdr);
-
return;
-
-
}
-
-
#if 0
-
check_flags(this_iphdr, this_tcphdr);
-
//ECN
-
-
#endif
-
/*查找添加流*/
-
/*
-
************* 三次握手的第一次握手*****************************************
-
*/
-
if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) {
-
/*是三次握手的第一个包*/
-
/*tcp里流不存在时:且tcp数据包里的(syn=1 && ack==0 && rst==0)时,添加一条tcp流*/
-
/*tcp第一次握手*/
-
if ((this_tcphdr->th_flags & TH_SYN) &&
-
!(this_tcphdr->th_flags & TH_ACK) &&
-
!(this_tcphdr->th_flags & TH_RST))
-
/*并且没有收到th_rest 包*/
-
add_new_tcp(this_tcphdr, this_iphdr);/*节点加入链表中*/
-
/*第一次握手完毕返回*/
-
return;
-
}
-
-
if (from_client) { /*从client
--> server的包*/
-
snd = &a_tcp->client;
-
rcv = &a_tcp->server;
-
}
-
else {/* server --> client的包 */
-
rcv = &a_tcp->client;
-
snd = &a_tcp->server;
-
}
-
-
/**********************************************************************
-
三次握手的第二次握手
-
-
************************************************************************/
-
/*tcp 三次握手, SYN ==1,ACK==1,tcp第二次握手(server -> client的同步响应)*/
-
if ((this_tcphdr->th_flags & TH_SYN)) {
-
if (from_client || a_tcp->client.state != TCP_SYN_SENT ||
-
a_tcp->server.state != TCP_CLOSE || !(this_tcphdr->th_flags & TH_ACK))
-
return;
-
-
/*第二次回应包的ACK 值为第一个包的序列号+1,在初始化的时候已经加一*/
-
if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack))
-
return;
-
-
-
/*第二个包服务端赋值*/
-
/*a_tcp 中服务端赋值,*/
-
a_tcp->server.state = TCP_SYN_RECV;
-
a_tcp->server.seq = ntohl(this_tcphdr->th_seq) + 1;
-
a_tcp->server.first_data_seq = a_tcp->server.seq;
-
a_tcp->server.ack_seq = ntohl(this_tcphdr->th_ack);
-
a_tcp->server.window = ntohs(this_tcphdr->th_win);
-
-
/*对于tcp 选项的赋值*/
-
//初始化客户端和服务器的时间截
-
-
if (a_tcp->client.ts_on) {
-
a_tcp->server.ts_on = get_ts(this_tcphdr, &a_tcp->server.curr_ts);
-
if (!a_tcp->server.ts_on)
-
a_tcp->client.ts_on = 0;
-
} else a_tcp->server.ts_on = 0;
-
-
//初始化窗口大小
-
-
if (a_tcp->client.wscale_on) {
-
a_tcp->server.wscale_on = get_wscale(this_tcphdr, &a_tcp->server.wscale);
-
if (!a_tcp->server.wscale_on) {
-
a_tcp->client.wscale_on = 0;
-
a_tcp->client.wscale = 1;
-
a_tcp->server.wscale = 1;
-
}
-
} else {
-
a_tcp->server.wscale_on = 0;
-
a_tcp->server.wscale = 1;
-
}
-
/*第二次握手完毕,返回*/
-
-
return;
-
}
-
-
-
-
/*
-
(如果有数据存在或者修列号不等于确认号的)并且
-
序列号在窗口之外
-
已经确认过的序号
-
*/
-
-
if (
-
! ( !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq )
-
&&
-
/*th_seq - (ack_seq+ wscale) > 0 或者th_seq+datalen - ack_sql < 0*/
-
( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) ||
-
before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq)
-
)
-
)
-
return;
-
-
/*发送th_rst 重新开启一个连接*/
-
if ((this_tcphdr->th_flags & TH_RST)) {
-
/*是tcp 数据*/
-
if (a_tcp->nids_state == NIDS_DATA) {
-
struct lurker_node *i;
-
a_tcp->nids_state = NIDS_RESET;
-
for (i = a_tcp->listeners; i; i = i->next)
-
(i->item) (a_tcp, &i->data);
-
}
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
-
-
/* PAWS check */
-
if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) &&
-
before(tmp_ts, snd->curr_ts))
-
return;
-
-
-
-
/*
-
**********************************************************************
-
第三次握手包
-
**********************************************************************
-
*/
-
/*
-
-
从client --> server的包
-
是从三次握手的第三个包分析开始的,进行一部分数据分析,和初始化
-
连接状态
-
*/
-
-
if ((this_tcphdr->th_flags & TH_ACK)) {
-
if (from_client && a_tcp->client.state == TCP_SYN_SENT &&
-
a_tcp->server.state == TCP_SYN_RECV) {
-
if (ntohl(this_tcphdr->th_ack) == a_tcp->server.seq) {
-
a_tcp->client.state = TCP_ESTABLISHED;
-
a_tcp->client.ack_seq = ntohl(this_tcphdr->th_ack);
-
{
-
struct proc_node *i;
-
struct lurker_node *j;
-
void *data;
-
-
a_tcp->server.state = TCP_ESTABLISHED;
-
a_tcp->nids_state = NIDS_JUST_EST;
-
/*开始全双工传输,client server 连接已经建立起来了*/
-
/*三次握手tcp ip 连接建立*/
-
for (i = tcp_procs; i; i = i->next) {
-
char whatto = 0;
-
-
char cc = a_tcp->client.collect;
-
char sc = a_tcp->server.collect;
-
char ccu = a_tcp->client.collect_urg;
-
char scu = a_tcp->server.collect_urg;
-
/*进入回调函数处理*/
-
/*
-
如果在相应端口出现
-
client.collect ++ ;
-
测审计次数据
-
对应用来说tcp 连接已经建立
-
*/
-
-
-
(i->item) (a_tcp, &data);
-
/**/
-
if (cc < a_tcp->client.collect)
-
whatto |= COLLECT_cc;
-
if (ccu < a_tcp->client.collect_urg)
-
whatto |= COLLECT_ccu;
-
if (sc < a_tcp->server.collect)
-
whatto |= COLLECT_sc;
-
if (scu < a_tcp->server.collect_urg)
-
whatto |= COLLECT_scu;
-
if (nids_params.one_loop_less) {
-
if (a_tcp->client.collect >=2) {
-
a_tcp->client.collect=cc;
-
whatto&=~COLLECT_cc;
-
}
-
if (a_tcp->server.collect >=2 ) {
-
a_tcp->server.collect=sc;
-
whatto&=~COLLECT_sc;
-
}
-
}
-
-
/*加入监听队列,开始数据接收*/
-
if (whatto) {
-
j = mknew(struct lurker_node);
-
j->item = i->item;/*放入监听队列*/
-
j->data = data;
-
j->whatto = whatto;
-
-
j->next = a_tcp->listeners;
-
a_tcp->listeners = j;
-
}
-
-
}
-
-
-
/*不存在监听着*/{
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
if (!a_tcp->listeners)
-
-
a_tcp->nids_state = NIDS_DATA;
-
}
-
}
-
// return;
-
-
}
-
}
-
-
/*
-
************************************************************
-
挥手过程
-
*************************************************************
-
*/
-
/*数据结束的包的判断*/
-
if ((this_tcphdr->th_flags & TH_ACK)) {
-
-
/* 从数据传输过程不断更新服务器客户端的ack_seq
-
一直到接收到fin 包,数据传输结束
-
*/
-
handle_ack(snd, ntohl(this_tcphdr->th_ack));
-
-
if (rcv->state == FIN_SENT)
-
rcv->state = FIN_CONFIRMED;
-
if (rcv->state == FIN_CONFIRMED && snd->state == FIN_CONFIRMED) {
-
struct lurker_node *i;
-
a_tcp->nids_state = NIDS_CLOSE;
-
for (i = a_tcp->listeners; i; i = i->next)
-
(i->item) (a_tcp, &i->data);
-
nids_free_tcp_stream(a_tcp);
-
return;
-
}
-
}
-
-
/*
-
*************************************************************
-
数据处理过程
-
*************************************************************
-
*/
-
-
-
-
if (datalen + (this_tcphdr->th_flags & TH_FIN) > 0)
-
/*
-
-
a_tcp -----a_tcp 客户端连接包
-
this_tcphdr tcp 包头
-
snd-----发送包
-
rcv -----接收包
-
(char *) (this_tcphdr) + 4 * this_tcphdr->th_off -----数据包内容
-
datalen---------数据包长度
-
-
*/
-
-
tcp_queue(a_tcp, this_tcphdr, snd, rcv,
-
(char *) (this_tcphdr) + 4 * this_tcphdr->th_off,
-
datalen, skblen);
-
-
snd->window = ntohs(this_tcphdr->th_win);
-
-
if (rcv->rmem_alloc > 65535)
-
-
prune_queue(rcv, this_tcphdr);
-
-
if (!a_tcp->listeners)
-
nids_free_tcp_stream(a_tcp);
-
-
}
-
-
view plaincopy to clipboardprint?
-
//判断 该TCP 数据包是添加到数据区还是添加到list双向链表中
-
-
static void
-
tcp_queue(struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr,
-
struct half_stream * snd, struct half_stream* rcv,
-
char *data, int datalen, int skblen
-
)
-
{
-
-
u_int this_seq = ntohl(this_tcphdr->th_seq);
-
-
struct skbuff *pakiet, *tmp;
-
-
-
/*
-
#define EXP_SEQ (snd->first_data_seq + rcv->count + rcv->urg_count)
-
EXP_SEQ > this_seq
-
*/
-
-
/* 如果EXP_SEQ > = this_seq */
-
/*
-
-
EXP_SEQ 期望到达的数据
-
this_seq 实际到达的数据
-
-
*/
-
-
if ( !after(this_seq, EXP_SEQ) ) {
-
-
/*this_seq + datalen + (this_tcphdr->th_flags & TH_FIN)> EXP_SEQ*/
-
-
-
/*有重叠数据存在(重叠数据怎么处理呢)
-
-
也可能没有重叠数据
-
*/
-
-
if ( after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ) ) {
-
-
/* the packet straddles our window end */
-
get_ts(this_tcphdr, &snd->curr_ts);
-
-
add_from_skb(a_tcp, rcv, snd, data, datalen, this_seq,
-
(this_tcphdr->th_flags & TH_FIN),
-
(this_tcphdr->th_flags & TH_URG),
-
ntohs(this_tcphdr->th_urp) + this_seq - 1);
-
/*
-
* Do we have any old packets to ack that the above
-
* made visible? (Go forward from skb)
-
*/
-
-
-
-
/*从头节点释放节点*/
-
pakiet = rcv->list;
-
while (pakiet) {
-
/*
-
-
期望的序列号小于该包的序列号则直接返回
-
-
*/
-
if (after(pakiet->seq, EXP_SEQ))
-
break;
-
-
/*
-
-
对失序队列数据包的处理
-
-
如果包序列号加上长度还小于期望序列号
-
则把该包添加到数据区,并在失序队列中删除该包
-
-
*/
-
if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) {
-
add_from_skb(a_tcp, rcv, snd, pakiet->data,
-
pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg,
-
pakiet->urg_ptr + pakiet->seq - 1);
-
}
-
rcv->rmem_alloc -= pakiet->truesize;
-
-
/*从头节点释放链表*/
-
-
if (pakiet->prev)
-
pakiet->prev->next = pakiet->next;
-
else
-
rcv->list = pakiet->next;
-
if (pakiet->next)
-
pakiet->next->prev = pakiet->prev;
-
else
-
rcv->listtail = pakiet->prev;
-
tmp = pakiet->next;
-
free(pakiet->data);
-
free(pakiet);
-
pakiet = tmp;
-
}
-
}
-
else
-
return;
-
}
-
-
-
/*提前到达数据的加入失去顺序队列中链表*/
-
-
//序列号大于我们期望的序列号,则把该包添加到list双向链表中
-
-
-
-
/*链表加入节点 */
-
else {
-
-
/*初始化*/
-
struct skbuff *p = rcv->listtail;
-
/*
-
pakiet 加入rcv->listtal 链表中
-
*/
-
/*
-
pakiet 节点的初始化
-
-
*/
-
-
pakiet = mknew(struct skbuff);
-
pakiet->truesize = skblen;
-
rcv->rmem_alloc += pakiet->truesize;
-
-
/*数据包填充pakiet->data 中*/
-
pakiet->len = datalen;
-
pakiet->data = malloc(datalen);
-
if (!pakiet->data)
-
nids_params.no_mem("tcp_queue");
-
memcpy(pakiet->data, data, datalen);
-
-
/*是否是结束包*/
-
pakiet->fin = (this_tcphdr->th_flags & TH_FIN);
-
-
/* Some Cisco - at least - hardware accept to close a TCP connection
-
* even though packets were lost before the first TCP FIN packet and
-
* never retransmitted; this violates RFC 793, but since it really
-
* happens, it has to be dealt with... The idea is to introduce a 10s
-
* timeout after TCP FIN packets were sent by both sides so that
-
* corresponding libnids resources can be released instead of waiting
-
* for retransmissions which will never happen. -- Sebastien Raveau
-
*/
-
/*
-
-
硬件接收一个tcp 终止的链接,
-
即使包在一个结束包的时候丢失,并且不再重传,
-
处理这种方法就是引入时间机制处理
-
-
*/
-
-
if (pakiet->fin) {
-
snd->state = TCP_CLOSING;
-
if (rcv->state == FIN_SENT || rcv->state == FIN_CONFIRMED)
-
add_tcp_closing_timeout(a_tcp);
-
}
-
-
/*
-
-
seq,urg ,urg_ptr 赋值
-
-
*/
-
-
pakiet->seq = this_seq;
-
pakiet->urg = (this_tcphdr->th_flags & TH_URG);
-
pakiet->urg_ptr = ntohs(this_tcphdr->th_urp);
-
-
for (;;) {
-
-
if (!p || !after(p->seq, this_seq))
-
break;
-
p = p->prev;
-
}
-
-
if (!p) {
-
/*建立首节点*/
-
pakiet->prev = 0;
-
pakiet->next = rcv->list;
-
if (rcv->list)
-
rcv->list->prev = pakiet;
-
-
rcv->list = pakiet;
-
if (!rcv->listtail)
-
rcv->listtail = pakiet;
-
}
-
-
/*链表后插入*/
-
else {
-
pakiet->next = p->next;
-
p->next = pakiet;
-
pakiet->prev = p;
-
if (pakiet->next)
-
pakiet->next->prev = pakiet;
-
else
-
rcv->listtail = pakiet;
-
}
-
-
}
-
-
}
-
//判断 该TCP 数据包是添加到数据区还是添加到list双向链表中
-
-
static void
-
tcp_queue(struct tcp_stream * a_tcp, struct tcphdr * this_tcphdr,
-
struct half_stream * snd, struct half_stream* rcv,
-
char *data, int datalen, int skblen
-
)
-
{
-
u_int this_seq = ntohl(this_tcphdr->th_seq);
-
-
struct skbuff *pakiet, *tmp;
-
-
/*
-
#define EXP_SEQ (snd->first_data_seq + rcv->count + rcv->urg_count)
-
EXP_SEQ > this_seq
-
*/
-
/* 如果EXP_SEQ > = this_seq */
-
/*
-
EXP_SEQ 期望到达的数据
-
this_seq 实际到达的数据
-
*/
-
-
if ( !after(this_seq, EXP_SEQ) ) {
-
/*this_seq + datalen + (this_tcphdr->th_flags & TH_FIN)> EXP_SEQ*/
-
-
/*有重叠数据存在(重叠数据怎么处理呢)
-
也可能没有重叠数据
-
*/
-
-
if ( after(this_seq + datalen + (this_tcphdr->th_flags & TH_FIN), EXP_SEQ) ) {
-
-
/* the packet straddles our window end */
-
get_ts(this_tcphdr, &snd->curr_ts);
-
-
add_from_skb(a_tcp, rcv, snd, data, datalen, this_seq,
-
(this_tcphdr->th_flags & TH_FIN),
-
(this_tcphdr->th_flags & TH_URG),
-
ntohs(this_tcphdr->th_urp) + this_seq - 1);
-
/*
-
* Do we have any old packets to ack that the above
-
* made visible? (Go forward from skb)
-
*/
-
-
/*从头节点释放节点*/
-
pakiet = rcv->list;
-
while (pakiet) {
-
/*
-
期望的序列号小于该包的序列号则直接返回
-
*/
-
if (after(pakiet->seq, EXP_SEQ))
-
break;
-
-
/*
-
对失序队列数据包的处理
-
如果包序列号加上长度还小于期望序列号
-
则把该包添加到数据区,并在失序队列中删除该包
-
*/
-
if (after(pakiet->seq + pakiet->len + pakiet->fin, EXP_SEQ)) {
-
add_from_skb(a_tcp, rcv, snd, pakiet->data,
-
pakiet->len, pakiet->seq, pakiet->fin, pakiet->urg,
-
pakiet->urg_ptr + pakiet->seq - 1);
-
}
-
rcv->rmem_alloc -= pakiet->truesize;
-
-
/*从头节点释放链表*/
-
-
if (pakiet->prev)
-
pakiet->prev->next = pakiet->next;
-
else
-
rcv->list = pakiet->next;
-
if (pakiet->next)
-
pakiet->next->prev = pakiet->prev;
-
else
-
rcv->listtail = pakiet->prev;
-
tmp = pakiet->next;
-
free(pakiet->data);
-
free(pakiet);
-
pakiet = tmp;
-
}
-
}
-
else
-
return;
-
}
-
-
/*提前到达数据的加入失去顺序队列中链表*/
-
//序列号大于我们期望的序列号,则把该包添加到list双向链表中
-
-
-
/*链表加入节点 */
-
else {
-
/*初始化*/
-
struct skbuff *p = rcv->listtail;
-
/*
-
pakiet 加入rcv->listtal 链表中
-
*/
-
/*
-
pakiet 节点的初始化
-
-
*/
-
-
pakiet = mknew(struct skbuff);
-
pakiet->truesize = skblen;
-
rcv->rmem_alloc += pakiet->truesize;
-
/*数据包填充pakiet->data 中*/
-
pakiet->len = datalen;
-
pakiet->data = malloc(datalen);
-
if (!pakiet->data)
-
nids_params.no_mem("tcp_queue");
-
memcpy(pakiet->data, data, datalen);
-
/*是否是结束包*/
-
pakiet->fin = (this_tcphdr->th_flags & TH_FIN);
-
-
/* Some Cisco - at least - hardware accept to close a TCP connection
-
* even though packets were lost before the first TCP FIN packet and
-
* never retransmitted; this violates RFC 793, but since it really
-
* happens, it has to be dealt with... The idea is to introduce a 10s
-
* timeout after TCP FIN packets were sent by both sides so that
-
* corresponding libnids resources can be released instead of waiting
-
* for retransmissions which will never happen. -- Sebastien Raveau
-
*/
-
/*
-
硬件接收一个tcp 终止的链接,
-
即使包在一个结束包的时候丢失,并且不再重传,
-
处理这种方法就是引入时间机制处理
-
*/
-
-
if (pakiet->fin) {
-
snd->state = TCP_CLOSING;
-
if (rcv->state == FIN_SENT || rcv->state == FIN_CONFIRMED)
-
add_tcp_closing_timeout(a_tcp);
-
}
-
-
/*
-
-
seq,urg ,urg_ptr 赋值
-
*/
-
-
pakiet->seq = this_seq;
-
pakiet->urg = (this_tcphdr->th_flags & TH_URG);
-
pakiet->urg_ptr = ntohs(this_tcphdr->th_urp);
-
-
for (;;) {
-
-
if (!p || !after(p->seq, this_seq))
-
break;
-
p = p->prev;
-
}
-
-
if (!p) {
-
/*建立首节点*/
-
pakiet->prev = 0;
-
pakiet->next = rcv->list;
-
if (rcv->list)
-
rcv->list->prev = pakiet;
-
-
rcv->list = pakiet;
-
if (!rcv->listtail)
-
rcv->listtail = pakiet;
-
}
-
/*链表后插入*/
-
else {
-
pakiet->next = p->next;
-
p->next = pakiet;
-
pakiet->prev = p;
-
if (pakiet->next)
-
pakiet->next->prev = pakiet;
-
else
-
rcv->listtail = pakiet;
-
}
-
-
}
-
-
}
-
-
view plaincopy to clipboardprint?
-
/*
-
-
分配空间,数据保存rcv->data 中
-
长度为:rcv->count
-
新数据为date
-
长度为datalen
-
-
-
接收到新数据,重新分配空间,要根据收到的数据的大小
-
buffersize重分配的空间
-
*/
-
static void
-
add2buf(struct half_stream * rcv, char *data, int datalen)
-
{
-
-
int toalloc;
-
-
/*datalen + rcv->count - rcv->offset 如果大于buffersize 需要重新分配空间*/
-
-
if (datalen + rcv->count - rcv->offset > rcv->bufsize) {
-
/*如果rcv->data 不存在*/
-
if (!rcv->data) {
-
if (datalen < 2048)
-
toalloc = 4096;
-
else
-
toalloc = datalen * 2;
-
-
/*数据分配空间,bufsize 为分配空间的大小*/
-
rcv->data = malloc(toalloc);
-
rcv->bufsize = toalloc;
-
}
-
/*第一次分配空间,如果空间不够重新分配*/
-
else {
-
-
if (datalen < rcv->bufsize)
-
toalloc = 2 * rcv->bufsize;
-
else
-
toalloc = rcv->bufsize + 2*datalen;
-
-
rcv->data = realloc(rcv->data, toalloc);
-
rcv->bufsize = toalloc;
-
}
-
if (!rcv->data)
-
nids_params.no_mem("add2buf");
-
}
-
-
-
memcpy(rcv->data + rcv->count - rcv->offset, data, datalen);
-
-
rcv->count_new = datalen;
-
-
rcv->count += datalen; /*count
累加为收到的数据之和,从流开始建立*/
-
-
}
-
/*
-
分配空间,数据保存rcv->data 中
-
长度为:rcv->count
-
新数据为date
-
长度为datalen
-
-
接收到新数据,重新分配空间,要根据收到的数据的大小
-
buffersize重分配的空间
-
*/
-
static void
-
add2buf(struct half_stream * rcv, char *data, int datalen)
-
{
-
int toalloc;
-
/*datalen + rcv->count - rcv->offset 如果大于buffersize 需要重新分配空间*/
-
-
if (datalen + rcv->count - rcv->offset > rcv->bufsize) {
-
/*如果rcv->data 不存在*/
-
if (!rcv->data) {
-
if (datalen < 2048)
-
toalloc = 4096;
-
else
-
toalloc = datalen * 2;
-
/*数据分配空间,bufsize 为分配空间的大小*/
-
rcv->data = malloc(toalloc);
-
rcv->bufsize = toalloc;
-
}
-
/*第一次分配空间,如果空间不够重新分配*/
-
else {
-
-
if (datalen < rcv->bufsize)
-
toalloc = 2 * rcv->bufsize;
-
else
-
toalloc = rcv->bufsize + 2*datalen;
-
-
rcv->data = realloc(rcv->data, toalloc);
-
rcv->bufsize = toalloc;
-
}
-
if (!rcv->data)
-
nids_params.no_mem("add2buf");
-
}
-
-
memcpy(rcv->data + rcv->count - rcv->offset, data, datalen);
-
-
rcv->count_new = datalen;
-
-
rcv->count += datalen; /*count
累加为收到的数据之和,从流开始建立*/
-
}
-
view plaincopy to clipboardprint?
-
/*
-
-
通知服务器或者客户端接受数据
-
-
*/
-
-
static void
-
notify(struct tcp_stream * a_tcp, struct half_stream * rcv)
-
{
-
-
/*
-
-
监听节点
-
-
*/
-
struct lurker_node *i, **prev_addr;
-
char mask;
-
-
/*
-
-
紧急数据
-
-
-
*/
-
if (rcv->count_new_urg) {
-
if (!rcv->collect_urg)
-
return;
-
if (rcv == &a_tcp->client)
-
mask = COLLECT_ccu;
-
else
-
mask = COLLECT_scu;
-
-
ride_lurkers(a_tcp, mask);
-
goto prune_listeners;
-
}
-
-
-
/*
-
-
常规数据
-
-
*/
-
-
if (rcv->collect) {
-
if (rcv == &a_tcp->client)
-
mask = COLLECT_cc;
-
else
-
mask = COLLECT_sc;
-
-
/*
-
-
不断读取数据,一直到
-
-
-
读取到数据结束
-
-
*/
-
-
do {
-
int total;
-
-
/*
-
-
a_tcp 为为收到的datalen
-
-
total = dalalen;
-
-
*/
-
a_tcp->read = rcv->count - rcv->offset;
-
total = a_tcp->read;
-
-
/*处理监听节点上报信息*/
-
-
ride_lurkers(a_tcp, mask);
-
-
-
-
-
if (a_tcp->read > total-rcv->count_new)
-
rcv->count_new = total-a_tcp->read;
-
-
if (a_tcp->read > 0) {
-
-
/*
-
已经读过的数据部再读,把没有读的数据放在rcv->data 中,
-
继续循环,hlf->data 指向新数据
-
-
rcv->count_new 为新数据的长度
-
-
-
*/
-
memmove(rcv->data, rcv->data + a_tcp->read, rcv->count - rcv->offset - a_tcp->read);
-
-
/*rcv->ofset 最终== rcv->count */
-
rcv->offset += a_tcp->read;
-
}
-
}while (nids_params.one_loop_less && a_tcp->read>0 && rcv->count_new);
-
// we know that if one_loop_less!=0, we have only one callback to notify
-
-
-
/*
-
-
rcv->count_new 初始化为0
-
-
*/
-
rcv->count_new=0;
-
}
-
-
-
prune_listeners:
-
prev_addr = &a_tcp->listeners;
-
i = a_tcp->listeners;
-
while (i)
-
if (!i->whatto) {
-
*prev_addr = i->next;
-
free(i);
-
i = *prev_addr;
-
}
-
else {
-
prev_addr = &i->next;
-
i = i->next;
-
}
-
-
}
-
/*
-
通知服务器或者客户端接受数据
-
*/
-
static void
-
notify(struct tcp_stream * a_tcp, struct half_stream * rcv)
-
{
-
/*
-
监听节点
-
*/
-
struct lurker_node *i, **prev_addr;
-
char mask;
-
/*
-
紧急数据
-
-
*/
-
if (rcv->count_new_urg) {
-
if (!rcv->collect_urg)
-
return;
-
if (rcv == &a_tcp->client)
-
mask = COLLECT_ccu;
-
else
-
mask = COLLECT_scu;
-
-
ride_lurkers(a_tcp, mask);
-
goto prune_listeners;
-
}
-
-
/*
-
常规数据
-
*/
-
if (rcv->collect) {
-
if (rcv == &a_tcp->client)
-
mask = COLLECT_cc;
-
else
-
mask = COLLECT_sc;
-
/*
-
不断读取数据,一直到
-
-
读取到数据结束
-
*/
-
-
do {
-
int total;
-
/*
-
a_tcp 为为收到的datalen
-
total = dalalen;
-
*/
-
a_tcp->read = rcv->count - rcv->offset;
-
total = a_tcp->read;
-
-
/*处理监听节点上报信息*/
-
ride_lurkers(a_tcp, mask);
-
-
-
-
if (a_tcp->read > total-rcv->count_new)
-
rcv->count_new = total-a_tcp->read;
-
-
if (a_tcp->read > 0) {
-
-
/*
-
已经读过的数据部再读,把没有读的数据放在rcv->data 中,
-
继续循环,hlf->data 指向新数据
-
rcv->count_new 为新数据的长度
-
-
*/
-
memmove(rcv->data, rcv->data + a_tcp->read, rcv->count - rcv->offset - a_tcp->read);
-
/*rcv->ofset 最终== rcv->count */
-
rcv->offset += a_tcp->read;
-
}
-
}while (nids_params.one_loop_less && a_tcp->read>0 && rcv->count_new);
-
// we know that if one_loop_less!=0, we have only one callback to notify
-
-
/*
-
rcv->count_new 初始化为0
-
*/
-
rcv->count_new=0;
-
}
-
-
prune_listeners:
-
prev_addr = &a_tcp->listeners;
-
i = a_tcp->listeners;
-
while (i)
-
if (!i->whatto) {
-
*prev_addr = i->next;
-
free(i);
-
i = *prev_addr;
-
}
-
else {
-
prev_addr = &i->next;
-
i = i->next;
-
}
-
- }
libnids 中tcp流重组代码
最新推荐文章于 2015-05-07 14:42:53 发布