Merge pull request #3643 from cesanta/mdns

Add SD query and response to mDNS
This commit is contained in:
Sergio R. Caprile authored and GitHub committed 2026-07-24 11:50:09 -03:00
commit 61638caeae
10 files changed
+444 -93

No files matched your search

+2 -1
View File
@@ -8,7 +8,8 @@ char s_theone[] = "Server.local";
static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_MDNS_RESP) { // is this the one ?
struct mg_mdns_resp *resp = (struct mg_mdns_resp *) ev_data;
if (mg_strcasecmp(mg_str(s_theone), resp->name) == 0)
if (resp->rr->atype == MG_DNS_RTYPE_A &&
mg_strcasecmp(mg_str(s_theone), resp->name) == 0)
MG_INFO(("%.*s is: %M", resp->name.len, resp->name.buf, mg_print_ip, &resp->addr));
}
(void) c;
+25
View File
@@ -0,0 +1,25 @@
PROG ?= example # Program we are building
DELETE = rm -rf # Command to remove files
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
CFLAGS_MONGOOSE += -DMG_ENABLE_LINES
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
PROG ?= example.exe # Use .exe suffix for the binary
CC = gcc # Use MinGW gcc compiler
CFLAGS += -lws2_32 # Link against Winsock library
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
OUT ?= -o $(PROG) # Build output
endif
all: $(PROG) # Default target. Build and run program
$(RUN) ./$(PROG) $(ARGS)
$(PROG): $(SOURCES) # Build program from sources
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
clean: # Cleanup. Delete built program and all build artifacts
$(DELETE) $(PROG) *.o *.obj *.exe *.dSYM
+43
View File
@@ -0,0 +1,43 @@
Browses for `_http._tcp.local` services on the local network using mDNS/DNS-SD.
```sh
make
cc main.c mongoose.c -W -Wall -Wextra -g -I. -DMG_ENABLE_LINES -o example
./example
1304aa594 3 net.c:311:mg_mgr_init MG_IO_SIZE: 16384, TLS: none
1304aa594 3 net.c:224:mg_listen 1 4 udp://224.0.0.251:5353
1304aa594 3 sock.c:167:mg_send 1 4 0:0:0 34 err 0
1304aa594 3 sock.c:361:read_conn 1 4 0:0:0 34 err 0
1304aa594 3 dns.c:478:handle_mdns_query PTR request for _http._tcp
1304aa5d0 3 sock.c:361:read_conn 1 4 0:0:0 289 err 0
1304aa5d1 3 dns.c:703:handle_mdns_respo PTR response for _http._tcp.local from 3D03F3CPAU00096.local
1304aa5d1 2 main.c:15:mdns_ev_handler Got a response
SERVICE -> _http._tcp
NAME -> 3D03F3CPAU00096.local
PORT -> 80
TXT -> host=3D03F3CPAU00096mac=e0:50:8b:8d:2f:75ip=192.168.69.220
URL -> http://3D03F3CPAU00096.local:80
1304aa622 3 sock.c:361:read_conn 1 4 0:0:0 226 err 0
1304aa622 3 dns.c:703:handle_mdns_respo PTR response for _http._tcp.local from DIP-3TIR3020140717CCWR473261824.local
1304aa622 2 main.c:15:mdns_ev_handler Got a response
SERVICE -> _http._tcp
NAME -> DIP-3TIR3020140717CCWR473261824.local
PORT -> 80
ADDRESS -> 192.168.69.225
TXT -> path=/
URL -> http://192.168.69.225:80
1304aa6f5 3 sock.c:361:read_conn 1 4 0:0:0 169 err 0
1304aa6f5 3 dns.c:703:handle_mdns_respo PTR response for _http._tcp.local from PHILIPS_HD9255_3_6B7E5E.local
1304aa6f5 2 main.c:15:mdns_ev_handler Got a response
SERVICE -> _http._tcp
NAME -> PHILIPS_HD9255_3_6B7E5E.local
PORT -> 80
ADDRESS -> 192.168.69.167
TXT -> Device Type=Domestic Appliance
URL -> http://192.168.69.167:80
```
+58
View File
@@ -0,0 +1,58 @@
// Copyright (c) 2026 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
static char s_name[] = "Mongoose";
static char s_service[] = "_http._tcp";
static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_MDNS_RESP) {
struct mg_mdns_resp *resp = (struct mg_mdns_resp *) ev_data;
if (resp->rr->atype == MG_DNS_RTYPE_PTR &&
mg_strcasecmp(mg_str(s_service), resp->sd.srvcproto) == 0) {
char addr[40];
MG_INFO(("Got a response"));
printf("\tSERVICE -> %.*s\n", (int) resp->sd.srvcproto.len,
resp->sd.srvcproto.buf);
printf("\tNAME -> %.*s\n", (int) resp->name.len, resp->name.buf);
if (resp->sd.port != 0)
printf("\tPORT -> %u\n", resp->sd.port);
if (resp->addr.addr.ip4 != 0) {
mg_snprintf(addr, sizeof(addr), "%M", mg_print_ip, &resp->addr);
printf("\tADDRESS -> %s\n", addr);
}
if (resp->sd.txt.buf != NULL)
printf("\tTXT -> %.*s\n", (int) resp->sd.txt.len, resp->sd.txt.buf);
if (resp->addr.addr.ip4 != 0 && resp->addr.port != 0) {
mg_snprintf(addr, sizeof(addr), "http://%M:%u", mg_print_ip, &resp->addr,
mg_ntohs(resp->addr.port));
printf("\tURL -> %s\n", addr);
} else if (resp->sd.port != 0 && resp->name.buf != NULL) {
printf("\tURL -> http://%.*s:%u\n", (int) resp->name.len,
resp->name.buf, resp->sd.port);
}
printf("\n");
}
}
(void) c;
}
int main(void) {
struct mg_mgr mgr;
char query[256];
static struct mg_connection *c;
mg_log_set(MG_LL_DEBUG); // Set log level
mg_mgr_init(&mgr); // Initialise event manager
c = mg_mdns_listen(&mgr, mdns_ev_handler, s_name); // Start mDNS server
if (c == NULL) return 1;
mg_snprintf(query, sizeof(query), "%s.local", s_service);
// Request service providers
if (!mg_mdns_query(c, query, MG_DNS_RTYPE_PTR)) return 1;
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr);
return 0;
}
+1
View File
@@ -0,0 +1 @@
../../../mongoose.c
+1
View File
@@ -0,0 +1 @@
../../../mongoose.h