summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/Clients
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:53:26 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:32 +0200
commitf01edf10244ccd53e098abdc1773c1aa0e4c5f8d (patch)
tree958a1ee323520629c4f027de1d4c56715949aa5c /mDNSResponder/Clients
parentmDNSResponder: Update to v625.41.2 (diff)
downloadrtems-libbsd-f01edf10244ccd53e098abdc1773c1aa0e4c5f8d.tar.bz2
mDNSResponder: Update to v765.1.2
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-765.1.2.tar.gz Move mDNS_StartResolveService() and mDNS_StopResolveService() to an RTEMS-specific file (rtemsbsd/mdns/mDNSResolveService.c) using the v576.30.4 implementation. Apple removed these functions without explanation. Update #3522.
Diffstat (limited to 'mDNSResponder/Clients')
-rw-r--r--mDNSResponder/Clients/ClientCommon.c3
-rw-r--r--mDNSResponder/Clients/Java/nmakefile2
-rw-r--r--mDNSResponder/Clients/dns-sd.c606
-rw-r--r--mDNSResponder/Clients/dnsctl.c227
4 files changed, 679 insertions, 159 deletions
diff --git a/mDNSResponder/Clients/ClientCommon.c b/mDNSResponder/Clients/ClientCommon.c
index cb59e7b9..f96319ce 100644
--- a/mDNSResponder/Clients/ClientCommon.c
+++ b/mDNSResponder/Clients/ClientCommon.c
@@ -49,8 +49,9 @@ const char *GetNextLabel(const char *cstr, char label[64])
while (*cstr && *cstr != '.') // While we have characters in the label...
{
char c = *cstr++;
- if (c == '\\' && *cstr) // If we have a backslash, and it's not the last character of the string
+ if (c == '\\') // If escape character, check next character
{
+ if (*cstr == '\0') break; // If this is the end of the string, then break
c = *cstr++;
if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
{
diff --git a/mDNSResponder/Clients/Java/nmakefile b/mDNSResponder/Clients/Java/nmakefile
index 89168e0b..1758f7a4 100644
--- a/mDNSResponder/Clients/Java/nmakefile
+++ b/mDNSResponder/Clients/Java/nmakefile
@@ -29,7 +29,7 @@
############################################################################
-JDK = $(JAVA_HOME)
+JDK = "$(JAVA_HOME)"
CP = copy
RM = del /Q
diff --git a/mDNSResponder/Clients/dns-sd.c b/mDNSResponder/Clients/dns-sd.c
index 9469d24d..f36211e5 100644
--- a/mDNSResponder/Clients/dns-sd.c
+++ b/mDNSResponder/Clients/dns-sd.c
@@ -320,18 +320,70 @@ static char *DNSTypeName(unsigned short rr_type)
{
switch (rr_type)
{
- case kDNSServiceType_A: return("Addr");
- case kDNSServiceType_NS: return("NS");
- case kDNSServiceType_MX: return("MX");
- case kDNSServiceType_CNAME: return("CNAME");
- case kDNSServiceType_SOA: return("SOA");
- case kDNSServiceType_PTR: return("PTR");
- case kDNSServiceType_AAAA: return("AAAA");
- case kDNSServiceType_NSEC: return("NSEC");
- case kDNSServiceType_TSIG: return("TSIG");
- case kDNSServiceType_RRSIG: return("RRSIG");
- case kDNSServiceType_DNSKEY: return("DNSKEY");
- case kDNSServiceType_DS: return("DS");
+ case kDNSServiceType_A: return("Addr");
+ case kDNSServiceType_NS: return("NS");
+ case kDNSServiceType_MD: return("MD");
+ case kDNSServiceType_MF: return("MF");
+ case kDNSServiceType_CNAME: return("CNAME");
+ case kDNSServiceType_SOA: return("SOA");
+ case kDNSServiceType_MB: return("MB");
+ case kDNSServiceType_MG: return("MG");
+ case kDNSServiceType_MR: return("MR");
+ case kDNSServiceType_NULL: return("NULL");
+ case kDNSServiceType_WKS: return("WKS");
+ case kDNSServiceType_PTR: return("PTR");
+ case kDNSServiceType_HINFO: return("HINFO");
+ case kDNSServiceType_MINFO: return("MINFO");
+ case kDNSServiceType_MX: return("MX");
+ case kDNSServiceType_TXT: return("TXT");
+ case kDNSServiceType_RP: return("RP");
+ case kDNSServiceType_AFSDB: return("AFSDB");
+ case kDNSServiceType_X25: return("X25");
+ case kDNSServiceType_ISDN: return("ISDN");
+ case kDNSServiceType_RT: return("RT");
+ case kDNSServiceType_NSAP: return("NSAP");
+ case kDNSServiceType_NSAP_PTR: return("NSAP_PTR");
+ case kDNSServiceType_SIG: return("SIG");
+ case kDNSServiceType_KEY: return("KEY");
+ case kDNSServiceType_PX: return("PX");
+ case kDNSServiceType_GPOS: return("GPOS");
+ case kDNSServiceType_AAAA: return("AAAA");
+ case kDNSServiceType_LOC: return("LOC");
+ case kDNSServiceType_NXT: return("NXT");
+ case kDNSServiceType_EID: return("EID");
+ case kDNSServiceType_NIMLOC: return("NIMLOC");
+ case kDNSServiceType_SRV: return("SRV");
+ case kDNSServiceType_ATMA: return("ATMA");
+ case kDNSServiceType_NAPTR: return("NAPTR");
+ case kDNSServiceType_KX: return("KX");
+ case kDNSServiceType_CERT: return("CERT");
+ case kDNSServiceType_A6: return("A6");
+ case kDNSServiceType_DNAME: return("DNAME");
+ case kDNSServiceType_SINK: return("SINK");
+ case kDNSServiceType_OPT: return("OPT");
+ case kDNSServiceType_APL: return("APL");
+ case kDNSServiceType_DS: return("DS");
+ case kDNSServiceType_SSHFP: return("SSHFP");
+ case kDNSServiceType_IPSECKEY: return("IPSECKEY");
+ case kDNSServiceType_RRSIG: return("RRSIG");
+ case kDNSServiceType_NSEC: return("NSEC");
+ case kDNSServiceType_DNSKEY: return("DNSKEY");
+ case kDNSServiceType_DHCID: return("DHCID");
+ case kDNSServiceType_NSEC3: return("NSEC3");
+ case kDNSServiceType_NSEC3PARAM: return("NSEC3PARAM");
+ case kDNSServiceType_HIP: return("HIP");
+ case kDNSServiceType_SPF: return("SPF");
+ case kDNSServiceType_UINFO: return("UINFO");
+ case kDNSServiceType_UID: return("UID");
+ case kDNSServiceType_GID: return("GID");
+ case kDNSServiceType_UNSPEC: return("UNSPEC");
+ case kDNSServiceType_TKEY: return("TKEY");
+ case kDNSServiceType_TSIG: return("TSIG");
+ case kDNSServiceType_IXFR: return("IXFR");
+ case kDNSServiceType_AXFR: return("AXFR");
+ case kDNSServiceType_MAILB: return("MAILB");
+ case kDNSServiceType_MAILA: return("MAILA");
+ case kDNSServiceType_ANY: return("ANY");
default:
{
static char buffer[RR_TYPE_SIZE];
@@ -422,7 +474,9 @@ static DNSServiceProtocol GetProtocol(const char *s)
//*************************************************************************************************************
// Sample callback functions for each of the operation types
-static void printtimestamp(void)
+#define printtimestamp() printtimestamp_F(stdout)
+
+static void printtimestamp_F(FILE *outstream)
{
struct tm tm;
int ms;
@@ -443,10 +497,10 @@ static void printtimestamp(void)
strftime(new_date, sizeof(new_date), "%a %d %b %Y", &tm);
if (strncmp(date, new_date, sizeof(new_date)))
{
- printf("DATE: ---%s---\n", new_date); //display date only if it has changed
+ fprintf(outstream, "DATE: ---%s---\n", new_date); //display date only if it has changed
strncpy(date, new_date, sizeof(date));
}
- printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
+ fprintf(outstream, "%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
}
// formating time to RFC 4034 format
@@ -467,41 +521,50 @@ static void FormatTime(unsigned long te, unsigned char *buf, int bufsize)
static void print_usage(const char *arg0, int print_all)
{
+ // Print the commonly used command line options. These are listed in "the order they have been in historically".
fprintf(stderr, "%s -E (Enumerate recommended registration domains)\n", arg0);
fprintf(stderr, "%s -F (Enumerate recommended browsing domains)\n", arg0);
fprintf(stderr, "%s -R <Name> <Type> <Domain> <Port> [<TXT>...] (Register a service)\n", arg0);
- fprintf(stderr, "%s -B <Type> <Domain> (Browse for services instances)\n", arg0);
- fprintf(stderr, "%s -L <Name> <Type> <Domain> (Look up a service instance)\n", arg0);
- fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", arg0);
- fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
- fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -B <Type> <Domain> (Browse for service instances)\n", arg0);
+ fprintf(stderr, "%s -L <Name> <Type> <Domain> (Resolve a service instance)\n", arg0);
+ fprintf(stderr, "%s -Q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
fprintf(stderr, "%s -Z <Type> <Domain> (Output results in Zone File format)\n", arg0);
fprintf(stderr, "%s -G v4/v6/v4v6 <name> (Get address information for hostname)\n", arg0);
- fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -H (Print usage for complete command list)\n", arg0);
fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", arg0);
- if (print_all) //Print all available options for dns-sd tool
+ if (print_all) // Print all available options for dns-sd tool. Keep these in alphabetical order for easier maintenance.
{
- fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
- fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
+ fprintf(stderr, "\n");
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", arg0);
- fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
+ fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
+ fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", arg0);
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", arg0);
- fprintf(stderr, "%s -T (Test creating a large TXT record)\n", arg0);
fprintf(stderr, "%s -M (Test creating a registration with multiple TXT records)\n", arg0);
- fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", arg0);
+ fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", arg0);
fprintf(stderr, "%s -S (Test multiple operations on a shared socket)\n", arg0);
+ fprintf(stderr, "%s -T (Test creating a large TXT record)\n", arg0);
+ fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
+ fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
+ fprintf(stderr, "%s -ble (Use kDNSServiceInterfaceIndexBLE)\n", arg0);
+ fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
fprintf(stderr, "%s -i <Interface> (Run dns-sd cmd on a specific interface (en0/en1)\n", arg0);
- fprintf(stderr, "%s -lo (Run dns-sd cmd using local only interface)\n", arg0);
- fprintf(stderr, "%s -p2p (Use kDNSServiceInterfaceIndexP2P)\n", arg0);
fprintf(stderr, "%s -includep2p (Set kDNSServiceFlagsIncludeP2P flag)\n", arg0);
fprintf(stderr, "%s -includeAWDL (Set kDNSServiceFlagsIncludeAWDL flag)\n", arg0);
+ fprintf(stderr, "%s -intermediates (Set kDNSServiceFlagsReturnIntermediates flag)\n", arg0);
+ fprintf(stderr, "%s -ku (Set kDNSServiceFlagsKnownUnique flag)\n", arg0);
+ fprintf(stderr, "%s -lo (Run dns-sd cmd using local only interface)\n", arg0);
fprintf(stderr, "%s -optional (Set kDNSServiceFlagsValidateOptional flag)\n", arg0);
+ fprintf(stderr, "%s -p2p (Use kDNSServiceInterfaceIndexP2P)\n", arg0);
+ fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Equivalent to -Q with kDNSServiceFlagsSuppressUnusable set)\n", arg0);
fprintf(stderr, "%s -tc (Set kDNSServiceFlagsBackgroundTrafficClass flag)\n", arg0);
- fprintf(stderr, "%s -unicastResponse (Set kDNSServiceFlagsUnicastResponse flag)\n", arg0);
+ fprintf(stderr, "%s -test (Run basic API input range tests)\n", arg0);
fprintf(stderr, "%s -t1 (Set kDNSServiceFlagsThresholdOne flag)\n", arg0);
fprintf(stderr, "%s -tFinder (Set kDNSServiceFlagsThresholdFinder flag)\n", arg0);
fprintf(stderr, "%s -timeout (Set kDNSServiceFlagsTimeout flag)\n", arg0);
+ fprintf(stderr, "%s -unicastResponse (Set kDNSServiceFlagsUnicastResponse flag)\n", arg0);
+ fprintf(stderr, "%s -autoTrigger (Set kDNSServiceFlagsAutoTrigger flag)\n", arg0);
}
}
@@ -731,17 +794,20 @@ static void DNSSD_API resolve_reply(DNSServiceRef sdref, const DNSServiceFlags f
(void)context; // Unused
EXIT_IF_LIBDISPATCH_FATAL_ERROR(errorCode);
- if (errorCode)
- printf("Error code %d\n", errorCode);
- else
- {
- printtimestamp();
- printf("%s can be reached at %s:%u (interface %d)", fullname, hosttarget, PortAsNumber, ifIndex);
- if (flags) printf(" Flags: %X", flags);
- // Don't show degenerate TXT records containing nothing but a single empty string
- if (txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
- printf("\n");
- }
+ printtimestamp();
+
+ printf("%s ", fullname);
+
+ if (errorCode == kDNSServiceErr_NoSuchRecord) printf("No Such Record");
+ else if (errorCode) printf("error code %d\n", errorCode);
+ else printf("can be reached at %s:%u (interface %d)", hosttarget, PortAsNumber, ifIndex);
+
+ if (flags) printf(" Flags: %X", flags);
+
+ // Don't show degenerate TXT records containing nothing but a single empty string
+ if (!errorCode && txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
+
+ printf("\n");
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
@@ -776,6 +842,7 @@ static void myTimerCallBack(void)
{
if (updatetest[1] != 'Z') updatetest[1]++;
else updatetest[1] = 'A';
+ // The following line toggles the string length between 1 and 2 characters.
updatetest[0] = 3 - updatetest[0];
updatetest[2] = updatetest[1];
printtimestamp();
@@ -1249,7 +1316,7 @@ static void HandleEvents(void)
DNSServiceErrorType err = kDNSServiceErr_NoError;
if (client && FD_ISSET(dns_sd_fd, &readfds)) err = DNSServiceProcessResult(client );
else if (client_pa && FD_ISSET(dns_sd_fd2, &readfds)) err = DNSServiceProcessResult(client_pa);
- if (err) { fprintf(stderr, "DNSServiceProcessResult returned %d\n", err); stopNow = 1; }
+ if (err) { printtimestamp_F(stderr); fprintf(stderr, "DNSServiceProcessResult returned %d\n", err); stopNow = 1; }
}
else if (result == 0)
myTimerCallBack();
@@ -1306,18 +1373,6 @@ static void DNSSD_API MyRegisterRecordCallback(DNSServiceRef service, DNSRecordR
default: printf("Error %d\n", errorCode); break;
}
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
- // DNSServiceRemoveRecord(service, rec, 0); to test record removal
-
-#if 0 // To test updating of individual records registered via DNSServiceRegisterRecord
- if (!errorCode)
- {
- int x = 0x11111111;
- printf("Updating\n");
- DNSServiceUpdateRecord(service, rec, 0, sizeof(x), &x, 0);
- }
-#endif
-
- if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
static void getip(const char *const name, struct sockaddr_storage *result)
@@ -1403,6 +1458,215 @@ static char *gettype(char *buffer, char *typ)
return(typ);
}
+// Do some basic tests to verify API handles > 63 byte strings gracefully with
+// a returned error code.
+
+#define STRING_64_BYTES "_123456789012345678901234567890123456789012345678901234567890123"
+
+static int API_string_limit_test()
+{
+ const char * regtype;
+ DNSServiceRef sdRef = NULL;
+ const char * longHost = STRING_64_BYTES ".local";
+ const char * longDomain = "hostname." STRING_64_BYTES;
+
+ printf("Testing for error returns when various strings are > 63 bytes.\n");
+
+ printf("DNSServiceGetAddrInfo(), hostname = %s\n", longHost);
+ if (DNSServiceGetAddrInfo(&sdRef, 0, 0, 0, longHost, addrinfo_reply, 0) == 0)
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceGetAddrInfo(), hostname = %s\n", longDomain);
+ if (DNSServiceGetAddrInfo(&sdRef, 0, 0, 0, longDomain, addrinfo_reply, 0) == 0)
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceResolve(), name = %s\n", STRING_64_BYTES);
+ if (DNSServiceResolve(&sdRef, 0, 0, STRING_64_BYTES, "_test._tcp", "local", resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ regtype = STRING_64_BYTES "._tcp";
+ printf("DNSServiceResolve(), regtype = %s\n", regtype);
+ if (DNSServiceResolve(&sdRef, 0, 0, "instanceName", regtype, "local", resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceResolve(), domain = %s\n", STRING_64_BYTES);
+ if (DNSServiceResolve(&sdRef, 0, 0, "instanceName", "_test._tcp", STRING_64_BYTES, resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ printf("Testing for error returns when various strings are > 63 bytes: PASSED\n");
+ return 0;
+}
+
+// local prototypes for routines that don't have prototypes in dns_sd.h
+#if APPLE_OSX_mDNSResponder
+DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
+DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
+#endif
+
+static int API_NULL_input_test()
+{
+ printf("Running basic API input range tests with all parameters set to 0:\n");
+
+ // Test that API's handle NULL pointers by returning an error when appropriate.
+ printf("DNSServiceRefSockFD()\n");
+ if (DNSServiceRefSockFD(0) != -1)
+ {
+ printf("DNSServiceRefSockFD(): expected dnssd_InvalidSocket return\n");
+ return 1;
+ };
+
+ printf("DNSServiceProcessResult()\n");
+ if (DNSServiceProcessResult(0) == 0)
+ {
+ printf("DNSServiceProcessResult(): expected error return\n");
+ return 1;
+ };
+
+ // no return value, just verify it doesn't crash
+ printf("DNSServiceRefDeallocate()\n");
+ DNSServiceRefDeallocate(0);
+
+ printf("DNSServiceGetProperty()\n");
+ if (DNSServiceGetProperty(0, 0, 0) == 0)
+ {
+ printf("DNSServiceGetProperty(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceResolve()\n");
+ if (DNSServiceResolve(0, 0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceQueryRecord()\n");
+ if (DNSServiceQueryRecord(0, 0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceQueryRecord(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceGetAddrInfo()\n");
+ if (DNSServiceGetAddrInfo(0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceBrowse()\n");
+ if (DNSServiceBrowse(0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceBrowse(): expected error return\n");
+ return 1;
+ };
+
+#if APPLE_OSX_mDNSResponder
+ printf("DNSServiceSetDefaultDomainForUser()\n");
+ if (DNSServiceSetDefaultDomainForUser(0, 0) == 0)
+ {
+ printf("DNSServiceSetDefaultDomainForUser(): expected error return\n");
+ return 1;
+ };
+#endif
+
+ printf("DNSServiceRegister()\n");
+ if (DNSServiceRegister(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceRegister(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceEnumerateDomains()\n");
+ if (DNSServiceEnumerateDomains(0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceEnumerateDomains(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceCreateConnection()\n");
+ if (DNSServiceCreateConnection(0) == 0)
+ {
+ printf("DNSServiceCreateConnection(): expected error return\n");
+ return 1;
+ };
+
+#if APPLE_OSX_mDNSResponder
+ printf("DNSServiceCreateDelegateConnection()\n");
+ if (DNSServiceCreateDelegateConnection(0, 0, 0) == 0)
+ {
+ printf("DNSServiceCreateDelegateConnection(): expected error return\n");
+ return 1;
+ };
+#endif
+
+ printf("DNSServiceRegisterRecord()\n");
+ if (DNSServiceRegisterRecord(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceRegisterRecord(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceAddRecord()\n");
+ if (DNSServiceAddRecord(0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceAddRecord(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceUpdateRecord()\n");
+ if (DNSServiceUpdateRecord(0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceUpdateRecord(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceRemoveRecord()\n");
+ if (DNSServiceRemoveRecord(0, 0, 0) == 0)
+ {
+ printf("DNSServiceRemoveRecord(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceReconfirmRecord()\n");
+ if (DNSServiceReconfirmRecord(0, 0, 0, 0, 0, 0, 0) == 0)
+ {
+ printf("DNSServiceReconfirmRecord(): expected error return\n");
+ return 1;
+ };
+
+
+ printf("Basic API input range tests with all parameters set to 0: PASSED\n");
+ return 0;
+}
+
+static int API_input_range_test()
+{
+
+ if (API_string_limit_test())
+ return 1;
+
+ if (API_NULL_input_test())
+ return 1;
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
DNSServiceErrorType err;
@@ -1432,102 +1696,154 @@ int main(int argc, char **argv)
//TXTRecordSetValue(&txtRecord, "aaa", 1, "b");
//printf("%d\n", TXTRecordContainsKey(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), "Aaa"));
- if (argc > 1 && !strcmp(argv[1], "-lo"))
- {
- argc--;
- argv++;
- opinterface = kDNSServiceInterfaceIndexLocalOnly;
- printf("Using LocalOnly\n");
- }
-
- if (argc > 1 && (!strcmp(argv[1], "-p2p") || !strcmp(argv[1], "-P2P")))
- {
- argc--;
- argv++;
- opinterface = kDNSServiceInterfaceIndexP2P;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsIncludeP2P;
- printf("Setting kDNSServiceFlagsIncludeP2P\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-includeAWDL"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsIncludeAWDL;
- printf("Setting kDNSServiceFlagsIncludeAWDL\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-tc"))
+ while (argc > 1)
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsBackgroundTrafficClass;
- printf("Setting kDNSServiceFlagsBackgroundTrafficClass\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-t1"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsThresholdOne;
- printf("Setting kDNSServiceFlagsThresholdOne\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-tFinder"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsThresholdFinder;
- printf("Setting kDNSServiceFlagsThresholdFinder\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-wo"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsWakeOnlyService;
- printf("Setting kDNSServiceFlagsWakeOnlyService\n");
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "-unicastResponse"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsUnicastResponse;
- printf("Setting kDNSServiceFlagsUnicastResponse\n");
- }
- if (argc > 1 && !strcasecmp(argv[1], "-timeout"))
- {
- argc--;
- argv++;
- flags |= kDNSServiceFlagsTimeout;
- printf("Setting kDNSServiceFlagsTimeout\n");
- }
- if (argc > 1 && !strcasecmp(argv[1], "-optional"))
- {
- argc--;
- argv++;
- optional = 1;
- printf("Setting DNSSEC optional flag\n");
- }
+ int entryCount;
+
+ // record current argc to see if we process an argument in this pass
+ entryCount = argc;
+
+ if (argc > 1 && !strcmp(argv[1], "-test"))
+ {
+ argc--;
+ argv++;
+ return API_input_range_test();
+ }
+
+ if (argc > 1 && !strcmp(argv[1], "-lo"))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexLocalOnly;
+ printf("Using LocalOnly\n");
+ }
+
+ if (argc > 1 && (!strcasecmp(argv[1], "-p2p")))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexP2P;
+ }
+
+ if (argc > 1 && (!strcasecmp(argv[1], "-ble")))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexBLE;
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsIncludeP2P;
+ printf("Setting kDNSServiceFlagsIncludeP2P\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-includeAWDL"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsIncludeAWDL;
+ printf("Setting kDNSServiceFlagsIncludeAWDL\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-intermediates"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsReturnIntermediates;
+ printf("Setting kDNSServiceFlagsReturnIntermediates\n");
+ }
- if (argc > 2 && !strcmp(argv[1], "-i"))
- {
- opinterface = if_nametoindex(argv[2]);
- if (!opinterface) opinterface = atoi(argv[2]);
- if (!opinterface) { fprintf(stderr, "Unknown interface %s\n", argv[2]); goto Fail; }
- argc -= 2;
- argv += 2;
+ if (argc > 1 && !strcasecmp(argv[1], "-tc"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsBackgroundTrafficClass;
+ printf("Setting kDNSServiceFlagsBackgroundTrafficClass\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-t1"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsThresholdOne;
+ printf("Setting kDNSServiceFlagsThresholdOne\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-tFinder"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsThresholdFinder;
+ printf("Setting kDNSServiceFlagsThresholdFinder\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-wo"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsWakeOnlyService;
+ printf("Setting kDNSServiceFlagsWakeOnlyService\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-ku"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsKnownUnique;
+ printf("Setting kDNSServiceFlagsKnownUnique\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-unicastResponse"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsUnicastResponse;
+ printf("Setting kDNSServiceFlagsUnicastResponse\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-timeout"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsTimeout;
+ printf("Setting kDNSServiceFlagsTimeout\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-autoTrigger"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsAutoTrigger;
+ printf("Setting kDNSServiceFlagsAutoTrigger\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-optional"))
+ {
+ argc--;
+ argv++;
+ optional = 1;
+ printf("Setting DNSSEC optional flag\n");
+ }
+
+ if (argc > 2 && !strcmp(argv[1], "-i"))
+ {
+ opinterface = if_nametoindex(argv[2]);
+ if (!opinterface) opinterface = atoi(argv[2]);
+ if (!opinterface) { fprintf(stderr, "Unknown interface %s\n", argv[2]); goto Fail; }
+ argc -= 2;
+ argv += 2;
+ }
+
+ // Exit loop if if we didn't match one of the multi character options.
+ if (argc == entryCount)
+ break;
}
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
- operation = getfirstoption(argc, argv, "EFBZLlRPQqCAUNTMISVHhD"
+ operation = getfirstoption(argc, argv, "ABCDEFHILMNPQRSTUVZhlq"
"X"
"Gg"
, &opi);
diff --git a/mDNSResponder/Clients/dnsctl.c b/mDNSResponder/Clients/dnsctl.c
index f10f2259..e01c8fec 100644
--- a/mDNSResponder/Clients/dnsctl.c
+++ b/mDNSResponder/Clients/dnsctl.c
@@ -17,16 +17,20 @@
#include <sys/time.h>
#include <net/if.h> // if_nametoindex()
-#include <dispatch/dispatch.h>
#include "dns_services.h"
+#include <xpc/xpc.h>
+#include "dns_xpc.h"
//*************************************************************************************************************
// Globals:
//*************************************************************************************************************
static const char kFilePathSep = '/';
+
static DNSXConnRef ClientRef = NULL;
+static xpc_connection_t dnsctl_conn = NULL;
+
//*************************************************************************************************************
// Utility Funcs:
//*************************************************************************************************************
@@ -56,12 +60,31 @@ static void print_usage(const char *arg0)
fprintf(stderr, "%s USAGE: \n", arg0);
fprintf(stderr, "%s -DP Enable DNS Proxy with Default Parameters \n", arg0);
fprintf(stderr, "%s -DP [-o <output interface>] [-i <input interface(s)>] Enable DNS Proxy \n", arg0);
+ fprintf(stderr, "%s -L [1/2/3/4] Change mDNSResponder Logging Level \n", arg0);
+ fprintf(stderr, "%s -I Print mDNSResponder STATE INFO \n", arg0);
+}
+
+
+static bool DebugEnabled()
+{
+ return true; // keep this true to debug the XPC msgs
+}
+
+static void DebugLog(const char *prefix, xpc_object_t o)
+{
+ if (!DebugEnabled())
+ return;
+
+ char *desc = xpc_copy_description(o);
+ printf("%s: %s \n", prefix, desc);
+ free(desc);
}
//*************************************************************************************************************
// CallBack Funcs:
//*************************************************************************************************************
+
// DNSXEnableProxy Callback from the Daemon
static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
{
@@ -75,6 +98,8 @@ static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
DNSXRefDeAlloc(ClientRef); break;
case kDNSX_BadParam : printf(" BAD PARAMETER \n");
DNSXRefDeAlloc(ClientRef); break;
+ case kDNSX_Busy : printf(" BUSY \n");
+ DNSXRefDeAlloc(ClientRef); break;
case kDNSX_UnknownErr :
default : printf(" UNKNOWN ERR \n");
DNSXRefDeAlloc(ClientRef); break;
@@ -84,15 +109,56 @@ static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
}
//*************************************************************************************************************
+// XPC Funcs:
+//*************************************************************************************************************
-int main(int argc, char **argv)
+static void Init_Connection(const char *servname)
+{
+ dnsctl_conn = xpc_connection_create_mach_service(servname, dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
+
+ xpc_connection_set_event_handler(dnsctl_conn, ^(xpc_object_t event)
+ {
+ printf("InitConnection: [%s] \n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
+ });
+
+ xpc_connection_resume(dnsctl_conn);
+}
+
+static void SendDictToServer(xpc_object_t msg)
{
- DNSXErrorType err;
- // Default i/p intf is lo0 and o/p intf is primary interface
- IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0};
- IfIndex Opintf = kDNSIfindexAny;
+ DebugLog("SendDictToServer Sending msg to Daemon", msg);
+ xpc_connection_send_message_with_reply(dnsctl_conn, msg, dispatch_get_main_queue(), ^(xpc_object_t recv_msg)
+ {
+ xpc_type_t type = xpc_get_type(recv_msg);
+
+ if (type == XPC_TYPE_DICTIONARY)
+ {
+ DebugLog("SendDictToServer Received reply msg from Daemon", recv_msg);
+ /*
+ // If we ever want to do something based on the reply of the daemon
+ switch (daemon_status)
+ {
+ default:
+ break;
+ }
+ */
+ }
+ else
+ {
+ printf("SendDictToServer Received unexpected reply from daemon [%s]",
+ xpc_dictionary_get_string(recv_msg, XPC_ERROR_KEY_DESCRIPTION));
+ DebugLog("SendDictToServer Unexpected Reply contents", recv_msg);
+ }
+ exit(1);
+ });
+}
+
+//*************************************************************************************************************
+
+int main(int argc, char **argv)
+{
// Extract program name from argv[0], which by convention contains the path to this executable
const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
if (a0 == (const char *)1)
@@ -113,15 +179,20 @@ int main(int argc, char **argv)
if (argc < 2)
goto Usage;
- if ( !strcmp(argv[1], "-DP") || !strcmp(argv[1], "-dp") )
+ printtimestamp();
+ if (!strcasecmp(argv[1], "-DP"))
{
+ DNSXErrorType err;
+ // Default i/p intf is lo0 and o/p intf is primary interface
+ IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0};
+ IfIndex Opintf = kDNSIfindexAny;
+
if (argc == 2)
{
- printtimestamp();
- printf("Enabling DNSProxy on mDNSResponder with Default Parameters\n");
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
- if (err) fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
+ if (err)
+ fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
}
else if (argc > 2)
{
@@ -159,13 +230,96 @@ int main(int argc, char **argv)
argv++;
}
}
- printtimestamp();
printf("Enabling DNSProxy on mDNSResponder \n");
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
- if (err) fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
+ if (err)
+ fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
+ }
+ }
+ else if (!strcasecmp(argv[1], "-l"))
+ {
+ printf("Changing loglevel of mDNSResponder \n");
+ Init_Connection(kDNSCTLService);
+
+ // Create Dictionary To Send
+ xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
+
+ if (argc == 2)
+ {
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
+
+ SendDictToServer(dict);
+ xpc_release(dict);
+ dict = NULL;
+ }
+ else if (argc > 2)
+ {
+ argc--;
+ argv++;
+ switch (atoi(argv[1]))
+ {
+ case log_level1:
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
+ break;
+
+ case log_level2:
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level2);
+ break;
+
+ case log_level3:
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level3);
+ break;
+
+ case log_level4:
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level4);
+ break;
+
+ default:
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
+ break;
+ }
+ SendDictToServer(dict);
+ xpc_release(dict);
+ dict = NULL;
}
}
+ else if(!strcasecmp(argv[1], "-i"))
+ {
+ printf("Get STATE INFO of mDNSResponder \n");
+ Init_Connection(kDNSCTLService);
+
+ // Create Dictionary To Send
+ xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_uint64(dict, kDNSStateInfo, full_state);
+ SendDictToServer(dict);
+ xpc_release(dict);
+ dict = NULL;
+ }
+ else if(!strcasecmp(argv[1], "-th"))
+ {
+ printf("Sending Test message to mDNSResponder to forward to mDNSResponderHelper\n");
+ Init_Connection(kDNSCTLService);
+
+ // Create Dictionary To Send
+ xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_uint64(dict, kmDNSResponderTests, test_helper_ipc);
+ SendDictToServer(dict);
+ xpc_release(dict);
+ dict = NULL;
+ }
+ else if(!strcasecmp(argv[1], "-tl"))
+ {
+ printf("Testing mDNSResponder Logging\n");
+ Init_Connection(kDNSCTLService);
+
+ // Create Dictionary To Send
+ xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_uint64(dict, kmDNSResponderTests, test_mDNS_log);
+ SendDictToServer(dict);
+ xpc_release(dict);
+ dict = NULL;
+ }
else
{
goto Usage;
@@ -178,3 +332,52 @@ Usage:
return 0;
}
+/*
+
+#include <getopt.h>
+
+static int operation;
+
+static int getfirstoption(int argc, char **argv, const char *optstr, int *pOptInd)
+{
+ // Return the recognized option in optstr and the option index of the next arg.
+ int o = getopt(argc, (char *const *)argv, optstr);
+ *pOptInd = optind;
+ return o;
+}
+
+int opindex;
+operation = getfirstoption(argc, argv, "lLDdPp", &opindex);
+if (operation == -1)
+ goto Usage;
+
+
+
+switch (operation)
+{
+ case 'L':
+ case 'l':
+ {
+ printtimestamp();
+ printf("Change Verbosity Level of mDNSResponder\n");
+
+ Init_Connection(kDNSCTLService);
+
+ // Create Dictionary To Send
+ xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
+ if (dict == NULL)
+ printf("could not create the Msg Dict To Send! \n");
+ xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level2);
+
+ SendDictToServer(dict);
+
+ xpc_release(dict);
+ dict = NULL;
+ break;
+ }
+ // exit(1);
+
+}
+
+*/
+