B4J Question [SOLVED] Access mDNS data from program/ Using Nmap

Peter Lewis

Active Member
Licensed User
Longtime User
Hi,
I am looking to access UDP data from multicast address 224.0.0.251 port 5353 , jNetwork does not allow the entry of this IP.

From my previous post , it has been suggested to use Java with Javaobject.

Is this possible ? does anyone have any examples ?

I found this on Stackoverflow but do not how to format it to use in B4J , or that is actually works

Thank you

B4X:
import java.net.MulticastSocket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Main {
    public static void main(String[] args) {
        if( args.length == 0 ) runClient();
        if(args[0].equals("s")) runServer();
        else runClient();
    }

    static String mcastAddr = "239.255.100.100";  // Chosen at random from local network block at http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
    static int port = 4446;

    public static void runServer() {
        while (true) {
            try {
                MulticastSocket s = new MulticastSocket(port);
                InetAddress group = InetAddress.getByName(mcastAddr);
                s.joinGroup(group);

                byte[] recData = new byte[100];
                DatagramPacket receivePacket = new DatagramPacket(recData, recData.length);
                s.receive(receivePacket);
                String strrec = new String(recData,0,receivePacket.getLength());
                print("server received: " + strrec);
                print("from: " + receivePacket.getAddress().toString());

                if(strrec.equals("Are you there?")) {
                    String msg = "Here I am";
                    byte[] msgData = msg.getBytes();
                    DatagramPacket msgPacket = new DatagramPacket(msgData, msgData.length, receivePacket.getAddress(), receivePacket.getPort());
                    s.send(msgPacket);
                    print("server sent: " + msg + "\n");
                } else {
                    print("Didn't send; unrecognized message.");
                }


            } catch (Exception e) {
                print(e.toString());
            }
        }
    }

    public static void runClient() {
        try {
            DatagramSocket s = new DatagramSocket();

            String msg = "Are you there?";  // Magic string
            byte[] msgData = msg.getBytes();
            DatagramPacket datagramPacket = new DatagramPacket(msgData, msgData.length, InetAddress.getByName(mcastAddr), port);
            s.send(datagramPacket);
            print("client sent: " + msg);

            byte[] recData = new byte[100];
            DatagramPacket receivePacket = new DatagramPacket(recData, recData.length);
            s.receive(receivePacket);
            String strrec = new String(recData,0,receivePacket.getLength());
            print("client received: " + strrec);
            print("from " + receivePacket.getAddress().toString() + " : " + receivePacket.getPort());

            System.exit(0);
        } catch (Exception e) {
            print(e.toString());
        }
    }
    static void print(String s) {             System.out.println(s);         }
}

I have looked at other ways to get the information I am looking for.

1 is to monitor port 67

Message received: Length=308, Offset=0, Host=192.168.11.170, Port=68

This almost works perfectly.
The computer runs its own DHCP server allocating an initial IP address using 192.168.11.??? subnet
Now I can check which endpoints are alive without having to ping each IP address.

Once they are found , I need to REALLOCATE new IPs on a different Subnet using the same adapter. Which works well
but I cannot change the monitoring subnet to 192.168.10.???

restarted the program and it still only monitors 192.168.11.255, I want it to monitor 192.168.10.255 so I can receive the new data for port 68

This is the setup of the Ethernet Adapter so I can use it for both subnets


1734013552816.png
 
Last edited:
Solution
doesn't nmap suit your purposes? nmap -sn 192.168.12.1/24
it was suggested in your other thread, but in a different context.

install on your windows box and run it in a shell with b4j:

Dim executable As String = "c:\Program Files (x86)\Nmap\Nmap.exe"
Dim sh As Shell
sh.Initialize("sh", executable, Array("-v", "-sn","192.168.12.1/24") )

it actually uses the arp protocol which, in a way, is similar to what you were trying to do with mdns. check the full output

drgottjr

Expert
Licensed User
Longtime User
things are a little clearer to me now. for your purposes, would an mDNS broadcast that
returned the host names and their ip addresses be enough for you?

the example you show uses multicast, which is not the same as mDNS. the response from
an mDNS request is automatic (assuming your network allows such requests). there is no
particular "client" needed.

