• hk1337 7 minutes ago

    > Apple could not verify “whosthere” is free of malware that may harm your Mac or compromise your privacy.

    Couldn't run it on macOS Tahoe. I believe this requires me lowering the security to allow it, which is something I would rather not doing.

    • rvermeulen98 4 hours ago

      I've been working on a LAN discovery tool with a Terminal User Interface (TUI) written entirely in Go. It's called Whosthere, and it's designed to help you explore devices on your local network without requiring elevated privileges.

      It works by combining several discovery methods:

      - mDNS and SSDP scanning

      - ARP cache reading (after triggering ARP resolution via TCP/UDP sweeps)

      - OUI lookups to identify device manufacturers

      It also includes:

      - A fast, keyboard-driven TUI (powered by tview)

      - An optional built-in port scanner

      - Daemon mode with a simple HTTP API to fetch devices

      - Configurable theming and behavior via a YAML config file

      Why I built it:

      Mainly to learn, I've been programming in Go for about a year now and wanted to combine learning Go with learning more about networking in one single project. I've always been a big fan of TUI applications like lazygit, k9s, and dive. And then the idea came to build a TUI application that shows devices on your LAN. I am by no means a networking expert, but it was fun to figure out how ARP works, and discovery protocols such as mDNS and SSDP.

      Example usage:

      ---

      # install via HomeBrew brew tap ramonvermeulen/whosthere brew install whosthere

      # or with go install go install github.com/ramonvermeulen/whosthere@latest

      # run as TUI whosthere

      # run as daemon whosthere daemon --port 8080

      ---

      I'd love to hear your feedback, if you have ideas for additional features or improvements that is highly appreciated! Current platform support is Linux and MacOS.

      • nickcw 29 minutes ago

        Very nice tool :-)

        It would be great it it could show the reverse lookup of the IPs as on my LAN everything has a name and if it hasn't then it is probably an interloper!

      • mrcaramelpants an hour ago

        Surely a missed opportunity to name it “whogoesthere”

        • 84634E1A607A 2 hours ago

          Overall good work. I'd request an `-i` command-line parameter to specify the interface to scan (and I'd prefer ALL params being able to be read from command line params). I think it just performs a full scan initially on my laptop, following scans either didn't success or didn't involve TCP connect scan (I don't see ARP requests after the initial scan).

          • rvermeulen98 an hour ago

            That is indeed true, the initial scan only does a sweep of the subnet of the used network interface (up to a /16 max) once every 5 minutes (should make this configurable). On a subnet larger than /16 it will log a warning and scan from the first ip in the subnet up to where a /16 would end.

            I didn't want to burden the local network too much, so therefore build in this rule. The network interface can be configured via the yaml file, but I think it is a good idea to add flags for more of the configuration options that are currently supported via yaml.

          • kapitanjakc an hour ago

            Good stuff, this saves me the trouble of going through router GUI. And remembering if it was 192.168.1.1 or 0.1 or what were the admin/root passwords.

            • girishso 43 minutes ago

              Great tool, only thing I miss is it doesn't show SAMBA names.

              • petcat 2 hours ago

                I love the resurgence of TUI apps, but I wonder what the definition of "modern TUI" means in these cases. Does it basically mean just not using curses?

                • Daviey an hour ago

                  It means it has a dependency on X11.

                    $ go install github.com/ramonvermeulen/whosthere@latest
                    # golang.design/x/clipboard
                    clipboard_linux.c:14:10: fatal error: X11/Xlib.h: No such file or directory
                      14 | #include <X11/Xlib.h>
                         |          ^~~~~~~~~~~~
                    compilation terminated.
                  • petcat 27 minutes ago

                    Yikes, so it's a "TUI" app... that still requires a display server? So I can't run this TUI over SSH or a virtual terminal. Wondering what the point of a tui is that still requires a gui environment to run?

                    • Daviey 23 minutes ago

                      Sorry, I was unhelpfully flippant. You totally can, and I don't want to distract from the great app that has been shared. This bug was just a compile time issue, which needed X libs to bake in clipboard support which is optional at runtime.

                    • fellerts an hour ago

                      That has nothing to do with the UI framework. The X11 dependency comes as part of the clipboard integration (which I'd argue should be optional or even removed). Still, I wouldn't call it modern if Wayland is outright not supported.

                      • ok123456 5 minutes ago

                        What's modern about Wayland?

                        • rvermeulen98 an hour ago

                          I think this is only a problem when building from source, right? It is indeed because of the dependency on https://github.com/golang-design/clipboard.

                          I hesitated a bit bringing in this feature. On one hand, I really like to have clipboard support, on the other hand, I don't like that it requires you to change from static to dynamic linking (and have the x11 dependency).

                          Maybe I could write an install.sh script for installation that detects the OS and fetches the correct version/tarball from the Github release.

                  • Anonbrit 2 hours ago

                    It says 'Open ports: (None)' for all devices on my network, despite there being open ports on many of them (MacOS Tahoe 26.2 / installed via go)

                    • rvermeulen98 an hour ago

                      It doesn't start port scanning by default, maybe this is a feature I can build in the future. When you are on the `detail` view of a device, you can press `p` and that will open a pop-up to perform the port scan. Also the list of ports that will be scanned is a default list of common ports, and can be configured via the configuration yaml.

                    • coolius 2 hours ago

                      this is great! i had to tweak the config file on macos because it was using some weird interface (utun4) instead of en0. otherwise awesome tool, i am definitely going to be using this more often.

                      • rvermeulen98 an hour ago

                        Thanks, I am glad you like it! I couldn't find a Go API that just returns the OS "default" network interface, so struggled a bit with a correct implementation for that part.

                        When reading some blog posts, I found often a solution where it sends out an UDP dial to for example 8.8.8.8:53 because you can then get the network interface back from the connection it's local address. As fallback I implemented to pick the first non-loopback interface that is up.

                        Would be open to suggestions to do this in a better way!

                        • fellerts an hour ago

                          I think this package does exactly what you need: https://pkg.go.dev/github.com/google/gopacket/routing. Works on my machine (error handling left to the reader)

                              router, _ := routing.New()
                              iface, _, _, _ := router.Route(net.ParseIP("8.8.8.8"))
                              fmt.Println(iface.Name)
                          
                          this prints my Ethernet interface as expected. It doesn't make any requests, it just figures out where to route a packet. I guess it interfaces with the OS routing table.
                          • rvermeulen98 16 minutes ago

                            Thanks for sharing! This is definitely something I will look into, I am all in favor to simplify the current implementation of finding the "default" OS network interface.