1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker *
3*48a54d36SAndroid Build Coastguard Worker * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker *
5*48a54d36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker *
9*48a54d36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker *
11*48a54d36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker */
17*48a54d36SAndroid Build Coastguard Worker
18*48a54d36SAndroid Build Coastguard Worker #include <stdio.h> // For printf()
19*48a54d36SAndroid Build Coastguard Worker #include <stdlib.h> // For exit() etc.
20*48a54d36SAndroid Build Coastguard Worker #include <string.h> // For strlen() etc.
21*48a54d36SAndroid Build Coastguard Worker #include <unistd.h> // For select()
22*48a54d36SAndroid Build Coastguard Worker #include <signal.h> // For SIGINT, SIGTERM
23*48a54d36SAndroid Build Coastguard Worker #include <errno.h> // For errno, EINTR
24*48a54d36SAndroid Build Coastguard Worker #include <netinet/in.h> // For INADDR_NONE
25*48a54d36SAndroid Build Coastguard Worker #include <arpa/inet.h> // For inet_addr()
26*48a54d36SAndroid Build Coastguard Worker #include <netdb.h> // For gethostbyname()
27*48a54d36SAndroid Build Coastguard Worker
28*48a54d36SAndroid Build Coastguard Worker #include "mDNSEmbeddedAPI.h" // Defines the interface to the client layer above
29*48a54d36SAndroid Build Coastguard Worker #include "mDNSPosix.h" // Defines the specific types needed to run mDNS on this platform
30*48a54d36SAndroid Build Coastguard Worker #include "ExampleClientApp.h"
31*48a54d36SAndroid Build Coastguard Worker
32*48a54d36SAndroid Build Coastguard Worker // Compatibility workaround: Solaris 2.5 has no INADDR_NONE
33*48a54d36SAndroid Build Coastguard Worker #ifndef INADDR_NONE
34*48a54d36SAndroid Build Coastguard Worker #define INADDR_NONE (mDNSu32)0xffffffff
35*48a54d36SAndroid Build Coastguard Worker #endif
36*48a54d36SAndroid Build Coastguard Worker
37*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
38*48a54d36SAndroid Build Coastguard Worker // Globals
39*48a54d36SAndroid Build Coastguard Worker static mDNS mDNSStorage; // mDNS core uses this to store its globals
40*48a54d36SAndroid Build Coastguard Worker static mDNS_PlatformSupport PlatformStorage; // Stores this platform's globals
41*48a54d36SAndroid Build Coastguard Worker mDNSexport const char ProgramName[] = "mDNSProxyResponderPosix";
42*48a54d36SAndroid Build Coastguard Worker
43*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
44*48a54d36SAndroid Build Coastguard Worker // Proxy Host Registration
45*48a54d36SAndroid Build Coastguard Worker
46*48a54d36SAndroid Build Coastguard Worker typedef struct
47*48a54d36SAndroid Build Coastguard Worker {
48*48a54d36SAndroid Build Coastguard Worker mDNSv4Addr ip;
49*48a54d36SAndroid Build Coastguard Worker domainlabel hostlabel; // Conforms to standard DNS letter-digit-hyphen host name rules
50*48a54d36SAndroid Build Coastguard Worker AuthRecord RR_A; // 'A' (address) record for our ".local" name
51*48a54d36SAndroid Build Coastguard Worker AuthRecord RR_PTR; // PTR (reverse lookup) record
52*48a54d36SAndroid Build Coastguard Worker } ProxyHost;
53*48a54d36SAndroid Build Coastguard Worker
HostNameCallback(mDNS * const m,AuthRecord * const rr,mStatus result)54*48a54d36SAndroid Build Coastguard Worker mDNSlocal void HostNameCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
55*48a54d36SAndroid Build Coastguard Worker {
56*48a54d36SAndroid Build Coastguard Worker ProxyHost *f = (ProxyHost*)rr->RecordContext;
57*48a54d36SAndroid Build Coastguard Worker if (result == mStatus_NoError)
58*48a54d36SAndroid Build Coastguard Worker debugf("Host name successfully registered: %##s", rr->resrec.name->c);
59*48a54d36SAndroid Build Coastguard Worker else
60*48a54d36SAndroid Build Coastguard Worker {
61*48a54d36SAndroid Build Coastguard Worker debugf("Host name conflict for %##s", rr->resrec.name->c);
62*48a54d36SAndroid Build Coastguard Worker mDNS_Deregister(m, &f->RR_A);
63*48a54d36SAndroid Build Coastguard Worker mDNS_Deregister(m, &f->RR_PTR);
64*48a54d36SAndroid Build Coastguard Worker exit(-1);
65*48a54d36SAndroid Build Coastguard Worker }
66*48a54d36SAndroid Build Coastguard Worker }
67*48a54d36SAndroid Build Coastguard Worker
mDNS_RegisterProxyHost(mDNS * m,ProxyHost * p)68*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus mDNS_RegisterProxyHost(mDNS *m, ProxyHost *p)
69*48a54d36SAndroid Build Coastguard Worker {
70*48a54d36SAndroid Build Coastguard Worker char buffer[32];
71*48a54d36SAndroid Build Coastguard Worker
72*48a54d36SAndroid Build Coastguard Worker mDNS_SetupResourceRecord(&p->RR_A, mDNSNULL, mDNSInterface_Any, kDNSType_A, 60, kDNSRecordTypeUnique, AuthRecordAny, HostNameCallback, p);
73*48a54d36SAndroid Build Coastguard Worker mDNS_SetupResourceRecord(&p->RR_PTR, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 60, kDNSRecordTypeKnownUnique, AuthRecordAny, HostNameCallback, p);
74*48a54d36SAndroid Build Coastguard Worker
75*48a54d36SAndroid Build Coastguard Worker p->RR_A.namestorage.c[0] = 0;
76*48a54d36SAndroid Build Coastguard Worker AppendDomainLabel(&p->RR_A.namestorage, &p->hostlabel);
77*48a54d36SAndroid Build Coastguard Worker AppendLiteralLabelString(&p->RR_A.namestorage, "local");
78*48a54d36SAndroid Build Coastguard Worker
79*48a54d36SAndroid Build Coastguard Worker // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
80*48a54d36SAndroid Build Coastguard Worker mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.", p->ip.b[3], p->ip.b[2], p->ip.b[1], p->ip.b[0]);
81*48a54d36SAndroid Build Coastguard Worker MakeDomainNameFromDNSNameString(&p->RR_PTR.namestorage, buffer);
82*48a54d36SAndroid Build Coastguard Worker p->RR_PTR.ForceMCast = mDNStrue; // This PTR points to our dot-local name, so don't ever try to write it into a uDNS server
83*48a54d36SAndroid Build Coastguard Worker
84*48a54d36SAndroid Build Coastguard Worker p->RR_A. resrec.rdata->u.ipv4 = p->ip;
85*48a54d36SAndroid Build Coastguard Worker AssignDomainName(&p->RR_PTR.resrec.rdata->u.name, p->RR_A.resrec.name);
86*48a54d36SAndroid Build Coastguard Worker
87*48a54d36SAndroid Build Coastguard Worker mDNS_Register(m, &p->RR_A);
88*48a54d36SAndroid Build Coastguard Worker mDNS_Register(m, &p->RR_PTR);
89*48a54d36SAndroid Build Coastguard Worker
90*48a54d36SAndroid Build Coastguard Worker debugf("Made Proxy Host Records for %##s", p->RR_A.resrec.name->c);
91*48a54d36SAndroid Build Coastguard Worker
92*48a54d36SAndroid Build Coastguard Worker return(mStatus_NoError);
93*48a54d36SAndroid Build Coastguard Worker }
94*48a54d36SAndroid Build Coastguard Worker
95*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
96*48a54d36SAndroid Build Coastguard Worker // Service Registration
97*48a54d36SAndroid Build Coastguard Worker
98*48a54d36SAndroid Build Coastguard Worker // This sample ServiceCallback just calls mDNS_RenameAndReregisterService to automatically pick a new
99*48a54d36SAndroid Build Coastguard Worker // unique name for the service. For a device such as a printer, this may be appropriate.
100*48a54d36SAndroid Build Coastguard Worker // For a device with a user interface, and a screen, and a keyboard, the appropriate
101*48a54d36SAndroid Build Coastguard Worker // response may be to prompt the user and ask them to choose a new name for the service.
ServiceCallback(mDNS * const m,ServiceRecordSet * const sr,mStatus result)102*48a54d36SAndroid Build Coastguard Worker mDNSlocal void ServiceCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus result)
103*48a54d36SAndroid Build Coastguard Worker {
104*48a54d36SAndroid Build Coastguard Worker switch (result)
105*48a54d36SAndroid Build Coastguard Worker {
106*48a54d36SAndroid Build Coastguard Worker case mStatus_NoError: debugf("Callback: %##s Name Registered", sr->RR_SRV.resrec.name->c); break;
107*48a54d36SAndroid Build Coastguard Worker case mStatus_NameConflict: debugf("Callback: %##s Name Conflict", sr->RR_SRV.resrec.name->c); break;
108*48a54d36SAndroid Build Coastguard Worker case mStatus_MemFree: debugf("Callback: %##s Memory Free", sr->RR_SRV.resrec.name->c); break;
109*48a54d36SAndroid Build Coastguard Worker default: debugf("Callback: %##s Unknown Result %ld", sr->RR_SRV.resrec.name->c, result); break;
110*48a54d36SAndroid Build Coastguard Worker }
111*48a54d36SAndroid Build Coastguard Worker
112*48a54d36SAndroid Build Coastguard Worker if (result == mStatus_NoError)
113*48a54d36SAndroid Build Coastguard Worker {
114*48a54d36SAndroid Build Coastguard Worker char buffer[MAX_ESCAPED_DOMAIN_NAME];
115*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(sr->RR_SRV.resrec.name, buffer);
116*48a54d36SAndroid Build Coastguard Worker printf("Service %s now registered and active\n", buffer);
117*48a54d36SAndroid Build Coastguard Worker }
118*48a54d36SAndroid Build Coastguard Worker
119*48a54d36SAndroid Build Coastguard Worker if (result == mStatus_NameConflict)
120*48a54d36SAndroid Build Coastguard Worker {
121*48a54d36SAndroid Build Coastguard Worker char buffer1[MAX_ESCAPED_DOMAIN_NAME], buffer2[MAX_ESCAPED_DOMAIN_NAME];
122*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(sr->RR_SRV.resrec.name, buffer1);
123*48a54d36SAndroid Build Coastguard Worker mDNS_RenameAndReregisterService(m, sr, mDNSNULL);
124*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(sr->RR_SRV.resrec.name, buffer2);
125*48a54d36SAndroid Build Coastguard Worker printf("Name Conflict! %s renamed as %s\n", buffer1, buffer2);
126*48a54d36SAndroid Build Coastguard Worker }
127*48a54d36SAndroid Build Coastguard Worker }
128*48a54d36SAndroid Build Coastguard Worker
129*48a54d36SAndroid Build Coastguard Worker // RegisterService() is a simple wrapper function which takes C string
130*48a54d36SAndroid Build Coastguard Worker // parameters, converts them to domainname parameters, and calls mDNS_RegisterService()
RegisterService(mDNS * m,ServiceRecordSet * recordset,const char name[],const char type[],const char domain[],const domainname * host,mDNSu16 PortAsNumber,int argc,char ** argv)131*48a54d36SAndroid Build Coastguard Worker mDNSlocal void RegisterService(mDNS *m, ServiceRecordSet *recordset,
132*48a54d36SAndroid Build Coastguard Worker const char name[], const char type[], const char domain[],
133*48a54d36SAndroid Build Coastguard Worker const domainname *host, mDNSu16 PortAsNumber, int argc, char **argv)
134*48a54d36SAndroid Build Coastguard Worker {
135*48a54d36SAndroid Build Coastguard Worker domainlabel n;
136*48a54d36SAndroid Build Coastguard Worker domainname t, d;
137*48a54d36SAndroid Build Coastguard Worker unsigned char txtbuffer[1024], *bptr = txtbuffer;
138*48a54d36SAndroid Build Coastguard Worker char buffer[MAX_ESCAPED_DOMAIN_NAME];
139*48a54d36SAndroid Build Coastguard Worker
140*48a54d36SAndroid Build Coastguard Worker MakeDomainLabelFromLiteralString(&n, name);
141*48a54d36SAndroid Build Coastguard Worker MakeDomainNameFromDNSNameString(&t, type);
142*48a54d36SAndroid Build Coastguard Worker MakeDomainNameFromDNSNameString(&d, domain);
143*48a54d36SAndroid Build Coastguard Worker while (argc)
144*48a54d36SAndroid Build Coastguard Worker {
145*48a54d36SAndroid Build Coastguard Worker int len = strlen(argv[0]);
146*48a54d36SAndroid Build Coastguard Worker if (len > 255 || bptr + 1 + len >= txtbuffer + sizeof(txtbuffer)) break;
147*48a54d36SAndroid Build Coastguard Worker printf("STR: %s\n", argv[0]);
148*48a54d36SAndroid Build Coastguard Worker bptr[0] = len;
149*48a54d36SAndroid Build Coastguard Worker strcpy((char*)(bptr+1), argv[0]);
150*48a54d36SAndroid Build Coastguard Worker bptr += 1 + len;
151*48a54d36SAndroid Build Coastguard Worker argc--;
152*48a54d36SAndroid Build Coastguard Worker argv++;
153*48a54d36SAndroid Build Coastguard Worker }
154*48a54d36SAndroid Build Coastguard Worker
155*48a54d36SAndroid Build Coastguard Worker mDNS_RegisterService(m, recordset,
156*48a54d36SAndroid Build Coastguard Worker &n, &t, &d, // Name, type, domain
157*48a54d36SAndroid Build Coastguard Worker host, mDNSOpaque16fromIntVal(PortAsNumber),
158*48a54d36SAndroid Build Coastguard Worker txtbuffer, bptr-txtbuffer, // TXT data, length
159*48a54d36SAndroid Build Coastguard Worker mDNSNULL, 0, // Subtypes
160*48a54d36SAndroid Build Coastguard Worker mDNSInterface_Any, // Interface ID
161*48a54d36SAndroid Build Coastguard Worker ServiceCallback, mDNSNULL, 0); // Callback, context, flags
162*48a54d36SAndroid Build Coastguard Worker
163*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(recordset->RR_SRV.resrec.name, buffer);
164*48a54d36SAndroid Build Coastguard Worker printf("Made Service Records for %s\n", buffer);
165*48a54d36SAndroid Build Coastguard Worker }
166*48a54d36SAndroid Build Coastguard Worker
167*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
168*48a54d36SAndroid Build Coastguard Worker // Service non-existence assertion
169*48a54d36SAndroid Build Coastguard Worker // (claiming a service name without actually providing a service at that name, to prevent anyone else using that name)
170*48a54d36SAndroid Build Coastguard Worker // This is useful to avoid confusion between similar services
171*48a54d36SAndroid Build Coastguard Worker // e.g. A printer that implements IPP printing service using the name "My Printer", but doesn't implement LPR service,
172*48a54d36SAndroid Build Coastguard Worker // should also claim the LPR service name "My Printer" to stop a different printer offering LPR service under the same name,
173*48a54d36SAndroid Build Coastguard Worker // since it would be confusing to users to have two equivalent services with the same name.
174*48a54d36SAndroid Build Coastguard Worker
NoSuchServiceCallback(mDNS * const m,AuthRecord * const rr,mStatus result)175*48a54d36SAndroid Build Coastguard Worker mDNSlocal void NoSuchServiceCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
176*48a54d36SAndroid Build Coastguard Worker {
177*48a54d36SAndroid Build Coastguard Worker const domainname *proxyhostname = (const domainname *)rr->RecordContext;
178*48a54d36SAndroid Build Coastguard Worker switch (result)
179*48a54d36SAndroid Build Coastguard Worker {
180*48a54d36SAndroid Build Coastguard Worker case mStatus_NoError: debugf("Callback: %##s Name Registered", rr->resrec.name->c); break;
181*48a54d36SAndroid Build Coastguard Worker case mStatus_NameConflict: debugf("Callback: %##s Name Conflict", rr->resrec.name->c); break;
182*48a54d36SAndroid Build Coastguard Worker case mStatus_MemFree: debugf("Callback: %##s Memory Free", rr->resrec.name->c); break;
183*48a54d36SAndroid Build Coastguard Worker default: debugf("Callback: %##s Unknown Result %ld", rr->resrec.name->c, result); break;
184*48a54d36SAndroid Build Coastguard Worker }
185*48a54d36SAndroid Build Coastguard Worker
186*48a54d36SAndroid Build Coastguard Worker if (result == mStatus_NoError)
187*48a54d36SAndroid Build Coastguard Worker {
188*48a54d36SAndroid Build Coastguard Worker char buffer[MAX_ESCAPED_DOMAIN_NAME];
189*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(rr->resrec.name, buffer);
190*48a54d36SAndroid Build Coastguard Worker printf("Non-existence assertion %s now registered and active\n", buffer);
191*48a54d36SAndroid Build Coastguard Worker }
192*48a54d36SAndroid Build Coastguard Worker
193*48a54d36SAndroid Build Coastguard Worker if (result == mStatus_NameConflict)
194*48a54d36SAndroid Build Coastguard Worker {
195*48a54d36SAndroid Build Coastguard Worker domainlabel n;
196*48a54d36SAndroid Build Coastguard Worker domainname t, d;
197*48a54d36SAndroid Build Coastguard Worker char buffer1[MAX_ESCAPED_DOMAIN_NAME], buffer2[MAX_ESCAPED_DOMAIN_NAME];
198*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(rr->resrec.name, buffer1);
199*48a54d36SAndroid Build Coastguard Worker DeconstructServiceName(rr->resrec.name, &n, &t, &d);
200*48a54d36SAndroid Build Coastguard Worker IncrementLabelSuffix(&n, mDNStrue);
201*48a54d36SAndroid Build Coastguard Worker mDNS_RegisterNoSuchService(m, rr, &n, &t, &d, proxyhostname, mDNSInterface_Any, NoSuchServiceCallback, mDNSNULL, mDNSfalse);
202*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(rr->resrec.name, buffer2);
203*48a54d36SAndroid Build Coastguard Worker printf("Name Conflict! %s renamed as %s\n", buffer1, buffer2);
204*48a54d36SAndroid Build Coastguard Worker }
205*48a54d36SAndroid Build Coastguard Worker }
206*48a54d36SAndroid Build Coastguard Worker
RegisterNoSuchService(mDNS * m,AuthRecord * const rr,domainname * proxyhostname,const char name[],const char type[],const char domain[])207*48a54d36SAndroid Build Coastguard Worker mDNSlocal void RegisterNoSuchService(mDNS *m, AuthRecord *const rr, domainname *proxyhostname,
208*48a54d36SAndroid Build Coastguard Worker const char name[], const char type[], const char domain[])
209*48a54d36SAndroid Build Coastguard Worker {
210*48a54d36SAndroid Build Coastguard Worker domainlabel n;
211*48a54d36SAndroid Build Coastguard Worker domainname t, d;
212*48a54d36SAndroid Build Coastguard Worker char buffer[MAX_ESCAPED_DOMAIN_NAME];
213*48a54d36SAndroid Build Coastguard Worker MakeDomainLabelFromLiteralString(&n, name);
214*48a54d36SAndroid Build Coastguard Worker MakeDomainNameFromDNSNameString(&t, type);
215*48a54d36SAndroid Build Coastguard Worker MakeDomainNameFromDNSNameString(&d, domain);
216*48a54d36SAndroid Build Coastguard Worker mDNS_RegisterNoSuchService(m, rr, &n, &t, &d, proxyhostname, mDNSInterface_Any, NoSuchServiceCallback, proxyhostname, mDNSfalse);
217*48a54d36SAndroid Build Coastguard Worker ConvertDomainNameToCString(rr->resrec.name, buffer);
218*48a54d36SAndroid Build Coastguard Worker printf("Made Non-existence Record for %s\n", buffer);
219*48a54d36SAndroid Build Coastguard Worker }
220*48a54d36SAndroid Build Coastguard Worker
221*48a54d36SAndroid Build Coastguard Worker //*************************************************************************************************************
222*48a54d36SAndroid Build Coastguard Worker // Main
223*48a54d36SAndroid Build Coastguard Worker
main(int argc,char ** argv)224*48a54d36SAndroid Build Coastguard Worker mDNSexport int main(int argc, char **argv)
225*48a54d36SAndroid Build Coastguard Worker {
226*48a54d36SAndroid Build Coastguard Worker mStatus status;
227*48a54d36SAndroid Build Coastguard Worker sigset_t signals;
228*48a54d36SAndroid Build Coastguard Worker
229*48a54d36SAndroid Build Coastguard Worker if (argc < 3) goto usage;
230*48a54d36SAndroid Build Coastguard Worker
231*48a54d36SAndroid Build Coastguard Worker status = mDNS_Init(&mDNSStorage, &PlatformStorage,
232*48a54d36SAndroid Build Coastguard Worker mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
233*48a54d36SAndroid Build Coastguard Worker mDNS_Init_DontAdvertiseLocalAddresses,
234*48a54d36SAndroid Build Coastguard Worker mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
235*48a54d36SAndroid Build Coastguard Worker if (status) { fprintf(stderr, "Daemon start: mDNS_Init failed %d\n", (int)status); return(status); }
236*48a54d36SAndroid Build Coastguard Worker
237*48a54d36SAndroid Build Coastguard Worker mDNSPosixListenForSignalInEventLoop(SIGINT);
238*48a54d36SAndroid Build Coastguard Worker mDNSPosixListenForSignalInEventLoop(SIGTERM);
239*48a54d36SAndroid Build Coastguard Worker
240*48a54d36SAndroid Build Coastguard Worker if (!strcmp(argv[1], "-"))
241*48a54d36SAndroid Build Coastguard Worker {
242*48a54d36SAndroid Build Coastguard Worker domainname proxyhostname;
243*48a54d36SAndroid Build Coastguard Worker AuthRecord proxyrecord;
244*48a54d36SAndroid Build Coastguard Worker if (argc < 5) goto usage;
245*48a54d36SAndroid Build Coastguard Worker proxyhostname.c[0] = 0;
246*48a54d36SAndroid Build Coastguard Worker AppendLiteralLabelString(&proxyhostname, argv[2]);
247*48a54d36SAndroid Build Coastguard Worker AppendLiteralLabelString(&proxyhostname, "local");
248*48a54d36SAndroid Build Coastguard Worker RegisterNoSuchService(&mDNSStorage, &proxyrecord, &proxyhostname, argv[3], argv[4], "local.");
249*48a54d36SAndroid Build Coastguard Worker }
250*48a54d36SAndroid Build Coastguard Worker else
251*48a54d36SAndroid Build Coastguard Worker {
252*48a54d36SAndroid Build Coastguard Worker ProxyHost proxyhost;
253*48a54d36SAndroid Build Coastguard Worker ServiceRecordSet proxyservice;
254*48a54d36SAndroid Build Coastguard Worker
255*48a54d36SAndroid Build Coastguard Worker proxyhost.ip.NotAnInteger = inet_addr(argv[1]);
256*48a54d36SAndroid Build Coastguard Worker if (proxyhost.ip.NotAnInteger == INADDR_NONE) // INADDR_NONE is 0xFFFFFFFF
257*48a54d36SAndroid Build Coastguard Worker {
258*48a54d36SAndroid Build Coastguard Worker struct hostent *h = gethostbyname(argv[1]);
259*48a54d36SAndroid Build Coastguard Worker if (h) proxyhost.ip.NotAnInteger = *(long*)h->h_addr;
260*48a54d36SAndroid Build Coastguard Worker }
261*48a54d36SAndroid Build Coastguard Worker if (proxyhost.ip.NotAnInteger == INADDR_NONE) // INADDR_NONE is 0xFFFFFFFF
262*48a54d36SAndroid Build Coastguard Worker {
263*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "%s is not valid host address\n", argv[1]);
264*48a54d36SAndroid Build Coastguard Worker return(-1);
265*48a54d36SAndroid Build Coastguard Worker }
266*48a54d36SAndroid Build Coastguard Worker
267*48a54d36SAndroid Build Coastguard Worker MakeDomainLabelFromLiteralString(&proxyhost.hostlabel, argv[2]);
268*48a54d36SAndroid Build Coastguard Worker
269*48a54d36SAndroid Build Coastguard Worker mDNS_RegisterProxyHost(&mDNSStorage, &proxyhost);
270*48a54d36SAndroid Build Coastguard Worker
271*48a54d36SAndroid Build Coastguard Worker if (argc >=6)
272*48a54d36SAndroid Build Coastguard Worker RegisterService(&mDNSStorage, &proxyservice, argv[3], argv[4], "local.",
273*48a54d36SAndroid Build Coastguard Worker proxyhost.RR_A.resrec.name, atoi(argv[5]), argc-6, &argv[6]);
274*48a54d36SAndroid Build Coastguard Worker }
275*48a54d36SAndroid Build Coastguard Worker
276*48a54d36SAndroid Build Coastguard Worker do
277*48a54d36SAndroid Build Coastguard Worker {
278*48a54d36SAndroid Build Coastguard Worker struct timeval timeout = { 0x3FFFFFFF, 0 }; // wait until SIGINT or SIGTERM
279*48a54d36SAndroid Build Coastguard Worker mDNSBool gotSomething;
280*48a54d36SAndroid Build Coastguard Worker mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &signals, &gotSomething);
281*48a54d36SAndroid Build Coastguard Worker }
282*48a54d36SAndroid Build Coastguard Worker while ( !( sigismember( &signals, SIGINT) || sigismember( &signals, SIGTERM)));
283*48a54d36SAndroid Build Coastguard Worker
284*48a54d36SAndroid Build Coastguard Worker mDNS_Close(&mDNSStorage);
285*48a54d36SAndroid Build Coastguard Worker
286*48a54d36SAndroid Build Coastguard Worker return(0);
287*48a54d36SAndroid Build Coastguard Worker
288*48a54d36SAndroid Build Coastguard Worker usage:
289*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "%s ip hostlabel [srvname srvtype port txt [txt ...]]\n", argv[0]);
290*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "ip Real IP address (or valid host name) of the host where the service actually resides\n");
291*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "hostlabel First label of the dot-local host name to create for this host, e.g. \"foo\" for \"foo.local.\"\n");
292*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "srvname Descriptive name of service, e.g. \"Stuart's Ink Jet Printer\"\n");
293*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "srvtype IANA service type, e.g. \"_ipp._tcp\" or \"_ssh._tcp\", etc.\n");
294*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "port Port number where the service resides (1-65535)\n");
295*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "txt Additional name/value pairs specified in service definition, e.g. \"pdl=application/postscript\"\n");
296*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "e.g. %s 169.254.12.34 thehost (just create a dot-local host name)\n", argv[0]);
297*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "or %s 169.254.12.34 thehost \"My Printer\" _printer._tcp. 515 rp=lpt1 pdl=application/postscript\n", argv[0]);
298*48a54d36SAndroid Build Coastguard Worker fprintf(stderr, "or %s - thehost \"My Printer\" _printer._tcp. (assertion of non-existence)\n", argv[0]);
299*48a54d36SAndroid Build Coastguard Worker return(-1);
300*48a54d36SAndroid Build Coastguard Worker }
301