2 * Copyright (c) 2000, 2001 Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: nb.c,v 1.1.1.2 2001/07/06 22:38:42 conrad Exp $
36 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
37 * Use is subject to license terms.
40 #include <sys/param.h>
41 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
56 #include <netsmb/netbios.h>
57 #include <netsmb/smb_lib.h>
58 #include <netsmb/nb_lib.h>
60 void nb_ctx_setnbflags(struct nb_ctx
*, int ns_ena
, int bc_ena
);
61 int nb_ctx_setwins(struct nb_ctx
*, const char *, const char *);
64 * API for seting NetBIOS name lookup flags:
65 * NetBIOS name lookup enable,
66 * NetBIOS broadcast enable.
69 smb_ctx_setnbflags(struct smb_ctx
*ctx
, int ns_ena
, int bc_ena
)
71 struct nb_ctx
*nb
= ctx
->ct_nb
;
76 nb_ctx_setnbflags(nb
, ns_ena
, bc_ena
);
81 * API for library consumer to set wins1, wins2
84 smb_ctx_setwins(struct smb_ctx
*ctx
, const char *wins1
, const char *wins2
)
86 struct nb_ctx
*nb
= ctx
->ct_nb
;
91 return (nb_ctx_setwins(nb
, wins1
, wins2
));
95 * API for library consumer to set NB scope.
98 smb_ctx_setscope(struct smb_ctx
*ctx
, const char *scope
)
100 struct nb_ctx
*nb
= ctx
->ct_nb
;
105 return (nb_ctx_setscope(nb
, scope
));
109 nb_ctx_create(struct nb_ctx
**ctxpp
)
113 ctx
= malloc(sizeof (struct nb_ctx
));
116 bzero(ctx
, sizeof (struct nb_ctx
));
122 nb_ctx_done(struct nb_ctx
*ctx
)
131 nb_ctx_setnbflags(struct nb_ctx
*nb
, int ns_ena
, int bc_ena
)
133 nb
->nb_flags
&= ~(NBCF_NS_ENABLE
| NBCF_BC_ENABLE
);
135 nb
->nb_flags
|= NBCF_NS_ENABLE
;
137 nb
->nb_flags
|= NBCF_BC_ENABLE
;
142 nb_ctx_setwins(struct nb_ctx
*ctx
, const char *wins1
, const char *wins2
)
153 error
= nb_resolvehost_in(wins1
, &ina
);
155 smb_error(dgettext(TEXT_DOMAIN
, "can't resolve %s"),
159 ctx
->nb_wins1
= ina
.s_addr
;
164 error
= nb_resolvehost_in(wins2
, &ina
);
166 smb_error(dgettext(TEXT_DOMAIN
, "can't resolve %s"),
170 ctx
->nb_wins2
= ina
.s_addr
;
176 * This is called by "smbutil lookup" to handle the
177 * "-w wins_server" option. Let the semantics of
178 * this option be: Use specified WINS server only.
179 * If specified server is the broadcast address,
180 * set broadcast mode (and no WINS servers).
183 nb_ctx_setns(struct nb_ctx
*ctx
, const char *addr
)
187 error
= nb_ctx_setwins(ctx
, addr
, NULL
);
191 /* Deal with explicit request for broadcast. */
192 if (ctx
->nb_wins1
== INADDR_BROADCAST
) {
194 ctx
->nb_flags
|= NBCF_BC_ENABLE
;
200 nb_ctx_setscope(struct nb_ctx
*ctx
, const char *scope
)
202 size_t slen
= strlen(scope
);
205 smb_error(dgettext(TEXT_DOMAIN
,
206 "scope '%s' is too long"), 0, scope
);
207 return (ENAMETOOLONG
);
210 ctx
->nb_scope
= malloc(slen
+ 1);
211 if (ctx
->nb_scope
== NULL
)
213 nls_str_upper(ctx
->nb_scope
, scope
);
218 * Now get the WINS server IP addresses directly
219 * when reading the RC files, so no longer need to
220 * lookup any names here.
223 nb_ctx_resolve(struct nb_ctx
*ctx
)
225 ctx
->nb_flags
|= NBCF_RESOLVED
;
234 * All of these are normally system-wide settings;
235 * the checks are in rc_parse() in rcfile.c.
238 nb_ctx_readrcsection(struct rcfile
*rcfile
, struct nb_ctx
*ctx
,
239 const char *sname
, int level
)
249 /* External callers pass NULL to get the default. */
254 rc_getint(rcfile
, sname
, "nbtimeout", &ctx
->nb_timo
);
255 rc_getstringptr(rcfile
, sname
, "nbscope", &p
);
257 nb_ctx_setscope(ctx
, p
);
260 * Get "wins1", "wins2" config strings.
261 * Also support legacy "nbns".
263 rc_getstringptr(rcfile
, sname
, "wins1", &wins1
);
265 rc_getstringptr(rcfile
, sname
, "nbns", &wins1
);
266 rc_getstringptr(rcfile
, sname
, "wins2", &wins2
);
269 error
= nb_ctx_setwins(ctx
, wins1
, wins2
);
271 smb_error(dgettext(TEXT_DOMAIN
,
272 "invalid address specified in the section %s"),
279 * Want to use nb_ctx_setnbflags here, but
280 * have to get both boolean values first,
281 * either from settings or defaults.
283 nbns_enable
= nbns_broadcast
= 1; /* defaults */
284 rc_getbool(rcfile
, sname
, "nbns_enable", &nbns_enable
);
285 rc_getbool(rcfile
, sname
, "nbns_broadcast", &nbns_broadcast
);
286 nb_ctx_setnbflags(ctx
, nbns_enable
, nbns_broadcast
);
291 #ifdef I18N /* never defined, permits xgettext(1) to pick out strings */
292 static const char *nb_err_rcode
[] = {
293 gettext("bad request/response format"),
294 gettext("NBNS server failure"),
295 gettext("no such name"),
296 gettext("unsupported request"),
297 gettext("request rejected"),
298 gettext("name already registered)"
301 static const char *nb_err
[] = {
302 gettext("host not found"),
303 gettext("too many redirects"),
304 gettext("invalid response"),
305 gettext("NETBIOS name too long"),
306 gettext("no interface to broadcast on and no NBNS server specified")
309 static const char *nb_err_rcode
[] = {
310 "bad request/response format",
311 "NBNS server failure",
313 "unsupported request",
315 "name already registered"
318 static const char *nb_err
[] = {
320 "too many redirects",
322 "NETBIOS name too long",
323 "no interface to broadcast on and no NBNS server specified"
328 nb_strerror(int error
)
332 if (error
<= NBERR_ACTIVE
)
333 return (nb_err_rcode
[error
- 1]);
334 else if (error
>= NBERR_HOSTNOTFOUND
&& error
< NBERR_MAX
)
335 return (nb_err
[error
- NBERR_HOSTNOTFOUND
]);