ses: SUN plugin doesn't actually need libnvfru
[unleashed.git] / usr / src / lib / libsmbfs / smb / nb_name.c
blob812900aca9c4f21931c1901ff9a7b1de70f2b686
1 /*
2 * Copyright (c) 2000, Boris Popov
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
30 * SUCH DAMAGE.
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>
37 #include <ctype.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <strings.h>
43 #include <libintl.h>
44 #include <assert.h>
46 #include <netsmb/netbios.h>
47 #include <netsmb/smb_lib.h>
48 #include <netsmb/nb_lib.h>
49 #include <netsmb/mchain.h>
50 #include "private.h"
52 int
53 nb_snballoc(struct sockaddr_nb **dst)
55 struct sockaddr_nb *snb;
56 int slen;
58 slen = sizeof (struct sockaddr_nb);
59 snb = malloc(slen);
60 if (snb == NULL)
61 return (ENOMEM);
62 bzero(snb, slen);
63 snb->snb_family = AF_NETBIOS;
64 *dst = snb;
65 return (0);
68 void
69 nb_snbfree(struct sockaddr *snb)
71 free(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.
80 int
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;
87 int error;
89 if (peer && (peer->sa_family != AF_INET))
90 return (EPROTONOSUPPORT);
91 error = nb_snballoc(&snb);
92 if (error)
93 return (error);
95 if (strcmp(np->nn_name, "*") == 0) {
96 /* Star is special: No blanks, type, etc. */
97 snb->snb_name[0] = '*';
98 } else {
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;
105 if (peer) {
106 /*LINTED*/
107 sin = (struct sockaddr_in *)peer;
108 snb->snb_ipaddr = sin->sin_addr.s_addr;
110 *dst = snb;
111 return (0);
115 nb_name_len(struct nb_name *np)
117 char *name;
118 int len, sclen;
120 len = 1 + NB_ENCNAMELEN;
121 if (np->nn_scope == NULL)
122 return (len + 1);
123 sclen = 0;
124 for (name = np->nn_scope; *name; name++) {
125 if (*name == '.') {
126 sclen = 0;
127 } else {
128 if (sclen < NB_MAXLABLEN) {
129 sclen++;
130 len++;
134 return (len + 1);
138 nb_encname_len(const uchar_t *str)
140 const uchar_t *cp = str;
141 int len, blen;
143 if ((cp[0] & 0xc0) == 0xc0)
144 return (-1); /* first two bytes are offset to name */
146 len = 1;
147 for (;;) {
148 blen = *cp;
149 if (blen++ == 0)
150 break;
151 len += blen;
152 cp += blen;
154 return (len);
158 nb_name_encode(struct mbdata *mbp, struct nb_name *nn)
160 char *plen;
161 uchar_t ch;
162 char *p, namebuf[NB_NAMELEN+1];
163 int i, lblen;
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.
180 /* NAME_LENGTH */
181 mb_put_uint8(mbp, (2 * NB_NAMELEN));
183 /* ENCODED_NAME */
184 for (i = 0; i < NB_NAMELEN; i++) {
185 ch = namebuf[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);
206 return (0);
209 (void) mb_fit(mbp, 1, &plen);
210 *plen = 0; /* will update below */
211 lblen = 0;
212 for (p = nn->nn_scope; ; p++) {
213 if (*p == '\0') {
214 *plen = lblen;
215 if (lblen)
216 mb_put_uint8(mbp, 0);
217 break;
219 if (*p == '.') {
220 *plen = lblen;
221 (void) mb_fit(mbp, 1, &plen);
222 *plen = 0;
223 lblen = 0;
224 } else {
225 if (lblen < NB_MAXLABLEN) {
226 mb_put_uint8(mbp, *p);
227 lblen++;
232 return (0);