async_dnssd/
ffi.rs

1// #![allow(dead_code)]
2
3// https://github.com/apple-oss-distributions/mDNSResponder/blob/main/mDNSShared/dns_sd.h
4// https://github.com/avahi/avahi/blob/master/avahi-compat-libdns_sd/dns_sd.h
5
6use std::os::raw::{
7	c_char,
8	c_int,
9	c_void,
10};
11
12// type without an instance
13pub enum DNSServiceT {}
14pub type DNSServiceRef = *mut DNSServiceT;
15
16// type without an instance
17pub enum DNSRecordT {}
18pub type DNSRecordRef = *mut DNSRecordT;
19
20pub type DNSServiceFlags = u32;
21// pub const FLAGS_NONE                 : DNSServiceFlags = 0x0;
22pub const FLAGS_MORE_COMING: DNSServiceFlags = 0x1;
23pub const FLAGS_ADD: DNSServiceFlags = 0x2;
24pub const FLAGS_DEFAULT: DNSServiceFlags = 0x4;
25pub const FLAGS_NO_AUTO_RENAME: DNSServiceFlags = 0x8;
26pub const FLAGS_SHARED: DNSServiceFlags = 0x10;
27pub const FLAGS_UNIQUE: DNSServiceFlags = 0x20;
28pub const FLAGS_BROWSE_DOMAINS: DNSServiceFlags = 0x40;
29pub const FLAGS_REGISTRATION_DOMAINS: DNSServiceFlags = 0x80;
30// unix only?
31#[cfg(unix)]
32pub const FLAGS_LONG_LIVED_QUERY: DNSServiceFlags = 0x100;
33#[cfg(not(unix))]
34pub const FLAGS_LONG_LIVED_QUERY: DNSServiceFlags = 0;
35// pub const FLAGS_ALLOW_REMOTE_QUERY: DNSServiceFlags = 0x200;
36// pub const FLAGS_FORCE_MULTICAST: DNSServiceFlags = 0x400;
37
38/// Maximum length of full name including trailing dot and terminating NULL
39///
40/// See [`kDNSServiceMaxDomainName`](https://developer.apple.com/documentation/dnssd/kdnsservicemaxdomainname)
41pub const MAX_DOMAIN_NAME: usize = 1009;
42
43pub const INTERFACE_INDEX_ANY: u32 = 0;
44pub const INTERFACE_INDEX_LOCAL_ONLY: u32 = !0;
45pub const INTERFACE_INDEX_UNICAST: u32 = !1;
46pub const INTERFACE_INDEX_P2P: u32 = !2;
47
48macro_rules! c_api_enum {
49	($(#[$m:meta])* $name:ident : $ty:tt => $($case:ident = $val:expr,)* ) => (
50		#[derive(Clone,Copy,Eq,PartialEq,Ord,PartialOrd,Hash,Debug)]
51		#[repr($ty)]
52		$(#[$m])*
53		pub enum $name {
54			$($case = $val,)*
55		}
56		impl $name {
57			pub fn try_from(value: $ty) -> Option<Self> {
58				$(if value == $val {
59					Some(Self::$case)
60				} else)* {
61					None
62				}
63			}
64		}
65	)
66}
67
68pub type DNSServiceErrorType = i32;
69
70c_api_enum! {
71#[non_exhaustive]
72DNSServiceNoError: i32 =>
73	NoError               = 0,
74/* source unclear
75	// windows "TCP Connection Status"
76	// these 3 overlap with error codes below
77	ConnectionPending     = -65570,
78	ConnectionFailed      = -65571,
79	ConnectionEstablished = -65572,
80*/
81	// windows "Non-error values"
82	GrowCache             = -65790,
83	ConfigChanged         = -65791,
84	MemFree               = -65792,
85}
86
87c_api_enum! {
88/// Known error codes
89///
90/// See [`DNSServiceErrorType`](https://developer.apple.com/documentation/dnssd/1823426-anonymous)
91#[non_exhaustive]
92DNSServiceError: i32 =>
93	Unknown                   = -65537,
94	NoSuchName                = -65538,
95	NoMemory                  = -65539,
96	BadParam                  = -65540,
97	BadReference              = -65541,
98	BadState                  = -65542,
99	BadFlags                  = -65543,
100	Unsupported               = -65544,
101	NotInitialized            = -65545,
102	// NoCache                = -65546,
103	AlreadyRegistered         = -65547,
104	NameConflict              = -65548,
105	Invalid                   = -65549,
106	Firewall                  = -65550,
107	Incompatible              = -65551,
108	BadInterfaceIndex         = -65552,
109	Refused                   = -65553,
110	NoSuchRecord              = -65554,
111	NoAuth                    = -65555,
112	NoSuchKey                 = -65556,
113	NATTraversal              = -65557,
114	DoubleNAT                 = -65558,
115	BadTime                   = -65559,
116	BadSig                    = -65560,
117	BadKey                    = -65561,
118	Transient                 = -65562,
119	ServiceNotRunning         = -65563,
120	NATPortMappingUnsupported = -65564,
121	NATPortMappingDisabled    = -65565,
122	NoRouter                  = -65566,
123	PollingMode               = -65567,
124	Timeout                   = -65568,
125	DefunctConnection         = -65569,
126	PolicyDenied              = -65570,
127	NotPermitted              = -65571,
128	StaleData                 = -65572,
129}
130
131pub type DNSServiceDomainEnumReply = Option<
132	unsafe extern "C" fn(
133		sd_ref: DNSServiceRef,
134		flags: DNSServiceFlags,
135		interface_index: u32,
136		error_code: DNSServiceErrorType,
137		reply_domain: *const c_char,
138		context: *mut c_void,
139	),
140>;
141pub type DNSServiceRegisterReply = Option<
142	unsafe extern "C" fn(
143		sd_ref: DNSServiceRef,
144		flags: DNSServiceFlags,
145		error_code: DNSServiceErrorType,
146		name: *const c_char,
147		reg_type: *const c_char,
148		domain: *const c_char,
149		context: *mut c_void,
150	),
151>;
152pub type DNSServiceBrowseReply = Option<
153	unsafe extern "C" fn(
154		sd_ref: DNSServiceRef,
155		flags: DNSServiceFlags,
156		interface_index: u32,
157		error_code: DNSServiceErrorType,
158		service_name: *const c_char,
159		reg_type: *const c_char,
160		reply_domain: *const c_char,
161		context: *mut c_void,
162	),
163>;
164pub type DNSServiceResolveReply = Option<
165	unsafe extern "C" fn(
166		sd_ref: DNSServiceRef,
167		flags: DNSServiceFlags,
168		interface_index: u32,
169		error_code: DNSServiceErrorType,
170		fullname: *const c_char,
171		host_target: *const c_char,
172		port: u16,
173		txt_len: u16,
174		txt_record: *const u8,
175		context: *mut c_void,
176	),
177>;
178pub type DNSServiceRegisterRecordReply = Option<
179	unsafe extern "C" fn(
180		sd_ref: DNSServiceRef,
181		record_ref: DNSRecordRef,
182		flags: DNSServiceFlags,
183		error_code: DNSServiceErrorType,
184		context: *mut c_void,
185	),
186>;
187pub type DNSServiceQueryRecordReply = Option<
188	unsafe extern "C" fn(
189		sd_ref: DNSServiceRef,
190		flags: DNSServiceFlags,
191		interface_index: u32,
192		error_code: DNSServiceErrorType,
193		fullname: *const c_char,
194		rr_type: u16,
195		rr_class: u16,
196		rd_len: u16,
197		rdata: *const u8,
198		ttl: u32,
199		context: *mut c_void,
200	),
201>;
202
203unsafe extern "C" {
204	pub fn DNSServiceRefSockFD(sd_ref: DNSServiceRef) -> c_int;
205	pub fn DNSServiceProcessResult(sd_ref: DNSServiceRef) -> DNSServiceErrorType;
206	pub fn DNSServiceRefDeallocate(sd_ref: DNSServiceRef);
207	pub fn DNSServiceEnumerateDomains(
208		sd_ref: *mut DNSServiceRef,
209		flags: DNSServiceFlags,
210		interface_index: u32,
211		callback: DNSServiceDomainEnumReply,
212		context: *mut c_void,
213	) -> DNSServiceErrorType;
214	pub fn DNSServiceRegister(
215		sd_ref: *mut DNSServiceRef,
216		flags: DNSServiceFlags,
217		interface_index: u32,
218		name: *const c_char,
219		reg_type: *const c_char,
220		domain: *const c_char,
221		host: *const c_char,
222		port: u16,
223		txt_len: u16,
224		txt_record: *const u8,
225		callback: DNSServiceRegisterReply,
226		context: *mut c_void,
227	) -> DNSServiceErrorType;
228	pub fn DNSServiceAddRecord(
229		sd_ref: DNSServiceRef,
230		record_ref: *mut DNSRecordRef,
231		flags: DNSServiceFlags,
232		rr_type: u16,
233		rd_len: u16,
234		rdata: *const u8,
235		ttl: u32,
236	) -> DNSServiceErrorType;
237	pub fn DNSServiceUpdateRecord(
238		sd_ref: DNSServiceRef,
239		record_ref: DNSRecordRef,
240		flags: DNSServiceFlags,
241		rd_len: u16,
242		rdata: *const u8,
243		ttl: u32,
244	) -> DNSServiceErrorType;
245	pub fn DNSServiceRemoveRecord(
246		sd_ref: DNSServiceRef,
247		record_ref: DNSRecordRef,
248		flags: DNSServiceFlags,
249	) -> DNSServiceErrorType;
250	pub fn DNSServiceBrowse(
251		sd_ref: *mut DNSServiceRef,
252		flags: DNSServiceFlags,
253		interface_index: u32,
254		reg_type: *const c_char,
255		domain: *const c_char,
256		callback: DNSServiceBrowseReply,
257		context: *mut c_void,
258	) -> DNSServiceErrorType;
259	pub fn DNSServiceResolve(
260		sd_ref: *mut DNSServiceRef,
261		flags: DNSServiceFlags,
262		interface_index: u32,
263		name: *const c_char,
264		reg_type: *const c_char,
265		domain: *const c_char,
266		callback: DNSServiceResolveReply,
267		context: *mut c_void,
268	) -> DNSServiceErrorType;
269	pub fn DNSServiceCreateConnection(sd_ref: *mut DNSServiceRef) -> DNSServiceErrorType;
270	pub fn DNSServiceRegisterRecord(
271		sd_ref: DNSServiceRef,
272		record_ref: *mut DNSRecordRef,
273		flags: DNSServiceFlags,
274		interface_index: u32,
275		fullname: *const c_char,
276		rr_type: u16,
277		rr_class: u16,
278		rd_len: u16,
279		rdata: *const u8,
280		ttl: u32,
281		callback: DNSServiceRegisterRecordReply,
282		context: *mut c_void,
283	) -> DNSServiceErrorType;
284	pub fn DNSServiceQueryRecord(
285		sd_ref: *mut DNSServiceRef,
286		flags: DNSServiceFlags,
287		interface_index: u32,
288		fullname: *const c_char,
289		rr_type: u16,
290		rr_class: u16,
291		callback: DNSServiceQueryRecordReply,
292		context: *mut c_void,
293	) -> DNSServiceErrorType;
294	pub fn DNSServiceReconfirmRecord(
295		flags: DNSServiceFlags,
296		interface_index: u32,
297		fullname: *const c_char,
298		rr_type: u16,
299		rr_class: u16,
300		rd_len: u16,
301		rdata: *const u8,
302	) -> DNSServiceErrorType;
303	pub fn DNSServiceConstructFullName(
304		fullName: *mut c_char,
305		service: *const c_char,
306		reg_type: *const c_char,
307		domain: *const c_char,
308	) -> c_int;
309}
310
311// TXTRecordRef utils not wrapped - should be easy enough to implement
312// in pure rust
313
314/* Not used so far:
315#[cfg(windows)]
316mod ffi_windows {
317	use super::DNSServiceErrorType;
318	use std::os::raw::{
319		c_int,
320		c_void,
321	};
322
323	pub type DNSServiceInitializeFlags = u32;
324	pub const INITIALIZE_FLAGS_NONE: DNSServiceInitializeFlags = 0x0;
325	pub const INITIALIZE_FLAGS_ADVERTISE: DNSServiceInitializeFlags = 0x1;
326	pub const INITIALIZE_FLAGS_NO_SERVER_CHECK: DNSServiceInitializeFlags = 0x2;
327
328	pub type DNSPropertyCode = u32;
329
330	pub const PROPERTY_CODE_VERSION: DNSPropertyCode = 0x76657273;
331	#[repr(C)]
332	pub struct DnsPropertyVersion {
333		pub code: DNSPropertyCode,
334
335		pub client_current_version: u32,
336		pub client_oldest_server_version: u32,
337		pub server_current_version: u32,
338		pub server_oldest_client_version: u32,
339	}
340
341	extern "C" {
342		pub fn DNSServiceInitialize(
343			inFlags: DNSServiceInitializeFlags,
344			inCacheEntryCount: c_int,
345		) -> DNSServiceErrorType;
346		pub fn DNSServiceFinalize();
347		pub fn DNSServiceCheckVersion() -> DNSServiceErrorType;
348
349		// TODO? DNSPropertyData on windows.
350		// the c API uses a union... - using void instead here
351		pub fn DNSServiceCopyProperty(
352			inCode: DNSPropertyCode,
353			outData: *mut c_void,
354		) -> DNSServiceErrorType;
355		pub fn DNSServiceReleaseProperty(
356			inData: *mut c_void,
357		) -> DNSServiceErrorType;
358	}
359}
360#[cfg(windows)]
361pub use self::ffi_windows::*;
362*/