I solved the problem by adding after the "pcap_compile" and "pcap_setfilter" functions in my callback routine a "pcap_loop" in order to provide again to PCAP the callback address function. I don' understand why the callback address was not set anymore properly. Is it necessary to invoke the pcap_loop function after changing the filter expression ?
Could you also tell me if PCAP may loose some packets during the filter expression change ?
I have attached the code flow (I keep only the interesting part). When the application is starting, the main procedure invoke the scheduler which initialize the PCAP resources by calling "libpcap_startup" (this function calls the several API functions "pcap_open_live,pcap_lookupnet,pcap_compile,pcap_filter...) and then "pcap_loop" by providing the callback address routine ("util_libpcap_callback").
In the callback routine, the filtering expression may be modified (based on some particular criteria. Code not shown) by calling "pcap_compile" and "pcap_setfilter" . It is after that that I needed to invoke a new "pcap_loop" that I don't really understand.
Please, let me know if the sequence is correct ?
Thank you a lot for your help.
Regards,
Alain.
/***************************************************************/
*
* Packet scheduler
*
/***************************************************************/
int util_packet_scheduler ()
{
// initialization code not shown
util_libpcap_startup (main_device_name,
pcap_filter_type);
result = pcap_loop (util_pcap_ptrs.pcap_t_ptr,
-1,
(pcap_handler) util_libpcap_callback,
(u_char *) main_device_name);
return (0);
}
/*************************************************************************
*
* NAME: util_libpcap_startup
*
/*************************************************************************
int util_libpcap_startup (char *device_name_ptr,
int pcap_filter_type)
{
struct bpf_program bpf_pgm;
bpf_u_int32 netp;
bpf_u_int32 maskp;
char * error_text_ptr;
int result;
char errbuf[PCAP_ERRBUF_SIZE];
if (strlen(main_pcap_offline_filename) != NULL)
{
// open the previously saved file containing a packet capture data
util_pcap_ptrs.pcap_t_ptr = pcap_open_offline (main_pcap_offline_filename,errbuf);
if (util_pcap_ptrs.pcap_t_ptr == NULL)
{
sn_error_obj.display_snooper_error(EC_FILE_OPEN_ERROR,errbuf);
}
}
else
{
if (device_name_ptr == NULL)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_LOOKUPDEV_STRING_NAME,errbuf);
sn_error_obj.display_snooper_error(EC_LISTENING_INTERFACE,(char *) device_name_ptr );
// open a network device for packet capture
util_pcap_ptrs.pcap_t_ptr = pcap_open_live (device_name_ptr,IP_DATA_MAX,TRUE,1,errbuf);
if (util_pcap_ptrs.pcap_t_ptr == NULL)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_OPENLIVE_STRING_NAME,errbuf);
// get the network address and subnet mask for the network device
result = pcap_lookupnet (device_name_ptr,&netp,&maskp,errbuf);
if (result == -1)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_LOOKUPNET_STRING_NAME,errbuf);
}
if (main_file_option == TRUE)
{
// Creates a file for writing packet capture data
util_pcap_ptrs.pcap_dump_file_ptr = pcap_dump_open (util_pcap_ptrs.pcap_t_ptr,arg_file_name);
if (util_pcap_ptrs.pcap_dump_file_ptr == NULL)
{
// Error occured during the open
// get the error text from "pcap_geterr
error_text_ptr = pcap_geterr(util_pcap_ptrs.pcap_t_ptr);
sn_error_obj.display_snooper_error(EC_FILE_OPEN_ERROR,error_text_ptr);
}
}
// compile the filter expression into a filter program
working_buffer[0] = '\0';
// filter only on the ones defined for the display
util_libpcap_compute_filter_expression (working_buffer,pcap_filter_type);
result = pcap_compile (util_pcap_ptrs.pcap_t_ptr,&bpf_pgm,working_buffer,TRUE,maskp);
if (result == -1)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_COMPILE_STRING_NAME);
// printf ("The reason may be a configuration issue with the snooper config file \n");
// loads a filter program into a packet capture device
result = pcap_setfilter (util_pcap_ptrs.pcap_t_ptr,&bpf_pgm);
if (result == -1)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_SETFILTER_STRING_NAME);
return (TRUE);
}
/*************************************************************************
*
* NAME: util_pcap_callback
*
*************************************************************************/
void util_libpcap_callback (u_char *user, const struct pcap_pkthdr *header, const u_char *pdata)
{
int result = TRUE;
int packet_type;
int result_1;
struct bpf_program bpf_pgm;
// decode packet ........... Code not shown
// change the filering expression dynamically based upon previous treatment. Code not shown
working_buffer[0] = '\0';
strcat ( working_buffer, new_filter_expression);
result_1 = pcap_compile (util_pcap_ptrs.pcap_t_ptr,&bpf_pgm,working_buffer,TRUE,maskp);
if (result_1 == -1)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_COMPILE_STRING_NAME);
// loads a filter program into a packet capture device
result_1 = pcap_setfilter (util_pcap_ptrs.pcap_t_ptr,&bpf_pgm);
if (result_1 == -1)
sn_error_obj.display_snooper_error(EC_ERROR_FROM_PCAP_LIB,(char *) LIBPCAP_SETFILTER_STRING_NAME);
// Should I need to do that ?????
result = pcap_loop (util_pcap_ptrs.pcap_t_ptr,
-1, // read one packet at a time
(pcap_handler) util_libpcap_callback,
(u_char *) main_device_name);
}
}
At 05:00 PM 12/3/2001 -0800, Guy Harris wrote:
> I am now implementing some new features in my application which requires
> to change dynamically the filtering expression.
> I am invoking in my callback routine the "pcap_compile" and
> "pcap_setfilter" functions in order to modify the filter expression
> dynamically.
> When doing that, the system crashes each time.
On what OS are you doing this?
By "system crashes", do you mean that the application crashes (core
dump), or the entire system crashes (kernel panic/etc.)?
If the entire system crashes, that's a kernel bug; report it to whoever
maintains the OS (or its kernel), and supply a sample program.
If the application crashes, could you show us a stack trace?
