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