Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupt pool Thread #292

Open
MarkusRost opened this issue Jan 3, 2022 · 0 comments
Open

Interrupt pool Thread #292

MarkusRost opened this issue Jan 3, 2022 · 0 comments

Comments

@MarkusRost
Copy link

Hello,

I use the SendArpRequest example to read the MAC adress of an other IP. When the IP is not reachable, a thread named "pool-15-thread-1" is not stop and still alive.

How can I stop these Thread?

Here my code:
`import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.pcap4j.core.BpfProgram.BpfCompileMode;
import org.pcap4j.core.NotOpenException;
import org.pcap4j.core.PacketListener;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.PcapNativeException;
import org.pcap4j.core.PcapNetworkInterface;
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode;
import org.pcap4j.core.Pcaps;
import org.pcap4j.packet.ArpPacket;
import org.pcap4j.packet.EthernetPacket;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.namednumber.ArpHardwareType;
import org.pcap4j.packet.namednumber.ArpOperation;
import org.pcap4j.packet.namednumber.EtherType;
import org.pcap4j.util.ByteArrays;
import org.pcap4j.util.MacAddress;

public class SendArpRequest
{
private static final String COUNT_KEY = SendArpRequest.class.getName() + ".count";
private static int COUNT;
private static final String READ_TIMEOUT_KEY = SendArpRequest.class.getName() + ".readTimeout";
private static int READ_TIMEOUT; // [ms]
private static final String SNAPLEN_KEY = SendArpRequest.class.getName() + ".snaplen";
private static int SNAPLEN; // [bytes]

private String sourceIP = "";

private MacAddress sourceMac = MacAddress.getByName( "fe:00:01:02:03:04" );
private static MacAddress resolvedAddr = null;
private String destinationIP = "";

private Debug debug;
private ConfigRead config;

public SendArpRequest( Debug d, ConfigRead c, String sourceIP, String sourceMac ) 
{
	this.debug = d;
	this.config = c;
	this.sourceIP = sourceIP;
	this.sourceMac = MacAddress.getByName( sourceMac );
	
	COUNT = Integer.getInteger( COUNT_KEY, config.getArpCount() );
	READ_TIMEOUT = Integer.getInteger( READ_TIMEOUT_KEY, config.getArpTimeout() ); // [ms]
	SNAPLEN = Integer.getInteger( SNAPLEN_KEY, config.getArpPacketSize() ); // [bytes]
	
	debug.print( 2, "ARP Objekt initialisiert mit SourceIP: " + sourceIP + " und Source Mac: " + sourceMac );
}

public String searchMacAddress( String destinationIP ) throws RuntimeException
{
	debug.print( 2, "Suche nach Macadresse für: " + destinationIP );
    
	String erg = "";
	Boolean state = true;
	
	this.destinationIP = destinationIP;
	resolvedAddr = null;
	
	/*
	System.out.println(COUNT_KEY + ": " + COUNT);
    System.out.println(READ_TIMEOUT_KEY + ": " + READ_TIMEOUT);
    System.out.println(SNAPLEN_KEY + ": " + SNAPLEN);
    System.out.println("\n");
	*/
	
    PcapNetworkInterface nif;

    try
    {
    	nif = Pcaps.getDevByAddress( InetAddress.getByName( this.sourceIP ) );
    }
    catch( Exception e )
    {
    	debug.print( 1, "Source Netzwerk Interface nicht gefunden: " + e.getMessage() );
    	return erg;
    }

    if( nif == null )
    {
    	debug.print( 1, "Source Netzwerk Interface nicht gefunden!" );
    	return erg;
    }

    debug.print( 2, "Suche über folgendes Inerface: " + nif.getName() + " (" + nif.getDescription() + ")" );
    
    PcapHandle handle = null;
    PcapHandle sendHandle = null;
    ExecutorService pool = null;

    try
    {
	    handle = nif.openLive( SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT );
	    sendHandle = nif.openLive( SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT );
	    pool = Executors.newSingleThreadExecutor();
	    	    	
    	handle.setFilter( "arp and src host " + destinationIP + " and dst host " + this.sourceIP + " and ether dst " + Pcaps.toBpfString( this.sourceMac ), BpfCompileMode.OPTIMIZE );

    	PacketListener listener = new PacketListener()
    	{
            public void gotPacket( Packet packet )
            {
            	if( packet.contains( ArpPacket.class ))
            	{
            		ArpPacket arp = packet.get( ArpPacket.class );
            		if( arp.getHeader().getOperation().equals( ArpOperation.REPLY ))
            		{
            			SendArpRequest.resolvedAddr = arp.getHeader().getSrcHardwareAddr();
            		}
            	}

            	debug.print( 3, "Empfangenes Packet: " + packet );

            }
    	};

    	Task t = new Task( handle, listener );
	    pool.execute( t );
	
	    ArpPacket.Builder arpBuilder = new ArpPacket.Builder();
	    try
	    {
	    	arpBuilder
	          .hardwareType( ArpHardwareType.ETHERNET )
	          .protocolType( EtherType.IPV4 )
	          .hardwareAddrLength( (byte)MacAddress.SIZE_IN_BYTES )
	          .protocolAddrLength( (byte)ByteArrays.INET4_ADDRESS_SIZE_IN_BYTES )
	          .operation( ArpOperation.REQUEST )
	          .srcHardwareAddr( this.sourceMac )
	          .srcProtocolAddr( InetAddress.getByName( this.sourceIP ))
	          .dstHardwareAddr( MacAddress.ETHER_BROADCAST_ADDRESS )
	          .dstProtocolAddr( InetAddress.getByName( destinationIP ));
	    }
	    catch( UnknownHostException e )
	    {
	    	debug.print( 1, "Fehler beim Bau des ARP Pakets: " + e.getMessage() );
	    	return erg;
	    }

	    EthernetPacket.Builder etherBuilder = new EthernetPacket.Builder();
	    etherBuilder.dstAddr( MacAddress.ETHER_BROADCAST_ADDRESS )
	    	.srcAddr( this.sourceMac )
	        .type( EtherType.ARP )
	        .payloadBuilder( arpBuilder )
	        .paddingAtBuild( true );

	    for( int i = 0; i < COUNT; i++ ) 
	    {
	        Packet p = etherBuilder.build();
	        
	        debug.print( 3, "Gesendetes Packet: " + p );
	        
	        sendHandle.sendPacket(p);
	        
	        try
	        {
	        	Thread.sleep( 1000 );
	        }
	        catch( InterruptedException e )
	        {
	        	break;
	        }
	    }
	    
	    debug.print( 2, "Pakete gesendet" );
	    
	    int i = 0;
	    
	    while( true )
	    {
	    	if( resolvedAddr != null )
	    	{
	    		break;
	    	}
	    	
	    	i = i + 1;
	    	
	    	if( i >= 10 )
	    	{
	    		pool.shutdown();
	    		pool.shutdownNow();
	    		throwRuntimeException();
	    	}
	    	
	    	try
	        {
	        	Thread.sleep( 100 );
	        }
	        catch( InterruptedException e )
	        {
	        	break;
	        }
	    }
    }
    catch( RuntimeException re )
    {
    	debug.print( 1, "Runtime Error bei ARP Abfrage: " + re.getMessage() );
    	state = false;
    	throw new RuntimeException( re );
    }
    catch( Exception e )
    {
    	debug.print( 1, "Fehler bei ARP Abfrage: " + e.getMessage() );
    	return erg;
	}
    finally
    {
    	if( state == true )
    	{	
	    	if (handle != null && handle.isOpen())
	    	{
	    		handle.close();
	    	}
	    	if (sendHandle != null && sendHandle.isOpen())
	    	{
	    		sendHandle.close();
	    	}
	    	if (pool != null && !pool.isShutdown())
	    	{
	    		pool.shutdown();
	    	}
    	}
    	
    	debug.print( 2, destinationIP + " was resolved to " + resolvedAddr );
    }
    return resolvedAddr.toString();
}

private void throwRuntimeException()
{
	throw new RuntimeException( "RunTime Fehler bei " + destinationIP );
}

private static class Task implements Runnable
{

	private PcapHandle handle;
	private PacketListener listener;

    public Task(PcapHandle handle, PacketListener listener) 
    {
    	this.handle = handle;
    	this.listener = listener;
    }

    @Override
    public void run() 
    {
    	try
    	{
    		handle.loop(COUNT, listener);
    	} 
    	catch (PcapNativeException e)
    	{
    		e.printStackTrace();
    	}
    	catch (InterruptedException e)
    	{
    		e.printStackTrace();
    	} 
    	catch (NotOpenException e)
    	{
    		e.printStackTrace();
    	}
    }

}

}`

Thanks

Markus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant