@@ -51,7 +51,7 @@ typedef struct {
5151 arp_response_t * response ;
5252 struct in_addr target_ip ;
5353 int timeout_ms ;
54- int finished ;
54+ volatile int finished ;
5555} capture_thread_args_t ;
5656
5757/*
@@ -144,7 +144,7 @@ static PyObject *perform_arp_scan(PyObject *self, PyObject *args) {
144144
145145 // Open pcap handle
146146 char errbuf [PCAP_ERRBUF_SIZE ];
147- pcap_t * handle = pcap_open_live (iface , 65536 , 1 , timeout_ms , errbuf );
147+ pcap_t * handle = pcap_open_live (iface , 65536 , 1 , 10 , errbuf );
148148 if (!handle ) {
149149 PyErr_SetString (PyExc_RuntimeError , errbuf );
150150 return NULL ;
@@ -154,7 +154,7 @@ static PyObject *perform_arp_scan(PyObject *self, PyObject *args) {
154154 struct bpf_program fp ;
155155 char filter_exp [64 ];
156156 snprintf (filter_exp , sizeof (filter_exp ), "arp src host %s" , dst_ip_str );
157- if (pcap_compile (handle , & fp , filter_exp , 0 , PCAP_NETMASK_UNKNOWN ) == -1 ) {
157+ if (pcap_compile (handle , & fp , filter_exp , 1 , PCAP_NETMASK_UNKNOWN ) == -1 ) {
158158 pcap_close (handle );
159159 PyErr_SetString (PyExc_RuntimeError , "Failed to compile filter" );
160160 return NULL ;
@@ -207,25 +207,34 @@ static PyObject *perform_arp_scan(PyObject *self, PyObject *args) {
207207 return NULL ;
208208 }
209209
210+ // Release the GIL for the blocking network operations so other Python
211+ // threads (e.g. the ThreadPoolExecutor workers) can run concurrently.
212+ int send_failed ;
213+ Py_BEGIN_ALLOW_THREADS
214+
210215 // Send ARP request
211- if (pcap_sendpacket (handle , packet , sizeof (packet )) != 0 ) {
212- pthread_cancel (tid );
213- pcap_close (handle );
214- PyErr_SetString (PyExc_RuntimeError , "Failed to send ARP packet" );
215- return NULL ;
216- }
216+ send_failed = (pcap_sendpacket (handle , packet , sizeof (packet )) != 0 );
217217
218- // Wait for response or timeout
219- while (!thread_args .finished && timeout_ms > 0 ) {
220- usleep (10000 ); // Sleep for 10ms
221- timeout_ms -= 10 ;
218+ if (!send_failed ) {
219+ // Wait for response or timeout
220+ while (!thread_args .finished && timeout_ms > 0 ) {
221+ usleep (10000 ); // Sleep for 10ms
222+ timeout_ms -= 10 ;
223+ }
222224 }
223225
224226 // Clean up
225227 pthread_cancel (tid );
226228 pthread_join (tid , NULL );
227229 pcap_close (handle );
228230
231+ Py_END_ALLOW_THREADS
232+
233+ if (send_failed ) {
234+ PyErr_SetString (PyExc_RuntimeError , "Failed to send ARP packet" );
235+ return NULL ;
236+ }
237+
229238 // Return results
230239 if (response .found ) {
231240 char mac_str [18 ];
0 commit comments