I am currently trying to listen for all UDP Traffic being broadcasted on the network using a specific port. For now lets say the port is 12345. When the data arrives the plan is to redirect the data out port 13579.
Currently I am trying to learn/use the library of PCAP4J. Using the tutorial found on their site (https://www.pcap4j.org/) I have been able to connect and look at data.
Sample Code Thus Far:
InetAddress ip = InetAddress.getByName("127.0.0.1");
PcapNetworkInterface nif = Pcaps.getDevByAddress(ip);
System.out.println("GOT NIF");
PromiscuousMode mode = PromiscuousMode.PROMISCUOUS;
int timeout = 10;
PcapHandle handle = nif.openLive(snapLen, mode, timeout);
System.out.println("GOT HANDEL");
Packet packet = handle.getNextPacketEx();
handle.close();
Questions:
Am I correct in assuming that I am looking at all traffic being sent to 127.0.0.1?
Is there an attribute of the packet that would allow me to say "This packet is on port 12345", or is there a way to configure PCAP4J to only listen to the port of 12345?
Related
I would like to bind a MulticastSocket to the address 127.0.0.1 (Socket should only be reachable within the current host) but with the following code example i got a
java.net.SocketException: Network is unreachable: Datagram send failed exception
Is there a way to fix the problem? Here is my code
int port = 6677;
InetAddress group = InetAddress.getByName("232.0.1.10");
try(MulticastSocket s = new MulticastSocket(new InetSocketAddress(InetAddress.getByName("127.0.0.1"),port))){
String msg = "Hello";
s.joinGroup(group);
DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),group, port);
s.send(hi);
}
Multicast is a little odd when compared to traditional UDP communication. The whole point is to share data on a known "channel", simultaneously, to anyone who wants access. This sharing is "signaled" to the network by using an IP address in the range 224.0.0.1 to 239.255.255.255. If you try to bind to 127.0.0.1, you just aren't doing Multicast anymore. And if you take a minute and think about it, that makes sense - you can't share the internal interface with other computers.
I need to create a java application that functions similar to WireShark in that it is able to listen to UDP traffic. But I need to know more about the datagram than just the data, I need to know the sender's IP and mac address. It there a way to accomplish this in Java?
Here is a screen shot of what I am talking about from Wireshark
WireShark Image
Notice the Ethernet II stack has the mac and the Internet Protocoal Version 4 has Src Ip.
The use case of this is that there are multiple devices on the network emitting data (as in this msg is STS:ANT:OK:8). But I need to know what the mac and IP is of this sender so I can categorize the msgs by sender and mac. (technically I can have duplicate IPs on the network.) So both are needed. This also allows me to show error cases where this is occurring.
IP protocol is underlying tool for UDP/TCP or other layers. You may need to capture the packets and listen to specific port (filter IP messages for UDP port)
Otherwise you can use external server commands to get it done more efficiently.
Here is an example (from How could I sniff network traffic in Java?):
public static void main(String[] args) throws Exception {
File f = new File("sample.pcap");
EthernetDecoder eth = new EthernetDecoder();
IpDecoder ip = new IpDecoder();
TcpDecoder tcp = new TcpDecoder(new TcpPortProtocolMapper());
UdpDecoder udp = new UdpDecoder(new UdpPortProtocolMapper());
eth.register(EthernetType.IPV4, ip);
ip.register(InternetProtocol.TCP, tcp);
ip.register(InternetProtocol.UDP, udp);
PcapInputStream is = new PcapFileInputStream(f);
while (true) {
// getPacket() will throws EOFException and you should call is.close()
PcapPacket packet = is.getPacket();
eth.decode(packet);
}
}
When we send data (in this case) to a client/server, does this really matter to use the same port number?
My guess is no, because it doesn't matter which port you are using when sending data to. (The protocol gives it to you randomly internally - this is the idea?) The only thing has to be kept, the port has to be any availabe one on the receiver machine(above 1000, because those are reserverd by the system), and if that receiver decides to send something back, he or she will have enough information about sender: his IP address, port number ect. As far as i know, a received packed provides with all of that info.
Below is just an illustration of what i've said above.
public class Server {
public static void main(String[] args) {
GameServer server = new GameSever(9822);
server.start();
InetAddress address = null;
int port = 7877;
try {
address = InetAddress.getByName("192.168.0.2");
} catch (UnknownHostException e) {
e.printStackTrace();
}
server.send(new byte[] { 1, 2, 3 }, address, port);
}
}
When a server listens on a computer, it specifies a port it wants it's connections coming in from , so ports are important for setting up servers. This is useful as you can have multiple applications listening on different ports without the different applications accidentally talking to eachother. So you should decide on a port that isn't a standard( 80 is for HTTP for example) to exclusively use for you gameserver so the client knows which port to send the requests to.
If you want to handle multiple connections at once the best thing to do is threading.
When we send data (in this case) to a client/server, does this really
matter to use the same port number? My guess is no, because it doesn't
matter which port you are using when sending data to.
Firstly, use the terms client and server distinguishly(as generally client initiates by sending the message, to which the server responds).
Next, the port which you're using is logically of no significance, the reason being server uses request.getPort() to determine the port while seding the response; (request is a DatagramPacket sent by the client).
Though you can hardcode the port at server(if known beforehand), but, it is a bad idea. What in those applications where you've no idea about who sent the datagram packet?
Java documentation by Oracle also uses an example of client-server where client's port number is left for the constructor to pick. It mentions :
Mostly, the client uses a constructor that does not require a port number. This constructor just binds the DatagramSocket to any available local port.
It doesn't matter what port the client is bound to because the DatagramPackets contain the addressing information. The server gets the port number from the DatagramPackets and send its response to that port.
MORE INFO (taken from Java Network Programming) :
public DatagramSocket() throws SocketException
This constructor creates a socket that is bound to an anonymous port. For example:
DatagramSocket client = new DatagramSocket();
Pick this constructor for a client that initiates a conversation with a server. In this scenario, you don’t care what port the socket is bound to because the server will send its response to the port from which the datagram originated. Letting the system assign a port means that you don’t have to worry about finding an unused port. If, for some reason, you need to know the local port, you can find out with the getLocalPort() method.
NOTE : The same socket can receive the datagrams that a server sends back to it(underlying implementation).
Whereas, the below constructor creates a socket that listens for incoming datagrams on a particular port, specified by the port argument :
public DatagramSocket(int port) throws SocketException
Use this constructor to write a server that listens on a well-known port.
Short answer:
Your guess is correct.
Longer answer:
Client gets a random port number when sending data to a server and each packet has a header which contains the info about client's port, ip address ect. So server can easily retreive this information and send anything back.
Whereas the server needs to be bind to a specific port in order to clients be able to send data to that server because when you use UDP, you need to specify an IP address and a port.
I'm new to Java socket programming and I'm currently developing a small peer to peer UDP chatting room application which allow multiple clients to chat with each other.
My question is how do I make a client discover all other connected clients once he hit the connect button providing only one of the connected clients ip and port? The program only runs on local network.
You can use a unique feature of UDP which is broadcasting
On IPv4 (which you are probably using) the address for broadcasting is 255.255.255.255. Any datagram sent to that address will be sent to all UDP clients on the network for that port.
What you can do for your chat application is to have each client send a packet to the UDP broadcast identifying itself, such as maybe the nickname of the user. All the other clients will see that packet, and you will be able to parse the packet and display a list of all the chat clients on the network.
Here is an example of sending a Datagram to broadcast:
DatagramSocket s = new DatagramSocket();
s.setBroadcast(true);
DatagramPacket dp = new DatagramPacket("insert data here".getBytes(), "insert data here".length(), new InetSocketAddress("255.255.255.255", 5000));
s.send(dp);
Another client can receive it like this:
DatagramSocket s = new DatagramSocket();
s.setBroadcast(true);
DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
s.receive(dp);
The received DatagramPacket will contain the IP and port of the client who had broadcasted it.
One simple possibility would be that every client stores the other peers it knows of and passes the list to any new clients connecting.
Don't forget of authenticating your peers. You can try to use the OpenSSL (very easy) to generate some certificates and use it in association to ssl.
Edit: a bot told me to be more specific so here it is:
Local Networks (LANs) are not always safe, so, to be sure, I would recommend you use OpenSSL to generate certificates for authentication and private keys for encryption, in this way, you can communicate safely.
Python ssl module is a good example.
I'm trying to send data to an Xbee antenna with a serial port in Java using the jssc library.
I want to be able to send and receive multiple data packets on the same connection.
The problem I have is that my code only send my first packet after either I close the port, or I end the program.
I based my code on the tutorial at this link: http://www.codeproject.com/Tips/801262/Sending-and-receiving-strings-from-COM-port-via-jS
Here is my code:
serialPort = new SerialPort("COM4");
try {
// opening port
serialPort.openPort();
serialPort.setParams(SerialPort.BAUDRATE_38400,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN |
SerialPort.FLOWCONTROL_RTSCTS_OUT);
serialPort.addEventListener(new PortReader(), SerialPort.MASK_RXCHAR);
byte[] fifo = new byte[13];
fifo[0] = 0x7E;
fifo[1] = 0x00;
fifo[2] = 0x09;
fifo[3] = 0x01;
fifo[4] = 0x01;
fifo[5] = 0x00;
fifo[6] = 0x01;
fifo[7] = 0x00;
fifo[8] = 0x54;
fifo[9] = 0x65;
fifo[10] = 0x73;
fifo[11] = 0x74;
fifo[12] = 0x5C;
result = serialPort.writeBytes(fifo);
The event for the reception of data is working, my only problem is sending. I already checked the baud rate of the other device my Xbee is talking to.
EDIT
When I connect my Xbee to an FT232's UART (http://www.seeedstudio.com/depot/UartSBee-V5-p-1752.html), this situation occurs.
When I connect directly the RS-232 to the XBee, the transmission is sent immediately.
How long are you waiting for the bytes to go out before you close/exit? You might need to go into the FTDI driver properties and update the settings for packetization and latency. It's likely waiting for more data in the driver on your PC before sending it over the USB connection to the FT232.
If you have your program wait a few seconds, you should find that the message is eventually going out without needing to close the serial port or exit the program (which closes the serial port as well).
After writing data to serial port try to flush it out of serial port so that it actually gets sent out of serial port. Also consider other serial port libraries for serial port communication like serial communication manager etc.