]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/dDNS.c
mDNSResponder-98.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / dDNS.c
1 /*
2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 */
26
27 #include "dDNS.h"
28 #include "DNSCommon.h"
29 #include <winsock2.h>
30 #include <iphlpapi.h>
31 #include <ws2tcpip.h>
32
33 typedef struct SearchListElem
34 {
35 struct SearchListElem *next;
36 domainname domain;
37 int flag;
38 DNSQuestion BrowseQ;
39 DNSQuestion DefBrowseQ;
40 DNSQuestion LegacyBrowseQ;
41 DNSQuestion RegisterQ;
42 DNSQuestion DefRegisterQ;
43 ARListElem *AuthRecs;
44 } SearchListElem;
45 // for domain enumeration and default browsing/registration
46 static SearchListElem *SearchList = mDNSNULL; // where we search for _browse domains
47 static DNSQuestion LegacyBrowseDomainQ; // our local enumeration query for _legacy._browse domains
48 static DNameListElem *DefBrowseList = mDNSNULL; // cache of answers to above query (where we search for empty string browses)
49 static DNameListElem *DefRegList = mDNSNULL; // manually generated list of domains where we register for empty string registrations
50 static ARListElem *SCPrefBrowseDomains = mDNSNULL; // manually generated local-only PTR records for browse domains we get from SCPreferences
51
52 static domainname dDNSRegDomain; // Default wide-area zone for service registration
53 static domainname dDNSBrowseDomain; // Default wide-area zone for legacy ("empty string") browses
54 static domainname dDNSHostname;
55
56
57 mStatus dDNS_SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
58 {
59 if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
60
61 if (sa->sa_family == AF_INET)
62 {
63 struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
64 ip->type = mDNSAddrType_IPv4;
65 ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
66 return(mStatus_NoError);
67 }
68
69 if (sa->sa_family == AF_INET6)
70 {
71 struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
72 ip->type = mDNSAddrType_IPv6;
73 #if !defined(_WIN32)
74 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
75 #else
76 if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
77 #endif
78 ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
79 return(mStatus_NoError);
80 }
81
82 LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
83 return(mStatus_Invalid);
84 }
85
86 mDNSlocal void MarkSearchListElem(domainname *domain)
87 {
88 SearchListElem *new, *ptr;
89
90 // if domain is in list, mark as pre-existent (0)
91 for (ptr = SearchList; ptr; ptr = ptr->next)
92 if (SameDomainName(&ptr->domain, domain))
93 {
94 if (ptr->flag != 1) ptr->flag = 0; // gracefully handle duplicates - if it is already marked as add, don't bump down to preexistent
95 break;
96 }
97
98 // if domain not in list, add to list, mark as add (1)
99 if (!ptr)
100 {
101 new = mallocL("MarkSearchListElem - SearchListElem", sizeof(SearchListElem));
102 if (!new) { LogMsg("ERROR: MarkSearchListElem - malloc"); return; }
103 bzero(new, sizeof(SearchListElem));
104 AssignDomainName(&new->domain, domain);
105 new->flag = 1; // add
106 new->next = SearchList;
107 SearchList = new;
108 }
109 }
110
111 //!!!KRS here is where we will give success/failure notification to the UI
112 mDNSlocal void SCPrefsdDNSCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
113 {
114 (void)m; // unused
115 debugf("SCPrefsdDNSCallback: result %d for registration of name %##s", result, rr->resrec.name->c);
116 dDNSPlatformSetNameStatus(rr->resrec.name, result);
117 }
118
119 mDNSlocal void FreeARElemCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
120 {
121 ARListElem *elem = rr->RecordContext;
122
123 (void)m; // unused
124
125 if (result == mStatus_MemFree) freeL("FreeARElemCallback", elem);
126 }
127
128 mDNSlocal void FoundDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord)
129 {
130 SearchListElem *slElem = question->QuestionContext;
131 ARListElem *arElem, *ptr, *prev;
132 AuthRecord *dereg;
133 const char *name;
134 mStatus err;
135
136 if (AddRecord)
137 {
138 arElem = mallocL("FoundDomain - arElem", sizeof(ARListElem));
139 if (!arElem) { LogMsg("ERROR: malloc"); return; }
140 mDNS_SetupResourceRecord(&arElem->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, arElem);
141 if (question == &slElem->BrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowse];
142 else if (question == &slElem->DefBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseDefault];
143 else if (question == &slElem->LegacyBrowseQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeBrowseLegacy];
144 else if (question == &slElem->RegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistration];
145 else if (question == &slElem->DefRegisterQ) name = mDNS_DomainTypeNames[mDNS_DomainTypeRegistrationDefault];
146 else { LogMsg("FoundDomain - unknown question"); return; }
147
148 MakeDomainNameFromDNSNameString(arElem->ar.resrec.name, name);
149 AppendDNSNameString (arElem->ar.resrec.name, "local");
150 AssignDomainName(&arElem->ar.resrec.rdata->u.name, &answer->rdata->u.name);
151 err = mDNS_Register(m, &arElem->ar);
152 if (err)
153 {
154 LogMsg("ERROR: FoundDomain - mDNS_Register returned %d", err);
155 freeL("FoundDomain - arElem", arElem);
156 return;
157 }
158 arElem->next = slElem->AuthRecs;
159 slElem->AuthRecs = arElem;
160 }
161 else
162 {
163 ptr = slElem->AuthRecs;
164 prev = NULL;
165 while (ptr)
166 {
167 if (SameDomainName(&ptr->ar.resrec.rdata->u.name, &answer->rdata->u.name))
168 {
169 debugf("Deregistering PTR %s -> %s", ptr->ar.resrec.name->c, ptr->ar.resrec.rdata->u.name.c);
170 dereg = &ptr->ar;
171 if (prev) prev->next = ptr->next;
172 else slElem->AuthRecs = ptr->next;
173 ptr = ptr->next;
174 err = mDNS_Deregister(m, dereg);
175 if (err) LogMsg("ERROR: FoundDomain - mDNS_Deregister returned %d", err);
176 }
177 else
178 {
179 prev = ptr;
180 ptr = ptr->next;
181 }
182 }
183 }
184 }
185
186 mDNSexport DNameListElem *mDNSPlatformGetSearchDomainList(void)
187 {
188 return mDNS_CopyDNameList(DefBrowseList);
189 }
190
191 mDNSexport DNameListElem *mDNSPlatformGetRegDomainList(void)
192 {
193 return mDNS_CopyDNameList(DefRegList);
194 }
195
196 mDNSlocal void AddDefRegDomain(domainname *d)
197 {
198 DNameListElem *newelem = NULL, *ptr;
199
200 // make sure name not already in list
201 for (ptr = DefRegList; ptr; ptr = ptr->next)
202 {
203 if (SameDomainName(&ptr->name, d))
204 { debugf("duplicate addition of default reg domain %##s", d->c); return; }
205 }
206
207 newelem = mallocL("DNameListElem", sizeof(*newelem));
208 if (!newelem) { LogMsg("Error - malloc"); return; }
209 AssignDomainName(&newelem->name, d);
210 newelem->next = DefRegList;
211 DefRegList = newelem;
212
213 dDNSPlatformDefaultRegDomainChanged(d, mDNStrue);
214 udsserver_default_reg_domain_changed(d, mDNStrue);
215 }
216
217 mDNSlocal void RemoveDefRegDomain(domainname *d)
218 {
219 DNameListElem *ptr = DefRegList, *prev = NULL;
220
221 while (ptr)
222 {
223 if (SameDomainName(&ptr->name, d))
224 {
225 if (prev) prev->next = ptr->next;
226 else DefRegList = ptr->next;
227 freeL("DNameListElem", ptr);
228 dDNSPlatformDefaultRegDomainChanged(d, mDNSfalse);
229 udsserver_default_reg_domain_changed(d, mDNSfalse);
230 return;
231 }
232 prev = ptr;
233 ptr = ptr->next;
234 }
235 debugf("Requested removal of default registration domain %##s not in contained in list", d->c);
236 }
237
238
239 mDNSlocal void FoundDefBrowseDomain(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord)
240 {
241 DNameListElem *ptr, *prev, *new;
242 (void)m; // unused;
243 (void)question; // unused
244
245 if (AddRecord)
246 {
247 new = mallocL("FoundDefBrowseDomain", sizeof(DNameListElem));
248 if (!new) { LogMsg("ERROR: malloc"); return; }
249 AssignDomainName(&new->name, &answer->rdata->u.name);
250 new->next = DefBrowseList;
251 DefBrowseList = new;
252 dDNSPlatformDefaultBrowseDomainChanged(&new->name, mDNStrue);
253 udsserver_default_browse_domain_changed(&new->name, mDNStrue);
254 return;
255 }
256 else
257 {
258 ptr = DefBrowseList;
259 prev = NULL;
260 while (ptr)
261 {
262 if (SameDomainName(&ptr->name, &answer->rdata->u.name))
263 {
264 dDNSPlatformDefaultBrowseDomainChanged(&ptr->name, mDNSfalse);
265 udsserver_default_browse_domain_changed(&ptr->name, mDNSfalse);
266 if (prev) prev->next = ptr->next;
267 else DefBrowseList = ptr->next;
268 freeL("FoundDefBrowseDomain", ptr);
269 return;
270 }
271 prev = ptr;
272 ptr = ptr->next;
273 }
274 LogMsg("FoundDefBrowseDomain: Got remove event for domain %s not in list", answer->rdata->u.name.c);
275 }
276 }
277
278
279 mDNSlocal mStatus RegisterNameServers( mDNS *const m )
280 {
281 IPAddrListElem * list;
282 IPAddrListElem * elem;
283
284 mDNS_DeleteDNSServers(m); // deregister orig list
285
286 list = dDNSPlatformGetDNSServers();
287
288 for ( elem = list; elem; elem = elem->next )
289 {
290 LogOperation("RegisterNameServers: Adding %#a", &elem->addr);
291 mDNS_AddDNSServer(m, &elem->addr, NULL);
292 }
293
294 dDNS_FreeIPAddrList( list );
295
296 return mStatus_NoError;
297 }
298
299
300 mDNSlocal mStatus RegisterSearchDomains( mDNS *const m )
301 {
302 SearchListElem *ptr, *prev, *freeSLPtr;
303 DNameListElem * elem;
304 DNameListElem * list;
305 ARListElem *arList;
306 mStatus err;
307 mDNSBool dict = 1;
308
309 // step 1: mark each elem for removal (-1), unless we aren't passed a dictionary in which case we mark as preexistent
310 for (ptr = SearchList; ptr; ptr = ptr->next) ptr->flag = dict ? -1 : 0;
311
312 // get all the domains from "Search Domains" field of sharing prefs
313
314 list = dDNSPlatformGetSearchDomainList();
315
316 for ( elem = list; elem; elem = elem->next )
317 {
318 MarkSearchListElem(&elem->name);
319 }
320
321 mDNS_FreeDNameList( list );
322
323 list = dDNSPlatformGetDomainName();
324
325 if ( list )
326 {
327 MarkSearchListElem( &list->name );
328 mDNS_FreeDNameList( list );
329 }
330
331 list = dDNSPlatformGetReverseMapSearchDomainList( );
332
333 for ( elem = list; elem; elem = elem->next )
334 {
335 MarkSearchListElem(&elem->name);
336 }
337
338 mDNS_FreeDNameList( list );
339
340 if (dDNSRegDomain.c[0]) MarkSearchListElem(&dDNSRegDomain); // implicitly browse reg domain too (no-op if same as BrowseDomain)
341
342 // delete elems marked for removal, do queries for elems marked add
343 prev = mDNSNULL;
344 ptr = SearchList;
345 while (ptr)
346 {
347 if (ptr->flag == -1) // remove
348 {
349 mDNS_StopQuery(m, &ptr->BrowseQ);
350 mDNS_StopQuery(m, &ptr->RegisterQ);
351 mDNS_StopQuery(m, &ptr->DefBrowseQ);
352 mDNS_StopQuery(m, &ptr->DefRegisterQ);
353 mDNS_StopQuery(m, &ptr->LegacyBrowseQ);
354
355 // deregister records generated from answers to the query
356 arList = ptr->AuthRecs;
357 ptr->AuthRecs = mDNSNULL;
358 while (arList)
359 {
360 AuthRecord *dereg = &arList->ar;
361 arList = arList->next;
362 debugf("Deregistering PTR %s -> %s", dereg->resrec.name->c, dereg->resrec.rdata->u.name.c);
363 err = mDNS_Deregister(m, dereg);
364 if (err) LogMsg("ERROR: RegisterSearchDomains mDNS_Deregister returned %d", err);
365 }
366
367 // remove elem from list, delete
368 if (prev) prev->next = ptr->next;
369 else SearchList = ptr->next;
370 freeSLPtr = ptr;
371 ptr = ptr->next;
372 freeL("RegisterSearchDomains - freeSLPtr", freeSLPtr);
373 continue;
374 }
375
376 if (ptr->flag == 1) // add
377 {
378 mStatus err1, err2, err3, err4, err5;
379 err1 = mDNS_GetDomains(m, &ptr->BrowseQ, mDNS_DomainTypeBrowse, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
380 err2 = mDNS_GetDomains(m, &ptr->DefBrowseQ, mDNS_DomainTypeBrowseDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
381 err3 = mDNS_GetDomains(m, &ptr->RegisterQ, mDNS_DomainTypeRegistration, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
382 err4 = mDNS_GetDomains(m, &ptr->DefRegisterQ, mDNS_DomainTypeRegistrationDefault, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
383 err5 = mDNS_GetDomains(m, &ptr->LegacyBrowseQ, mDNS_DomainTypeBrowseLegacy, &ptr->domain, mDNSInterface_Any, FoundDomain, ptr);
384 if (err1 || err2 || err3 || err4 || err5)
385 LogMsg("GetDomains for domain %##s returned error(s):\n"
386 "%d (mDNS_DomainTypeBrowse)\n"
387 "%d (mDNS_DomainTypeBrowseDefault)\n"
388 "%d (mDNS_DomainTypeRegistration)\n"
389 "%d (mDNS_DomainTypeRegistrationDefault)"
390 "%d (mDNS_DomainTypeBrowseLegacy)\n",
391 ptr->domain.c, err1, err2, err3, err4, err5);
392 ptr->flag = 0;
393 }
394
395 if (ptr->flag) { LogMsg("RegisterSearchDomains - unknown flag %d. Skipping.", ptr->flag); }
396
397 prev = ptr;
398 ptr = ptr->next;
399 }
400
401 return mStatus_NoError;
402 }
403
404 // Add or remove a user-specified domain to the list of empty-string browse domains
405 // Also register a non-legacy _browse PTR record so that the domain appears in enumeration lists
406 mDNSlocal void SetSCPrefsBrowseDomain(mDNS *m, const domainname *d, mDNSBool add)
407 {
408 AuthRecord rec;
409
410 LogMsg("%s default browse domain %##s", add ? "Adding" : "Removing", d->c);
411
412 // Create dummy record pointing to the domain to be added/removed
413 mDNS_SetupResourceRecord(&rec, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, mDNSNULL, mDNSNULL);
414 AssignDomainName(&rec.resrec.rdata->u.name, d);
415
416 // add/remove the "_legacy" entry
417 MakeDomainNameFromDNSNameString(rec.resrec.name, mDNS_DomainTypeNames[mDNS_DomainTypeBrowseLegacy]);
418 AppendDNSNameString (rec.resrec.name, "local");
419 FoundDefBrowseDomain(m, &LegacyBrowseDomainQ, &rec.resrec, add);
420
421 if (add)
422 {
423 mStatus err;
424
425 // allocate/register a non-legacy _browse PTR record
426 ARListElem *ptr = mallocL("ARListElem", sizeof(*ptr));
427 mDNS_SetupResourceRecord(&ptr->ar, mDNSNULL, mDNSInterface_LocalOnly, kDNSType_PTR, 7200, kDNSRecordTypeShared, FreeARElemCallback, ptr);
428 MakeDomainNameFromDNSNameString(ptr->ar.resrec.name, mDNS_DomainTypeNames[mDNS_DomainTypeBrowse]);
429 AppendDNSNameString (ptr->ar.resrec.name, "local");
430 AssignDomainName(&ptr->ar.resrec.rdata->u.name, d);
431 err = mDNS_Register(m, &ptr->ar);
432 if (err)
433 {
434 LogMsg("SetSCPrefsBrowseDomain: mDNS_Register returned error %d", err);
435 freeL("ARListElem", ptr);
436 }
437 else
438 {
439 ptr->next = SCPrefBrowseDomains;
440 SCPrefBrowseDomains = ptr;
441 }
442 }
443 else
444 {
445 ARListElem **remove = &SCPrefBrowseDomains;
446 while (*remove && !SameDomainName(&(*remove)->ar.resrec.rdata->u.name, d)) remove = &(*remove)->next;
447 if (!*remove) { LogMsg("SetSCPrefsBrowseDomain (remove) - domain %##s not found!", d->c); return; }
448 mDNS_Deregister(m, &(*remove)->ar);
449 *remove = (*remove)->next;
450 }
451 }
452
453
454 mStatus dDNS_Setup( mDNS *const m )
455 {
456 static mDNSBool LegacyNATInitialized = mDNSfalse;
457 mDNSBool dict = mDNStrue;
458 mDNSAddr ip;
459 mDNSAddr r;
460 // YO CFDictionaryRef dict;
461 // YO CFStringRef key;
462 domainname BrowseDomain, RegDomain, fqdn;
463
464 // get fqdn, zone from SCPrefs
465 dDNSPlatformGetConfig(&fqdn, &RegDomain, &BrowseDomain);
466
467 // YO if (!fqdn.c[0] && !RegDomain.c[0]) ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &fqdn, &RegDomain);
468
469 if (!SameDomainName(&RegDomain, &dDNSRegDomain))
470 {
471 if (dDNSRegDomain.c[0])
472 {
473 RemoveDefRegDomain(&dDNSRegDomain);
474 SetSCPrefsBrowseDomain(m, &dDNSRegDomain, mDNSfalse); // if we were automatically browsing in our registration domain, stop
475 }
476
477 AssignDomainName(&dDNSRegDomain, &RegDomain);
478
479 if (dDNSRegDomain.c[0])
480 {
481 dDNSPlatformSetSecretForDomain(m, &dDNSRegDomain);
482 AddDefRegDomain(&dDNSRegDomain);
483 SetSCPrefsBrowseDomain(m, &dDNSRegDomain, mDNStrue);
484 }
485 }
486
487 if (!SameDomainName(&BrowseDomain, &dDNSBrowseDomain))
488 {
489 if (dDNSBrowseDomain.c[0]) SetSCPrefsBrowseDomain(m, &dDNSBrowseDomain, mDNSfalse);
490 AssignDomainName(&dDNSBrowseDomain, &BrowseDomain);
491 if (dDNSBrowseDomain.c[0]) SetSCPrefsBrowseDomain(m, &dDNSBrowseDomain, mDNStrue);
492 }
493
494 if (!SameDomainName(&fqdn, &dDNSHostname))
495 {
496 if (dDNSHostname.c[0]) mDNS_RemoveDynDNSHostName(m, &dDNSHostname);
497 AssignDomainName(&dDNSHostname, &fqdn);
498 if (dDNSHostname.c[0])
499 {
500 dDNSPlatformSetSecretForDomain(m, &fqdn); // no-op if "zone" secret, above, is to be used for hostname
501 mDNS_AddDynDNSHostName(m, &dDNSHostname, SCPrefsdDNSCallback, mDNSNULL);
502 dDNSPlatformSetNameStatus(&dDNSHostname, 1);
503 }
504 }
505
506 // get DNS settings
507 // YO SCDynamicStoreRef store = SCDynamicStoreCreate(mDNSNULL, CFSTR("mDNSResponder:dDNSConfigChanged"), mDNSNULL, mDNSNULL);
508 // YO if (!store) return;
509
510 // YO key = SCDynamicStoreKeyCreateNetworkGlobalEntity(mDNSNULL, kSCDynamicStoreDomainState, kSCEntNetDNS);
511 // YO if (!key) { LogMsg("ERROR: DNSConfigChanged - SCDynamicStoreKeyCreateNetworkGlobalEntity"); CFRelease(store); return; }
512 // YO dict = SCDynamicStoreCopyValue(store, key);
513 // YO CFRelease(key);
514
515 // handle any changes to search domains and DNS server addresses
516 if ( dDNSPlatformRegisterSplitDNS(m) != mStatus_NoError)
517 if (dict) RegisterNameServers( m ); // fall back to non-split DNS aware configuration on failure
518 RegisterSearchDomains( m ); // note that we register name servers *before* search domains
519 // if (dict) CFRelease(dict);
520
521 // get IPv4 settings
522 // YO key = SCDynamicStoreKeyCreateNetworkGlobalEntity(mDNSNULL,kSCDynamicStoreDomainState, kSCEntNetIPv4);
523 // YO if (!key) { LogMsg("ERROR: RouterChanged - SCDynamicStoreKeyCreateNetworkGlobalEntity"); CFRelease(store); return; }
524 // YO dict = SCDynamicStoreCopyValue(store, key);
525 // YO CFRelease(key);
526 // YO CFRelease(store);
527 // YO if (!dict)
528 // YO { mDNS_SetPrimaryInterfaceInfo(m, mDNSNULL, mDNSNULL); return; } // lost v4
529
530 // handle router changes
531 // YO mDNSAddr r;
532 // YO char buf[256];
533 // YO r.type = mDNSAddrType_IPv4;
534 // YO r.ip.v4.NotAnInteger = 0;
535 // YO CFStringRef router = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
536 // YO if (router)
537 // YO {
538 // YO if (!CFStringGetCString(router, buf, 256, kCFStringEncodingUTF8))
539 // YO LogMsg("Could not convert router to CString");
540 // YO else inet_aton(buf, (struct in_addr *)&r.ip.v4);
541 // YO }
542
543 // handle router and primary interface changes
544
545 ip.type = r.type = mDNSAddrType_IPv4;
546 ip.ip.v4.NotAnInteger = r.ip.v4.NotAnInteger = 0;
547
548 if ( dDNSPlatformGetPrimaryInterface( m, &ip, &r ) == mStatus_NoError )
549 {
550 mDNS_SetPrimaryInterfaceInfo(m, &ip, r.ip.v4.NotAnInteger ? &r : mDNSNULL);
551 }
552
553 return mStatus_NoError;
554 }
555
556
557 // Construction of Default Browse domain list (i.e. when clients pass NULL) is as follows:
558 // 1) query for b._dns-sd._udp.local on LocalOnly interface
559 // (.local manually generated via explicit callback)
560 // 2) for each search domain (from prefs pane), query for b._dns-sd._udp.<searchdomain>.
561 // 3) for each result from (2), register LocalOnly PTR record b._dns-sd._udp.local. -> <result>
562 // 4) result above should generate a callback from question in (1). result added to global list
563 // 5) global list delivered to client via GetSearchDomainList()
564 // 6) client calls to enumerate domains now go over LocalOnly interface
565 // (!!!KRS may add outgoing interface in addition)
566
567 mStatus dDNS_InitDNSConfig(mDNS *const m)
568 {
569 mStatus err;
570
571 // start query for domains to be used in default (empty string domain) browses
572 err = mDNS_GetDomains(m, &LegacyBrowseDomainQ, mDNS_DomainTypeBrowseLegacy, NULL, mDNSInterface_LocalOnly, FoundDefBrowseDomain, NULL);
573
574 // provide .local automatically
575 SetSCPrefsBrowseDomain(m, &localdomain, mDNStrue);
576 return mStatus_NoError;
577 }
578
579 void
580 dDNS_FreeIPAddrList(IPAddrListElem * list)
581 {
582 IPAddrListElem * fptr;
583
584 while (list)
585 {
586 fptr = list;
587 list = list->next;
588 mDNSPlatformMemFree(fptr);
589 }
590 }