Ok so the program is designed to take in connections, validate them, and resend that validation code. Before anyone get's angry it's just a simple little project and is not designed to be overly complex haha. However for some very strange reason the function is hanging on send.setAddess(packet.getAddress); I know this because I have commented out each individual line of code that deals with the Datagram packet "send" and have found that it "hangs" (or never progresses forward in the method again) on that particular line. Any thoughts? Am I doing something cluelessly wrong? I tried it on a linux server as well to make sure it didn't have anything to do with me and the same crap happened.
public static boolean authorize(String n, DatagramPacket packet) {
DatagramPacket send = new DatagramPacket(new byte[4096], 4096);
try {
System.out.println("in auth");
String[] t1 = n.split("%#");
String name = t1[1];
int k = genKey(name);
clients.put(name, k);
send.setAddress(packet.getAddress());
System.out.println("set add");
send.setPort(packet.getPort());
System.out.println("set port");
send.setData(("l-succeed%#" + Integer.toString(k)).getBytes());
System.out.println("set data");
main.dispathcer(send);
System.out.println("called send");
return true;
} catch(Exception e) {
send.setData("l-failed".getBytes());
main.dispathcer(send);
return false;
}
}
EDIT: it took 6 minutes before the authorization token was received by the client. So obviously the setAddress() works but is taking far too long...
It's possible that the process is hanging because there's an issue doing DNS resolution on the address for packet when you call .getAddress(). A few DNS calls are made in order to create the InetAddress object. On these machines, are you able to do a reverse DNS lookup on the IP that the packet packet came from? Try setting an entry for this IP in your /etc/hosts file.
Related
IMPORTANT
I have been blocked by hotmail services. There is a control mechanism
called spamhaus which kicked me out. I'm stuck right now.
I am trying to detect an email address is valid and if its valid then check if this email address potentially used (I know that its not certain). For example, lets assume that there is a website with domain myimaginarydomain.com. If I run code below, I guess it won't fail because domain address is valid. But nobody can take an email address with that domain.
Is there any way to find out that email address is valid? (In this case its invalid)
I don't want to send confirmation email
Sending ping may be useful?
public class Application {
private static EmailValidator validator = EmailValidator.getInstance();
public static void main(String[] args) {
while (true) {
Scanner scn = new Scanner(System.in);
String email = scn.nextLine();
boolean isValid = validateEmail(email);
System.out.println("Syntax is : " + isValid);
if (isValid) {
String domain = email.split("#")[1];
try {
int test = doLookup(domain);
System.out.println(domain + " has " + test + " mail servers");
} catch (NamingException e) {
System.out.println(domain + " has 0 mail servers");
}
}
}
}
private static boolean validateEmail(String email) {
return validator.isValid(email);
}
static int doLookup(String hostName) throws NamingException {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs =
ictx.getAttributes(hostName, new String[]{"MX"});
Attribute attr = attrs.get("MX");
if (attr == null) return (0);
return (attr.size());
}
}
There is no failsafe way to do this in all cases, but, assuming the server uses SMTP then https://www.labnol.org/software/verify-email-address/18220/ gives quite a good tutorial on one method that may work.
The method used in the tutorial relies on OS tools, so you will need to ensure they exist before using them. a ProcessBuilder may help. Alternatively, you can open a socket directly in code and avoid using OS-dependent tools.
Essentially, you find out what the mail servers are (using nslookup), then telnet to one of the mail servers and start writing an email:
3a: Connect to the mail server:
telnet gmail-smtp-in.l.google.com 25
3b: Say hello to the other server
HELO
3c: Identify yourself with some fictitious email address
mail from:<labnol#labnol.org>
3d: Type the recipient’s email address that you are trying to verify:
rcpt to:<billgates#gmail.com>
The server response for rcpt to command will give you an idea whether an email address is valid or not. You’ll get an “OK” if the address exists else a 550 error
There really is no sensible way except trying to send a notification with a token to the address and ask the other party to confirm it, usually by visiting a web-page:
the recipients MX may be unavailable at the moment but come back online later, so you cannot rely on a lookup in real time;
just because the MX accepts the email doesn't mean that the address is valid, the message could bounce later down the pipe (think UUCP);
if this is some kind of registration service, you need to provide some confirmation step anyway as otherwise it'd become too easy to subscribe random strangers on the internet that do not want your service.
I want to implement basic network check functionality to test if the provided url is responding or not (eg. ping www.google.com).It must provide operational information indicating, for example, that a requested service is not available or that a host could not be reached. I am able to achive it using icmp4j library. But i want to achieve the same using pcap4j library. I want to put the url in text box and click on connect button which will call pcap4j api to check whether the host is responding or not.
You can create ICMPv4 Echo (ping) on Ethernet packets using the Builders of IcmpV4EchoPacket, IcmpV4CommonPacket, IpV4Packet, and EthernetPacket and send them by PcapHandle.sendPacket(). Please refer to org.pcap4j.sample.SendFragmentedEcho in pcap4j-sample project.
You will need to implement ARP to resolve IP addresses to MAC addresses like org.pcap4j.sample.SendArpRequest in pcap4j-sample project.
And you will also need to implement a feature to find the next hop (default gateway or so) from the given IP address somehow. Pcap4J doesn't provide API to support this implementation. (Java doesn't provide API to get routing table...)
You'd maybe better use java.net.InetAddress#isReachable() instead.
It took me more than a year to figure this out, as I wanted to make a traceroute with pcap4j, so here is what I did:
Get your IPv4 Address and Mac Address, this can be easily achieved by querying the PcapNetworkInterface
Get target IP Address, if you have a DNS Name you need to resolve it beforehand.
Get target Mac Address.
Target is in the same subnet: send an ARP Request to resolve the mac (alternatively, a mac broadcast will likely work fine too).
Target is in different subnet: you need to get the mac of your gateway server then, this is not as easy. Assuming you have other network traffic going on, you could listen for incoming packets and get the source mac, where the source IP address is from a different subnet, this is likely the mac address of your gateway server.
Create IcmpV4EchoPacket and sent it
Listen for incoming ICMP traffic, you will get one of these three:
A IcmpV4EchoReplyPacket which is likely to be an answer to your request (check identifier and sequence number to be sure)
A IcmpV4TimeExceededPacket if the target could not be reached with the time-to-live you specified
Nothing, routers and pinged targets are free to ignore and not answer your request
Variables that need to be filled:
short IDENTIFIER; // identifer may be any 16 bit interger
short SEQUENCE; // sequence may be any 16 bit integer
byte TTL; // time to live (1-255)
Inet4Address IP_TARGET; // ip address of your ping target
Inet4Address IP_ORIGIN; // your own ip address
MacAddress MAC_TARGET; // target or gateway mac address
MacAddress MAC_SOURCE; // your own mac address
PcapNetworkInterface PCAP4J_NETWORK_INTERFACE; // network interface used to execute the ping
How to make a ICMP Echo Request Packet (as payload of IcmpV4CommonPacket of IpV4Packet of EthernetPacket):
public Packet buildPacket() {
IcmpV4EchoPacket.Builder icmpV4Echo = new IcmpV4EchoPacket.Builder()
.identifier(IDENTIFIER) // optional, default zero
.sequenceNumber(SEQUENCE); // optional, default zero
IcmpV4CommonPacket.Builder icmpV4Common = new IcmpV4CommonPacket.Builder()
.type(IcmpV4Type.ECHO) // type is echo
.code(IcmpV4Code.NO_CODE) // echo request doesn't need this
.payloadBuilder(icmpV4Echo)
.correctChecksumAtBuild(true);
IpV4Packet.Builder ipv4Builder = new IpV4Packet.Builder()
.correctChecksumAtBuild(true)
.correctLengthAtBuild(true)
.dstAddr(IP_TARGET) // IPv4 Address where tp send the request
.payloadBuilder(icmpV4Common)
.protocol(IpNumber.ICMPV4) // payload is ICMPV4
.srcAddr(IP_ORIGIN) // Your own IPv4 Address
.tos(IpV4Rfc1349Tos.newInstance((byte) 0))
.ttl(TTL) // time to live (1-255)
.version(IpVersion.IPV4); // IP Version is IPv4
EthernetPacket.Builder etherBuilder = new EthernetPacket.Builder()
.dstAddr(MAC_TARGET) // the targets mac address
.srcAddr(MAC_SOURCE) // your own mac address
.type(EtherType.IPV4) // payload protocl is IPv4
.payloadBuilder(ipv4Builder)
.paddingAtBuild(true);
return etherBuilder.build(); // build your packet
}
Listener for ICMP Echo Answers or timeouts:
public PacketListener buildListener() {
return new PacketListener() {
#Override
public void gotPacket(Packet packet) {
if (!(packet instanceof EthernetPacket))
return;
EthernetPacket ethernetPacket = (EthernetPacket) packet;
packet = ethernetPacket.getPayload();
if (!(packet instanceof IpV4Packet))
return;
IpV4Packet ipV4Packet = (IpV4Packet) packet;
IpV4Header ipV4Header = ipV4Packet.getHeader();
packet = ipV4Packet.getPayload();
if (!(packet instanceof IcmpV4CommonPacket))
return;
IcmpV4CommonPacket icmpPacket = (IcmpV4CommonPacket) packet;
packet = icmpPacket.getPayload();
// successful reply just measure time and done
if (packet instanceof IcmpV4EchoReplyPacket) {
IcmpV4EchoReplyPacket icmpV4EchoReplyPacket = (IcmpV4EchoReplyPacket) packet;
IcmpV4EchoReplyHeader icmpV4EchoReplyHeader = icmpV4EchoReplyPacket.getHeader();
if (icmpV4EchoReplyHeader.getIdentifier() != identifier)
return;
if (icmpV4EchoReplyHeader.getSequenceNumber() != sequence)
return;
// here you got an echo reply
System.out.println(packet);
return;
}
// try handle time to live exceeded messages
if (packet instanceof IcmpV4TimeExceededPacket) {
packet = packet.getPayload(); // original IPv4
if (!(packet instanceof IpV4Packet))
return;
packet = packet.getPayload(); // original ICMP common
if (!(packet instanceof IcmpV4CommonPacket))
return;
packet = packet.getPayload(); // original ICMP echo
if (!(packet instanceof IcmpV4EchoPacket))
return;
IcmpV4EchoHeader icmpV4EchoHeader = ((IcmpV4EchoPacket)packet).getHeader();
if (icmpV4EchoHeader.getIdentifier() != IDENTIFIER)
return;
if(icmpV4EchoHeader.getSequenceNumber() != SEQUENCE)
return;
// HERE you got an answer, that the time to live has been used up
System.out.println(packet);
return;
}
};
}
Combining it togther:
public static void main(String[] args) throws IOException, PcapNativeException, NotOpenException, InterruptedException {
try (PcapHandle handle = PCAP4J_NETWORK_INTERFACE.openLive(1024, PromiscuousMode.PROMISCUOUS, 1000)) {
// set filter to only get incoming ICMP traffic
handle.setFilter("icmp and dst host " + Pcaps.toBpfString(IP_ORIGIN), BpfCompileMode.OPTIMIZE);
// send ARP request
Packet p = buildPacket();
handle.sendPacket(p);
// wait (forever) for ARP answer
PacketListener listener = buildListener();
handle.loop(-1, listener);
}
}
So the way I have done this Multi-Client Server and client connection, is to have the server create a new Thread for each client, and then use a while loop to constantly recieve, output, store, and then send the data from each of the clients to the specific client for this Thread by using ArrayList:
while (!finished) {
numberofclients = Server.clients.size();
inStream = new ObjectInputStream(socket.getInputStream());
v3f = (Vector3f) inStream.readObject();//recieve object from client
clientinfo.setText("[" + clientindex + "] " + clientname + ": " //jlabel to show this clients position in server class
+ (int) v3f.x + "," + (int) v3f.y + "," + (int) v3f.z);
FontToFit(clientinfo);
Server.clientpos.set(clientindex-1, v3f);//the arraylist of client positions
outStream = new ObjectOutputStream(socket.getOutputStream());
outStream.writeObject(Server.clientpos);//send the clients positions
}
It works great for my game, each player connects, and you can see where each one is (although its not terribly fast), but I cannot hope to advance with this game if I continue to use sockets this way. I also plan to make a chat in the game, but if I used that right now, it would conflict with the data being sent for their positions. I wish I knew how to only send information when needed, and the client would only try to receive it when needed.
In the server class some method like:
public void SendPositionsToAll(){
for(ClientThread ct : clients){//for each client
ct.SendPos(ct.x, ct.y, ct.z);// run method in ClientThread
}
}
And then in ClientThread:
public void SendPos(double x, double y, double z){
outStream = new ObjectOutputStream(socket.getOutputStream());
outStream.writeObject(new Vector3f(x,y,z));
}
With something similar for the chat. I have no clue if it is possible (guessing it is) but any help would be awesome.
dedicate a thread to receiving messages and queueing them.
dedicate a thread to sending objects that have been queued for it.
you could continue to use serialization, but as you say it's not terribly effecient.
..or you could implement a communication protocol that packs just the essential information.
If you do, I highly recommend making it human readable. Doing so will make your debugging
life a whole lot easier.
My work is developing software for network capable cameras for retail enviroments. One of the peices of software my team is developing is a webserver that retrieves various reports generated in HTML by the camera itself (which has its own embedded webserver) and stored on the camera. Our software will then GET these reports from the camera and store it on a central webserver.
While we are fine plugging in the IPs of the cameras into our software, I am developing a simple Java class that will query the network and locate all cameras on the network.
The problem though is that while it runs just fine on my PC, and my coworker's PC, when we attempt to run it on the actual webserver PC that will host our software... it runs, but says every IP in the subnet is offline / unreachable EXCEPT for the gateway IP.
For example, if I run it from my PC or my coworkers PC when plugged into the closed LAN, I get the following active IPs found along with a flag telling me if its a camera or not.
(gateway is 192.168.0.1, subnet mask is 255.255.255.0, which means full range of 256 devices to be looked for)
IP:/192.168.0.1 Active:true Camera:false
IP:/192.168.0.100 Active:true Camera:true <- this is camera 1
IP:/192.168.0.101 Active:true Camera:true <- this is camera 2
IP:/192.168.0.103 Active:true Camera:false <- my PC
IP:/192.168.0.104 Active:true Camera:false <- this is our webserver
But for some reason, when running the same program from the webserver PC, using the same JRE, I only get the following found
IP:/192.168.0.1 Active:true Camera:false
Now my code, instead of enumerating through each IP in order on the main Thread, instead creates a seperate Thread for each IP to be checked and runs them concurrently (else it would take little over 21 minutes to enumerate through the entire IP range at a timeout of 5000ms / IP). The main Thread then re-runs these IP scan threads every 15 seconds over and over.
I have checked that all the threads are running to completion on all the PCs, no exceptions are being thrown. Even verified that none of the threads are getting stuck. Each Thread takes about 5001 to 5050ms from start to complete, and those Threads that have an active IP finish sooner (>5000ms), so I know that its correctly waiting the full 5000ms in the ipAddr.isReachable(5000) method.
Me and my coworker are stumped at this point while it seems to reach those active IPs fine when run on our PCs, yet getting no response from the webserver PC???
We have ruled out firewall issues, admin access issues, etc.. The only difference is that our webserver is Embedded Win XP, and our PCs are Windows 7.
This has us stumped. Any ideas why?
Below is the code that is running each IP Thread:
public void CheckIP() {
new Thread() {
#Override
public void run() {
try {
isActive = ipAddr.isReachable(5000);
if (isActive) {
if (!isCamera) {
isCamera = new IpHttpManager().GetResponse(ipAddr.toString());
}
} else {
isCamera = false;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
EDIT: Here is the code that builds each IP to check after determining the range based on gateway and subnet...
for(int i=subMin; i<=subMax; i++) {
byte[] ip = new byte[] {(byte)oct[0],(byte)oct[1],(byte)oct[2],(byte)i};
try {
scanners[subCount] = new IpScan(InetAddress.getByAddress(ip));
subCount++;
} catch (UnknownHostException e) {
e.printStackTrace();
}}
Thanks everyone, but I never did figure out or pinpoint why this oddity was happening. Everything I checked for was not the cause, so this question can be closed.
In any case, I ended up working around it completely. Instead of using InetAddress, I just went native and built my own ICMP ping class instead, via JNA, invoking Windows libraries IPHLPAPI.DLL and WSOCK32.DLL. Here is what I used...
public interface InetAddr extends StdCallLibrary {
InetAddr INSTANCE = (InetAddr)
Native.loadLibrary("wsock32.dll", InetAddr.class);
ULONG inet_addr(String cp); //in_addr creator. Creates the in_addr C struct used below
}
public interface IcmpEcho extends StdCallLibrary {
IcmpEcho INSTANCE = (IcmpEcho)
Native.loadLibrary("iphlpapi.dll", IcmpEcho.class);
int IcmpSendEcho(
HANDLE IcmpHandle, //Handle to the ICMP
ULONG DestinationAddress, //Destination address, in the form of an in_addr C Struct defaulted to ULONG
Pointer RequestData, //Pointer to the buffer where my Message to be sent is
short RequestSize, //size of the above buffer. sizeof(Message)
byte[] RequestOptions, //OPTIONAL!! Can set this to NULL
Pointer ReplyBuffer, //Pointer to the buffer where the replied echo is written to
int ReplySize, //size of the above buffer. Normally its set to the sizeof(ICMP_ECHO_REPLY), but arbitrarily set it to 256 bytes
int Timeout); //time, as int, for timeout
HANDLE IcmpCreateFile(); //win32 ICMP Handle creator
boolean IcmpCloseHandle(HANDLE IcmpHandle); //win32 ICMP Handle destroyer
}
And then using those to create the following method...
public void SendReply(String ipAddress) {
final IcmpEcho icmpecho = IcmpEcho.INSTANCE;
final InetAddr inetAddr = InetAddr.INSTANCE;
HANDLE icmpHandle = icmpecho.IcmpCreateFile();
byte[] message = new String("thisIsMyMessage!".toCharArray()).getBytes();
Memory messageData = new Memory(32); //In C/C++ this would be: void *messageData = (void*) malloc(message.length);
messageData.write(0, message, 0, message.length); //but ignored the length and set it to 32 bytes instead for now
Pointer requestData = messageData;
Pointer replyBuffer = new Memory(256);
replyBuffer.clear(256);
// HERE IS THE NATIVE CALL!!
reply = icmpecho.IcmpSendEcho(icmpHandle,
inetAddr.inet_addr(ipAddress),
requestData,
(short) 32,
null,
replyBuffer,
256,
timeout);
// NATIVE CALL DONE, CHECK REPLY!!
icmpecho.IcmpCloseHandle(icmpHandle);
}
public boolean IsReachable () {
return (reply > 0);
}
My guess is that your iteration logic to determine the different ip address is based upon different configuration hence your pc's fetches all addresses but your webserver doesn't.
Try adding debug in the logic where you build up the list of ip adresses to check.
I am a beginner in Java and I am working at a project involving sockets and external devices.
I have done a small listener for the units and I am having some problems sending messages to the devices.
The unit has 2 messages that is sending to the server:
1. the Heart Beat message witch is in hex
2. the actual data which is a string and looks like: field1,field2,field3,field4
The listener is opening a new thread for each device and is wait for messages.
I use an DataInputStream for receiving the messages and DataOutputStream for sending the messages. Each time a unit is connecting to the server, it opens a new thread and gets the heart beat, from that heart beat I know what type of device is and who is it. If the device is new I will configure it based on 2 unique serials which the unit knows to send me and I have to compare them to the database.
My problem is in the part in which I ask the device for the 2 serials. It takes a long time 30 to 40 seconds. It has to be under 10 seconds for send the command (tested on another tcp server).
Here is that part of code:
String [] commands = deviceDetails.getConfigCommands().split(";"); // I take the commands from a file, and looks like: command1;command2
for (int i=0; i<commands.length; i++) {
sendCommand = commands[i].getBytes(); // sendCommand is a byte[]
out.write(sendCommand);
out.flush();
loop: while (true) {
in.read(buffer); // buffer is a byte[]
String[] result = new String(buffer, "ASCII").split(":|="); // the response from the unit looks like: ok:commandname=code, i need the code
if (configCounter ==2 && imei.equals("")) {
i = 0;
break loop;
} else if(configCounter == 2 && simid.equals("")) {
i = 1;
break loop;
}
configCounter++;
switch (result[1]) {
case "IMEI":
imei = result[2];
break loop;
case "SIMID":
simid = result[2];
break loop;
}
}
}
in the while I am waiting for the response from the unit. but before that I am trying to send the command to the unit and it takes about 30-40 second for each command.
Can anyone tell me what's the problem in the code above? How can I make the DataOutputStream send the command faster than 30-40 seconds??
Thank you!