1 /*
2  * Copyright (c) 2010 Christiano F. Haesbaert <haesbaert@haesbaert.org>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef _MDNSD_H_
18 #define	_MDNSD_H_
19 
20 #include <sys/param.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/tree.h>
24 #include <sys/types.h>
25 #include <net/if_arp.h>
26 #include <net/if.h>
27 #include <netinet/in.h>
28 #include <netinet/if_ether.h>
29 
30 #include <event.h>
31 #include <imsg.h>
32 
33 #include "mdns.h"
34 #include "control.h"
35 
36 #define MDNSD_USER		"_mdnsd"
37 #define ALL_MDNS_DEVICES	"224.0.0.251"
38 #define MDNS_TTL		255
39 #define MDNS_PORT		5353
40 #define TTL_A			120
41 #define TTL_AAAA		120
42 #define TTL_HNAME		120
43 #define TTL_SRV			(75 * 60)
44 #define TTL_TXT			(75 * 60)
45 #define TTL_PTR			(75 * 60)
46 #define MDNS_QUERY		0
47 #define MDNS_RESPONSE		1
48 #define INTERVAL_PROBETIME	250000
49 #define RANDOM_PROBETIME	arc4random_uniform(250000)
50 #define FIRST_QUERYTIME		(arc4random_uniform(120000) + 20000)
51 #define MAXQUERYTIME		(60 * 60) /* one hour */
52 #define ALL_IFACE		(NULL)
53 
54 #define ANSWERS(qrrs, rrs)						\
55 	((((qrrs)->type == T_ANY) || ((qrrs)->type == (rrs)->type))  && \
56 	    (qrrs)->class == (rrs)->class                            &&	\
57 	    (strcmp((qrrs)->dname, (rrs)->dname)) == 0)
58 
59 #define RR_UNIQ(rr) ((rr)->flags & RR_FLAG_CACHEFLUSH)
60 #define RR_AUTH(rr) ((rr)->auth_refcount > 0)
61 #define RR_INADDRANY(rr)						\
62 	((rr)->rrs.type == T_A && (rr)->rdata.A.s_addr == INADDR_ANY)
63 
64 #define CACHE_FOREACH_RRS(var, rrs)		\
65 	/* struct rr *var */			\
66 	/* struct rrs *rrs */			\
67 	for ((var) = cache_lookup(rrs);		\
68 	     (var) != NULL;			\
69 	     (var) = cache_next_by_rrs(var))
70 
71 #define CACHE_FOREACH_DNAME(var, var2, dname)				\
72 	/* struct rr *var */						\
73 	/* struct cache_node *var2 */					\
74 	/* char dname[MAXHOSTNAMELEN] */				\
75 	for (((var2) = cache_lookup_dname(dname)),			\
76 		 (var2) ?						\
77 		 ((var) = LIST_FIRST(&(var2)->rr_list)) : NULL ;	\
78 	     (var2) != NULL && (var) != NULL;				\
79 	     (var) = LIST_NEXT(var, centry))				\
80 
81 struct rrset {
82 	LIST_ENTRY(rrset) entry;	       /* List link */
83 	char            dname[MAXHOSTNAMELEN]; /* Domain Name */
84 	u_int16_t       type;		       /* RR type: T_A, T_PTR... */
85 	u_int16_t       class;		       /* C_IN */
86 };
87 
88 struct cache_node {
89 	RB_ENTRY(cache_node) entry;	/* Cache RBTREE link */
90 	LIST_HEAD(, rr)	     rr_list;	/* List of RR under dname */
91 	char		     dname[MAXHOSTNAMELEN]; /* domain name */
92 };
93 
94 struct hinfo {
95 	char    cpu[MAXCHARSTR]; /* Cpu name */
96 	char    os[MAXCHARSTR];	 /* Operating System name */
97 };
98 
99 struct srv {
100 	u_int16_t       priority; /* Used only by application */
101 	u_int16_t       weight;	  /* Used only by application */
102 	u_int16_t       port;	  /* Service port, tcp or udp */
103 	char            target[MAXHOSTNAMELEN]; /* Service host */
104 };
105 
106 struct rr {
107 	LIST_ENTRY(rr)		centry;	/* Cache entry */
108 	LIST_ENTRY(rr)		pentry;	/* Packet entry */
109 	struct rrset		rrs;	/* RR tripple */
110 	u_int32_t		ttl;	/* DNS Time to live */
111 	union {
112 		/* IPv4 Address, if INADDR_ANY, use the interface address, this
113 		 * is how we can have the same RR with multiple addresses */
114 		struct in_addr	A;
115 		char		CNAME[MAXHOSTNAMELEN]; /* CNAME */
116 		char		PTR[MAXHOSTNAMELEN];   /* PTR */
117 		char		NS[MAXHOSTNAMELEN];    /* Name server */
118 		char		TXT[MAXCHARSTR];       /* Text */
119 		struct srv	SRV;		       /* Service */
120 		struct hinfo	HINFO;		       /* Host Info */
121 
122 	} rdata;
123 	struct cache_node	*cn;	/* Cache parent node */
124 	int			 auth_refcount; /* Number of pges holding us */
125 	int			 revision; /* at 80% of ttl, then 90% and 95% */
126 	struct event		 timer; /* revision timer */
127 	struct timespec		 age;	/* Timestamp of when we got this RR. */
128 	u_int			 flags;	/* RR Flags */
129 #define RR_FLAG_CACHEFLUSH	0x01	/* Unique record */
130 #define RR_FLAG_PUBLISHED	0x02	/* Published record */
131 };
132 
133 struct pkt {
134 	TAILQ_ENTRY(pkt)	entry;	/* Deferred pkt queue */
135 	u_int			flags;	/* Packet flags */
136 #define PKT_FLAG_LEGACY 0x1		/* Legacy unicast packet */
137 	HEADER			h;	/* Packet header */
138 	LIST_HEAD(, question)	qlist;	/* Question section */
139 	LIST_HEAD(, rr)		anlist;	/* Answer section */
140 	LIST_HEAD(, rr)		nslist;	/* Authority section */
141 	LIST_HEAD(, rr)		arlist;	/* Additional section */
142 	struct sockaddr_in	ipsrc;	/* Received ipsource */
143 	struct event		timer;	/* Timer for truncated pkts */
144 	struct iface	       *iface;  /* Received interface */
145 };
146 
147 struct question {
148 	LIST_ENTRY(question)	entry;	   /* Packet link */
149 	RB_ENTRY(question)	qst_entry; /* Question Tree link */
150 	struct rrset		rrs;	   /* RR tripple */
151 	u_int			flags;	   /* Question flags */
152 #define QST_FLAG_UNIRESP 0x1		   /* Accepts unicast response */
153 	int			active;	   /* Active controllers */
154 	u_int			sent;	   /* Used in question_fsm */
155 	struct timespec		lastsent;  /* Last time we sent this question */
156 	struct timespec		sched;	   /* Next scheduled time to send */
157 };
158 
159 enum query_style {
160 	QUERY_LOOKUP,		/* A simple single-shot query */
161 	QUERY_BROWSE,		/* A Continuous Querying query */
162 	QUERY_RESOLVE,		/* A service resolve query */
163 };
164 
165 struct query {
166 	LIST_ENTRY(query)	 entry;	 /* Query link */
167 	LIST_HEAD(, rrset)	 rrslist;/* List of question tree keys */
168 	struct ctl_conn		*ctl;	 /* Owner */
169 	enum query_style	 style;	 /* Style */
170 	struct event		 timer;	 /* query_fsm() timer */
171 	u_int			 count;	 /* Used in query_fsm() */
172 	struct rrset		*ms_srv; /* The SRV in QUERY_RESOLVE */
173 	struct rrset		*ms_a;   /* The A in QUERY_RESOLVE */
174 	struct rrset		*br_ptr; /* The PTR in QUERY_BROWSE */
175 };
176 
177 enum pg_state {
178 	PG_STA_NEW,
179 	PG_STA_COMMITED,
180 	PG_STA_COLLISION
181 };
182 /* Publish Group */
183 struct pg {
184 	TAILQ_ENTRY(pg)		entry;		/* pg_queue link */
185 	LIST_HEAD(, pge)	pge_list;	/* List of pge */
186 	struct ctl_conn		*c;		/* Owner */
187 	char			name[MAXHOSTNAMELEN]; /* Name id */
188 	u_int			flags;		/* Misc flags */
189 	enum pg_state		state;		/* enum pg_state */
190 };
191 
192 /* Publish Group Entry types */
193 enum pge_type {
194 	PGE_TYPE_CUSTOM,	/* Unused */
195 	PGE_TYPE_SERVICE,	/* A DNS-SD Service */
196 	PGE_TYPE_ADDRESS	/* A Primary Address */
197 };
198 
199 enum pge_state {
200 	PGE_STA_UNPUBLISHED,		/* Initial state */
201 	PGE_STA_PROBING,		/* Probing state */
202 	PGE_STA_ANNOUNCING,		/* Considered announced */
203 	PGE_STA_PUBLISHED,		/* Finished announcing */
204 };
205 
206 #define PGE_RR_MAX 32
207 struct pge {
208 	TAILQ_ENTRY(pge)  entry;	/* pge_queue link */
209 	LIST_ENTRY(pge)	  pge_entry;	/* Group link */
210 	struct pg	 *pg;		/* Parent Publish Group */
211 	enum pge_type	  pge_type;	/* Type of this entry */
212 	u_int		  pge_flags;	/* Misc flags */
213 #define PGE_FLAG_INC_A	  0x01		/* Include primary T_A record */
214 #define PGE_FLAG_INTERNAL 0x02		/* TODO: kill and test for pg */
215 	struct question  *pqst;		/* Probing Question, may be NULL */
216 	struct rr	 *rr[PGE_RR_MAX]; /* Array of to publish rr */
217 #define PGE_RR_PRIM 0			/* The T_A record for primary address */
218 	int		  nrr;		/* Members in rr array */
219 	struct iface	 *iface;	/* Iface to be published */
220 	struct event	  timer;	/* FSM timer */
221 	enum pge_state	  state;	/* FSM state */
222 	u_int		  sent;		/* How many sent packets */
223 };
224 
225 /* Publish Group Queue, should hold all publishing groups */
226 typedef TAILQ_HEAD(, pg) pg_q;
227 extern pg_q pg_queue;
228 
229 /* Publish Group Entry Queue, should hold all publishing group entries */
230 typedef TAILQ_HEAD(, pge) pge_q;
231 extern pge_q pge_queue;
232 
233 struct kif {
234 	char			ifname[IF_NAMESIZE];
235 	u_int64_t		baudrate;
236 	int			flags;
237 	int			mtu;
238 	u_short			ifindex;
239 	u_int8_t		media_type;
240 	u_int8_t		link_state;
241 	struct ether_addr	ea;
242 };
243 
244 /* interface states */
245 #define IF_STA_DOWN		0x01
246 #define IF_STA_ACTIVE		(~IF_STA_DOWN)
247 #define IF_STA_ANY		0x7f
248 
249 /* interface events */
250 enum iface_event {
251 	IF_EVT_NOTHING,
252 	IF_EVT_UP,
253 	IF_EVT_DOWN
254 };
255 
256 /* interface actions */
257 enum iface_action {
258 	IF_ACT_NOTHING,
259 	IF_ACT_STRT,
260 	IF_ACT_RST
261 };
262 
263 /* interface types */
264 enum iface_type {
265 	IF_TYPE_POINTOPOINT,
266 	IF_TYPE_BROADCAST,
267 	IF_TYPE_NBMA,
268 	IF_TYPE_POINTOMULTIPOINT
269 };
270 
271 struct iface {
272 	LIST_ENTRY(iface)	 entry;
273 	struct pge		*pge_workstation;
274 	char			 name[IF_NAMESIZE];
275 	struct in_addr		 addr;
276 	struct in_addr		 dst;
277 	struct in_addr		 mask;
278 	u_int64_t		 baudrate;
279 	time_t			 uptime;
280 	u_int			 mtu;
281 	int			 fd; /* XXX */
282 	int			 state;
283 	u_short			 ifindex;
284 	u_int16_t		 cost;
285 	u_int16_t		 flags;
286 	enum iface_type		 type;
287 	u_int8_t		 linktype;
288 	u_int8_t		 media_type;
289 	u_int8_t		 linkstate;
290 	struct ether_addr	 ea;
291 };
292 
293 /* interface.c */
294 const char	*if_action_name(int);
295 const char	*if_event_name(int);
296 int		 if_act_reset(struct iface *);
297 int		 if_act_start(struct iface *);
298 int		 if_fsm(struct iface *, enum iface_event);
299 int		 if_join_group(struct iface *, struct in_addr *);
300 int		 if_leave_group(struct iface *, struct in_addr *);
301 int		 if_set_mcast(struct iface *);
302 int		 if_set_mcast_loop(int);
303 int		 if_set_mcast_ttl(int, u_int8_t);
304 int		 if_set_opt(int);
305 int		 if_set_tos(int, int);
306 struct iface	*if_find_index(u_short);
307 struct iface	*if_find_iface(unsigned int, struct in_addr);
308 struct iface	*if_new(struct kif *);
309 void		 if_set_recvbuf(int);
310 
311 struct mdnsd_conf {
312 	LIST_HEAD(, iface)	iface_list; /* Our interface list */
313 	int			mdns_sock;  /* MDNS socket bound to udp 5353 */
314 	struct event		ev_mdns;    /* MDNS socket event */
315 	struct hinfo		hi;	    /* MDNS Host Info */
316 	char			myname[MAXHOSTNAMELEN]; /* Hostname */
317 	struct pge	       *pge_primary;/* Primary pge addresses */
318 	int			no_workstation;	/* Don't publish workstation */
319 };
320 
321 /* kiface.c */
322 int		 kif_init(void);
323 void		 kif_cleanup(void);
324 struct kif	*kif_findname(char *);
325 void		 kev_init(void);
326 void		 kev_cleanup(void);
327 
328 /* mdnsd.c */
329 int	peersuser(int);
330 void	reversstr(char [MAXHOSTNAMELEN], struct in_addr *);
331 int	mdnsd_imsg_compose_ctl(struct ctl_conn *, u_int16_t, void *, u_int16_t);
332 void	imsg_event_add(struct imsgev *);
333 int	imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, pid_t,
334     int, void *, u_int16_t);
335 
336 /* packet.c */
337 void	  packet_init(void);
338 void	  recv_packet(int, short, void *);
339 int	  send_packet(struct iface *, void *, size_t, struct sockaddr_in *);
340 void	  pkt_process(int, short, void *);
341 int	  pkt_sendto(struct pkt *, struct iface *, struct sockaddr_in *);
342 int	  pkt_send(struct pkt *, struct iface *);
343 void	  pkt_init(struct pkt *);
344 void	  pkt_cleanup(struct pkt *);
345 void	  pkt_add_question(struct pkt *, struct question *);
346 void	  pkt_add_anrr(struct pkt *, struct rr *);
347 void	  pkt_add_nsrr(struct pkt *, struct rr *);
348 void	  pkt_add_arrr(struct pkt *, struct rr *);
349 int	  rr_rdata_cmp(struct rr *, struct rr *);
350 u_int32_t rr_ttl_left(struct rr *);
351 void	  pktcomp_reset(int, u_int8_t *, u_int16_t);
352 int	  rr_set(struct rr *, char [MAXHOSTNAMELEN], u_int16_t, u_int16_t,
353     u_int32_t, u_int, void *, size_t);
354 
355 /* mdns.c */
356 void		 publish_init(void);
357 void		 publish_allrr(struct iface *);
358 int		 publish_insert(struct iface *, struct rr *);
359 int		 publish_delete(struct iface *, struct rr *);
360 struct rr	*publish_lookupall(struct rrset *);
361 void		 publish_fsm(int, short, void *);
362 void		 query_init(void);
363 void		 query_fsm(int, short, void *);
364 struct query	*query_lookup(struct rrset *);
365 void		 query_remove(struct query *);
366 struct question	*question_add(struct rrset *);
367 void		 question_remove(struct rrset *);
368 void		 cache_init(void);
369 int		 cache_insert(struct rr *);
370 int		 cache_delete(struct rr *);
371 void		 cache_schedrev(struct rr *);
372 void		 cache_rev(int, short, void *);
373 int		 cache_node_cmp(struct cache_node *, struct cache_node *);
374 int		 cache_process(struct rr *);
375 struct rr	*cache_lookup(struct rrset *);
376 struct cache_node *cache_lookup_dname(const char *);
377 struct rr	*cache_next_by_rrs(struct rr *);
378 int		 rrset_cmp(struct rrset *, struct rrset *);
379 int		 rr_notify_in(struct rr *);
380 int		 rr_notify_out(struct rr *);
381 struct rr	*rr_dup(struct rr *);
382 struct question *question_dup(struct question *);
383 void		 pg_init(void);
384 void		 pg_publish_byiface(struct iface *);
385 struct pg	*pg_get(int, char [MAXHOSTNAMELEN], struct ctl_conn *);
386 void		 pg_kill(struct pg *);
387 int		 pg_published(struct pg *);
388 struct pge	*pge_from_ms(struct pg *, struct mdns_service *, struct iface *);
389 void		 pge_kill(struct pge *);
390 void		 pge_fsm(int, short, void *);
391 void		 pge_fsm_restart(struct pge *, struct timeval *);
392 void		 pge_initprimary(void);
393 struct pge	*pge_new_workstation(struct iface *);
394 void		 pge_revert_probe(struct pge *);
395 void		 pge_conflict_drop(struct pge *);
396 struct rr *	 auth_get(struct rr *);
397 void		 auth_release(struct rr *);
398 int		 rr_send_goodbye(struct rr *);
399 int		 rr_send_an(struct rr *);
400 void		 conflict_resolve_by_rr(struct rr *);
401 
402 /* control.c */
403 typedef TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns_t;
404 extern	ctl_conns_t ctl_conns;
405 int     control_send_rr(struct ctl_conn *, struct rr *, int);
406 int	control_send_ms(struct ctl_conn *, struct mdns_service *, int);
407 int     control_try_answer_ms(struct ctl_conn *, char[MAXHOSTNAMELEN]);
408 int	control_notify_pg(struct ctl_conn *, struct pg *, int);
409 
410 
411 #endif /* _MDNSD_H_ */
412