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