]> git.ipfire.org Git - thirdparty/shairport-sync.git/blame - tinysvcmdns.h
Update check_classic_systemd_basic.yml
[thirdparty/shairport-sync.git] / tinysvcmdns.h
CommitLineData
592119bc
PL
1// This file is the concatenation of mdnsd.h and mdns.h
2// from tinysvcmdns with minor modifications
3// The code was taken from https://bitbucket.org/geekman/tinysvcmdns at revision e34b562
4
5/*
6 * tinysvcmdns - a tiny MDNS implementation for publishing services
7 * Copyright (C) 2011 Darell Tan
8 * All rights reserved.
82518dc3 9 *
592119bc
PL
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _TINYSVCMDNS_H
34
35//******************************************************//
36// mdns.h //
37//******************************************************//
38#include <stdint.h>
39#include <stdlib.h>
40#include <string.h>
41
42#ifdef _WIN32
43#include <winsock.h>
44#else
45#include <arpa/inet.h>
46#endif
47
87a0475c
MB
48#define MALLOC_ZERO_STRUCT(x, type) \
49 x = malloc(sizeof(struct type)); \
3001f39b
MB
50 if (x) \
51 memset(x, 0, sizeof(struct type));
592119bc 52
87a0475c 53#define DECL_MALLOC_ZERO_STRUCT(x, type) struct type *MALLOC_ZERO_STRUCT(x, type)
592119bc
PL
54
55struct rr_data_srv {
87a0475c
MB
56 uint16_t priority;
57 uint16_t weight;
58 uint16_t port;
59 uint8_t *target; // host
592119bc
PL
60};
61
62struct rr_data_txt {
87a0475c
MB
63 struct rr_data_txt *next;
64 uint8_t *txt;
592119bc
PL
65};
66
67struct rr_data_nsec {
87a0475c 68 // uint8_t *name; // same as record
592119bc 69
87a0475c
MB
70 // NSEC occupies the 47th bit, 5 bytes
71 // uint8_t bitmap_len; // = 5
72 uint8_t bitmap[5]; // network order: first byte contains LSB
592119bc
PL
73};
74
75struct rr_data_ptr {
87a0475c
MB
76 uint8_t *name; // NULL if entry is to be used
77 struct rr_entry *entry;
592119bc
PL
78};
79
80struct rr_data_a {
87a0475c 81 uint32_t addr;
592119bc
PL
82};
83
84struct rr_data_aaaa {
87a0475c 85 struct in6_addr *addr;
592119bc
PL
86};
87
88struct rr_entry {
87a0475c
MB
89 uint8_t *name;
90
91 enum rr_type {
92 RR_A = 0x01,
93 RR_PTR = 0x0C,
94 RR_TXT = 0x10,
95 RR_AAAA = 0x1C,
96 RR_SRV = 0x21,
97 RR_NSEC = 0x2F,
98 RR_ANY = 0xFF,
99 } type;
100
101 uint32_t ttl;
102
103 // for use in Questions only
104 char unicast_query;
105
106 // for use in Answers only
107 char cache_flush;
108
109 uint16_t rr_class;
110
111 // RR data
112 union {
113 struct rr_data_nsec NSEC;
114 struct rr_data_srv SRV;
115 struct rr_data_txt TXT;
116 struct rr_data_ptr PTR;
117 struct rr_data_a A;
118 struct rr_data_aaaa AAAA;
119 } data;
592119bc
PL
120};
121
122struct rr_list {
87a0475c
MB
123 struct rr_entry *e;
124 struct rr_list *next;
592119bc
PL
125};
126
127struct rr_group {
87a0475c 128 uint8_t *name;
592119bc 129
87a0475c 130 struct rr_list *rr;
592119bc 131
87a0475c 132 struct rr_group *next;
592119bc
PL
133};
134
87a0475c
MB
135#define MDNS_FLAG_RESP (1 << 15) // Query=0 / Response=1
136#define MDNS_FLAG_AA (1 << 10) // Authoritative
137#define MDNS_FLAG_TC (1 << 9) // TrunCation
138#define MDNS_FLAG_RD (1 << 8) // Recursion Desired
139#define MDNS_FLAG_RA (1 << 7) // Recursion Available
140#define MDNS_FLAG_Z (1 << 6) // Reserved (zero)
592119bc 141
87a0475c 142#define MDNS_FLAG_GET_RCODE(x) (x & 0x0F)
592119bc
PL
143#define MDNS_FLAG_GET_OPCODE(x) ((x >> 11) & 0x0F)
144
145// gets the PTR target name, either from "name" member or "entry" member
87a0475c
MB
146#define MDNS_RR_GET_PTR_NAME(rr) \
147 (rr->data.PTR.name != NULL ? rr->data.PTR.name : rr->data.PTR.entry->name)
592119bc
PL
148
149struct mdns_pkt {
87a0475c
MB
150 uint16_t id; // transaction ID
151 uint16_t flags;
152 uint16_t num_qn;
153 uint16_t num_ans_rr;
154 uint16_t num_auth_rr;
155 uint16_t num_add_rr;
156
157 struct rr_list *rr_qn; // questions
158 struct rr_list *rr_ans; // answer RRs
159 struct rr_list *rr_auth; // authority RRs
160 struct rr_list *rr_add; // additional RRs
592119bc
PL
161};
162
163struct mdns_pkt *mdns_parse_pkt(uint8_t *pkt_buf, size_t pkt_len);
164
165void mdns_init_reply(struct mdns_pkt *pkt, uint16_t id);
166size_t mdns_encode_pkt(struct mdns_pkt *answer, uint8_t *pkt_buf, size_t pkt_len);
167
168void mdns_pkt_destroy(struct mdns_pkt *p);
169void rr_group_destroy(struct rr_group *group);
170struct rr_group *rr_group_find(struct rr_group *g, uint8_t *name);
171struct rr_entry *rr_entry_find(struct rr_list *rr_list, uint8_t *name, uint16_t type);
172struct rr_entry *rr_entry_match(struct rr_list *rr_list, struct rr_entry *entry);
173void rr_group_add(struct rr_group **group, struct rr_entry *rr);
174
175int rr_list_count(struct rr_list *rr);
176int rr_list_append(struct rr_list **rr_head, struct rr_entry *rr);
177struct rr_entry *rr_list_remove(struct rr_list **rr_head, struct rr_entry *rr);
178void rr_list_destroy(struct rr_list *rr, char destroy_items);
179
180struct rr_entry *rr_create_ptr(uint8_t *name, struct rr_entry *d_rr);
181struct rr_entry *rr_create_srv(uint8_t *name, uint16_t port, uint8_t *target);
182struct rr_entry *rr_create_aaaa(uint8_t *name, struct in6_addr *addr);
183struct rr_entry *rr_create_a(uint8_t *name, uint32_t addr);
184struct rr_entry *rr_create(uint8_t *name, enum rr_type type);
185void rr_set_nsec(struct rr_entry *rr_nsec, enum rr_type type);
186void rr_add_txt(struct rr_entry *rr_txt, const char *txt);
187
188const char *rr_get_type_name(enum rr_type type);
189
190uint8_t *create_label(const char *txt);
191uint8_t *create_nlabel(const char *name);
192char *nlabel_to_str(const uint8_t *name);
193uint8_t *dup_label(const uint8_t *label);
194uint8_t *dup_nlabel(const uint8_t *n);
195uint8_t *join_nlabel(const uint8_t *n1, const uint8_t *n2);
196
197// compares 2 names
198static inline int cmp_nlabel(const uint8_t *L1, const uint8_t *L2) {
87a0475c 199 return strcmp((char *)L1, (char *)L2);
592119bc
PL
200}
201
202//******************************************************//
203// mdnsd.h //
204//******************************************************//
205
206struct mdnsd;
207struct mdns_service;
208
209// starts a MDNS responder instance
210// returns NULL if unsuccessful
211struct mdnsd *mdnsd_start();
212
213// stops the given MDNS responder instance
214void mdnsd_stop(struct mdnsd *s);
215
216// sets the hostname for the given MDNS responder instance
217void mdnsd_set_hostname(struct mdnsd *svr, const char *hostname, uint32_t ip);
218
219// sets the hostname for the given MDNS responder instance, with an ipv6 address
220void mdnsd_set_hostname_v6(struct mdnsd *svr, const char *hostname, struct in6_addr *addr);
221
222// adds an additional RR
223void mdnsd_add_rr(struct mdnsd *svr, struct rr_entry *rr);
224
225// registers a service with the MDNS responder instance
82518dc3 226struct mdns_service *mdnsd_register_svc(struct mdnsd *svr, const char *instance_name,
87a0475c
MB
227 const char *type, uint16_t port, const char *hostname,
228 const char *txt[]);
592119bc
PL
229
230// destroys the mdns_service struct returned by mdnsd_register_svc()
231void mdns_service_destroy(struct mdns_service *srv);
232
592119bc 233#endif // _TINYSVCMDNS_H