怎么利用libnids tcp重组的数据重组

博客访问: 2895909
博文数量: 102
博客积分: 3189
博客等级: 中校
技术积分: 4225
注册时间:
认证徽章:
出没于杭州和青岛的程序猿一枚,对内核略懂一二
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
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;
&&check_flags(this_iphdr, this_tcphdr);
/*查找添加流*/
&&&&************* 三次握手的第一次握手*****************************************
&&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;
&&&&&&&&&&&&&&&&(如果有数据存在或者修列号不等于确认号的)并且
&&&&&&&&序列号在窗口之外
&&&&&&&&已经确认过的序号
&&&&! ( !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))
&&&&**********************************************************************
&&&&&&&&&&&&&&&&&&&&&&&&第三次握手包
&&&&**********************************************************************
&&从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;
************************************************************
&&&&&&&&&&&&&&&&挥手过程
*************************************************************
/*数据结束的包的判断*/
&&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);
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;
&&check_flags(this_iphdr, this_tcphdr);
/*查找添加流*/
&************* 三次握手的第一次握手*****************************************
&&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;
&&&&&&&&&&&&&&&&(如果有数据存在或者修列号不等于确认号的)并且
&&序列号在窗口之外
&&&已经确认过的序号
&&&! ( !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))
&**********************************************************************
&&&&&&第三次握手包
&**********************************************************************
&&从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;
************************************************************
&&&&挥手过程
*************************************************************
/*数据结束的包的判断*/
&&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;
&&&&&&rcv->list = pakiet->next;
&&&&if (pakiet->next)
&&&&&&pakiet->next->prev = pakiet->prev;
&&&&&&rcv->listtail = pakiet->prev;
&&&&tmp = pakiet->next;
&&&&free(pakiet->data);
&&&&free(pakiet);
&&&&pakiet = tmp;
&&&&&&return;
/*提前到达数据的加入失去顺序队列中链表*/
//序列号大于我们期望的序列号,则把该包添加到list双向链表中
&&/*链表加入节点 */
&&&&/*初始化*/
&&&&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
&&&&&* 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))
&对失序队列数据包的处理
&&&&如果包序列号加上长度还小于期望序列号
&&&&则把该包添加到数据区,并在失序队列中删除该包
&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;
&&&rcv->list = pakiet->next;
&if (pakiet->next)
&&&pakiet->next->prev = pakiet->prev;
&&&rcv->listtail = pakiet->prev;
&tmp = pakiet->next;
&free(pakiet->data);
&free(pakiet);
&pakiet = tmp;
&&&&&&return;
/*提前到达数据的加入失去顺序队列中链表*/
//序列号大于我们期望的序列号,则把该包添加到list双向链表中
&&/*链表加入节点 */
&&&&/*初始化*/
&&&&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
&&&&&* 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))
&&&&&&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;
&&&&&&mask = COLLECT_scu;
&&&&ride_lurkers(a_tcp, mask);
&&&&goto prune_listeners;
&&if (rcv->collect) {
&&&&if (rcv == &a_tcp->client)
&&&&&&mask = COLLECT_cc;
&&&&&&mask = COLLECT_sc;
&&不断读取数据,一直到
&&读取到数据结束
&&&&&&&&&&&&int total;
&&&&&&&&/*
&&&&&&&&&&&&a_tcp 为为收到的datalen
&&&&&&&&&&&&total =
&&&&&&&&*/
&&&&&&&&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;
&&&&&&mask = COLLECT_scu;
&&&&ride_lurkers(a_tcp, mask);
&&&&goto prune_listeners;
&&if (rcv->collect) {
&&&&if (rcv == &a_tcp->client)
&&&&&&mask = COLLECT_cc;
&&&&&&mask = COLLECT_sc;
&&不断读取数据,一直到
&&读取到数据结束
&&&&&&&&&int total;
&&&a_tcp 为为收到的datalen
&&&total =
&&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;
阅读(8021) | 评论(0) | 转发(2) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 libnids获取udp数据包 的文章

 

随机推荐