1 #ifndef MDNSD_H_
2 #define MDNSD_H_
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include "mdnsd_config.h"
9 #include "1035.h"
10 #if !defined(__bool_true_false_are_defined) && defined(_MSC_VER) && _MSC_VER < 1600
11 // VS 2008 has no stdbool.h
12 #define bool	short
13 #define true	1
14 #define false	0
15 #else
16 #include <stdbool.h>
17 #endif
18 #include <stdio.h>
19 
20 #define QCLASS_IN (1)
21 
22 #if MDNSD_LOGLEVEL <= 100
23 #define MDNSD_LOG_TRACE(...) do { \
24 		printf("mdnsd: TRACE - "); printf(__VA_ARGS__); printf("\n"); } while(0)
25 #else
26 #define MDNSD_LOG_TRACE(...) do {} while(0)
27 #endif
28 
29 #if MDNSD_LOGLEVEL <= 200
30 #define MDNSD_LOG_DEBUG(...) do { \
31 		printf("mdnsd: DEBUG - "); printf(__VA_ARGS__); printf("\n"); } while(0)
32 #else
33 #define MDNSD_LOG_DEBUG(...) do {} while(0)
34 #endif
35 
36 #if MDNSD_LOGLEVEL <= 300
37 #define MDNSD_LOG_INFO(...) do { \
38 		printf("mdnsd: INFO  - "); printf(__VA_ARGS__); printf("\n"); } while(0)
39 #else
40 #define MDNSD_LOG_INFO(...) do {} while(0)
41 #endif
42 
43 #if MDNSD_LOGLEVEL <= 400
44 #define MDNSD_LOG_WARNING(...) do { \
45 		printf("mdnsd: WARN  - "); printf(__VA_ARGS__); printf("\n"); } while(0)
46 #else
47 #define MDNSD_LOG_WARNING(...) do {} while(0)
48 #endif
49 
50 #if MDNSD_LOGLEVEL <= 500
51 #define MDNSD_LOG_ERROR(...) do { \
52 		printf("mdnsd: ERROR - "); printf(__VA_ARGS__); printf("\n"); } while(0)
53 #else
54 #define MDNSD_LOG_ERROR(...) do {} while(0)
55 #endif
56 
57 #if MDNSD_LOGLEVEL <= 600
58 #define MDNSD_LOG_FATAL(...) do { \
59 		printf("mdnsd: FATAL - "); printf(__VA_ARGS__); printf("\n"); } while(0)
60 #else
61 #define MDNSD_LOG_FATAL(...) do {} while(0)
62 #endif
63 
64 /* Main daemon data */
65 typedef struct mdns_daemon mdns_daemon_t;
66 /* Record entry */
67 typedef struct mdns_record mdns_record_t;
68 
69 /* Callback for received record. Data is passed from the register call */
70 typedef void (*mdnsd_record_received_callback)(const struct resource* r, void* data);
71 
72 /* Answer data */
73 typedef struct mdns_answer {
74 	char *name;
75 	unsigned short int type;
76 	unsigned long int ttl;
77 	unsigned short int rdlen;
78 	unsigned char *rdata;
79 	struct in_addr ip;	/* A */
80 	char *rdname;		/* NS/CNAME/PTR/SRV */
81 	struct {
82 		//cppcheck-suppress unusedStructMember
83 		unsigned short int priority, weight, port;
84 	} srv;			/* SRV */
85 } mdns_answer_t;
86 
87 /**
88  * Global functions
89  */
90 
91 /**
92  * Create a new mdns daemon for the given class of names (usually 1) and
93  * maximum frame size
94  */
95 mdns_daemon_t MDNSD_EXPORT * mdnsd_new(int clazz, int frame);
96 
97 /**
98  * Gracefully shutdown the daemon, use mdnsd_out() to get the last
99  * packets
100  */
101 void MDNSD_EXPORT mdnsd_shutdown(mdns_daemon_t *d);
102 
103 /**
104  * Flush all cached records (network/interface changed)
105  */
106 void MDNSD_EXPORT mdnsd_flush(mdns_daemon_t *d);
107 
108 /**
109  * Free given mdns_daemon_t *(should have used mdnsd_shutdown() first!)
110  */
111 void MDNSD_EXPORT mdnsd_free(mdns_daemon_t *d);
112 
113 /**
114  * Register callback which is called when a record is received. The data parameter is passed to the callback.
115  * Calling this multiple times overwrites the previous register.
116  */
117 void MDNSD_EXPORT mdnsd_register_receive_callback(mdns_daemon_t *d, mdnsd_record_received_callback cb, void* data);
118 
119 /**
120  * I/O functions
121  */
122 
123 /**
124  * Oncoming message from host (to be cached/processed)
125  */
126 int MDNSD_EXPORT mdnsd_in(mdns_daemon_t *d, struct message *m, unsigned long int ip, unsigned short int port);
127 
128 /**
129  * Outgoing messge to be delivered to host, returns >0 if one was
130  * returned and m/ip/port set
131  */
132 int MDNSD_EXPORT mdnsd_out(mdns_daemon_t *d, struct message *m, unsigned long int *ip, unsigned short int *port);
133 
134 /**
135  * returns the max wait-time until mdnsd_out() needs to be called again
136  */
137 struct timeval MDNSD_EXPORT * mdnsd_sleep(mdns_daemon_t *d);
138 
139 /**
140  * Q/A functions
141  */
142 
143 /**
144  * Register a new query
145  *
146  * The answer() callback is called whenever one is found/changes/expires
147  * (immediate or anytime after, mdns_answer_t valid until ->ttl==0)
148  * either answer returns -1, or another mdnsd_query() with a %NULL answer
149  * will remove/unregister this query
150  */
151 void MDNSD_EXPORT mdnsd_query(mdns_daemon_t *d, const char *host, int type, int (*answer)(mdns_answer_t *a, void *arg), void *arg);
152 
153 /**
154  * Returns the first (if last == NULL) or next answer after last from
155  * the cache mdns_answer_t only valid until an I/O function is called
156  */
157 mdns_answer_t MDNSD_EXPORT *mdnsd_list(mdns_daemon_t *d, const char *host, int type, mdns_answer_t *last);
158 
159 /**
160  * Returns the next record of the given record, i.e. the value of next field.
161  * @param r the base record
162  * @return r->next
163  */
164 mdns_record_t MDNSD_EXPORT *mdnsd_record_next(const mdns_record_t* r) ;
165 
166 /**
167  * Gets the record data
168  */
169 const mdns_answer_t MDNSD_EXPORT *mdnsd_record_data(const mdns_record_t* r) ;
170 
171 
172 /**
173  * Publishing functions
174  */
175 
176 /**
177  * Create a new unique record
178  *
179  * Call mdnsd_list() first to make sure the record is not used yet.
180  *
181  * The conflict() callback is called at any point when one is detected
182  * and unable to recover after the first data is set_*(), any future
183  * changes effectively expire the old one and attempt to create a new
184  * unique record
185  */
186 mdns_record_t MDNSD_EXPORT * mdnsd_unique(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl, void (*conflict)(char *host, int type, void *arg), void *arg);
187 
188 /**
189  * Create a new shared record
190  */
191 mdns_record_t MDNSD_EXPORT * mdnsd_shared(mdns_daemon_t *d, const char *host, unsigned short int type, unsigned long int ttl);
192 
193 /**
194  * Get a previously created record based on the host name. NULL if not found. Does not return records for other hosts.
195  * If multiple records are found, use record->next to iterate over all the results.
196  */
197 mdns_record_t MDNSD_EXPORT * mdnsd_get_published(const mdns_daemon_t *d, const char *host);
198 
199 /**
200  * Check if there is already a query for the given host
201  */
202 int MDNSD_EXPORT mdnsd_has_query(const mdns_daemon_t *d, const char *host);
203 
204 /**
205  * de-list the given record
206  */
207 void MDNSD_EXPORT mdnsd_done(mdns_daemon_t *d, mdns_record_t *r);
208 
209 /**
210  * These all set/update the data for the given record, nothing is
211  * published until they are called
212  */
213 void MDNSD_EXPORT mdnsd_set_raw(mdns_daemon_t *d, mdns_record_t *r, const char *data, unsigned short int len);
214 void MDNSD_EXPORT mdnsd_set_host(mdns_daemon_t *d, mdns_record_t *r, const char *name);
215 void MDNSD_EXPORT mdnsd_set_ip(mdns_daemon_t *d, mdns_record_t *r, struct in_addr ip);
216 void MDNSD_EXPORT mdnsd_set_srv(mdns_daemon_t *d, mdns_record_t *r, unsigned short int priority, unsigned short int weight, unsigned short int port, char *name);
217 
218 /**
219  * Process input queue and output queue. Should be called at least the time which is returned in nextSleep.
220  * Returns 0 on success, 1 on read error, 2 on write error
221  */
222 unsigned short int MDNSD_EXPORT mdnsd_step(mdns_daemon_t *d, int mdns_socket, bool processIn, bool processOut, struct timeval *nextSleep);
223 
224 #ifdef __cplusplus
225 } // extern "C"
226 #endif
227 
228 #endif	/* MDNSD_H_ */
229