⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mprobe_pbuffer.c

📁 LInux BootLoader的说明文档
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
    文件名:mprobe_pbuffer.c
*/

#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
//#include "packet_memory.h"
#include "inet.h"
#include "mprobe_pbuffer.h"

#include "inet.h"

#include "probe_main.h"

//extern packet_array * __packet_buffer ;


extern u_int32_t print_num;


/*  缺省的缓冲区大小    */
#ifndef MPROBE_PBUFFER_DEFAULT_CAPACITY
#define MPROBE_PBUFFER_DEFAULT_CAPACITY 2*KB
#endif          /*  #ifndef MPROBE_PBUFFER_DEFAULT_CAPACITY */


/*****************************************************************************/

/*
    _pbuffer_packet_validate	-	检查数据的合法性并购造packet_t结构
    ->@const uint8_t *	packet	: 采集到的数据封包
    ->@uint16_t			len		:   采集到的数据封包的长度
    ->@time_t			tm		:	数据封包采集时间
    <->@unsigned char *validate	:	是否是因为数据报损坏而无法构造packet_t,是返回1
    !packet_t *					:   构造成功的packet_t结构指针,构造失败或者采集到的数据封包
									不符合要求,将返回NULL
*/
packet_t *
_pbuffer_packet_validate(const uint8_t * packet , uint16_t len ,
	time_t tm ,	unsigned char * validate) ;

/*
    _pbuffer_flush_cache    -   将一个队列的数据加入至另外一个队列
    ->@packets_t  * target_cache    :   被加入的队列
    ->@packets_t *  source_cache    :   加入的队列,该队列将被清空
    !void
*/

void
_pbuffer_flush_cache(packets_t * target_cache , packets_t * source_cache) ;

/*
    _pbuffer_insert_packet      -   将packet_t放入缓冲队列
    ->@pbuffer_t *      pbuffer	:	数据封包缓冲区
    ->@packet_t *   packet		:	用于存放数据封包的结构
    !int						:   放入成功,返回0,否则返回-1
*/

int
_pbuffer_insert_packet(pbuffer_t * pbuffer , packet_t * packet) ;

/*
    _pbuffer_destroy_queue	-	释放缓存数据封包队列
    ->@packets_t *	packets	:   数据封包队列
    !void                                   :   
*/    

void
_pbuffer_destroy_queue(packets_t  * packets) ; 

/*****************************************************************************/

/*
    pbuffer_open        -        打开缓冲区
    ->@unsigned long capacity	:    缓冲区的容量
    !pbuffer_t *				:    缓冲区句柄
*/
void *
pbuffer_open(unsigned long capacity)
{
    pbuffer_t * pbuffer = NULL ;

    if(capacity < MPROBE_PBUFFER_DEFAULT_CAPACITY)
        capacity = MPROBE_PBUFFER_DEFAULT_CAPACITY; 

    pbuffer = malloc(sizeof(pbuffer_t)) ;
    if(pbuffer == NULL){
        return pbuffer ;
    }

	bzero(pbuffer , sizeof(pbuffer_t)) ;

    pbuffer->max_memory = capacity ;
	pbuffer->full_memory = 0 ;

    pthread_mutex_init(&(pbuffer->mutex) , NULL) ;
    pthread_cond_init(&(pbuffer->cond_full)  , NULL) ;
    pthread_cond_init(&(pbuffer->cond_empty) , NULL) ;
    TAILQ_INIT(&(pbuffer->buffer)) ;
    TAILQ_INIT(&(pbuffer->cache)) ;
    TAILQ_INIT(&(pbuffer->prefetch)) ;

    return pbuffer ;
}

