root/src/vfs/smbfs/helpers/lib/netmask.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. get_netmask
  2. get_netmask
  3. get_netmask
  4. get_netmask
  5. main

   1 /*
   2    Unix SMB/Netbios implementation.
   3    Version 1.9.
   4    code to query kernel netmask
   5 
   6    Copyright (C) Andrew Tridgell 1998
   7 
   8    Copyright (C) 2011-2019
   9    Free Software Foundation, Inc.
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  25  */
  26 
  27 
  28 /* working out the netmask for an interface is an incredibly non-portable
  29    thing. We have several possible implementations below, and autoconf
  30    tries each of them to see what works 
  31 
  32    Note that this file does _not_ include includes.h. That is so this code
  33    can be called directly from the autoconf tests. That also means
  34    this code cannot use any of the normal Samba debug stuff or defines.
  35    This is standalone code.
  36 
  37  */
  38 
  39 #ifndef AUTOCONF
  40 #include "config.h"
  41 #endif
  42 
  43 #include <stdlib.h>
  44 #include <string.h>
  45 
  46 #ifdef HAVE_NETMASK_IFCONF
  47 
  48 #include <stdio.h>
  49 #include <unistd.h>
  50 #include <sys/types.h>
  51 #include <sys/socket.h>
  52 #include <netinet/in.h>
  53 #include <arpa/inet.h>
  54 #include <netdb.h>
  55 #include <sys/ioctl.h>
  56 #include <net/if.h>
  57 
  58 #ifndef SIOCGIFCONF
  59 #include <sys/sockio.h>
  60 #endif
  61 
  62 /*
  63  * Prototype for gcc in fussy mode.
  64  */
  65 
  66 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
  67 
  68 /****************************************************************************
  69   get the netmask address for a local interface
  70 ****************************************************************************/
  71 int
  72 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
     /* [previous][next][first][last][top][bottom][index][help]  */
  73 {
  74     struct ifconf ifc;
  75     char buff[2048];
  76     int fd, i, n;
  77     struct ifreq *ifr = NULL;
  78 
  79     if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
  80     {
  81 #ifdef DEBUG
  82         fprintf (stderr, "socket failed\n");
  83 #endif
  84         return -1;
  85     }
  86 
  87     ifc.ifc_len = sizeof (buff);
  88     ifc.ifc_buf = buff;
  89     if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
  90     {
  91 #ifdef DEBUG
  92         fprintf (stderr, "SIOCGIFCONF failed\n");
  93 #endif
  94         close (fd);
  95         return -1;
  96     }
  97 
  98     ifr = ifc.ifc_req;
  99 
 100     n = ifc.ifc_len / sizeof (struct ifreq);
 101 
 102 #ifdef DEBUG
 103     fprintf (stderr, "%d interfaces - looking for %s\n", n, inet_ntoa (*ipaddr));
 104 #endif
 105 
 106     /* Loop through interfaces, looking for given IP address */
 107     for (i = n - 1; i >= 0; i--)
 108     {
 109         if (ioctl (fd, SIOCGIFADDR, &ifr[i]) != 0)
 110         {
 111 #ifdef DEBUG
 112             fprintf (stderr, "SIOCGIFADDR failed\n");
 113 #endif
 114             continue;
 115         }
 116 
 117 #ifdef DEBUG
 118         fprintf (stderr, "interface %s\n",
 119                  inet_ntoa ((*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr));
 120 #endif
 121         if (ipaddr->s_addr != (*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr.s_addr)
 122         {
 123             continue;
 124         }
 125 
 126         if (ioctl (fd, SIOCGIFNETMASK, &ifr[i]) != 0)
 127         {
 128 #ifdef DEBUG
 129             fprintf (stderr, "SIOCGIFNETMASK failed\n");
 130 #endif
 131             close (fd);
 132             return -1;
 133         }
 134         close (fd);
 135         (*nmask) = ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr;
 136 #ifdef DEBUG
 137         fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
 138 #endif
 139         return 0;
 140     }
 141 
 142 #ifdef DEBUG
 143     fprintf (stderr, "interface not found\n");
 144 #endif
 145 
 146     close (fd);
 147     return -1;
 148 }
 149 
 150 #elif defined(HAVE_NETMASK_IFREQ)
 151 
 152 #include <stdio.h>
 153 #include <sys/types.h>
 154 #include <sys/socket.h>
 155 #include <netinet/in.h>
 156 #include <arpa/inet.h>
 157 #include <netdb.h>
 158 #include <sys/ioctl.h>
 159 #include <net/if.h>
 160 
 161 #ifndef SIOCGIFCONF
 162 #include <sys/sockio.h>
 163 #endif
 164 
 165 #ifndef I_STR
 166 #include <sys/stropts.h>
 167 #endif
 168 
 169 
 170 /****************************************************************************
 171 this should cover most of the rest of systems
 172 ****************************************************************************/
 173 int
 174 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
     /* [previous][next][first][last][top][bottom][index][help]  */
 175 {
 176     struct ifreq ifreq;
 177     struct strioctl strioctl;
 178     struct ifconf *ifc;
 179     char buff[2048];
 180     int fd, i, n;
 181     struct ifreq *ifr = NULL;
 182 
 183     if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
 184     {
 185 #ifdef DEBUG
 186         fprintf (stderr, "socket failed\n");
 187 #endif
 188         return -1;
 189     }
 190 
 191     ifc = (struct ifconf *) buff;
 192     ifc->ifc_len = BUFSIZ - sizeof (struct ifconf);
 193     strioctl.ic_cmd = SIOCGIFCONF;
 194     strioctl.ic_dp = (char *) ifc;
 195     strioctl.ic_len = sizeof (buff);
 196     if (ioctl (fd, I_STR, &strioctl) < 0)
 197     {
 198 #ifdef DEBUG
 199         fprintf (stderr, "SIOCGIFCONF failed\n");
 200 #endif
 201         close (fd);
 202         return -1;
 203     }
 204 
 205     ifr = (struct ifreq *) ifc->ifc_req;
 206 
 207     /* Loop through interfaces, looking for given IP address */
 208     n = ifc->ifc_len / sizeof (struct ifreq);
 209 
 210     for (i = 0; i < n; i++, ifr++)
 211     {
 212 #ifdef DEBUG
 213         fprintf (stderr, "interface %s\n",
 214                  inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr));
 215 #endif
 216         if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
 217         {
 218             break;
 219         }
 220     }
 221 
 222 #ifdef DEBUG
 223     if (i == n)
 224     {
 225         fprintf (stderr, "interface not found\n");
 226         close (fd);
 227         return -1;
 228     }
 229 #endif
 230 
 231     ifreq = *ifr;
 232 
 233     strioctl.ic_cmd = SIOCGIFNETMASK;
 234     strioctl.ic_dp = (char *) &ifreq;
 235     strioctl.ic_len = sizeof (struct ifreq);
 236     if (ioctl (fd, I_STR, &strioctl) != 0)
 237     {
 238 #ifdef DEBUG
 239         fprintf (stderr, "Failed SIOCGIFNETMASK\n");
 240 #endif
 241         close (fd);
 242         return -1;
 243     }
 244 
 245     close (fd);
 246     *nmask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr;
 247 #ifdef DEBUG
 248     fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
 249 #endif
 250     return 0;
 251 }
 252 
 253 #elif defined(HAVE_NETMASK_AIX)
 254 
 255 #include <stdio.h>
 256 #include <unistd.h>             /* close() declaration for gcc in fussy mode */
 257 #include <sys/types.h>
 258 #include <sys/socket.h>
 259 #include <netinet/in.h>
 260 #include <arpa/inet.h>
 261 #include <netdb.h>
 262 #include <sys/ioctl.h>
 263 #include <net/if.h>
 264 
 265 #ifndef SIOCGIFCONF
 266 #include <sys/sockio.h>
 267 #endif
 268 
 269 /*
 270  * Prototype for gcc in fussy mode.
 271  */
 272 
 273 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
 274 
 275 /****************************************************************************
 276 this one is for AIX
 277 ****************************************************************************/
 278 
 279 int
 280 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
     /* [previous][next][first][last][top][bottom][index][help]  */
 281 {
 282     char buff[2048];
 283     int fd, i;
 284     struct ifconf ifc;
 285     struct ifreq *ifr = NULL;
 286 
 287     if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
 288     {
 289 #ifdef DEBUG
 290         fprintf (stderr, "socket failed\n");
 291 #endif
 292         return -1;
 293     }
 294 
 295 
 296     ifc.ifc_len = sizeof (buff);
 297     ifc.ifc_buf = buff;
 298 
 299     if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
 300     {
 301 #ifdef DEBUG
 302         fprintf (stderr, "SIOCGIFCONF failed\n");
 303 #endif
 304         close (fd);
 305         return -1;
 306     }
 307 
 308     ifr = ifc.ifc_req;
 309     /* Loop through interfaces, looking for given IP address */
 310     i = ifc.ifc_len;
 311     while (i > 0)
 312     {
 313 #ifdef DEBUG
 314         fprintf (stderr, "interface %s\n",
 315                  inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr));
 316 #endif
 317         if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
 318         {
 319             break;
 320         }
 321         i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
 322         ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
 323     }
 324 
 325 
 326 #ifdef DEBUG
 327     if (i <= 0)
 328     {
 329         fprintf (stderr, "interface not found\n");
 330         close (fd);
 331         return -1;
 332     }
 333 #endif
 334 
 335     if (ioctl (fd, SIOCGIFNETMASK, ifr) != 0)
 336     {
 337 #ifdef DEBUG
 338         fprintf (stderr, "SIOCGIFNETMASK failed\n");
 339 #endif
 340         close (fd);
 341         return -1;
 342     }
 343 
 344     close (fd);
 345 
 346     (*nmask) = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
 347 #ifdef DEBUG
 348     fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
 349 #endif
 350     return 0;
 351 }
 352 
 353 #else /* a dummy version */
 354 struct in_addr;                 /* it may not have been declared before */
 355 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
 356 int
 357 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
     /* [previous][next][first][last][top][bottom][index][help]  */
 358 {
 359     return -1;
 360 }
 361 #endif
 362 
 363 
 364 #ifdef AUTOCONF
 365 /* this is the autoconf driver to test get_netmask() */
 366 
 367 main ()
     /* [previous][next][first][last][top][bottom][index][help]  */
 368 {
 369     char buf[1024];
 370     struct hostent *hp;
 371     struct in_addr ip, nmask;
 372 
 373     if (gethostname (buf, sizeof (buf) - 1) != 0)
 374     {
 375         fprintf (stderr, "gethostname failed\n");
 376         exit (1);
 377     }
 378 
 379     hp = gethostbyname (buf);
 380 
 381     if (!hp)
 382     {
 383         fprintf (stderr, "gethostbyname failed\n");
 384         exit (1);
 385     }
 386 
 387     memcpy ((char *) &ip, (char *) hp->h_addr, hp->h_length);
 388 
 389     if (get_netmask (&ip, &nmask) == 0)
 390         exit (0);
 391 
 392     fprintf (stderr, "get_netmask failed\n");
 393     exit (1);
 394 }
 395 #endif

/* [previous][next][first][last][top][bottom][index][help]  */