diff options
author | sheldonh <sheldonh@FreeBSD.org> | 2001-12-14 11:06:03 +0000 |
---|---|---|
committer | sheldonh <sheldonh@FreeBSD.org> | 2001-12-14 11:06:03 +0000 |
commit | 4e260b134ff188548ec2c8a16a37570a4abf1257 (patch) | |
tree | 672d7786f89ed3b67f221098cb86cf0bc53ad5e3 /contrib/smbfs/lib/smb/nb_name.c | |
download | FreeBSD-src-4e260b134ff188548ec2c8a16a37570a4abf1257.zip FreeBSD-src-4e260b134ff188548ec2c8a16a37570a4abf1257.tar.gz |
Import smbfs-1.4.1.
This is Boris Popov's SMB/CIFS file system implementation for FreeBSD.
Obtained from: Boris Popov via ftp://ftp.butya.kz/pub/smbfs/
Diffstat (limited to 'contrib/smbfs/lib/smb/nb_name.c')
-rw-r--r-- | contrib/smbfs/lib/smb/nb_name.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/contrib/smbfs/lib/smb/nb_name.c b/contrib/smbfs/lib/smb/nb_name.c new file mode 100644 index 0000000..24b1a80 --- /dev/null +++ b/contrib/smbfs/lib/smb/nb_name.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2000, Boris Popov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Boris Popov. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: nb_name.c,v 1.1 2000/07/16 01:52:07 bp Exp $ + */ +#include <sys/param.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <netsmb/netbios.h> +#include <netsmb/smb_lib.h> +#include <netsmb/nb_lib.h> + +int +nb_snballoc(int namelen, struct sockaddr_nb **dst) +{ + struct sockaddr_nb *snb; + int slen; + + slen = namelen + sizeof(*snb) - sizeof(snb->snb_name); + snb = malloc(slen); + if (snb == NULL) + return ENOMEM; + bzero(snb, slen); + snb->snb_family = AF_NETBIOS; + snb->snb_len = slen; + *dst = snb; + return 0; +} + +void +nb_snbfree(struct sockaddr *snb) +{ + free(snb); +} + +/* + * Create a full NETBIOS address + */ +int +nb_sockaddr(struct sockaddr *peer, struct nb_name *np, + struct sockaddr_nb **dst) + +{ + struct sockaddr_nb *snb; + int nmlen, error; + + if (peer && (peer->sa_family != AF_INET && peer->sa_family != AF_IPX)) + return EPROTONOSUPPORT; + nmlen = nb_name_len(np); + if (nmlen < NB_ENCNAMELEN) + return EINVAL; + error = nb_snballoc(nmlen, &snb); + if (error) + return error; + if (nmlen != nb_name_encode(np, snb->snb_name)) + printf("a bug somewhere in the nb_name* code\n"); + if (peer) + memcpy(&snb->snb_tran, peer, peer->sa_len); + *dst = snb; + return 0; +} + +int +nb_name_len(struct nb_name *np) +{ + u_char *name; + int len, sclen; + + len = 1 + NB_ENCNAMELEN; + if (np->nn_scope == NULL) + return len + 1; + sclen = 0; + for (name = np->nn_scope; *name; name++) { + if (*name == '.') { + sclen = 0; + } else { + if (sclen < NB_MAXLABLEN) { + sclen++; + len++; + } + } + } + return len + 1; +} + +int +nb_encname_len(const char *str) +{ + const u_char *cp = (const u_char *)str; + int len, blen; + + if ((cp[0] & 0xc0) == 0xc0) + return -1; /* first two bytes are offset to name */ + + len = 1; + for (;;) { + blen = *cp; + if (blen++ == 0) + break; + len += blen; + cp += blen; + } + return len; +} + +#define NBENCODE(c) ((u_short)(((u_char)(c) >> 4) | \ + (((u_char)(c) & 0xf) << 8)) + 0x4141) + +static void +memsetw(char *dst, int n, u_short word) +{ + while (n--) { + *(u_short*)dst = word; + dst += 2; + } +} + +int +nb_name_encode(struct nb_name *np, u_char *dst) +{ + u_char *name, *plen; + u_char *cp = dst; + int i, lblen; + + *cp++ = NB_ENCNAMELEN; + name = np->nn_name; + if (name[0] == '*' && name[1] == 0) { + *(u_short*)cp = NBENCODE('*'); + memsetw(cp + 2, NB_NAMELEN - 1, NBENCODE(' ')); + cp += NB_ENCNAMELEN; + } else { + for (i = 0; *name && i < NB_NAMELEN; i++, cp += 2, name++) + *(u_short*)cp = NBENCODE(toupper(*name)); + i = NB_NAMELEN - i - 1; + if (i > 0) { + memsetw(cp, i, NBENCODE(' ')); + cp += i * 2; + } + *(u_short*)cp = NBENCODE(np->nn_type); + cp += 2; + } + *cp = 0; + if (np->nn_scope == NULL) + return nb_encname_len(dst); + plen = cp++; + lblen = 0; + for (name = np->nn_scope; ; name++) { + if (*name == '.' || *name == 0) { + *plen = lblen; + plen = cp++; + *plen = 0; + if (*name == 0) + break; + } else { + if (lblen < NB_MAXLABLEN) { + *cp++ = *name; + lblen++; + } + } + } + return nb_encname_len(dst); +} + |