source: vendor/3.6.0/source3/client/dnsbrowse.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

File size: 5.0 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#include "system/select.h"
27
28/* Holds service instances found during DNS browse */
29struct mdns_smbsrv_result
30{
31 char *serviceName;
32 char *regType;
33 char *domain;
34 uint32_t ifIndex;
35 struct mdns_smbsrv_result *nextResult;
36};
37
38/* Maintains state during DNS browse */
39struct mdns_browse_state
40{
41 struct mdns_smbsrv_result *listhead; /* Browse result list head */
42 int browseDone;
43
44};
45
46
47static void
48do_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)
52{
53 printf("SMB service available on %s port %u\n",
54 hosttarget, ntohs(port));
55}
56
57
58static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
59{
60 DNSServiceRef mdns_conn_sdref = NULL;
61 int mdnsfd;
62 int fdsetsz;
63 int ret;
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 int revents;
81
82 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, 1000, &revents);
83 if (ret <= 0 && errno != EINTR) {
84 break;
85 }
86
87 if (revents & (POLLIN|POLLHUP|POLLERR)) {
88 /* Invoke callback function */
89 DNSServiceProcessResult(mdns_conn_sdref);
90 break;
91 }
92 }
93
94 TALLOC_FREE(fdset);
95 DNSServiceRefDeallocate(mdns_conn_sdref);
96}
97
98
99static void
100do_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)
104{
105 struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context;
106 struct mdns_smbsrv_result *bresult;
107
108 if (bstatep == NULL) {
109 return;
110 }
111
112 if (errorCode != kDNSServiceErr_NoError) {
113 bstatep->browseDone = 1;
114 return;
115 }
116
117 if (flags & kDNSServiceFlagsMoreComing) {
118 bstatep->browseDone = 0;
119 } else {
120 bstatep->browseDone = 1;
121 }
122
123 if (!(flags & kDNSServiceFlagsAdd)) {
124 return;
125 }
126
127 bresult = TALLOC_ARRAY(talloc_tos(), struct mdns_smbsrv_result, 1);
128 if (bresult == NULL) {
129 return;
130 }
131
132 if (bstatep->listhead != NULL) {
133 bresult->nextResult = bstatep->listhead;
134 }
135
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;
141}
142
143int do_smb_browse(void)
144{
145 int mdnsfd;
146 int fdsetsz;
147 int ret;
148 struct mdns_browse_state bstate;
149 struct mdns_smbsrv_result *resptr;
150 struct timeval tv;
151 DNSServiceRef mdns_conn_sdref = NULL;
152 DNSServiceErrorType err;
153
154 TALLOC_CTX * ctx = talloc_stackframe();
155
156 ZERO_STRUCT(bstate);
157
158 err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
159 do_smb_browse_reply, &bstate);
160
161 if (err != kDNSServiceErr_NoError) {
162 d_printf("Error connecting to the Multicast DNS daemon\n");
163 TALLOC_FREE(ctx);
164 return 1;
165 }
166
167 mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
168 for (;;) {
169 int revents;
170
171 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, &revents, 1000);
172 if (ret <= 0 && errno != EINTR) {
173 break;
174 }
175
176 if (revents & (POLLIN|POLLHUP|POLLERR)) {
177 /* Invoke callback function */
178 if (DNSServiceProcessResult(mdns_conn_sdref)) {
179 break;
180 }
181 if (bstate.browseDone) {
182 break;
183 }
184 }
185 }
186
187 DNSServiceRefDeallocate(mdns_conn_sdref);
188
189 if (bstate.listhead != NULL) {
190 resptr = bstate.listhead;
191 while (resptr != NULL) {
192 struct mdns_smbsrv_result *oldresptr;
193 oldresptr = resptr;
194
195 /* Resolve smb service instance */
196 do_smb_resolve(resptr);
197
198 resptr = resptr->nextResult;
199 }
200 }
201
202 TALLOC_FREE(ctx);
203 return 0;
204}
205
206#else /* WITH_DNSSD_SUPPORT */
207
208int do_smb_browse(void)
209{
210 d_printf("DNS-SD browsing is not supported on this platform\n");
211 return 1;
212}
213
214#endif /* WITH_DNSSD_SUPPORT */
215
216
Note: See TracBrowser for help on using the repository browser.