you mention having to obtain hosts' mac addresses - not ip addresses - in order to determine
whether or not they are up.

i am happy to post a java object example of an mDNS request, but not if its purpose does not
match your (initial) goal.
 
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
things are a little clearer to me now. for your purposes, would an mDNS broadcast that
returned the host names and their ip addresses be enough for you?

the example you show uses multicast, which is not the same as mDNS. the response from
an mDNS request is automatic (assuming your network allows such requests). there is no
particular "client" needed.

you mention having to obtain hosts' mac addresses - not ip addresses - in order to determine
whether or not they are up.

i am happy to post a java object example of an mDNS request, but not if its purpose does not
match your (initial) goal.
Hi
Thank you for your response. Actually either the IP Address or the MAC address will be good enough. If you understand I have 50 ESP devices using DHCP with the DNS server on the machine which allocates the IP dependant on the MAC address which is in the DB. Once the 50 ESPs are placed in ANY order, I have to Assign new IPs to them so that each column is sequential. My biggest problem is having to ping the subnet to find all the ESPs.

1734044790876.png

So after they are found using Ping, I allocate them and then they get a new IP address.
So each esp could have a Different IP address depending where the staff puts the ESP at the next function at a different venue

So the ESP's appear on the left side and I drag them into the table on the right, then in each box is the original IP and the new IP all sored in the tag.


1734045425215.png


to have an understanding of what I am doing does help. At the moment it works well but it is a time issue. the faster I can get the IP addresses will save time. This is what it looks like when setup - shown is a 4mx6m. I designed the panels with a 4 port Ethernet switch and an Ethernet ESP inside each panel

1734045856119.png


The update to the post was to use the DHCP port to determine the allocation of the initial IP, That works well but when it changes over to the new IP I lose the ability to verify it has been allocated.

I watched on wireshark port 5353 and that gives both so that would be first prize using the mDNS system. Ethernet is connected directly to the ESP from the Laptop. The 4 port switches are all dumb
 
Last edited:
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
sorry, it's not going to work. mDNS is priviledged.

wireshark grabs what it's monitoring at a lower level than at the socket layer. you can't
compare what it does to what udpsocket does. after trying a number of times and different
ways using java object without errors (but also without responses), i realized java object
with inline java (or a 3rd party jar) wasn't even needed. i could obtain the same lack of results
using b4x and jnetwork. this is because mDNS is a special variant of udp in between broadcast
and multicast. that is to say, the broadcast address and the port are technically accessible,
but the mDNS request itself isn't.

i realize this doesn't solve your problem, but you may want to clear up any confusion.
broadcast is available to all hosts on the network.
multicast is available to hosts that have joined "the group" listening to certain broadcasts.
mDNS is available to hosts that meet certain criteria, one of which can be so broad as to
include all hosts on the network. since mDNS returns the host name and ip address of hosts
that meet the criteria, you get a list of all the hosts. from there you can see which hosts do
not have an ip address. the big difference between broadcast and multicast and mDNS is
that response to an mDNS request is automatic; you don't have to code some kind of client.

this is not the primary purpose of mDNS, but it works. but the host making the mDNS request
apparently has to be root or similar. or you would have to find a library that operates at the
same level as wireshark. or run a x-nix utility as has been suggested (in your other theme).

the example you posted, was not an example of mDNS, but it would be simple enough to run
with java object.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
full disclosure. attached is an example which uses both java's standard mDNS (via javaobject) and a b4x version. as mentioned, the result is the same for both: no errors, no results.

the inline java version has 2 methods. the first method uses mDNS to search for hosts running a service on the network. this is the usual purpose for using mDNS. i have no such hosts on my tiny network. but you might. if you try that method, maybe you get a response. the second method just tries to get a response from any host on the network. the b4x code implements the same request but without the inline java.

note: the inline java calls are blocking. hence the timeouts and sleep(). the b4x code is asynch.
i've also included the java library for mdns. copy that to your b4j add'l libraries folder
 

