diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-19 08:53:26 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-20 11:23:32 +0200 |
commit | f01edf10244ccd53e098abdc1773c1aa0e4c5f8d (patch) | |
tree | 958a1ee323520629c4f027de1d4c56715949aa5c /mDNSResponder/Clients | |
parent | mDNSResponder: Update to v625.41.2 (diff) | |
download | rtems-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.c | 3 | ||||
-rw-r--r-- | mDNSResponder/Clients/Java/nmakefile | 2 | ||||
-rw-r--r-- | mDNSResponder/Clients/dns-sd.c | 606 | ||||
-rw-r--r-- | mDNSResponder/Clients/dnsctl.c | 227 |
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); + +} + +*/ + |