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
27
/* Holds service instances found during DNS browse */
28
struct mdns_smbsrv_result
34
struct mdns_smbsrv_result *nextResult;
37
/* Maintains state during DNS browse */
38
struct mdns_browse_state
40
struct mdns_smbsrv_result *listhead; /* Browse result list head */
47
do_smb_resolve_reply (DNSServiceRef sdRef, DNSServiceFlags flags,
48
uint32_t interfaceIndex, DNSServiceErrorType errorCode,
49
const char *fullname, const char *hosttarget, uint16_t port,
50
uint16_t txtLen, const unsigned char *txtRecord, void *context)
52
printf("SMB service available on %s port %u\n",
53
hosttarget, ntohs(port));
57
static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
59
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);
84
fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
85
fdset = TALLOC_ZERO(ctx, fdsetsz);
86
FD_SET(mdnsfd, fdset);
91
/* Wait until response received from mDNS daemon */
92
ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
93
if (ret <= 0 && errno != EINTR) {
97
if (FD_ISSET(mdnsfd, fdset)) {
98
/* Invoke callback function */
99
DNSServiceProcessResult(mdns_conn_sdref);
105
DNSServiceRefDeallocate(mdns_conn_sdref);
110
do_smb_browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags,
111
uint32_t interfaceIndex, DNSServiceErrorType errorCode,
112
const char *serviceName, const char *regtype,
113
const char *replyDomain, void *context)
115
struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context;
116
struct mdns_smbsrv_result *bresult;
118
if (bstatep == NULL) {
122
if (errorCode != kDNSServiceErr_NoError) {
123
bstatep->browseDone = 1;
127
if (flags & kDNSServiceFlagsMoreComing) {
128
bstatep->browseDone = 0;
130
bstatep->browseDone = 1;
133
if (!(flags & kDNSServiceFlagsAdd)) {
137
bresult = TALLOC_ARRAY(talloc_tos(), struct mdns_smbsrv_result, 1);
138
if (bresult == NULL) {
142
if (bstatep->listhead != NULL) {
143
bresult->nextResult = bstatep->listhead;
146
bresult->serviceName = talloc_strdup(talloc_tos(), serviceName);
147
bresult->regType = talloc_strdup(talloc_tos(), regtype);
148
bresult->domain = talloc_strdup(talloc_tos(), replyDomain);
149
bresult->ifIndex = interfaceIndex;
150
bstatep->listhead = bresult;
153
int do_smb_browse(void)
158
fd_set *fdset = NULL;
159
struct mdns_browse_state bstate;
160
struct mdns_smbsrv_result *resptr;
162
DNSServiceRef mdns_conn_sdref = NULL;
163
DNSServiceErrorType err;
165
TALLOC_CTX * ctx = talloc_stackframe();
169
err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
170
do_smb_browse_reply, &bstate);
172
if (err != kDNSServiceErr_NoError) {
173
d_printf("Error connecting to the Multicast DNS daemon\n");
178
mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
184
fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
185
fdset = TALLOC_ZERO(ctx, fdsetsz);
186
FD_SET(mdnsfd, fdset);
191
/* Wait until response received from mDNS daemon */
192
ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
193
if (ret <= 0 && errno != EINTR) {
197
if (FD_ISSET(mdnsfd, fdset)) {
198
/* Invoke callback function */
199
if (DNSServiceProcessResult(mdns_conn_sdref)) {
202
if (bstate.browseDone) {
208
DNSServiceRefDeallocate(mdns_conn_sdref);
210
if (bstate.listhead != NULL) {
211
resptr = bstate.listhead;
212
while (resptr != NULL) {
213
struct mdns_smbsrv_result *oldresptr;
216
/* Resolve smb service instance */
217
do_smb_resolve(resptr);
219
resptr = resptr->nextResult;
227
#else /* WITH_DNSSD_SUPPORT */
229
int do_smb_browse(void)
231
d_printf("DNS-SD browsing is not supported on this platform\n");
235
#endif /* WITH_DNSSD_SUPPORT */