Attachments

  • mdns.zip
    3 KB · Views: 17
  • jmdns-3.4.1.jar
    200.1 KB · Views: 20
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
full disclosure. attached is an example which uses both java's standard mDNS (via javaobject) and a b4x version. as mentioned, the result is the same for both: no errors, no results.

the inline java version has 2 methods. the first method uses mDNS to search for hosts running a service on the network. this is the usual purpose for using mDNS. i have no such hosts on my tiny network. but you might. if you try that method, maybe you get a response. the second method just tries to get a response from any host on the network. the b4x code implements the same request but without the inline java.

note: the inline java calls are blocking. hence the timeouts and sleep(). the b4x code is asynch.
i've also included the java library for mdns. copy that to your b4j add'l libraries folder
Thank you. I will only be able to try it on Sunday. Will keep you posted
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the real purpose in posting the example was to show you how to use javaobject either inline or with a 3rd party library. mdns is not as easy to work with as it appears. mainly due to os support and firewall issues. in addition, you're trying to use it in a way it wasn't designed for. that wireshark easily does what you're trying to do with mdns is because wireshark isn't really using mdns; it's operating at a lower level in the network stack.

if your setup fully supports mdns (and finding that out may not be easy), you could theoretically look for "printer.local" or a host running an http service with the java example. that's not going to help with your main problem, but you would at least see how mdns was supposed to work. it's a targeted "broadcast" where you name the
target in advance, and if the target is up, it answers. trying to get all the hosts to answer isn't going to work unless they all happen to be valid targets (eg, if you have 50
http servers, they would respond if you made an mDNS request for http servers on your network). wireshark, on the other hand, is able to monitor anybody on port 5353, irrespective of why they happen to be there.
 
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
the real purpose in posting the example was to show you how to use javaobject either inline or with a 3rd party library. mdns is not as easy to work with as it appears. mainly due to os support and firewall issues. in addition, you're trying to use it in a way it wasn't designed for. that wireshark easily does what you're trying to do with mdns is because wireshark isn't really using mdns; it's operating at a lower level in the network stack.

if your setup fully supports mdns (and finding that out may not be easy), you could theoretically look for "printer.local" or a host running an http service with the java example. that's not going to help with your main problem, but you would at least see how mdns was supposed to work. it's a targeted "broadcast" where you name the
target in advance, and if the target is up, it answers. trying to get all the hosts to answer isn't going to work unless they all happen to be valid targets (eg, if you have 50
http servers, they would respond if you made an mDNS request for http servers on your network). wireshark, on the other hand, is able to monitor anybody on port 5353, irrespective of why they happen to be there.
Seems like I always try to use something differently from what it is designed for. I understand now that Wireshark works at a lower layer and hence works. Thank you for the Info on that. Saves me time trying to find a solution there.

I suppose the DHCP requests on port 68 will have to be part of the solution eventhough it only caters for the initial IP only , but is solves a lot of the delays. There was another option I could do is to send a MQTT message from each ESP with its IP address as soon as it is assigned. Remember the secondary IPs I will know what it should be. It is the initial one that is the problem one. From 100 panels/ESPs in store, I do not know which ones are been used , so the fast discovery does help. I have timed it , the ESP communicates every 8 seconds with the DHCP server. I have 24 ESPs laid out tomorrow at a function, so I will be able o see how everything responds.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
just to try to close some loose ends here, i can use my freebsd box to query individual hosts. i used avahi (avahi is a zero-configuration networking system that uses mdns.) if the os on which the hosts reside supports mdns, they respond automatically (zero-configuration) to mdns requests. again, it's not the answer to your problem, but it was annoying not to be able to get it to do what it's supposed to do. with the right os and tool, it does work. there are other tools which sit on top of mdns. and there are tools which sit under mdns (like wireshark).
 
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
just to try to close some loose ends here, i can use my freebsd box to query individual hosts. i used avahi (avahi is a zero-configuration networking system that uses mdns.) if the os on which the hosts reside supports mdns, they respond automatically (zero-configuration) to mdns requests. again, it's not the answer to your problem, but it was annoying not to be able to get it to do what it's supposed to do. with the right os and tool, it does work. there are other tools which sit on top of mdns. and there are tools which sit under mdns (like wireshark).
Yes in my research I have come across Avahi. Unfortunately I cannot use Linux. Having a second device running Linus is not an option. I need to look at the jNetwork carefully, I have 24 ESPs connected yesterday and rand the program to sniff out DHCP but it only found 3 IP addresses. I did not have time to reprogram and check. I will have 9 panels setup this week so I can play around with it and see why I do not get all 24 panels(ESPs).

