2 * Copyright (c) 2000, 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_name.c,v 1.11 2004/12/11 05:23:59 lindak Exp $
35 #include <sys/param.h>
36 #include <sys/socket.h>
46 #include <netsmb/netbios.h>
47 #include <netsmb/smb_lib.h>
48 #include <netsmb/nb_lib.h>
49 #include <netsmb/mchain.h>
53 nb_snballoc(struct sockaddr_nb
**dst
)
55 struct sockaddr_nb
*snb
;
58 slen
= sizeof (struct sockaddr_nb
);
63 snb
->snb_family
= AF_NETBIOS
;
69 nb_snbfree(struct sockaddr
*snb
)
75 * Create a full NETBIOS address
76 * Passed names should already be upper case.
77 * Stores the names truncated or blank padded.
78 * NetBIOS name encoding happens later.
81 nb_sockaddr(struct sockaddr
*peer
, struct nb_name
*np
,
82 struct sockaddr_nb
**dst
)
85 struct sockaddr_nb
*snb
;
86 struct sockaddr_in
*sin
;
89 if (peer
&& (peer
->sa_family
!= AF_INET
))
90 return (EPROTONOSUPPORT
);
91 error
= nb_snballoc(&snb
);
95 if (strcmp(np
->nn_name
, "*") == 0) {
96 /* Star is special: No blanks, type, etc. */
97 snb
->snb_name
[0] = '*';
99 /* Normal name: pad with blanks, add type. */
100 snprintf(snb
->snb_name
, NB_NAMELEN
,
101 "%-15.15s", np
->nn_name
);
102 snb
->snb_name
[15] = (char)np
->nn_type
;
107 sin
= (struct sockaddr_in
*)peer
;
108 snb
->snb_ipaddr
= sin
->sin_addr
.s_addr
;
115 nb_name_len(struct nb_name
*np
)
120 len
= 1 + NB_ENCNAMELEN
;
121 if (np
->nn_scope
== NULL
)
124 for (name
= np
->nn_scope
; *name
; name
++) {
128 if (sclen
< NB_MAXLABLEN
) {
138 nb_encname_len(const uchar_t
*str
)
140 const uchar_t
*cp
= str
;
143 if ((cp
[0] & 0xc0) == 0xc0)
144 return (-1); /* first two bytes are offset to name */
158 nb_name_encode(struct mbdata
*mbp
, struct nb_name
*nn
)
162 char *p
, namebuf
[NB_NAMELEN
+1];
165 bcopy(nn
->nn_name
, namebuf
, NB_NAMELEN
);
166 namebuf
[NB_NAMELEN
-1] = (char)nn
->nn_type
;
167 namebuf
[NB_NAMELEN
] = '\0'; /* for debug */
170 * Do the NetBIOS "first-level encoding" here.
171 * (RFC1002 explains this weirdness...)
173 * Here is what we marshall:
174 * uint8_t NAME_LENGTH (always 32)
175 * uint8_t ENCODED_NAME[32]
176 * uint8_t SCOPE_LENGTH
177 * Scope follows here, then another null.
181 mb_put_uint8(mbp
, (2 * NB_NAMELEN
));
184 for (i
= 0; i
< NB_NAMELEN
; i
++) {
186 mb_put_uint8(mbp
, 'A' + ((ch
>> 4) & 0xF));
187 mb_put_uint8(mbp
, 'A' + ((ch
) & 0xF));
191 * NetBIOS "scope" sting encoding,
192 * a.k.a second-level encoding.
193 * See RFC1002 for the details.
195 * Note: plen points to the length byte at the
196 * start of each string. This keeps a pointer
197 * to the location and fills it in after the
198 * length of the string is determined.
200 * One string of length zero terminates.
201 * With no scope string, the zero-length
202 * string is the only thing there.
204 if (nn
->nn_scope
== NULL
) {
205 mb_put_uint8(mbp
, 0);
209 (void) mb_fit(mbp
, 1, &plen
);
210 *plen
= 0; /* will update below */
212 for (p
= nn
->nn_scope
; ; p
++) {
216 mb_put_uint8(mbp
, 0);
221 (void) mb_fit(mbp
, 1, &plen
);
225 if (lblen
< NB_MAXLABLEN
) {
226 mb_put_uint8(mbp
, *p
);