content: package net.azib.ipscan.core.net;
  
  import com.sun.jna.Library;
  import com.sun.jna.Native;
  import com.sun.jna.Pointer;
  import com.sun.jna.Structure;
  
  import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.List;
  
  import static java.lang.reflect.Modifier.isStatic;
  
  /**
   * JNA binding for iphlpapi.dll for ICMP and ARP support under Windows
   */
  public interface WinIpHlpDll extends Library {
  	WinIpHlpDll dll = Loader.load();
  	class Loader {
  		public static WinIpHlpDll load() {
  			try {
  				return Native.loadLibrary("iphlpapi", WinIpHlpDll.class);
  			}
  			catch (UnsatisfiedLinkError e) {
  				return Native.loadLibrary("icmp", WinIpHlpDll.class);
  			}
  		}
  	}
  
  	class AutoOrderedStructure extends Structure {
  		// this is a requirement of newer JNA, possibly it won't work on some JVM, but probability is quite small
  		@Override protected List<String> getFieldOrder() {
  			ArrayList<String> fields = new ArrayList<>();
  			for (Field field : getClass().getFields()) {
  				if (!isStatic(field.getModifiers()))
  					fields.add(field.getName());
  			}
  			return fields;
  		}
  	}
  
  	/**
  	 * Wrapper for Microsoft's <a href="http://msdn.microsoft.com/en-US/library/aa366045.aspx">IcmpCreateFile</a>
  	 */
  	Pointer IcmpCreateFile();
  
  	/**
  	 * Wrapper for Microsoft's <a href="https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmp6createfile">Icmp6CreateFile</a>
  	 */
  	Pointer Icmp6CreateFile();
  
  	/**
  	 * Wrapper for Microsoft's <a href="http://msdn.microsoft.com/en-us/library/aa366043.aspx">IcmpCloseHandle</a>
  	 */
  	boolean IcmpCloseHandle(Pointer hIcmp);
  
  	/**
  	 * Wrapper for Microsoft's <a href="http://msdn.microsoft.com/EN-US/library/aa366050.aspx">IcmpSendEcho</a>
  	 */
  	int IcmpSendEcho(
  			Pointer hIcmp,
  			IpAddrByVal destinationAddress,
  			Pointer requestData,
  			short requestSize,
  			IpOptionInformationByRef requestOptions,
  			Pointer replyBuffer,
  			int replySize,
  			int timeout
  	);
  
  	/**
  	 * Wrapper for Microsoft's <a href="https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmp6sendecho2">Icmp6SendEcho2</a>
  	 */
  	int Icmp6SendEcho2(
  			Pointer hIcmp,
  			Pointer event,
  			Pointer apcRoutine,
  			Pointer apcContext,
  			Ip6SockAddrByRef sourceAddress,
  			Ip6SockAddrByRef destinationAddress,
  			Pointer requestData,
  			short requestSize,
  			IpOptionInformationByRef requestOptions,
  			Pointer replyBuffer,
  			int replySize,
  			int timeout
  	);
  
  	/**
  	 * Wrapper for Microsoft's <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366358(v=vs.85).aspx">SendARP</a>
  	 */
  	int SendARP(
  			IpAddrByVal destIP,
  			int srcIP,
  			Pointer pMacAddr,
  			Pointer pPhyAddrLen
  	);
  
  	class IpAddr extends AutoOrderedStructure {
  		public byte[] bytes = new byte[4];
  	}
  
  	class IpAddrByVal extends IpAddr implements Structure.ByValue {
  	}
  
  	class Ip6SockAddr extends AutoOrderedStructure {
  		public short family = 10;
  		public short port;
  		public int flowInfo;
  		public byte[] bytes = new byte[16];
  		public int scopeId;
  	}
  
  	class Ip6SockAddrByRef extends Ip6SockAddr implements Structure.ByReference {
  	}
  
  	class IpOptionInformation extends AutoOrderedStructure {
  		public byte ttl;
  		public byte tos;
  		public byte flags;
  		public byte optionsSize;
  		public Pointer optionsData;
  	}
  
  	class IpOptionInformationByVal
  			extends IpOptionInformation implements Structure.ByValue {
  	}
  
  	class IpOptionInformationByRef
  			extends IpOptionInformation implements Structure.ByReference {
  	}
  
  	class IcmpEchoReply extends AutoOrderedStructure {
  		public IpAddrByVal address;
  		public int status;
  		public int roundTripTime;
  		public short dataSize;
  		public short reserved;
  		public Pointer data;
  		public IpOptionInformationByVal options;
  
  		public IcmpEchoReply() {
  		}
  
  		public IcmpEchoReply(Pointer p) {
  			useMemory(p);
  			read();
  		}
  	}
  
  	class Icmp6EchoReply extends AutoOrderedStructure {
  		public short port;
  		public byte[] flowInfo = new byte[4];
  		public byte[] addressBytes = new byte[16];
  		public int scopeId;
  		public int status;
  		public int roundTripTime;
  
  		public Icmp6EchoReply() {
  		}
  
  		public Icmp6EchoReply(Pointer p) {
  			useMemory(p);
  			read();
  		}
  	}
  }
  