/* * Author: Yasunori Nakazawa, Yasunobu Chiba * * Copyright (C) 2008-2012 NEC Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "pcap_private.h" #include "pcap_queue.h" #include "queue.h" #include "trema.h" static int QUEUE_LIMIT = 65536; static queue *packet_queue = NULL; bool create_pcap_queue( void ) { assert( packet_queue == NULL ); packet_queue = create_queue(); if ( packet_queue == NULL ) { return false; } return true; } bool delete_pcap_queue( void ) { assert( packet_queue != NULL ); bool ret = delete_queue( packet_queue ); if ( !ret ) { return false; } return true; } buffer * create_pcap_packet( void *pcap_header, size_t pcap_len, void *dump_header, size_t dump_len, void *data, size_t data_len ) { size_t length = pcap_len + dump_len + data_len; assert( length != 0 ); assert( pcap_header != NULL && dump_header != NULL ); buffer *buf = alloc_buffer_with_length( length ); assert( buf != NULL ); if ( pcap_header != NULL && pcap_len > 0 ) { void *d = append_back_buffer( buf, pcap_len ); assert( d != NULL ); memcpy( d, pcap_header, pcap_len ); } if ( dump_header != NULL && dump_len > 0 ) { void *d = append_back_buffer( buf, dump_len ); assert( d != NULL ); memcpy( d, dump_header, dump_len ); } if ( data != NULL && data_len > 0 ) { void *d = append_back_buffer( buf, data_len ); assert( d != NULL ); memcpy( d, data, data_len ); } return buf; } bool delete_pcap_packet( buffer *packet ) { assert( packet != NULL ); free_buffer( packet ); return true; } queue_status enqueue_pcap_packet( buffer *packet ) { if ( packet_queue->length >= QUEUE_LIMIT ) { return QUEUE_FULL; } enqueue( packet_queue, packet ); return QUEUE_SUCCESS; } queue_status peek_pcap_packet( buffer **packet ) { assert( packet != NULL ); if ( packet_queue == NULL ) { return QUEUE_EMPTY; } *packet = peek( packet_queue ); if ( *packet == NULL ) { return QUEUE_EMPTY; } return QUEUE_SUCCESS; } queue_status dequeue_pcap_packet( buffer **packet ) { assert( packet != NULL ); if ( packet_queue == NULL ) { return QUEUE_EMPTY; } *packet = dequeue( packet_queue ); if ( *packet == NULL ) { return QUEUE_EMPTY; } return QUEUE_SUCCESS; } static bool compare_timestamp( const buffer *x, const buffer *y ) { struct pcap_pkthdr_private *px = x->data; struct pcap_pkthdr_private *py = y->data; if ( ( px->ts.tv_sec > py->ts.tv_sec ) || ( px->ts.tv_sec == py->ts.tv_sec && px->ts.tv_usec > py->ts.tv_usec ) ) { return true; } return false; } bool sort_pcap_queue( void ) { assert( packet_queue != NULL ); return sort_queue( packet_queue, compare_timestamp ); } void set_max_pcap_queue_length( int length ) { assert( length >= 0 ); QUEUE_LIMIT = length; } int get_pcap_queue_length( void ) { assert( packet_queue != NULL ); return packet_queue->length; } void foreach_pcap_queue( void function( buffer *data ) ) { assert( packet_queue != NULL ); foreach_queue( packet_queue, function ); } /* * Local variables: * c-basic-offset: 2 * indent-tabs-mode: nil * End: */