2 Unix SMB/CIFS implementation.
4 Copyright (C) Rishi Srivatsavai 2007
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "client/client_proto.h"
23 #ifdef WITH_DNSSD_SUPPORT
26 #include "system/select.h"
28 /* Holds service instances found during DNS browse */
29 struct mdns_smbsrv_result
35 struct mdns_smbsrv_result *nextResult;
38 /* Maintains state during DNS browse */
39 struct mdns_browse_state
41 struct mdns_smbsrv_result *listhead; /* Browse result list head */
48 do_smb_resolve_reply (DNSServiceRef sdRef, DNSServiceFlags flags,
49 uint32_t interfaceIndex, DNSServiceErrorType errorCode,
50 const char *fullname, const char *hosttarget, uint16_t port,
51 uint16_t txtLen, const unsigned char *txtRecord, void *context)
53 printf("SMB service available on %s port %u\n",
54 hosttarget, ntohs(port));
58 static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
60 DNSServiceRef mdns_conn_sdref = NULL;
65 DNSServiceErrorType err;
67 TALLOC_CTX * ctx = talloc_tos();
69 err = DNSServiceResolve(&mdns_conn_sdref, 0 /* flags */,
71 browsesrv->serviceName, browsesrv->regType, browsesrv->domain,
72 do_smb_resolve_reply, NULL);
74 if (err != kDNSServiceErr_NoError) {
78 mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
82 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, 1000, &revents);
83 if (ret <= 0 && errno != EINTR) {
87 if (revents & (POLLIN|POLLHUP|POLLERR)) {
88 /* Invoke callback function */
89 DNSServiceProcessResult(mdns_conn_sdref);
95 DNSServiceRefDeallocate(mdns_conn_sdref);
100 do_smb_browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags,
101 uint32_t interfaceIndex, DNSServiceErrorType errorCode,
102 const char *serviceName, const char *regtype,
103 const char *replyDomain, void *context)
105 struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context;
106 struct mdns_smbsrv_result *bresult;
108 if (bstatep == NULL) {
112 if (errorCode != kDNSServiceErr_NoError) {
113 bstatep->browseDone = 1;
117 if (flags & kDNSServiceFlagsMoreComing) {
118 bstatep->browseDone = 0;
120 bstatep->browseDone = 1;
123 if (!(flags & kDNSServiceFlagsAdd)) {
127 bresult = talloc_array(talloc_tos(), struct mdns_smbsrv_result, 1);
128 if (bresult == NULL) {
132 if (bstatep->listhead != NULL) {
133 bresult->nextResult = bstatep->listhead;
136 bresult->serviceName = talloc_strdup(talloc_tos(), serviceName);
137 bresult->regType = talloc_strdup(talloc_tos(), regtype);
138 bresult->domain = talloc_strdup(talloc_tos(), replyDomain);
139 bresult->ifIndex = interfaceIndex;
140 bstatep->listhead = bresult;
143 int do_smb_browse(void)
148 struct mdns_browse_state bstate;
149 struct mdns_smbsrv_result *resptr;
151 DNSServiceRef mdns_conn_sdref = NULL;
152 DNSServiceErrorType err;
154 TALLOC_CTX * ctx = talloc_stackframe();
158 err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
159 do_smb_browse_reply, &bstate);
161 if (err != kDNSServiceErr_NoError) {
162 d_printf("Error connecting to the Multicast DNS daemon\n");
167 mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
171 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, &revents, 1000);
172 if (ret <= 0 && errno != EINTR) {
176 if (revents & (POLLIN|POLLHUP|POLLERR)) {
177 /* Invoke callback function */
178 if (DNSServiceProcessResult(mdns_conn_sdref)) {
181 if (bstate.browseDone) {
187 DNSServiceRefDeallocate(mdns_conn_sdref);
189 if (bstate.listhead != NULL) {
190 resptr = bstate.listhead;
191 while (resptr != NULL) {
192 struct mdns_smbsrv_result *oldresptr;
195 /* Resolve smb service instance */
196 do_smb_resolve(resptr);
198 resptr = resptr->nextResult;
206 #else /* WITH_DNSSD_SUPPORT */
208 int do_smb_browse(void)
210 d_printf("DNS-SD browsing is not supported on this platform\n");
214 #endif /* WITH_DNSSD_SUPPORT */