mdns.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * tinysvcmdns - a tiny MDNS implementation for publishing services
  3. * Copyright (C) 2011 Darell Tan
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifndef __MDNS_H__
  29. #define __MDNS_H__
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <stdbool.h>
  34. #ifdef _WIN32
  35. #include <winsock.h>
  36. #else
  37. #include <arpa/inet.h>
  38. #endif
  39. #define MALLOC_ZERO_STRUCT(x, type) \
  40. x = malloc(sizeof(struct type)); \
  41. memset(x, 0, sizeof(struct type));
  42. #define DECL_MALLOC_ZERO_STRUCT(x, type) \
  43. struct type * MALLOC_ZERO_STRUCT(x, type)
  44. #define DECL_STRUCT(x, type) \
  45. struct type * x;
  46. #define DEFAULT_TTL_FOR_RECORD_WITH_HOSTNAME 120
  47. #define DEFAULT_TTL 4500
  48. #ifndef NDEBUG
  49. #define DEBUG_PRINTF(fmt, ...) mdnsd_log(false, fmt, ##__VA_ARGS__)
  50. #else
  51. #define DEBUG_PRINTF(...) ((void) 0)
  52. #endif
  53. struct rr_data_srv {
  54. uint16_t priority;
  55. uint16_t weight;
  56. uint16_t port;
  57. uint8_t *target; // host
  58. };
  59. struct rr_data_txt {
  60. struct rr_data_txt *next;
  61. uint8_t *txt;
  62. };
  63. struct rr_data_nsec {
  64. //uint8_t *name; // same as record
  65. // NSEC occupies the 47th bit, 5 bytes
  66. //uint8_t bitmap_len; // = 5
  67. uint8_t bitmap[5]; // network order: first byte contains LSB
  68. };
  69. struct rr_data_ptr {
  70. uint8_t *name; // NULL if entry is to be used
  71. struct rr_entry *entry;
  72. };
  73. struct rr_data_a {
  74. uint32_t addr;
  75. };
  76. struct rr_data_aaaa {
  77. struct in6_addr *addr;
  78. };
  79. typedef enum rr_type {
  80. RR_A = 0x01,
  81. RR_PTR = 0x0C,
  82. RR_TXT = 0x10,
  83. RR_AAAA = 0x1C,
  84. RR_SRV = 0x21,
  85. RR_NSEC = 0x2F,
  86. RR_ANY = 0xFF,
  87. } type;
  88. struct rr_entry {
  89. uint8_t *name;
  90. enum rr_type type;
  91. uint32_t ttl;
  92. char unicast_query;
  93. // for use in Answers only
  94. char cache_flush;
  95. uint16_t rr_class;
  96. // RR data
  97. union {
  98. struct rr_data_nsec NSEC;
  99. struct rr_data_srv SRV;
  100. struct rr_data_txt TXT;
  101. struct rr_data_ptr PTR;
  102. struct rr_data_a A;
  103. struct rr_data_aaaa AAAA;
  104. } data;
  105. };
  106. struct rr_list {
  107. struct rr_entry *e;
  108. struct rr_list *next;
  109. };
  110. struct rr_group {
  111. uint8_t *name;
  112. struct rr_list *rr;
  113. struct rr_group *next;
  114. };
  115. #define MDNS_FLAG_RESP (1 << 15) // Query=0 / Response=1
  116. #define MDNS_FLAG_AA (1 << 10) // Authoritative
  117. #define MDNS_FLAG_TC (1 << 9) // TrunCation
  118. #define MDNS_FLAG_RD (1 << 8) // Recursion Desired
  119. #define MDNS_FLAG_RA (1 << 7) // Recursion Available
  120. #define MDNS_FLAG_Z (1 << 6) // Reserved (zero)
  121. #define MDNS_FLAG_GET_RCODE(x) (x & 0x0F)
  122. #define MDNS_FLAG_GET_OPCODE(x) ((x >> 11) & 0x0F)
  123. // gets the PTR target name, either from "name" member or "entry" member
  124. #define MDNS_RR_GET_PTR_NAME(rr) (rr->data.PTR.name != NULL ? rr->data.PTR.name : rr->data.PTR.entry->name)
  125. struct mdns_pkt {
  126. uint16_t id; // transaction ID
  127. uint16_t flags;
  128. uint16_t num_qn;
  129. uint16_t num_ans_rr;
  130. uint16_t num_auth_rr;
  131. uint16_t num_add_rr;
  132. char unicast;
  133. struct rr_list *rr_qn; // questions
  134. struct rr_list *rr_ans; // answer RRs
  135. struct rr_list *rr_auth; // authority RRs
  136. struct rr_list *rr_add; // additional RRs
  137. };
  138. void mdnsd_log(bool force, char* fmt, ...);
  139. struct mdns_pkt *mdns_parse_pkt(uint8_t *pkt_buf, size_t pkt_len);
  140. void mdns_init_reply(struct mdns_pkt *pkt, uint16_t id);
  141. size_t mdns_encode_pkt(struct mdns_pkt *answer, uint8_t *pkt_buf, size_t pkt_len);
  142. void mdns_pkt_destroy(struct mdns_pkt *p);
  143. void rr_group_destroy(struct rr_group *group);
  144. struct rr_group *rr_group_find(struct rr_group *g, uint8_t *name);
  145. struct rr_entry *rr_entry_find(struct rr_list *rr_list, uint8_t *name, uint16_t type);
  146. struct rr_entry *rr_entry_match(struct rr_list *rr_list, struct rr_entry *entry);
  147. void rr_entry_destroy(struct rr_entry *rr);
  148. struct rr_entry *rr_entry_remove(struct rr_group *group, struct rr_entry *entry, enum rr_type type);
  149. void rr_group_add(struct rr_group **group, struct rr_entry *rr);
  150. void rr_group_clean(struct rr_group **head);
  151. int rr_list_count(struct rr_list *rr);
  152. int rr_list_append(struct rr_list **rr_head, struct rr_entry *rr);
  153. struct rr_entry *rr_list_remove(struct rr_list **rr_head, struct rr_entry *rr);
  154. void rr_list_destroy(struct rr_list *rr, char destroy_items);
  155. struct rr_entry *rr_create_ptr(uint8_t *name, struct rr_entry *d_rr);
  156. struct rr_entry *rr_create_srv(uint8_t *name, uint16_t port, uint8_t *target);
  157. struct rr_entry *rr_create_aaaa(uint8_t *name, struct in6_addr *addr);
  158. struct rr_entry *rr_create_a(uint8_t *name, struct in_addr addr);
  159. struct rr_entry *rr_create(uint8_t *name, enum rr_type type);
  160. void rr_set_nsec(struct rr_entry *rr_nsec, enum rr_type type);
  161. void rr_add_txt(struct rr_entry *rr_txt, const char *txt);
  162. const char *rr_get_type_name(enum rr_type type);
  163. uint8_t *create_label(const char *txt);
  164. uint8_t *create_nlabel(const char *name);
  165. char *nlabel_to_str(const uint8_t *name);
  166. uint8_t *dup_label(const uint8_t *label);
  167. uint8_t *dup_nlabel(const uint8_t *n);
  168. uint8_t *join_nlabel(const uint8_t *n1, const uint8_t *n2);
  169. // compares 2 names
  170. static inline int cmp_nlabel(const uint8_t *L1, const uint8_t *L2) {
  171. return strcmp((char *) L1, (char *) L2);
  172. }
  173. #endif /*!__MDNS_H__*/