Merge pull request #3449 from cesanta/mdns

Obtain IP adress for MDNS automatically
This commit is contained in:
Sergio R. Caprile authored and GitHub committed 2026-03-13 13:57:14 -03:00
commit 2121be1abe
8 files changed
+193 -85

No files matched your search

+72 -25
View File
@@ -260,7 +260,8 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4);
dm->resolved = true;
break; // Return success
} else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA && rr.aclass == 1) {
} else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA &&
rr.aclass == 1) {
dm->addr.is_ip6 = true;
memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16);
dm->resolved = true;
@@ -379,7 +380,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
uint16_t id;
mg_random(&id, sizeof(uint16_t));
// TODO(): traverse reqs and check id != reqs->txnid; repeat otherwise
if (reqs != NULL) id = (uint16_t) (reqs->txnid + 1); // no collision
if (reqs != NULL) id = (uint16_t) (reqs->txnid + 1); // no collision
d->txnid = id;
d->next = reqs;
c->mgr->active_dns_requests = d;
@@ -423,13 +424,26 @@ static uint8_t *build_name(struct mg_str *name, uint8_t *p) {
return p;
}
static uint8_t *build_a_record(struct mg_connection *c, uint8_t *p) {
void mg_getlocaddr(struct mg_connection *, struct mg_addr *, struct mg_addr *);
static uint8_t *build_a_record(struct mg_connection *c, uint8_t *p,
struct mg_addr *addr) {
memcpy(p, mdns_answer, sizeof(mdns_answer)), p += sizeof(mdns_answer);
if (addr != NULL && !addr->is_ip6) {
memcpy(p, &addr->addr.ip4, 4), p += 4;
} else {
#if MG_ENABLE_TCPIP
memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
#else
memcpy(p, c->data, 4), p += 4;
struct mg_addr loc, to;
memset(&loc, 0, sizeof(loc));
to.is_ip6 = false;
to.port = mg_htons(5353);
to.addr.ip4 = MG_IPV4(224, 0, 0, 51);
mg_getlocaddr(c, &to, &loc);
memcpy(p, &loc.addr.ip4, 4), p += 4;
#endif
}
return p;
}
@@ -523,7 +537,7 @@ static void handle_mdns_query(struct mg_connection *c) {
qh->num_questions = mg_htons(1); // parser sanity
mg_dns_parse_name(c->recv.buf, c->recv.len, 12, name, sizeof(name));
name_len = (uint8_t) strlen(name); // verify it ends in .local
if (strcmp(".local", &name[name_len - 6]) != 0 ||
if (name_len <= 6 || strcmp(".local", &name[name_len - 6]) != 0 ||
(rr.aclass != 1 && rr.aclass != 0xff))
return;
name[name_len -= 6] = '\0'; // remove .local
@@ -545,7 +559,8 @@ static void handle_mdns_query(struct mg_connection *c) {
("PTR request for %s", req.is_listing ? "services listing" : name));
req.reqname = mg_str_n(name, name_len);
} else if (rr.atype == MG_DNS_RTYPE_SRV || rr.atype == MG_DNS_RTYPE_TXT) {
MG_DEBUG(("%s request for %s", rr.atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", name));
MG_DEBUG(("%s request for %s",
rr.atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", name));
// if possible, check it starts with our name, users will check it ends
// in a service name they handle
if (c->fn_data != NULL) {
@@ -602,7 +617,7 @@ static void handle_mdns_query(struct mg_connection *c) {
offset = mg_htons((uint16_t) (o - buf));
memcpy(p, &offset, 2); // point to target name, in record
*p |= 0xC0, p += 2;
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
} else if (rr.atype == MG_DNS_RTYPE_TXT) {
p = build_srv_name(p, req.r);
p = build_txt_record(p, req.r);
@@ -619,16 +634,17 @@ static void handle_mdns_query(struct mg_connection *c) {
offset = mg_htons((uint16_t) (o - buf));
memcpy(p, &offset, 2); // point to target name, in record
*p |= 0xC0, p += 2;
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
} else { // A requested
// RFC-6762 6: 0 Auth, 0 Additional RRs
if (respname->buf == NULL || respname->len == 0) return;
p = build_name(respname, p);
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
}
if (!req.is_unicast) mg_multicast_restore(c, (uint8_t *) &c->loc);
mg_send(c, buf, (size_t) (p - buf)); // And send it!
MG_DEBUG(("mDNS %c response sent", req.is_unicast ? 'U' : 'M'));
MG_DEBUG(("%M > %M", mg_print_ip_port, &c->loc, mg_print_ip_port, &c->rem));
MG_DEBUG(("mDNS %s response sent", req.is_unicast ? "unicast" : "mcast"));
}
}
@@ -641,22 +657,27 @@ static void handle_mdns_response(struct mg_connection *c) {
MG_VERBOSE(("mDNS response parsed, result=%d", (int) n));
if (n > 0) {
// RFC-6762 Appendix C, RFC2181 11: m(n + 1-63), max 255 + 0x0
char name[256];
char name[256];
uint8_t name_len;
struct mg_mdns_resp resp;
memset(&resp, 0, sizeof(resp));
if (rh->num_answers > mg_htons(1)) MG_DEBUG(("ignoring > 1 answers"));
mg_dns_parse_name(c->recv.buf, c->recv.len, 12, name, sizeof(name));
name_len = (uint8_t) strlen(name); // verify it ends in .local
MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype, (unsigned int) rr.aclass, name));
if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A && (rr.aclass & 0x7FFF) == 1) {
MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype,
(unsigned int) rr.aclass, name));
if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A &&
(rr.aclass & 0x7FFF) == 1) {
resp.addr.is_ip6 = false;
memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 4, 4);
MG_DEBUG(("A response from %.*s = %M", name_len, name, mg_print_ip, &resp.addr));
// } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA && (rr.aclass & 0x7FFF) == 1) {
// resp.addr.is_ip6 = true;
// memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 16], 16);
// MG_DEBUG(("AAAA response from %.*s = %M", name_len, name, mg_print_ip, &resp.addr));
memcpy(resp.addr.addr.ip, (char *) (rh + 1) + n - 4, 4);
MG_DEBUG(("A response from %.*s = %M", name_len, name, mg_print_ip,
&resp.addr));
// } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA &&
// (rr.aclass & 0x7FFF) == 1) {
// resp.addr.is_ip6 = true;
// memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 16], 16);
// MG_DEBUG(("AAAA response from %.*s = %M", name_len, name,
// mg_print_ip, &resp.addr));
} else {
return;
}
@@ -697,9 +718,10 @@ struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
return c;
}
bool mg_mdns_query(struct mg_connection *c, const char *name, unsigned int rtype) {
bool mg_mdns_query(struct mg_connection *c, const char *name,
unsigned int rtype) {
struct mg_str name_;
name_.buf = (char *)name, name_.len = strlen(name);
name_.buf = (char *) name, name_.len = strlen(name);
mg_multicast_restore(c, (uint8_t *) &c->loc);
(void) rtype;
return mg_dns_send(c, &name_, 0, false);
@@ -10417,15 +10439,17 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
a->is_ip6 = is_ip6;
a->port = usa->sin.sin_port;
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (is_ip6) {
memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip));
a->port = usa->sin6.sin6_port;
a->scope_id = (uint8_t) usa->sin6.sin6_scope_id;
}
} else
#endif
{
a->port = usa->sin.sin_port;
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
}
}
static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
@@ -10436,6 +10460,29 @@ static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
}
}
// Get the local 'addr' the stack will use to connect to 'to'
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr);
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr) {
union usa usa;
socklen_t slen;
MG_SOCKET_TYPE fd;
int rc, af = to->is_ip6 ? AF_INET6 : AF_INET;
fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
if (fd == MG_INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
return;
}
// NOTE(): TI-RTOS NDK may require binding
slen = tousa(to, &usa);
if ((rc = connect(fd, &usa.sa, slen)) != 0) {
mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
return;
}
setlocaddr(fd, addr);
closesocket(fd);
}
static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
if (n == MG_IO_WAIT) {
// Do nothing
+8 -9
View File
@@ -2950,12 +2950,11 @@ size_t mg_mqtt_next_prop(struct mg_mqtt_message *, struct mg_mqtt_prop *,
#define MG_DNS_RTYPE_A 1
#define MG_DNS_RTYPE_PTR 12
#define MG_DNS_RTYPE_TXT 16
#define MG_DNS_RTYPE_AAAA 28
#define MG_DNS_RTYPE_SRV 33
#define MG_DNS_RTYPE_A 1
#define MG_DNS_RTYPE_PTR 12
#define MG_DNS_RTYPE_TXT 16
#define MG_DNS_RTYPE_AAAA 28
#define MG_DNS_RTYPE_SRV 33
// Mongoose sends DNS queries that contain only one question:
// either A (IPv4) or AAAA (IPv6) address lookup.
@@ -2998,7 +2997,7 @@ struct mg_mdns_req {
struct mg_dnssd_record *r;
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name to use in response
struct mg_addr addr;
struct mg_addr *addr; // actual address to use in response
bool is_listing;
bool is_resp;
bool is_unicast;
@@ -3006,10 +3005,10 @@ struct mg_mdns_req {
struct mg_mdns_resp {
struct mg_dns_rr *rr;
// TODO(scaprile )struct mg_str srvcproto; struct mg_str txt; uint16_t port; ?
// TODO(scaprile )struct mg_str srvcproto; struct mg_str txt; uint16_t port; ?
struct mg_str name;
struct mg_addr addr;
// TODO(scaprile); bool has_A; bool has_PTR; bool has_SRV; bool has_TXT; ?
// TODO(scaprile); bool has_A; bool has_PTR; bool has_SRV; bool has_TXT; ?
};
void mg_resolve(struct mg_connection *, const char *url);
+44 -22
View File
@@ -139,7 +139,8 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4);
dm->resolved = true;
break; // Return success
} else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA && rr.aclass == 1) {
} else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA &&
rr.aclass == 1) {
dm->addr.is_ip6 = true;
memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16);
dm->resolved = true;
@@ -258,7 +259,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
uint16_t id;
mg_random(&id, sizeof(uint16_t));
// TODO(): traverse reqs and check id != reqs->txnid; repeat otherwise
if (reqs != NULL) id = (uint16_t) (reqs->txnid + 1); // no collision
if (reqs != NULL) id = (uint16_t) (reqs->txnid + 1); // no collision
d->txnid = id;
d->next = reqs;
c->mgr->active_dns_requests = d;
@@ -302,13 +303,26 @@ static uint8_t *build_name(struct mg_str *name, uint8_t *p) {
return p;
}
static uint8_t *build_a_record(struct mg_connection *c, uint8_t *p) {
void mg_getlocaddr(struct mg_connection *, struct mg_addr *, struct mg_addr *);
static uint8_t *build_a_record(struct mg_connection *c, uint8_t *p,
struct mg_addr *addr) {
memcpy(p, mdns_answer, sizeof(mdns_answer)), p += sizeof(mdns_answer);
if (addr != NULL && !addr->is_ip6) {
memcpy(p, &addr->addr.ip4, 4), p += 4;
} else {
#if MG_ENABLE_TCPIP
memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
memcpy(p, &c->mgr->ifp->ip, 4), p += 4;
#else
memcpy(p, c->data, 4), p += 4;
struct mg_addr loc, to;
memset(&loc, 0, sizeof(loc));
to.is_ip6 = false;
to.port = mg_htons(5353);
to.addr.ip4 = MG_IPV4(224, 0, 0, 51);
mg_getlocaddr(c, &to, &loc);
memcpy(p, &loc.addr.ip4, 4), p += 4;
#endif
}
return p;
}
@@ -402,7 +416,7 @@ static void handle_mdns_query(struct mg_connection *c) {
qh->num_questions = mg_htons(1); // parser sanity
mg_dns_parse_name(c->recv.buf, c->recv.len, 12, name, sizeof(name));
name_len = (uint8_t) strlen(name); // verify it ends in .local
if (strcmp(".local", &name[name_len - 6]) != 0 ||
if (name_len <= 6 || strcmp(".local", &name[name_len - 6]) != 0 ||
(rr.aclass != 1 && rr.aclass != 0xff))
return;
name[name_len -= 6] = '\0'; // remove .local
@@ -424,7 +438,8 @@ static void handle_mdns_query(struct mg_connection *c) {
("PTR request for %s", req.is_listing ? "services listing" : name));
req.reqname = mg_str_n(name, name_len);
} else if (rr.atype == MG_DNS_RTYPE_SRV || rr.atype == MG_DNS_RTYPE_TXT) {
MG_DEBUG(("%s request for %s", rr.atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", name));
MG_DEBUG(("%s request for %s",
rr.atype == MG_DNS_RTYPE_SRV ? "SRV" : "TXT", name));
// if possible, check it starts with our name, users will check it ends
// in a service name they handle
if (c->fn_data != NULL) {
@@ -481,7 +496,7 @@ static void handle_mdns_query(struct mg_connection *c) {
offset = mg_htons((uint16_t) (o - buf));
memcpy(p, &offset, 2); // point to target name, in record
*p |= 0xC0, p += 2;
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
} else if (rr.atype == MG_DNS_RTYPE_TXT) {
p = build_srv_name(p, req.r);
p = build_txt_record(p, req.r);
@@ -498,16 +513,17 @@ static void handle_mdns_query(struct mg_connection *c) {
offset = mg_htons((uint16_t) (o - buf));
memcpy(p, &offset, 2); // point to target name, in record
*p |= 0xC0, p += 2;
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
} else { // A requested
// RFC-6762 6: 0 Auth, 0 Additional RRs
if (respname->buf == NULL || respname->len == 0) return;
p = build_name(respname, p);
p = build_a_record(c, p);
p = build_a_record(c, p, req.addr);
}
if (!req.is_unicast) mg_multicast_restore(c, (uint8_t *) &c->loc);
mg_send(c, buf, (size_t) (p - buf)); // And send it!
MG_DEBUG(("mDNS %c response sent", req.is_unicast ? 'U' : 'M'));
MG_DEBUG(("%M > %M", mg_print_ip_port, &c->loc, mg_print_ip_port, &c->rem));
MG_DEBUG(("mDNS %s response sent", req.is_unicast ? "unicast" : "mcast"));
}
}
@@ -520,22 +536,27 @@ static void handle_mdns_response(struct mg_connection *c) {
MG_VERBOSE(("mDNS response parsed, result=%d", (int) n));
if (n > 0) {
// RFC-6762 Appendix C, RFC2181 11: m(n + 1-63), max 255 + 0x0
char name[256];
char name[256];
uint8_t name_len;
struct mg_mdns_resp resp;
memset(&resp, 0, sizeof(resp));
if (rh->num_answers > mg_htons(1)) MG_DEBUG(("ignoring > 1 answers"));
mg_dns_parse_name(c->recv.buf, c->recv.len, 12, name, sizeof(name));
name_len = (uint8_t) strlen(name); // verify it ends in .local
MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype, (unsigned int) rr.aclass, name));
if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A && (rr.aclass & 0x7FFF) == 1) {
MG_VERBOSE(("RR %u %u %s", (unsigned int) rr.atype,
(unsigned int) rr.aclass, name));
if (rr.alen == 4 && rr.atype == MG_DNS_RTYPE_A &&
(rr.aclass & 0x7FFF) == 1) {
resp.addr.is_ip6 = false;
memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 4, 4);
MG_DEBUG(("A response from %.*s = %M", name_len, name, mg_print_ip, &resp.addr));
// } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA && (rr.aclass & 0x7FFF) == 1) {
// resp.addr.is_ip6 = true;
// memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 16], 16);
// MG_DEBUG(("AAAA response from %.*s = %M", name_len, name, mg_print_ip, &resp.addr));
memcpy(resp.addr.addr.ip, (char *) (rh + 1) + n - 4, 4);
MG_DEBUG(("A response from %.*s = %M", name_len, name, mg_print_ip,
&resp.addr));
// } else if (rr.alen == 16 && rr.atype == MG_DNS_RTYPE_AAAA &&
// (rr.aclass & 0x7FFF) == 1) {
// resp.addr.is_ip6 = true;
// memcpy(resp.addr.addr.ip, (char *)(rh + 1) + n - 16], 16);
// MG_DEBUG(("AAAA response from %.*s = %M", name_len, name,
// mg_print_ip, &resp.addr));
} else {
return;
}
@@ -576,9 +597,10 @@ struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
return c;
}
bool mg_mdns_query(struct mg_connection *c, const char *name, unsigned int rtype) {
bool mg_mdns_query(struct mg_connection *c, const char *name,
unsigned int rtype) {
struct mg_str name_;
name_.buf = (char *)name, name_.len = strlen(name);
name_.buf = (char *) name, name_.len = strlen(name);
mg_multicast_restore(c, (uint8_t *) &c->loc);
(void) rtype;
return mg_dns_send(c, &name_, 0, false);
+8 -9
View File
@@ -3,12 +3,11 @@
#include "net.h"
#include "str.h"
#define MG_DNS_RTYPE_A 1
#define MG_DNS_RTYPE_PTR 12
#define MG_DNS_RTYPE_TXT 16
#define MG_DNS_RTYPE_AAAA 28
#define MG_DNS_RTYPE_SRV 33
#define MG_DNS_RTYPE_A 1
#define MG_DNS_RTYPE_PTR 12
#define MG_DNS_RTYPE_TXT 16
#define MG_DNS_RTYPE_AAAA 28
#define MG_DNS_RTYPE_SRV 33
// Mongoose sends DNS queries that contain only one question:
// either A (IPv4) or AAAA (IPv6) address lookup.
@@ -51,7 +50,7 @@ struct mg_mdns_req {
struct mg_dnssd_record *r;
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name to use in response
struct mg_addr addr;
struct mg_addr *addr; // actual address to use in response
bool is_listing;
bool is_resp;
bool is_unicast;
@@ -59,10 +58,10 @@ struct mg_mdns_req {
struct mg_mdns_resp {
struct mg_dns_rr *rr;
// TODO(scaprile )struct mg_str srvcproto; struct mg_str txt; uint16_t port; ?
// TODO(scaprile )struct mg_str srvcproto; struct mg_str txt; uint16_t port; ?
struct mg_str name;
struct mg_addr addr;
// TODO(scaprile); bool has_A; bool has_PTR; bool has_SRV; bool has_TXT; ?
// TODO(scaprile); bool has_A; bool has_PTR; bool has_SRV; bool has_TXT; ?
};
void mg_resolve(struct mg_connection *, const char *url);
+28 -3
View File
@@ -72,15 +72,17 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
a->is_ip6 = is_ip6;
a->port = usa->sin.sin_port;
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (is_ip6) {
memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip));
a->port = usa->sin6.sin6_port;
a->scope_id = (uint8_t) usa->sin6.sin6_scope_id;
}
} else
#endif
{
a->port = usa->sin.sin_port;
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
}
}
static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
@@ -91,6 +93,29 @@ static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
}
}
// Get the local 'addr' the stack will use to connect to 'to'
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr);
void mg_getlocaddr(struct mg_connection *c, struct mg_addr *to, struct mg_addr *addr) {
union usa usa;
socklen_t slen;
MG_SOCKET_TYPE fd;
int rc, af = to->is_ip6 ? AF_INET6 : AF_INET;
fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
if (fd == MG_INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
return;
}
// NOTE(): TI-RTOS NDK may require binding
slen = tousa(to, &usa);
if ((rc = connect(fd, &usa.sa, slen)) != 0) {
mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
return;
}
setlocaddr(fd, addr);
closesocket(fd);
}
static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
if (n == MG_IO_WAIT) {
// Do nothing
-5
View File
@@ -15,7 +15,6 @@ static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
}
int main(void) {
uint32_t response_ip = inet_addr("192.168.69.11");
struct mg_mgr mgr;
static struct mg_connection *c;
mg_log_set(MG_LL_DEBUG); // Set log level
@@ -24,10 +23,6 @@ int main(void) {
// Desired name must NOT have any dots in it, nor a domain
c = mg_mdns_listen(&mgr, mdns_ev_handler, "Mongoose"); // Start mDNS server
if (c == NULL) return 1;
// if not using our built-in TCP/IP stack, pass the IP address you want to
// use as a response, this depends on your underlying TCP/IP stack and number
// of interfaces available
memcpy(c->data, &response_ip, sizeof(response_ip));
if (!mg_mdns_query(c, s_theone, MG_DNS_RTYPE_A)) return 1;
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
+6 -7
View File
@@ -15,7 +15,10 @@
// Desired name must NOT have any dots in it, nor a domain
#define MDNS_NAME "mongoose-device"
#define WEB_SERVER_ADDR "http://0.0.0.0:8000" // port is hardcoded below
#define RESPONSE_IP "192.168.69.11"
// When not using our built-in TCP/IP stack, Mongoose responds with the address
// of the interface in which the request came in. If, for some reason, you want
// to use some other address, fill req->addr. See: mdns-client advanced example
#ifdef ADVANCED_EXAMPLE
// A TXT record data containing JSON, if actually needed.
@@ -80,7 +83,8 @@ static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
req->rr->atype == MG_DNS_RTYPE_TXT) {
// Mongoose already checked the host name for us, otherwise we need to do
// that ourselves first, then check for service name in db
struct mg_dnssd_record *r = (struct mg_dnssd_record *) dnssd_lookup(req->reqname);
struct mg_dnssd_record *r =
(struct mg_dnssd_record *) dnssd_lookup(req->reqname);
if (r == NULL) return;
req->r = r;
req->is_resp = true;
@@ -107,17 +111,12 @@ static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
int main(void) {
struct mg_mgr mgr;
static struct mg_connection *c;
uint32_t response_ip = inet_addr(RESPONSE_IP);
mg_log_set(MG_LL_DEBUG); // Set log level
mg_mgr_init(&mgr); // Initialise event manager
c = mg_mdns_listen(&mgr, mdns_ev_handler, MDNS_NAME);
if (c == NULL) return 1;
// if not using our built-in TCP/IP stack, pass the IP address you want to
// use as a response, this depends on your underlying TCP/IP stack and number
// of interfaces available
memcpy(c->data, &response_ip, sizeof(response_ip));
mg_http_listen(&mgr, WEB_SERVER_ADDR, http_ev_handler, NULL);
+27 -5
View File
@@ -3,23 +3,45 @@
#include "mongoose.h"
#ifdef ADVANCED_EXAMPLE
static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data);
#endif
int main(void) {
uint32_t response_ip = inet_addr("192.168.69.11");
struct mg_mgr mgr;
static struct mg_connection *c;
mg_log_set(MG_LL_DEBUG); // Set log level
mg_mgr_init(&mgr); // Initialise event manager
// Desired name must NOT have any dots in it, nor a domain
#ifndef ADVANCED_EXAMPLE
c = mg_mdns_listen(&mgr, NULL, "Mongoose"); // Start mDNS server
#else
c = mg_mdns_listen(&mgr, mdns_ev_handler, "Mongoose"); // Start mDNS server
#endif
if (c == NULL) return 1;
// if not using our built-in TCP/IP stack, pass the IP address you want to
// use as a response, this depends on your underlying TCP/IP stack and number
// of interfaces available
memcpy(c->data, &response_ip, sizeof(response_ip));
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr);
return 0;
}
// When not using our built-in TCP/IP stack, Mongoose responds with the address
// of the interface in which the request came in. If, for some reason, you want
// to use some other address, catch the MG_EV_MDNS_REQ event for MG_DNS_RTYPE_A
// requests, and fill your desired address
#ifdef ADVANCED_EXAMPLE
static void mdns_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_MDNS_REQ) {
struct mg_mdns_req *req = (struct mg_mdns_req *) ev_data;
if (req->rr->atype == MG_DNS_RTYPE_A) {
struct mg_addr myaddr;
memset(&myaddr, 0, sizeof(myaddr));
myaddr.addr.ip4 = MG_IPV4(1, 2, 3, 4);
req->addr = &myaddr;
}
}
(void) c;
}
#endif