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 */