source: branches/samba-3.3.x/source/client/dnsbrowse.c@ 694

Last change on this file since 694 was 578, checked in by Herwig Bauernfeind, 14 years ago

Update Samba 3.3 to 3.3.15 (security update)

File size: 5.7 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 DNS-SD browse client
4 Copyright (C) Rishi Srivatsavai 2007
5
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.
10
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.
15
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/>.
18*/
19
20#include "includes.h"
21#include "client/client_proto.h"
22
23#ifdef WITH_DNSSD_SUPPORT
24
25#include <dns_sd.h>
26
27/* Holds service instances found during DNS browse */
28struct mdns_smbsrv_result
29{
30 char *serviceName;
31 char *regType;
32 char *domain;
33 uint32_t ifIndex;
34 struct mdns_smbsrv_result *nextResult;
35};
36
37/* Maintains state during DNS browse */
38struct mdns_browse_state
39{
40 struct mdns_smbsrv_result *listhead; /* Browse result list head */
41 int browseDone;
42
43};
44
45
46static void
47do_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)
51{
52 printf("SMB service available on %s port %u\n",
53 hosttarget, ntohs(port));
54}
55
56
57static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
58{
59 DNSServiceRef mdns_conn_sdref = NULL;
60 int mdnsfd;
61 int fdsetsz;
62 int ret;
63 fd_set *fdset = NULL;
64 struct timeval tv;
65 DNSServiceErrorType err;
66
67 TALLOC_CTX * ctx = talloc_tos();
68
69 err = DNSServiceResolve(&mdns_conn_sdref, 0 /* flags */,
70 browsesrv->ifIndex,
71 browsesrv->serviceName, browsesrv->regType, browsesrv->domain,
72 do_smb_resolve_reply, NULL);
73
74 if (err != kDNSServiceErr_NoError) {
75 return;
76 }
77
78 mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
79 for (;;) {
80 if (fdset != NULL) {
81 TALLOC_FREE(fdset);
82 }
83
84 if (mdnsfd < 0 || mdnsfd >= FD_SETSIZE) {
85 errno = EBADF;
86 break;
87 }
88
89 fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
90 fdset = TALLOC_ZERO(ctx, fdsetsz);
91 FD_SET(mdnsfd, fdset);
92
93 tv.tv_sec = 1;
94 tv.tv_usec = 0;
95
96 /* Wait until response received from mDNS daemon */
97 ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
98 if (ret <= 0 && errno != EINTR) {
99 break;
100 }
101
102 if (FD_ISSET(mdnsfd, fdset)) {
103 /* Invoke callback function */
104 DNSServiceProcessResult(mdns_conn_sdref);
105 break;
106 }
107 }
108
109 TALLOC_FREE(fdset);
110 DNSServiceRefDeallocate(mdns_conn_sdref);
111}
112
113
114static void
115do_smb_browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags,
116 uint32_t interfaceIndex, DNSServiceErrorType errorCode,
117 const char *serviceName, const char *regtype,
118 const char *replyDomain, void *context)
119{
120 struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context;
121 struct mdns_smbsrv_result *bresult;
122
123 if (bstatep == NULL) {
124 return;
125 }
126
127 if (errorCode != kDNSServiceErr_NoError) {
128 bstatep->browseDone = 1;
129 return;
130 }
131
132 if (flags & kDNSServiceFlagsMoreComing) {
133 bstatep->browseDone = 0;
134 } else {
135 bstatep->browseDone = 1;
136 }
137
138 if (!(flags & kDNSServiceFlagsAdd)) {
139 return;
140 }
141
142 bresult = TALLOC_ARRAY(talloc_tos(), struct mdns_smbsrv_result, 1);
143 if (bresult == NULL) {
144 return;
145 }
146
147 if (bstatep->listhead != NULL) {
148 bresult->nextResult = bstatep->listhead;
149 }
150
151 bresult->serviceName = talloc_strdup(talloc_tos(), serviceName);
152 bresult->regType = talloc_strdup(talloc_tos(), regtype);
153 bresult->domain = talloc_strdup(talloc_tos(), replyDomain);
154 bresult->ifIndex = interfaceIndex;
155 bstatep->listhead = bresult;
156}
157
158int do_smb_browse(void)
159{
160 int mdnsfd;
161 int fdsetsz;
162 int ret;
163 fd_set *fdset = NULL;
164 struct mdns_browse_state bstate;
165 struct mdns_smbsrv_result *resptr;
166 struct timeval tv;
167 DNSServiceRef mdns_conn_sdref = NULL;
168 DNSServiceErrorType err;
169
170 TALLOC_CTX * ctx = talloc_stackframe();
171
172 ZERO_STRUCT(bstate);
173
174 err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
175 do_smb_browse_reply, &bstate);
176
177 if (err != kDNSServiceErr_NoError) {
178 d_printf("Error connecting to the Multicast DNS daemon\n");
179 TALLOC_FREE(ctx);
180 return 1;
181 }
182
183 mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
184 for (;;) {
185 if (fdset != NULL) {
186 TALLOC_FREE(fdset);
187 }
188
189 fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
190 fdset = TALLOC_ZERO(ctx, fdsetsz);
191
192 if (mdnsfd < 0 || mdnsfd >= FD_SETSIZE) {
193 errno = EBADF;
194 TALLOC_FREE(ctx);
195 return 1;
196 }
197
198 FD_SET(mdnsfd, fdset);
199
200 tv.tv_sec = 1;
201 tv.tv_usec = 0;
202
203 /* Wait until response received from mDNS daemon */
204 ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
205 if (ret <= 0 && errno != EINTR) {
206 break;
207 }
208
209 if (FD_ISSET(mdnsfd, fdset)) {
210 /* Invoke callback function */
211 if (DNSServiceProcessResult(mdns_conn_sdref)) {
212 break;
213 }
214 if (bstate.browseDone) {
215 break;
216 }
217 }
218 }
219
220 DNSServiceRefDeallocate(mdns_conn_sdref);
221
222 if (bstate.listhead != NULL) {
223 resptr = bstate.listhead;
224 while (resptr != NULL) {
225 struct mdns_smbsrv_result *oldresptr;
226 oldresptr = resptr;
227
228 /* Resolve smb service instance */
229 do_smb_resolve(resptr);
230
231 resptr = resptr->nextResult;
232 }
233 }
234
235 TALLOC_FREE(ctx);
236 return 0;
237}
238
239#else /* WITH_DNSSD_SUPPORT */
240
241int do_smb_browse(void)
242{
243 d_printf("DNS-SD browsing is not supported on this platform\n");
244 return 1;
245}
246
247#endif /* WITH_DNSSD_SUPPORT */
248
249
Note: See TracBrowser for help on using the repository browser.