@@ -128,14 +128,14 @@ namespace pcpp
128128#endif
129129 }
130130
131- static bool isTimestampProviderSupportedByDevice (pcap_t * pcap,
131+ static bool isTimestampProviderSupportedByDevice (const internal::PcapHandle& pcap,
132132 const PcapLiveDevice::TimestampProvider timestampProvider)
133133 {
134134#ifdef HAS_TIMESTAMP_TYPES_ENABLED
135135 const auto tstampType = getPcapTimestampProvider (timestampProvider);
136136
137137 int * supportedTstampTypesRaw;
138- const int numSupportedTstampTypes = pcap_list_tstamp_types (pcap, &supportedTstampTypesRaw);
138+ const int numSupportedTstampTypes = pcap_list_tstamp_types (pcap. get () , &supportedTstampTypesRaw);
139139
140140 struct TimestampTypesDeleter
141141 {
@@ -150,7 +150,7 @@ namespace pcpp
150150 if (numSupportedTstampTypes < 0 )
151151 {
152152 PCPP_LOG_ERROR (" Error retrieving timestamp types - default 'Host' will be used, error message: "
153- << pcap_geterr ( pcap) << " '" );
153+ << pcap. getLastError ( ) << " '" );
154154 return false ;
155155 }
156156
@@ -161,53 +161,50 @@ namespace pcpp
161161#endif
162162 }
163163
164- static void setTimestampProvider (pcap_t * pcap, const PcapLiveDevice::TimestampProvider timestampProvider)
164+ static void setTimestampProvider (internal::PcapHandle& pcap,
165+ const PcapLiveDevice::TimestampProvider timestampProvider)
165166 {
166167#ifdef HAS_TIMESTAMP_TYPES_ENABLED
167- if (isTimestampProviderSupportedByDevice (pcap, timestampProvider))
168+ if (! isTimestampProviderSupportedByDevice (pcap, timestampProvider))
168169 {
169- const int ret = pcap_set_tstamp_type (pcap, getPcapTimestampProvider (timestampProvider));
170- if (ret == 0 )
171- {
172- PCPP_LOG_DEBUG (" Timestamp provider was set" );
173- }
174- else
175- {
176- PCPP_LOG_ERROR (" Failed to set timestamping provider: '" << ret << " ', error message: '"
177- << pcap_geterr (pcap) << " '" );
178- }
170+ throw std::runtime_error (" Selected timestamping provider is not supported" );
179171 }
180- else
172+
173+ const int ret = pcap_set_tstamp_type (pcap.get (), getPcapTimestampProvider (timestampProvider));
174+ if (ret != 0 )
181175 {
182- PCPP_LOG_ERROR ( " Selected timestamping provider is not supported " );
176+ throw std::runtime_error ( " Cannot create the pcap device, error was: " + std::string (pcap. getLastError ()) );
183177 }
178+
184179#else
185- PCPP_LOG_ERROR (" Error setting timestamp provider - it is available only from libpcap 1.2" );
180+ throw std::runtime_error (" Error setting timestamp provider - it is available only from libpcap 1.2" );
186181#endif
187182 }
188183
189- static void setTimestampPrecision (pcap_t * pcap, const PcapLiveDevice::TimestampPrecision timestampPrecision)
184+ static void setTimestampPrecision (const internal::PcapHandle& pcap,
185+ const PcapLiveDevice::TimestampPrecision timestampPrecision)
190186 {
191187#ifdef HAS_TIMESTAMP_PRECISION_ENABLED
192- const int ret = pcap_set_tstamp_precision (pcap, getPcapPrecision (timestampPrecision));
193- if (ret == 0 )
188+ const int ret = pcap_set_tstamp_precision (pcap.get (), getPcapPrecision (timestampPrecision));
189+ switch (ret)
190+ {
191+ case 0 :
194192 {
195- PCPP_LOG_DEBUG (" Timestamp precision was set" );
196193 return ;
197194 }
198-
199- if (ret == PCAP_ERROR_TSTAMP_PRECISION_NOTSUP)
195+ case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:
200196 {
201- PCPP_LOG_ERROR (
197+ throw std::runtime_error (
202198 " Failed to set timestamping precision: the capture device does not support the requested precision" );
203199 }
204- else
200+ default :
205201 {
206- PCPP_LOG_ERROR (" Failed to set timestamping precision: '" << ret << " ', error message: '"
207- << pcap_geterr (pcap) << " '" );
202+ throw std::runtime_error (" Failed to set timestamping precision, error was: " +
203+ std::string (pcap.getLastError ()));
204+ }
208205 }
209206#else
210- PCPP_LOG_ERROR (" Error setting timestamp precision - it is available only from libpcap 1.5" );
207+ throw std::runtime_error (" Error setting timestamp precision - it is available only from libpcap 1.5" );
211208#endif
212209 }
213210
@@ -379,7 +376,7 @@ namespace pcpp
379376 PCPP_LOG_DEBUG (" Ended stats thread for device '" << m_InterfaceDetails.name << " '" );
380377 }
381378
382- pcap_t * PcapLiveDevice::doOpen (const DeviceConfiguration& config)
379+ internal::PcapHandle PcapLiveDevice::doOpen (const DeviceConfiguration& config)
383380 {
384381 char errbuf[PCAP_ERRBUF_SIZE] = { ' \0 ' };
385382 std::string device_name = m_InterfaceDetails.name ;
@@ -389,49 +386,45 @@ namespace pcpp
389386 device_name += " :" + std::to_string (config.nflogGroup & 0xffff );
390387 }
391388
392- pcap_t * pcap = pcap_create (device_name.c_str (), errbuf);
389+ auto pcap = internal::PcapHandle ( pcap_create (device_name.c_str (), errbuf) );
393390 if (!pcap)
394391 {
395- PCPP_LOG_ERROR (errbuf);
396- return pcap;
392+ throw std::runtime_error (" Cannot create the pcap device, error was: " + std::string (errbuf));
397393 }
398- int ret = pcap_set_snaplen (pcap, config.snapshotLength <= 0 ? DEFAULT_SNAPLEN : config.snapshotLength );
394+
395+ int ret = pcap_set_snaplen (pcap.get (), config.snapshotLength <= 0 ? DEFAULT_SNAPLEN : config.snapshotLength );
399396 if (ret != 0 )
400397 {
401- PCPP_LOG_ERROR ( pcap_geterr (pcap));
398+ throw std::runtime_error ( " Cannot set snaplan, error was: " + std::string (pcap. getLastError () ));
402399 }
403- ret = pcap_set_promisc (pcap, config.mode );
400+
401+ ret = pcap_set_promisc (pcap.get (), config.mode );
404402 if (ret != 0 )
405403 {
406- PCPP_LOG_ERROR ( pcap_geterr (pcap));
404+ throw std::runtime_error ( " Cannot set promiscuous mode, error was: " + std::string (pcap. getLastError () ));
407405 }
408406
409407 int timeout = (config.packetBufferTimeoutMs <= 0 ? LIBPCAP_OPEN_LIVE_TIMEOUT : config.packetBufferTimeoutMs );
410- ret = pcap_set_timeout (pcap, timeout);
408+ ret = pcap_set_timeout (pcap. get () , timeout);
411409 if (ret != 0 )
412410 {
413- PCPP_LOG_ERROR ( pcap_geterr (pcap));
411+ throw std::runtime_error ( " Cannot set timeout on device, error was: " + std::string (pcap. getLastError () ));
414412 }
415413
416414 if (config.packetBufferSize >= 100 )
417415 {
418- ret = pcap_set_buffer_size (pcap, config.packetBufferSize );
416+ ret = pcap_set_buffer_size (pcap. get () , config.packetBufferSize );
419417 if (ret != 0 )
420418 {
421- PCPP_LOG_ERROR ( pcap_geterr (pcap));
419+ throw std::runtime_error ( " Cannot set buffer size, error was: " + std::string (pcap. getLastError () ));
422420 }
423421 }
424422
425423#ifdef HAS_PCAP_IMMEDIATE_MODE
426- ret = pcap_set_immediate_mode (pcap, 1 );
427- if (ret == 0 )
428- {
429- PCPP_LOG_DEBUG (" Immediate mode is activated" );
430- }
431- else
424+ ret = pcap_set_immediate_mode (pcap.get (), 1 );
425+ if (ret != 0 )
432426 {
433- PCPP_LOG_ERROR (" Failed to activate immediate mode, error code: '" << ret << " ', error message: '"
434- << pcap_geterr (pcap) << " '" );
427+ throw std::runtime_error (" Cannot set immediate mode, error was: " + std::string (pcap.getLastError ()));
435428 }
436429#endif
437430
@@ -445,53 +438,52 @@ namespace pcpp
445438 setTimestampPrecision (pcap, config.timestampPrecision );
446439 }
447440
448- ret = pcap_activate (pcap);
441+ ret = pcap_activate (pcap. get () );
449442 if (ret != 0 )
450443 {
451- PCPP_LOG_ERROR (pcap_geterr (pcap));
452- pcap_close (pcap);
453- return nullptr ;
444+ throw std::runtime_error (" Cannot activate the device, error was: " + std::string (pcap.getLastError ()));
454445 }
455446
456- pcap_direction_t directionToSet = directionTypeMap (config.direction );
457- ret = pcap_setdirection (pcap, directionToSet);
458- if (ret == 0 )
447+ if (config.direction != PCPP_INOUT)
459448 {
460- if (config.direction == PCPP_IN)
461- {
462- PCPP_LOG_DEBUG (" Only incoming traffics will be captured" );
463- }
464- else if (config.direction == PCPP_OUT)
465- {
466- PCPP_LOG_DEBUG (" Only outgoing traffics will be captured" );
467- }
468- else
449+ pcap_direction_t directionToSet = directionTypeMap (config.direction );
450+ ret = pcap_setdirection (pcap.get (), directionToSet);
451+ if (ret != 0 )
469452 {
470- PCPP_LOG_DEBUG (" Both incoming and outgoing traffics will be captured" );
453+ throw std::runtime_error (" Failed to set direction for capturing packets, error was: " +
454+ std::string (pcap.getLastError ()));
471455 }
472456 }
473- else
457+
458+ switch (config.direction )
474459 {
475- PCPP_LOG_ERROR (" Failed to set direction for capturing packets, error code: '"
476- << ret << " ', error message: '" << pcap_geterr (pcap) << " '" );
460+ case PCPP_IN:
461+ {
462+ PCPP_LOG_DEBUG (" Only incoming traffics will be captured" );
477463 }
478-
479- if (pcap)
464+ case PCPP_OUT:
480465 {
481- int dlt = pcap_datalink (pcap);
482- const char * dlt_name = pcap_datalink_val_to_name (dlt);
483- if (dlt_name)
484- {
485- PCPP_LOG_DEBUG (" link-type " << dlt << " : " << dlt_name << " (" << pcap_datalink_val_to_description (dlt)
486- << " )" );
487- }
488- else
489- {
490- PCPP_LOG_DEBUG (" link-type " << dlt);
491- }
466+ PCPP_LOG_DEBUG (" Only outgoing traffics will be captured" );
467+ }
468+ default :
469+ {
470+ PCPP_LOG_DEBUG (" Both incoming and outgoing traffics will be captured" );
471+ }
472+ }
492473
493- m_LinkType = static_cast <LinkLayerType>(dlt);
474+ int dlt = pcap_datalink (pcap.get ());
475+ const char * dlt_name = pcap_datalink_val_to_name (dlt);
476+ if (dlt_name)
477+ {
478+ PCPP_LOG_DEBUG (" link-type " << dlt << " : " << dlt_name << " (" << pcap_datalink_val_to_description (dlt)
479+ << " )" );
480+ }
481+ else
482+ {
483+ PCPP_LOG_DEBUG (" link-type " << dlt);
494484 }
485+
486+ m_LinkType = static_cast <LinkLayerType>(dlt);
495487 return pcap;
496488 }
497489
@@ -503,7 +495,16 @@ namespace pcpp
503495 return true ;
504496 }
505497
506- auto pcapDescriptor = internal::PcapHandle (doOpen (config));
498+ internal::PcapHandle pcapDescriptor;
499+ try
500+ {
501+ pcapDescriptor = doOpen (config);
502+ }
503+ catch (std::exception& ex)
504+ {
505+ PCPP_LOG_ERROR (ex.what ());
506+ }
507+
507508 internal::PcapHandle pcapSendDescriptor;
508509
509510 // It's not possible to have two open instances of the same NFLOG device:group
@@ -513,7 +514,14 @@ namespace pcpp
513514 }
514515 else
515516 {
516- pcapSendDescriptor = internal::PcapHandle (doOpen (config));
517+ try
518+ {
519+ pcapSendDescriptor = doOpen (config);
520+ }
521+ catch (std::exception& ex)
522+ {
523+ PCPP_LOG_ERROR (ex.what ());
524+ }
517525 }
518526
519527 if (pcapDescriptor == nullptr || (!isNflogDevice () && pcapSendDescriptor == nullptr ))
0 commit comments