187866Ssheldonh/* 287866Ssheldonh * Copyright (c) 2000, Boris Popov 387866Ssheldonh * All rights reserved. 487866Ssheldonh * 587866Ssheldonh * Redistribution and use in source and binary forms, with or without 687866Ssheldonh * modification, are permitted provided that the following conditions 787866Ssheldonh * are met: 887866Ssheldonh * 1. Redistributions of source code must retain the above copyright 987866Ssheldonh * notice, this list of conditions and the following disclaimer. 1087866Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright 1187866Ssheldonh * notice, this list of conditions and the following disclaimer in the 1287866Ssheldonh * documentation and/or other materials provided with the distribution. 1387866Ssheldonh * 3. All advertising materials mentioning features or use of this software 1487866Ssheldonh * must display the following acknowledgement: 1587866Ssheldonh * This product includes software developed by Boris Popov. 1687866Ssheldonh * 4. Neither the name of the author nor the names of any co-contributors 1787866Ssheldonh * may be used to endorse or promote products derived from this software 1887866Ssheldonh * without specific prior written permission. 1987866Ssheldonh * 2087866Ssheldonh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2187866Ssheldonh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2287866Ssheldonh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2387866Ssheldonh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2487866Ssheldonh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2587866Ssheldonh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2687866Ssheldonh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2787866Ssheldonh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2887866Ssheldonh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2987866Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3087866Ssheldonh * SUCH DAMAGE. 3187866Ssheldonh * 3287866Ssheldonh * $Id: nb_net.c,v 1.4 2001/02/16 02:46:12 bp Exp $ 33125130Stjr * $FreeBSD$ 3487866Ssheldonh */ 3587866Ssheldonh#include <sys/param.h> 3687866Ssheldonh#include <sys/socket.h> 3787866Ssheldonh 3887866Ssheldonh#include <net/if.h> 3987866Ssheldonh 4087866Ssheldonh#include <ctype.h> 4187866Ssheldonh#include <netdb.h> 4287866Ssheldonh#include <err.h> 4387866Ssheldonh#include <errno.h> 4487866Ssheldonh#include <stdlib.h> 4587866Ssheldonh#include <string.h> 4687866Ssheldonh#include <stdio.h> 4787866Ssheldonh#include <unistd.h> 48126269Stjr#include <ifaddrs.h> 4987866Ssheldonh 5087866Ssheldonh#include <netsmb/netbios.h> 5187866Ssheldonh#include <netsmb/smb_lib.h> 5287866Ssheldonh#include <netsmb/nb_lib.h> 5387866Ssheldonh 5487866Ssheldonhint 5587866Ssheldonhnb_getlocalname(char *name) 5687866Ssheldonh{ 5787866Ssheldonh char buf[1024], *cp; 5887866Ssheldonh 5987866Ssheldonh if (gethostname(buf, sizeof(buf)) != 0) 6087866Ssheldonh return errno; 6187866Ssheldonh cp = strchr(buf, '.'); 6287866Ssheldonh if (cp) 6387866Ssheldonh *cp = 0; 6487866Ssheldonh strcpy(name, buf); 6587866Ssheldonh return 0; 6687866Ssheldonh} 6787866Ssheldonh 6887866Ssheldonhint 69150802Sbpnb_resolvehost_in(const char *name, struct sockaddr **dest, long smbtcpport) 7087866Ssheldonh{ 7187866Ssheldonh struct hostent* h; 7287866Ssheldonh struct sockaddr_in *sinp; 7387866Ssheldonh int len; 7487866Ssheldonh 7587866Ssheldonh h = gethostbyname(name); 7687866Ssheldonh if (!h) { 7787866Ssheldonh warnx("can't get server address `%s': ", name); 7887866Ssheldonh herror(NULL); 7987866Ssheldonh return ENETDOWN; 8087866Ssheldonh } 8187866Ssheldonh if (h->h_addrtype != AF_INET) { 8287866Ssheldonh warnx("address for `%s' is not in the AF_INET family", name); 8387866Ssheldonh return EAFNOSUPPORT; 8487866Ssheldonh } 8587866Ssheldonh if (h->h_length != 4) { 8687866Ssheldonh warnx("address for `%s' has invalid length", name); 8787866Ssheldonh return EAFNOSUPPORT; 8887866Ssheldonh } 8987866Ssheldonh len = sizeof(struct sockaddr_in); 9087866Ssheldonh sinp = malloc(len); 9187866Ssheldonh if (sinp == NULL) 9287866Ssheldonh return ENOMEM; 9387866Ssheldonh bzero(sinp, len); 9487866Ssheldonh sinp->sin_len = len; 9587866Ssheldonh sinp->sin_family = h->h_addrtype; 9687866Ssheldonh memcpy(&sinp->sin_addr.s_addr, h->h_addr, 4); 97150802Sbp sinp->sin_port = htons(smbtcpport); 9887866Ssheldonh *dest = (struct sockaddr*)sinp; 9987866Ssheldonh return 0; 10087866Ssheldonh} 10187866Ssheldonh 10287866Ssheldonhint 10387866Ssheldonhnb_enum_if(struct nb_ifdesc **iflist, int maxif) 10487866Ssheldonh{ 10587866Ssheldonh struct nb_ifdesc *ifd; 106126269Stjr struct ifaddrs *ifp, *p; 107126269Stjr int i; 10887866Ssheldonh 109126269Stjr if (getifaddrs(&ifp) < 0) 11087866Ssheldonh return errno; 11187866Ssheldonh 112126269Stjr *iflist = NULL; 113126269Stjr i = 0; 114126269Stjr for (p = ifp; p; p = p->ifa_next) { 11587866Ssheldonh 116126269Stjr if (i >= maxif) 117126269Stjr break; 118125130Stjr 119126269Stjr if ((p->ifa_addr->sa_family != AF_INET) || 120126269Stjr ((p->ifa_flags & (IFF_UP|IFF_BROADCAST)) 121126269Stjr != (IFF_UP|IFF_BROADCAST))) 122126269Stjr continue; 123126269Stjr if (strlen(p->ifa_name) >= sizeof(ifd->id_name)) 124126269Stjr continue; 12587866Ssheldonh 12687866Ssheldonh ifd = malloc(sizeof(struct nb_ifdesc)); 127126269Stjr if (ifd == NULL) { 128126269Stjr freeifaddrs(ifp); 129126269Stjr /* XXX should free stuff already in *iflist */ 13087866Ssheldonh return ENOMEM; 131126269Stjr } 13287866Ssheldonh bzero(ifd, sizeof(struct nb_ifdesc)); 133126269Stjr strcpy(ifd->id_name, p->ifa_name); 134126269Stjr ifd->id_flags = p->ifa_flags; 135126269Stjr ifd->id_addr = ((struct sockaddr_in *)p->ifa_addr)->sin_addr; 136126269Stjr ifd->id_mask = ((struct sockaddr_in *)p->ifa_netmask)->sin_addr; 13787866Ssheldonh ifd->id_next = *iflist; 13887866Ssheldonh *iflist = ifd; 139126269Stjr i++; 14087866Ssheldonh } 14187866Ssheldonh 142126269Stjr freeifaddrs(ifp); 143126269Stjr return 0; 144126269Stjr} 145126269Stjr 14687866Ssheldonh/*ARGSUSED*/ 14787866Ssheldonh/*int 14887866Ssheldonhnbns_resolvename(const char *name, struct sockaddr **dest) 14987866Ssheldonh{ 15087866Ssheldonh printf("NetBIOS name resolver is not included in this distribution.\n"); 15187866Ssheldonh printf("Please use '-I' option to specify an IP address of server.\n"); 15287866Ssheldonh return EHOSTUNREACH; 15387866Ssheldonh}*/ 15487866Ssheldonh/* 15587866Ssheldonhint 15687866Ssheldonhnb_hostlookup(struct nb_name *np, const char *server, const char *hint, 15787866Ssheldonh struct sockaddr_nb **dst) 15887866Ssheldonh{ 15987866Ssheldonh struct sockaddr_nb *snb; 16087866Ssheldonh int error; 16187866Ssheldonh 16287866Ssheldonh error = nb_sockaddr(NULL, np, &snb); 16387866Ssheldonh if (error) 16487866Ssheldonh return error; 16587866Ssheldonh do { 16687866Ssheldonh if (hint) { 167150802Sbp error = nb_resolvehost_in(host, snb, SMB_TCP_PORT); 16887866Ssheldonh if (error) 16987866Ssheldonh break; 17087866Ssheldonh } else { 17187866Ssheldonh error = nb_resolvename(server); 17287866Ssheldonh } 17387866Ssheldonh } while(0); 17487866Ssheldonh if (!error) { 17587866Ssheldonh *dst = snb; 17687866Ssheldonh } else 17787866Ssheldonh nb_snbfree(snb); 17887866Ssheldonh return error; 17987866Ssheldonh} 180125130Stjr*/ 181