/*
	pbuffer_close	-	关闭缓冲区
    ->@void *	pbuffer	:	缓冲区句柄
    !void
*/
void
pbuffer_close(void * pbuffer)
{
    pbuffer_t * tmp = (pbuffer_t *)pbuffer ;

    if(!tmp)
        return;

    /*  释放缓存队列    */
    pthread_mutex_lock(&(tmp->mutex)) ;
    _pbuffer_destroy_queue(&(tmp->buffer)) ;
    _pbuffer_destroy_queue(&(tmp->prefetch)) ;
    _pbuffer_destroy_queue(&(tmp->cache)) ;
    tmp->cache_memory = 0 ;
    tmp->use_memory = 0 ;
    tmp->prefetch_memory = 0 ;
    pthread_mutex_unlock(&(tmp->mutex)) ;

    pthread_mutex_destroy(&(tmp->mutex)) ;
    pthread_cond_destroy(&(tmp->cond_empty)) ;
    pthread_cond_destroy(&(tmp->cond_full)) ;

    free(tmp) ;
    return;

}

/*
    pbuffer_insert_packet   -   将待分析的数据封包放入缓冲区
    ->@pbuffer_t *   pbuffer			:   缓冲区句柄
    ->@const uint8_t *  packet			:   数据封包
    ->@uint16_t len 					:   数据封包长度
    ->@time_t	tm						:	数据封包捕获时间
    !int								:   放入成功,返回0,否则返回-1
*/
int
pbuffer_insert_packet(void  * pbuffer , const uint8_t * packet , uint16_t len , time_t tm)
{
    packet_t *  		p = NULL ;
    pbuffer_t * 		buffer = (pbuffer_t *)pbuffer ;
	unsigned char 		validate = 0 ;

    if(!pbuffer || !packet || !len){
        return -1 ;
    }

    p = _pbuffer_packet_validate(packet , len , tm , &validate) ;


    if(p == NULL){
		if(validate == 0){/*	已经没有空间可以供分配了	*/
			((pbuffer_t *)pbuffer)->full_memory = 1 ;/*	告诉取用数据封包的线程,系统没有空间分配了	*/
			pthread_cond_broadcast(&(((pbuffer_t *)pbuffer)->cond_full)) ;
			struct timespec	tm ;
			bzero(&tm , sizeof(struct timespec)) ;
			tm.tv_nsec = 40000 ;
			nanosleep(&tm , NULL) ;
     	   	return -1 ;
    	}else{
    		return -1 ;
    	}
    }

    return _pbuffer_insert_packet(buffer , p) ;
}

/*
    pbuffer_get_packet  -   从缓冲区中取得采集到的待分析的数据封包
    ->@pbuffer_t * pbuffer	:	缓冲区句柄
    !packet_t *				:	取得的数据包
*/
packet_t *
pbuffer_get_packet(void * pbuffer)
{
    pbuffer_t * buffer = (pbuffer_t *)pbuffer ;
    packet_t * tmp = NULL ;

    assert(pbuffer) ;

    if(buffer->prefetch_memory != 0){/* 预取队列有数据,先从这里取  */
        assert((buffer->prefetch).tqh_first != NULL) ;
		if(buffer->full_memory == 1){/*??*/
			fprintf(stdout , "pbuffer delete all session nodes\n") ;
			buffer->full_memory = 0 ;
		}
        tmp = (buffer->prefetch).tqh_first ;
        TAILQ_REMOVE(&(buffer->prefetch) , tmp , _list) ;
        buffer->prefetch_memory -= tmp->size ;

        assert(buffer->prefetch_memory >= 0) ;
        return tmp ;
    }

    /*  预取队列空了,从缓冲区中取出数据    */
    pthread_mutex_lock(&(buffer->mutex)) ;

    assert(buffer->prefetch_memory == 0) ;
	
    while((buffer->buffer).tqh_first == NULL){
		if(buffer->full_memory == 1){/* ?? */
			fprintf(stdout , "pbuffer delete all session nodes\n") ;
			buffer->full_memory = 0 ;
		}
        pthread_cond_wait(&(buffer->cond_full) , &(buffer->mutex)) ;
	}

    _pbuffer_flush_cache(&(buffer->prefetch) , &(buffer->buffer)) ;
    buffer->prefetch_memory = buffer->use_memory ;
	buffer->use_memory = 0 ;
    	pthread_mutex_unlock(&(buffer->mutex)) ;

	pthread_cond_broadcast(&(buffer->cond_empty)) ;
	

    tmp = (buffer->prefetch).tqh_first ;
    assert(tmp) ;
    TAILQ_REMOVE(&(buffer->prefetch) , tmp , _list) ;
    buffer->prefetch_memory -= tmp->size ;


    return tmp ;
}

