]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOS9/Responder.c
d1612f8771d5dea71bba53bd2cdc0440714b0c5c
[apple/mdnsresponder.git] / mDNSMacOS9 / Responder.c
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24
25 Change History (most recent first):
26
27 $Log: Responder.c,v $
28 Revision 1.2 2004/05/20 18:38:31 cheshire
29 Fix build broken by removal of 'kDNSServiceFlagsAutoRename' from dns_sd.h
30
31 Revision 1.1 2004/03/12 21:30:25 cheshire
32 Build a System-Context Shared Library from mDNSCore, for the benefit of developers
33 like Muse Research who want to be able to use mDNS/DNS-SD from GPL-licensed code.
34
35 */
36
37 #include <stdio.h> // For printf()
38 #include <string.h> // For strcpy()
39
40 #include <Events.h> // For WaitNextEvent()
41
42 #include <OpenTransport.h>
43 #include <OpenTptInternet.h>
44
45 #include <SIOUX.h> // For SIOUXHandleOneEvent()
46
47 #include "dns_sd.h"
48
49 typedef union { UInt8 b[2]; UInt16 NotAnInteger; } mDNSOpaque16;
50 static UInt16 mDNSVal16(mDNSOpaque16 x) { return((UInt16)(x.b[0]<<8 | x.b[1])); }
51 static mDNSOpaque16 mDNSOpaque16fromIntVal(UInt16 v)
52 { mDNSOpaque16 x; x.b[0] = (UInt8)(v >> 8); x.b[1] = (UInt8)(v & 0xFF); return(x); }
53
54 typedef struct RegisteredService_struct RegisteredService;
55 struct RegisteredService_struct
56 {
57 RegisteredService *next;
58 DNSServiceRef sdRef;
59 Boolean gotresult;
60 DNSServiceErrorType errorCode;
61 char namestr[64];
62 char typestr[kDNSServiceMaxDomainName];
63 char domstr [kDNSServiceMaxDomainName];
64 };
65
66 static RegisteredService p1, p2, afp, http, njp;
67 static RegisteredService *services = NULL, **nextservice = &services;
68
69 static void RegCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
70 const char *name, const char *regtype, const char *domain, void *context)
71 {
72 RegisteredService *rs = (RegisteredService *)context;
73 (void)sdRef; // Unused
74 (void)flags; // Unused
75 rs->gotresult = true;
76 rs->errorCode = errorCode;
77 strcpy(rs->namestr, name);
78 strcpy(rs->typestr, regtype);
79 strcpy(rs->domstr, domain);
80 }
81
82 static DNSServiceErrorType RegisterService(RegisteredService *rs, mDNSOpaque16 OpaquePort,
83 const char name[], const char type[], const char domain[], const char txtinfo[])
84 {
85 DNSServiceErrorType err;
86 unsigned char txtbuffer[257];
87 strncpy((char*)txtbuffer+1, txtinfo, 255);
88 txtbuffer[256] = 0;
89 txtbuffer[0] = (unsigned char)strlen((char*)txtbuffer);
90 rs->gotresult = 0;
91 rs->errorCode = kDNSServiceErr_NoError;
92 err = DNSServiceRegister(&rs->sdRef, /* kDNSServiceFlagsAutoRename*/ 0, 0,
93 name, type, domain, NULL, OpaquePort.NotAnInteger, (unsigned short)(1+txtbuffer[0]), txtbuffer, RegCallback, rs);
94 if (err)
95 printf("RegisterService(%s %s %s) failed %d\n", name, type, domain, err);
96 else
97 { *nextservice = rs; nextservice = &rs->next; }
98 return(err);
99 }
100
101 // RegisterFakeServiceForTesting() simulates the effect of services being registered on
102 // dynamically-allocated port numbers. No real service exists on that port -- this is just for testing.
103 static DNSServiceErrorType RegisterFakeServiceForTesting(RegisteredService *rs,
104 const char name[], const char type[], const char domain[], const char txtinfo[])
105 {
106 static UInt16 NextPort = 0xF000;
107 return RegisterService(rs, mDNSOpaque16fromIntVal(NextPort++), name, type, domain, txtinfo);
108 }
109
110 // CreateProxyRegistrationForRealService() checks to see if the given port is currently
111 // in use, and if so, advertises the specified service as present on that port.
112 // This is useful for advertising existing real services (Personal Web Sharing, Personal
113 // File Sharing, etc.) that currently don't register with mDNS Service Discovery themselves.
114 static DNSServiceErrorType CreateProxyRegistrationForRealService(RegisteredService *rs,
115 const char *servicetype, UInt16 PortAsNumber, const char txtinfo[])
116 {
117 mDNSOpaque16 OpaquePort = mDNSOpaque16fromIntVal(PortAsNumber);
118 InetAddress ia;
119 TBind bindReq;
120 OSStatus err;
121 TEndpointInfo endpointinfo;
122 EndpointRef ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &endpointinfo, &err);
123 if (!ep || err) { printf("OTOpenEndpoint (CreateProxyRegistrationForRealService) failed %d", err); return(err); }
124
125 ia.fAddressType = AF_INET;
126 ia.fPort = OpaquePort.NotAnInteger;
127 ia.fHost = 0;
128 bindReq.addr.maxlen = sizeof(ia);
129 bindReq.addr.len = sizeof(ia);
130 bindReq.addr.buf = (UInt8*)&ia;
131 bindReq.qlen = 0;
132 err = OTBind(ep, &bindReq, NULL);
133
134 if (err == kOTBadAddressErr)
135 err = RegisterService(rs, OpaquePort, "", servicetype, "local.", txtinfo);
136 else if (err)
137 printf("OTBind failed %d", err);
138
139 OTCloseProvider(ep);
140 return(err);
141 }
142
143 // YieldSomeTime() just cooperatively yields some time to other processes running on classic Mac OS
144 static Boolean YieldSomeTime(UInt32 milliseconds)
145 {
146 extern Boolean SIOUXQuitting;
147 EventRecord e;
148 WaitNextEvent(everyEvent, &e, milliseconds / 17, NULL);
149 SIOUXHandleOneEvent(&e);
150 return(SIOUXQuitting);
151 }
152
153 int main()
154 {
155 OSStatus err;
156 RegisteredService *s;
157
158 SIOUXSettings.asktosaveonclose = false;
159 SIOUXSettings.userwindowtitle = "\pMulticast DNS Responder";
160
161 printf("Multicast DNS Responder\n\n");
162 printf("This software reports errors using MacsBug breaks,\n");
163 printf("so if you don't have MacsBug installed your Mac may crash.\n\n");
164 printf("******************************************************************************\n\n");
165
166 err = InitOpenTransport();
167 if (err) { printf("InitOpenTransport failed %d", err); return(err); }
168
169 printf("Advertising Services...\n");
170
171 #define SRSET 0
172 #if SRSET==0
173 RegisterFakeServiceForTesting(&p1, "Web Server One", "_http._tcp.", "local.", "path=/index.html");
174 RegisterFakeServiceForTesting(&p2, "Web Server Two", "_http._tcp.", "local.", "path=/path.html");
175 #elif SRSET==1
176 RegisterFakeServiceForTesting(&p1, "Epson Stylus 900N", "_printer._tcp.", "local.", "rn=lpq1");
177 RegisterFakeServiceForTesting(&p2, "HP LaserJet", "_printer._tcp.", "local.", "rn=lpq2");
178 #else
179 RegisterFakeServiceForTesting(&p1, "My Printer", "_printer._tcp.", "local.", "rn=lpq3");
180 RegisterFakeServiceForTesting(&p2, "My Other Printer", "_printer._tcp.", "local.", "lrn=pq4");
181 #endif
182
183 // If AFP Server is running, register a record for it
184 CreateProxyRegistrationForRealService(&afp, "_afpovertcp._tcp.", 548, "");
185
186 // If Web Server is running, register a record for it
187 CreateProxyRegistrationForRealService(&http, "_http._tcp.", 80, "path=/index.html");
188
189 while (!YieldSomeTime(35))
190 for (s = services; s; s = s->next)
191 if (s->gotresult)
192 {
193 printf("%s %s %s registered\n", s->namestr, s->typestr, s->domstr);
194 s->gotresult = false;
195 }
196
197 for (s = services; s; s = s->next)
198 if (s->sdRef) DNSServiceRefDeallocate(s->sdRef);
199
200 CloseOpenTransport();
201 return(0);
202 }