nb_net.c revision 126269
1193323Sed/* 2193323Sed * Copyright (c) 2000, Boris Popov 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 1. Redistributions of source code must retain the above copyright 9193323Sed * notice, this list of conditions and the following disclaimer. 10193323Sed * 2. Redistributions in binary form must reproduce the above copyright 11193323Sed * notice, this list of conditions and the following disclaimer in the 12193323Sed * documentation and/or other materials provided with the distribution. 13193323Sed * 3. All advertising materials mentioning features or use of this software 14193323Sed * must display the following acknowledgement: 15193323Sed * This product includes software developed by Boris Popov. 16193323Sed * 4. Neither the name of the author nor the names of any co-contributors 17193323Sed * may be used to endorse or promote products derived from this software 18193323Sed * without specific prior written permission. 19193323Sed * 20193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23193323Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24193323Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29193323Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30193323Sed * SUCH DAMAGE. 31193323Sed * 32193323Sed * $Id: nb_net.c,v 1.4 2001/02/16 02:46:12 bp Exp $ 33193323Sed * $FreeBSD: head/contrib/smbfs/lib/smb/nb_net.c 126269 2004-02-26 08:49:19Z tjr $ 34193323Sed */ 35193323Sed#include <sys/param.h> 36193323Sed#include <sys/socket.h> 37193323Sed 38193323Sed#include <net/if.h> 39193323Sed 40193323Sed#include <ctype.h> 41193323Sed#include <netdb.h> 42193323Sed#include <err.h> 43193323Sed#include <errno.h> 44193323Sed#include <stdlib.h> 45193323Sed#include <string.h> 46193323Sed#include <stdio.h> 47193323Sed#include <unistd.h> 48193323Sed#include <ifaddrs.h> 49193323Sed 50193323Sed#include <netsmb/netbios.h> 51193323Sed#include <netsmb/smb_lib.h> 52193323Sed#include <netsmb/nb_lib.h> 53193323Sed 54193323Sedint 55193323Sednb_getlocalname(char *name) 56193323Sed{ 57193323Sed char buf[1024], *cp; 58193323Sed 59193323Sed if (gethostname(buf, sizeof(buf)) != 0) 60193323Sed return errno; 61193323Sed cp = strchr(buf, '.'); 62193323Sed if (cp) 63193323Sed *cp = 0; 64193323Sed strcpy(name, buf); 65193323Sed return 0; 66193323Sed} 67193323Sed 68193323Sedint 69193323Sednb_resolvehost_in(const char *name, struct sockaddr **dest) 70193323Sed{ 71193323Sed struct hostent* h; 72193323Sed struct sockaddr_in *sinp; 73193323Sed int len; 74193323Sed 75193323Sed h = gethostbyname(name); 76193323Sed if (!h) { 77193323Sed warnx("can't get server address `%s': ", name); 78193323Sed herror(NULL); 79193323Sed return ENETDOWN; 80193323Sed } 81193323Sed if (h->h_addrtype != AF_INET) { 82193323Sed warnx("address for `%s' is not in the AF_INET family", name); 83198090Srdivacky return EAFNOSUPPORT; 84193323Sed } 85193323Sed if (h->h_length != 4) { 86198090Srdivacky warnx("address for `%s' has invalid length", name); 87198090Srdivacky return EAFNOSUPPORT; 88198090Srdivacky } 89198090Srdivacky len = sizeof(struct sockaddr_in); 90198090Srdivacky sinp = malloc(len); 91193323Sed if (sinp == NULL) 92193323Sed return ENOMEM; 93193323Sed bzero(sinp, len); 94193323Sed sinp->sin_len = len; 95198090Srdivacky sinp->sin_family = h->h_addrtype; 96198090Srdivacky memcpy(&sinp->sin_addr.s_addr, h->h_addr, 4); 97193323Sed sinp->sin_port = htons(SMB_TCP_PORT); 98193323Sed *dest = (struct sockaddr*)sinp; 99193323Sed return 0; 100198090Srdivacky} 101198090Srdivacky 102193323Sedint 103193323Sednb_enum_if(struct nb_ifdesc **iflist, int maxif) 104193323Sed{ 105199481Srdivacky struct nb_ifdesc *ifd; 106199481Srdivacky struct ifaddrs *ifp, *p; 107193323Sed int i; 108193323Sed 109193323Sed if (getifaddrs(&ifp) < 0) 110193323Sed return errno; 111193323Sed 112193323Sed *iflist = NULL; 113193323Sed i = 0; 114193323Sed for (p = ifp; p; p = p->ifa_next) { 115193323Sed 116193323Sed if (i >= maxif) 117193323Sed break; 118193323Sed 119193323Sed if ((p->ifa_addr->sa_family != AF_INET) || 120193323Sed ((p->ifa_flags & (IFF_UP|IFF_BROADCAST)) 121193323Sed != (IFF_UP|IFF_BROADCAST))) 122193323Sed continue; 123193323Sed if (strlen(p->ifa_name) >= sizeof(ifd->id_name)) 124193323Sed continue; 125193323Sed 126193323Sed ifd = malloc(sizeof(struct nb_ifdesc)); 127193323Sed if (ifd == NULL) { 128193323Sed freeifaddrs(ifp); 129193323Sed /* XXX should free stuff already in *iflist */ 130193323Sed return ENOMEM; 131193323Sed } 132193323Sed bzero(ifd, sizeof(struct nb_ifdesc)); 133193323Sed strcpy(ifd->id_name, p->ifa_name); 134193323Sed ifd->id_flags = p->ifa_flags; 135193323Sed ifd->id_addr = ((struct sockaddr_in *)p->ifa_addr)->sin_addr; 136193323Sed ifd->id_mask = ((struct sockaddr_in *)p->ifa_netmask)->sin_addr; 137193323Sed ifd->id_next = *iflist; 138193323Sed *iflist = ifd; 139193323Sed i++; 140193323Sed } 141193323Sed 142193323Sed freeifaddrs(ifp); 143193323Sed return 0; 144193323Sed} 145193323Sed 146193323Sed/*ARGSUSED*/ 147193323Sed/*int 148193323Sednbns_resolvename(const char *name, struct sockaddr **dest) 149193323Sed{ 150193323Sed printf("NetBIOS name resolver is not included in this distribution.\n"); 151193323Sed printf("Please use '-I' option to specify an IP address of server.\n"); 152193323Sed return EHOSTUNREACH; 153193323Sed}*/ 154193323Sed/* 155193323Sedint 156193323Sednb_hostlookup(struct nb_name *np, const char *server, const char *hint, 157193323Sed struct sockaddr_nb **dst) 158193323Sed{ 159193323Sed struct sockaddr_nb *snb; 160193323Sed int error; 161193323Sed 162193323Sed error = nb_sockaddr(NULL, np, &snb); 163193323Sed if (error) 164193323Sed return error; 165193323Sed do { 166193323Sed if (hint) { 167193323Sed error = nb_resolvehost_in(host, snb); 168193323Sed if (error) 169193323Sed break; 170193323Sed } else { 171193323Sed error = nb_resolvename(server); 172193323Sed } 173193323Sed } while(0); 174193323Sed if (!error) { 175193323Sed *dst = snb; 176193323Sed } else 177193323Sed nb_snbfree(snb); 178193323Sed return error; 179193323Sed} 180193323Sed*/ 181193323Sed