This tool enables the discovery of reachable hosts on a local network through either the command line or via a server.
There are two options for running the tool:
- As a command-line application
- As a server to make GET requests against
Create a .env
at the root of the project and add the following fields:
RUNTIME_ENV=dev|test|prod # Included for posterity
LOG_LEVEL=silly|debug|info|warn|error
PORT=3000
Then, run npm install
npm install
ts-node
is recommended for running this, but it is possible to run without this tool.
run:
npx ts-node . --help
or:
npm i -g ts-node
ts-node . --help
run:
npm run build
node . --help
This app exposes the following three commands for operation:
list-interfaces List network interface names of the local system.
discover <name> Bind to a network interface on the local system and find
reachable hosts on the local network.
serve Start the LAN Discovery app as a server.
Again there are two ways to run the server.
npm run start
or:
ts-node . serve
With the server up, the following curl requests can be made:
curl localhost:3000/api/v1/nics # list network interface names on the local system.
curl localhost:3000/api/v1/nics/<name>/discover-lan
npm test
Collecting coverage:
npm run test:coverage
This section is for discussing design considerations of the application.
For this I've decided to use arpjs
to read the arp table of the local network to find pingable hosts. This is more efficient than scanning the network. It does lead to pinging the broadcast IPs however it would be trivial to avoid this by doing bit manipulation to determine the IP to skip. This wikipedia page describes the bit manipulation function.
This generally should be handled by an integration testing framework like supertest or nock. It might be overkill for this application and I'd like to not spend forever getting it just perfect. In a professional setting these tests would be a requirement for the pull request.
Not strictly necessary for this application as we are only sending strings to the application.
Swagger could potentially be useful for this application as a GUI for making requests to the server, but the API is not so overly complicated that doing cURLs would be a nuisance.
Both are used in this application so that the logging needed for the command line runs are not disabled by the user-set logging level. This also allows for heightened logging levels to help debug when running as a command-line where running a debugger might be more difficult.
This application is designed to be run either as a server application or a command line app. This way the app can be flexible to meet the needs of the user. The app can technically be dockerized but there are issues with the docker networks and exposing the network interfaces.
If you're interested in dockerizing the application, it can be done by creating the following files:
Dockerfile
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE $PORT
CMD [ "node", ".", "serve" ]
docker-compose.yml
version: "3"
services:
users:
env_file: ./.env
build: ./
ports:
- "${PORT}:${PORT}"