/*****************************************************************************/

/*
    _pbuffer_packet_validate	-	检查数据的合法性并购造packet_t结构
    ->@const uint8_t *	packet	: 采集到的数据封包
    ->@uint16_t			len		:   采集到的数据封包的长度
    ->@time_t			tm		:	数据封包采集时间
    <->@unsigned char *validate	:	是否是因为数据报损坏而无法构造packet_t,是返回1
    !packet_t *					:   构造成功的packet_t结构指针,构造失败或者采集到的数据封包
									不符合要求,将返回NULL
*/
packet_t *
_pbuffer_packet_validate(const u_int8_t * packet , u_int16_t len ,
	time_t tm ,	unsigned char * validate)
{
    packet_t * p = NULL ;
    u_int8_t *   ip_packet = NULL ;
    u_int8_t *   t_packet = NULL ;
    u_int16_t    t_len = 0 ;

	assert(validate) ;
    
    if(!packet || !len){
		*validate = 1 ;
        return p ;
    }
	
	if ( len > 1536)
	{
		printf("packet too big len = %d\n", len);
		*validate = 1 ;
		return p;
	}
/*
    if(len < sizeof(struct ether_header) || !ETHER_TYPE_IP(packet))
        return p ;

    if(len < sizeof(struct ether_header) + sizeof(struct ip))
        return p ;


    if(sizeof(struct ether_header) + IP_TOTAL_LEN(ip_packet) != len)
        return p ;
*/
    if ( ETHER_TYPE_IP(packet))
    {
        ip_packet = IP_PACKET(packet) ;
    }else if(ETHER_TYPE_8021Q(packet))
    {
        if(E8021Q_TYPE_IP( E8021Q_PACKET(packet)) ) 
            ip_packet = E8021Q_PACKET(packet) + 4;/* 4 是 802.1q 的头长 */
        else
        {
        *validate = 1 ;
        return p;   
        
        }
    }else
    {
        *validate = 1 ;
        return p;
        }
    
    if(!IP_FRAG_NO(ip_packet)){
        *validate = 1 ;
        return p ;  
    }
    /*  对传输层协议进行判断    */
    if(IP_PROTO_TCP(ip_packet)){/*  TCP数据 */
		struct ether_header * eth = (struct ether_header *)packet ;

        t_packet = ip_packet + IP_HDR_LEN(ip_packet) ;
		t_len = IP_TOTAL_LEN(ip_packet) - IP_HDR_LEN(ip_packet) ;
		if ( t_len > 1500 - 20 || t_len < 20)
		{
	//		printf("tcp packet len error  len = %d\n", t_len);
	//		int i;
	//		for(i=0;i<len;i++)
	//			printf("%02x-",packet[i]);
	//		printf("\n");
			printf("IP_TOTAL_LEN = %d  IP_HDR_LEN = %d\n",IP_TOTAL_LEN(ip_packet), IP_HDR_LEN(ip_packet));
			*validate = 1 ;
			return p;
		}
	
		u_int32_t	tcp_hdr_len;
		tcp_hdr_len = TCP_HDR_LEN(t_packet);
		if ( tcp_hdr_len < 20)
		{
			// printf("tcp_hdr_len error len is %d\n",tcp_hdr_len);
			*validate = 1 ;
			return p;
		}
	
        p = malloc( t_len * sizeof(u_int8_t) + sizeof(packet_t)) ;
        if(p == NULL){
			fprintf(stdout , "malloc memory failed\n") ;
			*validate = 0 ;
            return p ;
        }
		memcpy(p->s_mac , eth->ether_shost , ETH_ALEN) ;
		memcpy(p->d_mac , eth->ether_dhost , ETH_ALEN) ;
        p->size = t_len * sizeof(u_int8_t) + sizeof(packet_t) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -