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