nb_net.c revision 87866
1/*
2 * Copyright (c) 2000, Boris Popov
3 * All rights reserved.
4 *
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.
19 *
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.
31 *
32 * $Id: nb_net.c,v 1.4 2001/02/16 02:46:12 bp Exp $
33 */
34#include <sys/param.h>
35#include <sys/socket.h>
36#include <sys/ioctl.h>
37
38#include <net/if.h>
39
40#include <ctype.h>
41#include <netdb.h>
42#include <err.h>
43#include <errno.h>
44#include <stdlib.h>
45#include <string.h>
46#include <stdio.h>
47#include <unistd.h>
48
49#include <netsmb/netbios.h>
50#include <netsmb/smb_lib.h>
51#include <netsmb/nb_lib.h>
52
53int
54nb_getlocalname(char *name)
55{
56	char buf[1024], *cp;
57
58	if (gethostname(buf, sizeof(buf)) != 0)
59		return errno;
60	cp = strchr(buf, '.');
61	if (cp)
62		*cp = 0;
63	strcpy(name, buf);
64	return 0;
65}
66
67int
68nb_resolvehost_in(const char *name, struct sockaddr **dest)
69{
70	struct hostent* h;
71	struct sockaddr_in *sinp;
72	int len;
73
74	h = gethostbyname(name);
75	if (!h) {
76		warnx("can't get server address `%s': ", name);
77		herror(NULL);
78		return ENETDOWN;
79	}
80	if (h->h_addrtype != AF_INET) {
81		warnx("address for `%s' is not in the AF_INET family", name);
82		return EAFNOSUPPORT;
83	}
84	if (h->h_length != 4) {
85		warnx("address for `%s' has invalid length", name);
86		return EAFNOSUPPORT;
87	}
88	len = sizeof(struct sockaddr_in);
89	sinp = malloc(len);
90	if (sinp == NULL)
91		return ENOMEM;
92	bzero(sinp, len);
93	sinp->sin_len = len;
94	sinp->sin_family = h->h_addrtype;
95	memcpy(&sinp->sin_addr.s_addr, h->h_addr, 4);
96	sinp->sin_port = htons(SMB_TCP_PORT);
97	*dest = (struct sockaddr*)sinp;
98	return 0;
99}
100
101int
102nb_enum_if(struct nb_ifdesc **iflist, int maxif)
103{
104	struct ifconf ifc;
105	struct ifreq *ifrqp;
106	struct nb_ifdesc *ifd;
107	struct in_addr iaddr, imask;
108	char *ifrdata, *iname;
109	int s, rdlen, ifcnt, error, iflags, i;
110
111	*iflist = NULL;
112	s = socket(AF_INET, SOCK_DGRAM, 0);
113	if (s == -1)
114		return errno;
115
116	rdlen = maxif * sizeof(struct ifreq);
117	ifrdata = malloc(rdlen);
118	if (ifrdata == NULL) {
119		error = ENOMEM;
120		goto bad;
121	}
122	ifc.ifc_len = rdlen;
123	ifc.ifc_buf = ifrdata;
124	if (ioctl(s, SIOCGIFCONF, &ifc) != 0) {
125		error = errno;
126		goto bad;
127	}
128	ifrqp = ifc.ifc_req;
129	ifcnt = ifc.ifc_len / sizeof(struct ifreq);
130	error = 0;
131	for (i = 0; i < ifcnt; i++, ifrqp++) {
132		if (ioctl(s, SIOCGIFFLAGS, ifrqp) != 0)
133			continue;
134		iflags = ifrqp->ifr_flags;
135		if ((iflags & IFF_UP) == 0 || (iflags & IFF_BROADCAST) == 0)
136			continue;
137
138		if (ioctl(s, SIOCGIFADDR, ifrqp) != 0 ||
139		    ifrqp->ifr_addr.sa_family != AF_INET)
140			continue;
141		iname = ifrqp->ifr_name;
142		if (strlen(iname) >= sizeof(ifd->id_name))
143			continue;
144		iaddr = (*(struct sockaddr_in *)&ifrqp->ifr_addr).sin_addr;
145
146		if (ioctl(s, SIOCGIFNETMASK, ifrqp) != 0)
147			continue;
148		imask = ((struct sockaddr_in *)&ifrqp->ifr_addr)->sin_addr;
149
150		ifd = malloc(sizeof(struct nb_ifdesc));
151		if (ifd == NULL)
152			return ENOMEM;
153		bzero(ifd, sizeof(struct nb_ifdesc));
154		strcpy(ifd->id_name, iname);
155		ifd->id_flags = iflags;
156		ifd->id_addr = iaddr;
157		ifd->id_mask = imask;
158		ifd->id_next = *iflist;
159		*iflist = ifd;
160	}
161bad:
162	free(ifrdata);
163	close(s);
164	return error;
165}
166
167/*ARGSUSED*/
168/*int
169nbns_resolvename(const char *name, struct sockaddr **dest)
170{
171	printf("NetBIOS name resolver is not included in this distribution.\n");
172	printf("Please use '-I' option to specify an IP address of server.\n");
173	return EHOSTUNREACH;
174}*/
175/*
176int
177nb_hostlookup(struct nb_name *np, const char *server, const char *hint,
178	struct sockaddr_nb **dst)
179{
180	struct sockaddr_nb *snb;
181	int error;
182
183	error = nb_sockaddr(NULL, np, &snb);
184	if (error)
185		return error;
186	do {
187		if (hint) {
188			error = nb_resolvehost_in(host, snb);
189			if (error)
190				break;
191		} else {
192			error = nb_resolvename(server);
193		}
194	} while(0);
195	if (!error) {
196		*dst = snb;
197	} else
198		nb_snbfree(snb);
199	return error;
200}
201*/