-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmdnssd-core.h
158 lines (129 loc) · 4.16 KB
/
mdnssd-core.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once
#include "mdnssd.h"
#if !defined(_WIN32)
#define closesocket close
#endif
#ifndef TTL_MIN
#define TTL_MIN 120
#endif
#define DNS_HEADER_SIZE (12)
#define DNS_MAX_HOSTNAME_LENGTH (253)
#define DNS_MAX_LABEL_LENGTH (63)
#define MDNS_MULTICAST_ADDRESS "224.0.0.251"
#define MDNS_PORT (5353)
#define DNS_BUFFER_SIZE (32768)
#define MDNS_IGMP_HOST_MEMBERSHIP_REPORT (0x16)
// TODO find the right number for this
#define DNS_MESSAGE_MAX_SIZE (4096)
// DNS Resource Record types
// (RFC 1035 section 3.2.2)
#define DNS_RR_TYPE_A (1)
#define DNS_RR_TYPE_CNAME (5)
#define DNS_RR_TYPE_PTR (12)
#define DNS_RR_TYPE_TXT (16)
#define DNS_RR_TYPE_SRV (33)
// TODO not sure about this
#define MAX_RR_NAME_SIZE (256)
#define MAX_DEREFERENCE_COUNT (40)
#define NFREE(p) { if (p) free(p); }
struct mDNSMessageStruct{
uint16_t id;
uint16_t flags;
uint16_t qd_count;
uint16_t an_count;
uint16_t ns_count;
uint16_t ar_count;
char* data;
size_t data_size;
};
//} __attribute__((__packed__)); // ensure that struct is packed
typedef struct mDNSMessageStruct mDNSMessage;
typedef struct {
int qr;
int opcode;
int aa;
int tc;
int rd;
int ra;
int zero;
int ad;
int cd;
int rcode;
} mDNSFlags;
typedef struct {
char* qname;
uint16_t qtype;
uint16_t qclass;
int prefer_unicast_response;
} mDNSQuestion;
typedef struct {
char* name;
uint16_t type;
uint16_t class;
uint32_t ttl;
uint16_t rdata_length;
void* rdata;
} mDNSResourceRecord;
typedef struct slist_s {
struct slist_s *next;
enum {MDNS_CURRENT = 1, MDNS_UPDATED = 2, MDNS_EXPIRED = 3} status;
struct ttl_timing_s {
uint32_t last, wake;
uint32_t ttl;
} rr_srv, rr_ptr, rr_txt;
char *name, *hostname;
struct in_addr addr, host;
uint16_t port;
int txt_length;
char *txt;
} slist_t;
typedef struct alist_s {
struct alist_s *next;
struct ttl_timing_s rr;
char *name;
struct in_addr addr;
} alist_t;
typedef struct mdnssd_handle_s {
int sock;
enum { MDNS_IDLE, MDNS_RUNNING } state;
mdnssd_control_e control;
struct context_s {
const char* query;
slist_t* slist;
alist_t* alist;
uint32_t srecords, arecords;
} context;
} mdnssd_handle_t;
typedef struct item_s {
struct item_s *next;
} item_t;
typedef int compare_list_f(void *a, void *b);
static item_t *remove_item(item_t *a, item_t **list);
static item_t *insert_item(item_t *a, item_t **list);
/*
static item_t *insert_ordered_item(item_t *a, item_t **list, compare_list_f *compare);
static item_t *insert_tail_item(item_t *item, item_t **list);
*/
static void clear_list(item_t *list, void (*clean)(void *));
static void store_a(struct context_s *context, mDNSResourceRecord* rr);
static void store_other(struct in_addr host, struct context_s *context, char *message, mDNSResourceRecord* rr);
static int debug(const char* format, ...);
static mDNSFlags* mdns_parse_header_flags(uint16_t data);
static uint16_t mdns_pack_header_flags(mDNSFlags flags);
static char* mdns_pack_question(mDNSQuestion* q, size_t* size);
static void mdns_message_print(mDNSMessage* msg);
static mDNSMessage* mdns_build_query_message(char* query, uint16_t query_type, bool unicast);
static char* mdns_pack_message(mDNSMessage* msg, size_t* pack_length);
static int mdns_parse_question(char* message, char* data, int size);
static int mdns_parse_rr_a(char* data, struct in_addr *addr);
static int mdns_parse_rr_ptr(char* message, char* data, char **name);
static int mdns_parse_rr_srv(char* message, char* data, char **hostname, unsigned short *port);
static void mdns_parse_rr_txt(char* message, mDNSResourceRecord* rr, char **txt, int *length);
static int mdns_parse_rr(struct in_addr host, struct context_s *context, char* message, char* rrdata, int size, int is_answer);
static int mdns_parse_message_net(struct in_addr host, struct context_s *context, char* data, int size, mDNSMessage* msg);
static char* parse_rr_name(char* message, char* name, int *parsed);
static uint16_t get_offset(char* data);
static void free_resource_record(mDNSResourceRecord* rr);
static void clear_context(struct context_s *context);
static char* prepare_query_string(const char* name);
static int send_query(int sock, const char* query, uint16_t query_type, bool unicast);