summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/Clients/dns-sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/Clients/dns-sd.c')
-rw-r--r--mDNSResponder/Clients/dns-sd.c606
1 files changed, 461 insertions, 145 deletions
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);