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 53 int 54 nb_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 67 int 68 nb_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 101 int 102 nb_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 } 161 bad: 162 free(ifrdata); 163 close(s); 164 return error; 165 } 166 167 /*ARGSUSED*/ 168 /*int 169 nbns_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 /* 176 int 177 nb_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 */ 202