aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h')
-rw-r--r--ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h950
1 files changed, 459 insertions, 491 deletions
diff --git a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
index ff04b5d72..4b8e7a7f4 100644
--- a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
+++ b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
@@ -7,7 +7,8 @@
*
* https://github.com/mjansson/mdns
*
- * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions.
+ * This library is put in the public domain; you can redistribute it and/or
+ * modify it without any restrictions.
*
*/
@@ -31,76 +32,73 @@
#define MDNS_INVALID_POS ((size_t)-1)
-#define MDNS_STRING_CONST(s) (s), (sizeof((s))-1)
+#define MDNS_STRING_CONST(s) (s), (sizeof((s)) - 1)
#define MDNS_STRING_FORMAT(s) (int)((s).length), s.str
enum mdns_record_type {
- MDNS_RECORDTYPE_IGNORE = 0,
- //Address
- MDNS_RECORDTYPE_A = 1,
- //Domain Name pointer
- MDNS_RECORDTYPE_PTR = 12,
- //Arbitrary text string
- MDNS_RECORDTYPE_TXT = 16,
- //IP6 Address [Thomson]
- MDNS_RECORDTYPE_AAAA = 28,
- //Server Selection [RFC2782]
- MDNS_RECORDTYPE_SRV = 33
+ MDNS_RECORDTYPE_IGNORE = 0,
+ // Address
+ MDNS_RECORDTYPE_A = 1,
+ // Domain Name pointer
+ MDNS_RECORDTYPE_PTR = 12,
+ // Arbitrary text string
+ MDNS_RECORDTYPE_TXT = 16,
+ // IP6 Address [Thomson]
+ MDNS_RECORDTYPE_AAAA = 28,
+ // Server Selection [RFC2782]
+ MDNS_RECORDTYPE_SRV = 33
};
enum mdns_entry_type {
- MDNS_ENTRYTYPE_ANSWER = 1,
- MDNS_ENTRYTYPE_AUTHORITY = 2,
- MDNS_ENTRYTYPE_ADDITIONAL = 3
+ MDNS_ENTRYTYPE_ANSWER = 1,
+ MDNS_ENTRYTYPE_AUTHORITY = 2,
+ MDNS_ENTRYTYPE_ADDITIONAL = 3
};
-enum mdns_class {
- MDNS_CLASS_IN = 1
-};
+enum mdns_class { MDNS_CLASS_IN = 1 };
-typedef enum mdns_record_type mdns_record_type_t;
-typedef enum mdns_entry_type mdns_entry_type_t;
-typedef enum mdns_class mdns_class_t;
+typedef enum mdns_record_type mdns_record_type_t;
+typedef enum mdns_entry_type mdns_entry_type_t;
+typedef enum mdns_class mdns_class_t;
-typedef int (* mdns_record_callback_fn)(const struct sockaddr* from,
- mdns_entry_type_t entry, uint16_t type,
- uint16_t rclass, uint32_t ttl,
- const void* data, size_t size, size_t offset, size_t length,
- void* user_data);
+typedef int (*mdns_record_callback_fn)(const struct sockaddr* from,
+ mdns_entry_type_t entry, uint16_t type,
+ uint16_t rclass, uint32_t ttl,
+ const void* data, size_t size,
+ size_t offset, size_t length,
+ void* user_data);
-typedef struct mdns_string_t mdns_string_t;
-typedef struct mdns_string_pair_t mdns_string_pair_t;
-typedef struct mdns_record_srv_t mdns_record_srv_t;
-typedef struct mdns_record_txt_t mdns_record_txt_t;
+typedef struct mdns_string_t mdns_string_t;
+typedef struct mdns_string_pair_t mdns_string_pair_t;
+typedef struct mdns_record_srv_t mdns_record_srv_t;
+typedef struct mdns_record_txt_t mdns_record_txt_t;
struct mdns_string_t {
- const char* str;
- size_t length;
+ const char* str;
+ size_t length;
};
struct mdns_string_pair_t {
- size_t offset;
- size_t length;
- int ref;
+ size_t offset;
+ size_t length;
+ int ref;
};
struct mdns_record_srv_t {
- uint16_t priority;
- uint16_t weight;
- uint16_t port;
- mdns_string_t name;
+ uint16_t priority;
+ uint16_t weight;
+ uint16_t port;
+ mdns_string_t name;
};
struct mdns_record_txt_t {
- mdns_string_t key;
- mdns_string_t value;
+ mdns_string_t key;
+ mdns_string_t value;
};
-static int
-mdns_socket_open_ipv4(void);
+static int mdns_socket_open_ipv4(void);
-static int
-mdns_socket_setup_ipv4(int sock);
+static int mdns_socket_setup_ipv4(int sock);
#if 0
static int
@@ -112,8 +110,7 @@ static int
mdns_socket_setup_ipv6(int sock);
#endif
-static void
-mdns_socket_close(int sock);
+static void mdns_socket_close(int sock);
#if 0
static int
@@ -125,21 +122,18 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity,
mdns_record_callback_fn callback, void* user_data);
#endif
-static int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length,
- void* buffer, size_t capacity);
+static int mdns_query_send(int sock, mdns_record_type_t type, const char* name,
+ size_t length, void* buffer, size_t capacity);
-static size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity,
- mdns_record_callback_fn callback, void* user_data,
- uint8_t one_shot);
+static size_t mdns_query_recv(int sock, void* buffer, size_t capacity,
+ mdns_record_callback_fn callback, void* user_data,
+ uint8_t one_shot);
-static mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset,
- char* str, size_t capacity);
+static mdns_string_t mdns_string_extract(const void* buffer, size_t size,
+ size_t* offset, char* str,
+ size_t capacity);
-static int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset);
+static int mdns_string_skip(const void* buffer, size_t size, size_t* offset);
#if 0
static int
@@ -147,78 +141,80 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs,
const void* buffer_rhs, size_t size_rhs, size_t* ofs_rhs);
#endif
-static void*
-mdns_string_make(void* data, size_t capacity, const char* name, size_t length);
+static void* mdns_string_make(void* data, size_t capacity, const char* name,
+ size_t length);
-static mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
+static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer, size_t capacity);
-static mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
+static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer,
+ size_t capacity);
-static struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr);
+static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ struct sockaddr_in* addr);
-static struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr);
+static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer,
+ size_t size, size_t offset,
+ size_t length,
+ struct sockaddr_in6* addr);
-static size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity);
+static size_t mdns_record_parse_txt(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ mdns_record_txt_t* records,
+ size_t capacity);
// Implementations
-static int
-mdns_socket_open_ipv4(void) {
- int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0)
- return -1;
- if (mdns_socket_setup_ipv4(sock)) {
- mdns_socket_close(sock);
- return -1;
- }
- return sock;
+static int mdns_socket_open_ipv4(void) {
+ int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0) return -1;
+ if (mdns_socket_setup_ipv4(sock)) {
+ mdns_socket_close(sock);
+ return -1;
+ }
+ return sock;
}
-static int
-mdns_socket_setup_ipv4(int sock) {
- struct sockaddr_in saddr;
- memset(&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = INADDR_ANY;
+static int mdns_socket_setup_ipv4(int sock) {
+ struct sockaddr_in saddr;
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = INADDR_ANY;
#ifdef __APPLE__
- saddr.sin_len = sizeof(saddr);
+ saddr.sin_len = sizeof(saddr);
#endif
- if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr)))
- return -1;
+ if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))) return -1;
#ifdef _WIN32
- unsigned long param = 1;
- ioctlsocket(sock, FIONBIO, &param);
+ unsigned long param = 1;
+ ioctlsocket(sock, FIONBIO, &param);
#else
- const int flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ const int flags = fcntl(sock, F_GETFL, 0);
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
#endif
- unsigned char ttl = 1;
- unsigned char loopback = 1;
- struct ip_mreq req;
+ unsigned char ttl = 1;
+ unsigned char loopback = 1;
+ struct ip_mreq req;
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl));
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl,
+ sizeof(ttl));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback,
+ sizeof(loopback));
- memset(&req, 0, sizeof(req));
- req.imr_multiaddr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- req.imr_interface.s_addr = INADDR_ANY;
- if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
- return -1;
+ memset(&req, 0, sizeof(req));
+ req.imr_multiaddr.s_addr =
+ htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ req.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
+ return -1;
- return 0;
+ return 0;
}
#if 0
@@ -274,67 +270,58 @@ mdns_socket_setup_ipv6(int sock) {
}
#endif
-static void
-mdns_socket_close(int sock) {
+static void mdns_socket_close(int sock) {
#ifdef _WIN32
- closesocket(sock);
+ closesocket(sock);
#else
- close(sock);
+ close(sock);
#endif
}
-static int
-mdns_is_string_ref(uint8_t val) {
- return (0xC0 == (val & 0xC0));
-}
+static int mdns_is_string_ref(uint8_t val) { return (0xC0 == (val & 0xC0)); }
-static mdns_string_pair_t
-mdns_get_next_substring(const void* rawdata, size_t size, size_t offset) {
- const uint8_t* buffer = rawdata;
- mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
- if (!buffer[offset]) {
- pair.offset = offset;
- return pair;
- }
- if (mdns_is_string_ref(buffer[offset])) {
- if (size < offset + 2)
- return pair;
+static mdns_string_pair_t mdns_get_next_substring(const void* rawdata,
+ size_t size, size_t offset) {
+ const uint8_t* buffer = rawdata;
+ mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
+ if (!buffer[offset]) {
+ pair.offset = offset;
+ return pair;
+ }
+ if (mdns_is_string_ref(buffer[offset])) {
+ if (size < offset + 2) return pair;
- offset = (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]);
- if (offset >= size)
- return pair;
+ offset =
+ (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]);
+ if (offset >= size) return pair;
- pair.ref = 1;
- }
+ pair.ref = 1;
+ }
- size_t length = (size_t)buffer[offset++];
- if (size < offset + length)
- return pair;
+ size_t length = (size_t)buffer[offset++];
+ if (size < offset + length) return pair;
- pair.offset = offset;
- pair.length = length;
+ pair.offset = offset;
+ pair.length = length;
- return pair;
+ return pair;
}
-static int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
- size_t cur = *offset;
- mdns_string_pair_t substr;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if (substr.offset == MDNS_INVALID_POS)
- return 0;
- if (substr.ref) {
- *offset = cur + 2;
- return 1;
- }
- cur = substr.offset + substr.length;
- }
- while (substr.length);
-
- *offset = cur + 1;
- return 1;
+static int mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
+ size_t cur = *offset;
+ mdns_string_pair_t substr;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if (substr.offset == MDNS_INVALID_POS) return 0;
+ if (substr.ref) {
+ *offset = cur + 2;
+ return 1;
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ *offset = cur + 1;
+ return 1;
}
#if 0
@@ -378,142 +365,133 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs,
}
#endif
-static mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset,
- char* str, size_t capacity) {
- size_t cur = *offset;
- size_t end = MDNS_INVALID_POS;
- mdns_string_pair_t substr;
- mdns_string_t result = {str, 0};
- char* dst = str;
- size_t remain = capacity;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if (substr.offset == MDNS_INVALID_POS)
- return result;
- if (substr.ref && (end == MDNS_INVALID_POS))
- end = cur + 2;
- if (substr.length) {
- size_t to_copy = (substr.length < remain) ? substr.length : remain;
- memcpy(dst, (const char*)buffer + substr.offset, to_copy);
- dst += to_copy;
- remain -= to_copy;
- if (remain) {
- *dst++ = '.';
- --remain;
- }
- }
- cur = substr.offset + substr.length;
- }
- while (substr.length);
-
- if (end == MDNS_INVALID_POS)
- end = cur + 1;
- *offset = end;
-
- result.length = capacity - remain;
- return result;
+static mdns_string_t mdns_string_extract(const void* buffer, size_t size,
+ size_t* offset, char* str,
+ size_t capacity) {
+ size_t cur = *offset;
+ size_t end = MDNS_INVALID_POS;
+ mdns_string_pair_t substr;
+ mdns_string_t result = {str, 0};
+ char* dst = str;
+ size_t remain = capacity;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if (substr.offset == MDNS_INVALID_POS) return result;
+ if (substr.ref && (end == MDNS_INVALID_POS)) end = cur + 2;
+ if (substr.length) {
+ size_t to_copy = (substr.length < remain) ? substr.length : remain;
+ memcpy(dst, (const char*)buffer + substr.offset, to_copy);
+ dst += to_copy;
+ remain -= to_copy;
+ if (remain) {
+ *dst++ = '.';
+ --remain;
+ }
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ if (end == MDNS_INVALID_POS) end = cur + 1;
+ *offset = end;
+
+ result.length = capacity - remain;
+ return result;
}
-static size_t
-mdns_string_find(const char* str, size_t length, char c, size_t offset) {
- const void* found;
- if (offset >= length)
- return MDNS_INVALID_POS;
- found = memchr(str + offset, c, length - offset);
- if (found)
- return (size_t)((const char*)found - str);
- return MDNS_INVALID_POS;
+static size_t mdns_string_find(const char* str, size_t length, char c,
+ size_t offset) {
+ const void* found;
+ if (offset >= length) return MDNS_INVALID_POS;
+ found = memchr(str + offset, c, length - offset);
+ if (found) return (size_t)((const char*)found - str);
+ return MDNS_INVALID_POS;
}
-static void*
-mdns_string_make(void* data, size_t capacity, const char* name, size_t length) {
- size_t pos = 0;
- size_t last_pos = 0;
- size_t remain = capacity;
- unsigned char* dest = data;
- while ((last_pos < length) && ((pos = mdns_string_find(name, length, '.', last_pos)) != MDNS_INVALID_POS)) {
- size_t sublength = pos - last_pos;
- if (sublength < remain) {
- *dest = (unsigned char)sublength;
- memcpy(dest + 1, name + last_pos, sublength);
- dest += sublength + 1;
- remain -= sublength + 1;
- }
- else {
- return 0;
- }
- last_pos = pos + 1;
- }
- if (last_pos < length) {
- size_t sublength = length - last_pos;
- if (sublength < capacity) {
- *dest = (unsigned char)sublength;
- memcpy(dest + 1, name + last_pos, sublength);
- dest += sublength + 1;
- remain -= sublength + 1;
- }
- else {
- return 0;
- }
- }
- if (!remain)
- return 0;
- *dest++ = 0;
- return dest;
+static void* mdns_string_make(void* data, size_t capacity, const char* name,
+ size_t length) {
+ size_t pos = 0;
+ size_t last_pos = 0;
+ size_t remain = capacity;
+ unsigned char* dest = data;
+ while ((last_pos < length) &&
+ ((pos = mdns_string_find(name, length, '.', last_pos)) !=
+ MDNS_INVALID_POS)) {
+ size_t sublength = pos - last_pos;
+ if (sublength < remain) {
+ *dest = (unsigned char)sublength;
+ memcpy(dest + 1, name + last_pos, sublength);
+ dest += sublength + 1;
+ remain -= sublength + 1;
+ } else {
+ return 0;
+ }
+ last_pos = pos + 1;
+ }
+ if (last_pos < length) {
+ size_t sublength = length - last_pos;
+ if (sublength < capacity) {
+ *dest = (unsigned char)sublength;
+ memcpy(dest + 1, name + last_pos, sublength);
+ dest += sublength + 1;
+ remain -= sublength + 1;
+ } else {
+ return 0;
+ }
+ }
+ if (!remain) return 0;
+ *dest++ = 0;
+ return dest;
}
-static size_t
-mdns_records_parse(const struct sockaddr* from, const void* buffer, size_t size, size_t* offset,
- mdns_entry_type_t type, size_t records, mdns_record_callback_fn callback,
- void* user_data) {
- size_t parsed = 0;
- int do_callback = 1;
- for (size_t i = 0; i < records; ++i) {
- mdns_string_skip(buffer, size, offset);
- const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset));
-
- uint16_t rtype = ntohs(*data++);
- uint16_t rclass = ntohs(*data++);
- uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data); data += 2;
- uint16_t length = ntohs(*data++);
-
- *offset += 10;
-
- if (do_callback) {
- ++parsed;
- if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset, length,
- user_data))
- do_callback = 0;
- }
-
- *offset += length;
- }
- return parsed;
+static size_t mdns_records_parse(const struct sockaddr* from,
+ const void* buffer, size_t size,
+ size_t* offset, mdns_entry_type_t type,
+ size_t records,
+ mdns_record_callback_fn callback,
+ void* user_data) {
+ size_t parsed = 0;
+ int do_callback = 1;
+ for (size_t i = 0; i < records; ++i) {
+ mdns_string_skip(buffer, size, offset);
+ const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset));
+
+ uint16_t rtype = ntohs(*data++);
+ uint16_t rclass = ntohs(*data++);
+ uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data);
+ data += 2;
+ uint16_t length = ntohs(*data++);
+
+ *offset += 10;
+
+ if (do_callback) {
+ ++parsed;
+ if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset,
+ length, user_data))
+ do_callback = 0;
+ }
+
+ *offset += length;
+ }
+ return parsed;
}
static const uint8_t mdns_services_query[] = {
- // Transaction ID
- 0x00, 0x00,
- // Flags
- 0x00, 0x00,
- // 1 question
- 0x00, 0x01,
- // No answer, authority or additional RRs
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- // _services._dns-sd._udp.local.
- 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's',
- 0x07, '_', 'd', 'n', 's', '-', 's', 'd',
- 0x04, '_', 'u', 'd', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- // PTR record
- 0x00, MDNS_RECORDTYPE_PTR,
- // QU (unicast response) and class IN
- 0x80, MDNS_CLASS_IN
-};
+ // Transaction ID
+ 0x00, 0x00,
+ // Flags
+ 0x00, 0x00,
+ // 1 question
+ 0x00, 0x01,
+ // No answer, authority or additional RRs
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // _services._dns-sd._udp.local.
+ 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', 0x07, '_', 'd', 'n', 's',
+ '-', 's', 'd', 0x04, '_', 'u', 'd', 'p', 0x05, 'l', 'o', 'c', 'a', 'l',
+ 0x00,
+ // PTR record
+ 0x00, MDNS_RECORDTYPE_PTR,
+ // QU (unicast response) and class IN
+ 0x80, MDNS_CLASS_IN};
#if 0
static int
@@ -645,233 +623,223 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity,
static uint16_t mdns_transaction_id = 0;
-static int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length,
- void* buffer, size_t capacity) {
- if (capacity < (17 + length))
- return -1;
-
- uint16_t* data = buffer;
- //Transaction ID
- *data++ = htons(++mdns_transaction_id);
- //Flags
- *data++ = 0;
- //Questions
- *data++ = htons(1);
- //No answer, authority or additional RRs
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- //Name string
- data = mdns_string_make(data, capacity - 17, name, length);
- if (!data)
- return -1;
- //Record type
- *data++ = htons(type);
- //! Unicast response, class IN
- *data++ = htons(0x8000U | MDNS_CLASS_IN);
-
- struct sockaddr_storage addr_storage;
- struct sockaddr_in addr;
- struct sockaddr_in6 addr6;
- struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
- socklen_t saddrlen = sizeof(struct sockaddr_storage);
- if (getsockname(sock, saddr, &saddrlen))
- return -1;
- if (saddr->sa_family == AF_INET6) {
- memset(&addr6, 0, sizeof(struct sockaddr_in6));
- addr6.sin6_family = AF_INET6;
+static int mdns_query_send(int sock, mdns_record_type_t type, const char* name,
+ size_t length, void* buffer, size_t capacity) {
+ if (capacity < (17 + length)) return -1;
+
+ uint16_t* data = buffer;
+ // Transaction ID
+ *data++ = htons(++mdns_transaction_id);
+ // Flags
+ *data++ = 0;
+ // Questions
+ *data++ = htons(1);
+ // No answer, authority or additional RRs
+ *data++ = 0;
+ *data++ = 0;
+ *data++ = 0;
+ // Name string
+ data = mdns_string_make(data, capacity - 17, name, length);
+ if (!data) return -1;
+ // Record type
+ *data++ = htons(type);
+ //! Unicast response, class IN
+ *data++ = htons(0x8000U | MDNS_CLASS_IN);
+
+ struct sockaddr_storage addr_storage;
+ struct sockaddr_in addr;
+ struct sockaddr_in6 addr6;
+ struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
+ socklen_t saddrlen = sizeof(struct sockaddr_storage);
+ if (getsockname(sock, saddr, &saddrlen)) return -1;
+ if (saddr->sa_family == AF_INET6) {
+ memset(&addr6, 0, sizeof(struct sockaddr_in6));
+ addr6.sin6_family = AF_INET6;
#ifdef __APPLE__
- addr6.sin6_len = sizeof(struct sockaddr_in6);
+ addr6.sin6_len = sizeof(struct sockaddr_in6);
#endif
- addr6.sin6_addr.s6_addr[0] = 0xFF;
- addr6.sin6_addr.s6_addr[1] = 0x02;
- addr6.sin6_addr.s6_addr[15] = 0xFB;
- addr6.sin6_port = htons((unsigned short)5353);
- saddr = (struct sockaddr*)&addr6;
- saddrlen = sizeof(struct sockaddr_in6);
- }
- else {
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
+ addr6.sin6_addr.s6_addr[0] = 0xFF;
+ addr6.sin6_addr.s6_addr[1] = 0x02;
+ addr6.sin6_addr.s6_addr[15] = 0xFB;
+ addr6.sin6_port = htons((unsigned short)5353);
+ saddr = (struct sockaddr*)&addr6;
+ saddrlen = sizeof(struct sockaddr_in6);
+ } else {
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
#ifdef __APPLE__
- addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_len = sizeof(struct sockaddr_in);
#endif
- addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- addr.sin_port = htons((unsigned short)5353);
- saddr = (struct sockaddr*)&addr;
- saddrlen = sizeof(struct sockaddr_in);
- }
-
- if (sendto(sock, buffer, (char*)data - (char*)buffer, 0,
- saddr, saddrlen) < 0)
- return -1;
- return 0;
+ addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ addr.sin_port = htons((unsigned short)5353);
+ saddr = (struct sockaddr*)&addr;
+ saddrlen = sizeof(struct sockaddr_in);
+ }
+
+ if (sendto(sock, buffer, (char*)data - (char*)buffer, 0, saddr, saddrlen) < 0)
+ return -1;
+ return 0;
}
-static size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity,
- mdns_record_callback_fn callback, void* user_data,
- uint8_t one_shot) {
- struct sockaddr_in6 addr;
- struct sockaddr* saddr = (struct sockaddr*)&addr;
- memset(&addr, 0, sizeof(addr));
- saddr->sa_family = AF_INET;
+static size_t mdns_query_recv(int sock, void* buffer, size_t capacity,
+ mdns_record_callback_fn callback, void* user_data,
+ uint8_t one_shot) {
+ struct sockaddr_in6 addr;
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
+ memset(&addr, 0, sizeof(addr));
+ saddr->sa_family = AF_INET;
#ifdef __APPLE__
- saddr->sa_len = sizeof(addr);
+ saddr->sa_len = sizeof(addr);
#endif
- socklen_t addrlen = sizeof(addr);
- int ret = recvfrom(sock, buffer, capacity, 0,
- saddr, &addrlen);
- if (ret <= 0)
- return 0;
-
- size_t data_size = (size_t)ret;
- uint16_t* data = (uint16_t*)buffer;
-
- uint16_t transaction_id = ntohs(*data++);
- ++data;// uint16_t flags = ntohs(*data++);
- uint16_t questions = ntohs(*data++);
- uint16_t answer_rrs = ntohs(*data++);
- uint16_t authority_rrs = ntohs(*data++);
- uint16_t additional_rrs = ntohs(*data++);
-
- if (one_shot && transaction_id != mdns_transaction_id)// || (flags != 0x8400))
- return 0; //Not a reply to our last question
-
- if (questions > 1)
- return 0;
-
- //Skip questions part
- int i;
- for (i = 0; i < questions; ++i) {
- size_t ofs = (size_t)((char*)data - (char*)buffer);
- if (!mdns_string_skip(buffer, data_size, &ofs))
- return 0;
- data = (void*)((char*)buffer + ofs);
- ++data;
- ++data;
- }
-
- size_t records = 0;
- size_t offset = (size_t)((char*)data - (char*)buffer);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ANSWER, answer_rrs,
- callback, user_data);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_AUTHORITY, authority_rrs,
- callback, user_data);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs,
- callback, user_data);
- return records;
+ socklen_t addrlen = sizeof(addr);
+ int ret = recvfrom(sock, buffer, capacity, 0, saddr, &addrlen);
+ if (ret <= 0) return 0;
+
+ size_t data_size = (size_t)ret;
+ uint16_t* data = (uint16_t*)buffer;
+
+ uint16_t transaction_id = ntohs(*data++);
+ ++data; // uint16_t flags = ntohs(*data++);
+ uint16_t questions = ntohs(*data++);
+ uint16_t answer_rrs = ntohs(*data++);
+ uint16_t authority_rrs = ntohs(*data++);
+ uint16_t additional_rrs = ntohs(*data++);
+
+ if (one_shot &&
+ transaction_id != mdns_transaction_id) // || (flags != 0x8400))
+ return 0; // Not a reply to our last question
+
+ if (questions > 1) return 0;
+
+ // Skip questions part
+ int i;
+ for (i = 0; i < questions; ++i) {
+ size_t ofs = (size_t)((char*)data - (char*)buffer);
+ if (!mdns_string_skip(buffer, data_size, &ofs)) return 0;
+ data = (void*)((char*)buffer + ofs);
+ ++data;
+ ++data;
+ }
+
+ size_t records = 0;
+ size_t offset = (size_t)((char*)data - (char*)buffer);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ANSWER, answer_rrs, callback,
+ user_data);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_AUTHORITY, authority_rrs,
+ callback, user_data);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs,
+ callback, user_data);
+ return records;
}
-static mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- //PTR record is just a string
- if ((size >= offset + length) && (length >= 2))
- return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- mdns_string_t empty = {0, 0};
- return empty;
+static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer, size_t capacity) {
+ // PTR record is just a string
+ if ((size >= offset + length) && (length >= 2))
+ return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ mdns_string_t empty = {0, 0};
+ return empty;
}
-static mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- mdns_record_srv_t srv;
- memset(&srv, 0, sizeof(mdns_record_srv_t));
- // Read the priority, weight, port number and the discovery name
- // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
- // 2 bytes network-order unsigned priority
- // 2 bytes network-order unsigned weight
- // 2 bytes network-order unsigned port
- // string: discovery (domain) name, minimum 2 bytes when compressed
- if ((size >= offset + length) && (length >= 8)) {
- const uint16_t* recorddata = (const uint16_t*)((const char*)buffer + offset);
- srv.priority = ntohs(*recorddata++);
- srv.weight = ntohs(*recorddata++);
- srv.port = ntohs(*recorddata++);
- offset += 6;
- srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- }
- return srv;
+static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer,
+ size_t capacity) {
+ mdns_record_srv_t srv;
+ memset(&srv, 0, sizeof(mdns_record_srv_t));
+ // Read the priority, weight, port number and the discovery name
+ // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
+ // 2 bytes network-order unsigned priority
+ // 2 bytes network-order unsigned weight
+ // 2 bytes network-order unsigned port
+ // string: discovery (domain) name, minimum 2 bytes when compressed
+ if ((size >= offset + length) && (length >= 8)) {
+ const uint16_t* recorddata =
+ (const uint16_t*)((const char*)buffer + offset);
+ srv.priority = ntohs(*recorddata++);
+ srv.weight = ntohs(*recorddata++);
+ srv.port = ntohs(*recorddata++);
+ offset += 6;
+ srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ }
+ return srv;
}
-static struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in));
- addr->sin_family = AF_INET;
+static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ struct sockaddr_in* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
#ifdef __APPLE__
- addr->sin_len = sizeof(struct sockaddr_in);
+ addr->sin_len = sizeof(struct sockaddr_in);
#endif
- if ((size >= offset + length) && (length == 4))
- addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset);
- return addr;
+ if ((size >= offset + length) && (length == 4))
+ addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset);
+ return addr;
}
-static struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in6));
- addr->sin6_family = AF_INET6;
+static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer,
+ size_t size, size_t offset,
+ size_t length,
+ struct sockaddr_in6* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in6));
+ addr->sin6_family = AF_INET6;
#ifdef __APPLE__
- addr->sin6_len = sizeof(struct sockaddr_in6);
+ addr->sin6_len = sizeof(struct sockaddr_in6);
#endif
- if ((size >= offset + length) && (length == 16))
- addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset);
- return addr;
+ if ((size >= offset + length) && (length == 16))
+ addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset);
+ return addr;
}
-static size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity) {
- size_t parsed = 0;
- const char* strdata;
- size_t separator, sublength;
- size_t end = offset + length;
-
- if (size < end)
- end = size;
-
- while ((offset < end) && (parsed < capacity)) {
- strdata = (const char*)buffer + offset;
- sublength = *(const unsigned char*)strdata;
-
- ++strdata;
- offset += sublength + 1;
-
- separator = 0;
- for (size_t c = 0; c < sublength; ++c) {
- //DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
- if ((strdata[c] < 0x20) || (strdata[c] > 0x7E))
- break;
- if (strdata[c] == '=') {
- separator = c;
- break;
- }
- }
-
- if (!separator)
- continue;
-
- if (separator < sublength) {
- records[parsed].key.str = strdata;
- records[parsed].key.length = separator;
- records[parsed].value.str = strdata + separator + 1;
- records[parsed].value.length = sublength - (separator + 1);
- }
- else {
- records[parsed].key.str = strdata;
- records[parsed].key.length = sublength;
- }
-
- ++parsed;
- }
-
- return parsed;
+static size_t mdns_record_parse_txt(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ mdns_record_txt_t* records,
+ size_t capacity) {
+ size_t parsed = 0;
+ const char* strdata;
+ size_t separator, sublength;
+ size_t end = offset + length;
+
+ if (size < end) end = size;
+
+ while ((offset < end) && (parsed < capacity)) {
+ strdata = (const char*)buffer + offset;
+ sublength = *(const unsigned char*)strdata;
+
+ ++strdata;
+ offset += sublength + 1;
+
+ separator = 0;
+ for (size_t c = 0; c < sublength; ++c) {
+ // DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
+ if ((strdata[c] < 0x20) || (strdata[c] > 0x7E)) break;
+ if (strdata[c] == '=') {
+ separator = c;
+ break;
+ }
+ }
+
+ if (!separator) continue;
+
+ if (separator < sublength) {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = separator;
+ records[parsed].value.str = strdata + separator + 1;
+ records[parsed].value.length = sublength - (separator + 1);
+ } else {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = sublength;
+ }
+
+ ++parsed;
+ }
+
+ return parsed;
}
#ifdef _WIN32