Actually, just thought of a different way. At the moment I search the IPs looking for the first one I can find, Then I use the nodes registered in the ESP to discover the rest. When the program on the ESP runs (WLED) it auto discovers other WLED nodes on that same subnet.

What I can do is to add a ESP with a fixed IP which can be right at the computer and then I only have to get nodes on that IP which will save time as I do not have to search for the first IP.

I am going to test this solution this week.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
doesn't nmap suit your purposes? nmap -sn 192.168.12.1/24
it was suggested in your other thread, but in a different context.

install on your windows box and run it in a shell with b4j:

Dim executable As String = "c:\Program Files (x86)\Nmap\Nmap.exe"
Dim sh As Shell
sh.Initialize("sh", executable, Array("-v", "-sn","192.168.12.1/24") )

it actually uses the arp protocol which, in a way, is similar to what you were trying to do with mdns. check the full output
 

Attachments

  • nmap.txt
    13.3 KB · Views: 13
Upvote 0
Solution

Peter Lewis

Active Member
Licensed User
Longtime User
doesn't nmap suit your purposes? nmap -sn 192.168.12.1/24
it was suggested in your other thread, but in a different context.

install on your windows box and run it in a shell with b4j:

Dim executable As String = "c:\Program Files (x86)\Nmap\Nmap.exe"
Dim sh As Shell
sh.Initialize("sh", executable, Array("-v", "-sn","192.168.12.1/24") )

it actually uses the arp protocol which, in a way, is similar to what you were trying to do with mdns. check the full output
Hi, Yes I think it might. I still have to test it on multiple devices to see how long it takes to scan. Looks like a powerful option for me.
As soon as I tested I will let you know
Thank you
 
Upvote 0

Peter Lewis

Active Member
Licensed User
Longtime User
doesn't nmap suit your purposes? nmap -sn 192.168.12.1/24
it was suggested in your other thread, but in a different context.

install on your windows box and run it in a shell with b4j:

Dim executable As String = "c:\Program Files (x86)\Nmap\Nmap.exe"
Dim sh As Shell
sh.Initialize("sh", executable, Array("-v", "-sn","192.168.12.1/24") )

it actually uses the arp protocol which, in a way, is similar to what you were trying to do with mdns. check the full output
nMap does solve my problem. Thank you

B4X:
Sub Pings
   
    Dim executable As String = "c:\Program Files (x86)\Nmap\Nmap.exe"
    Dim sh As Shell
    sh.Initialize("sh2", executable, Array("-v", "-sn","-iL" ,"C:\ledfloordatasplitips\iplist.txt","-oX","-"))
    sh.Run(60000)
   
End Sub

Sub sh2_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)

Dim xm As Xml2Map
        xm.Initialize
        xm.StripNamespaces = True '<--- new in v1.01
        ParsedData = xm.Parse(StdOut)
        Dim hosts As Map = ParsedData.Get("nmaprun")
        Dim host2 As List =hosts.Get("host")
    For o=0 To host2.Size-1
        Dim attr As Map = host2.get(o)
        Dim addres As Map = attr.Get("address")
        Dim status As Map = attr.Get("status")
        Dim attribu As Map =addres.Get("Attributes")
        Dim st As Map = status.GetValueAt(0)

        Log("ip address "&attribu.GetValueAt(0))
        Log("Status "&st.Get("state"))
    Next
End Sub

Waiting for debugger to connect...
Program started.
ip address 192.168.1.1
Status up
ip address 192.168.1.97
Status up
ip address 192.168.1.98
Status up
ip address 192.168.1.100
Status up
ip address 192.168.1.107
Status up
ip address 192.168.1.142
Status up
ip address 192.168.1.155
Status up
ip address 192.168.1.45
Status down
 
Upvote 0
Top