Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: netmask.c
===================================================================
--- netmask.c	(nonexistent)
+++ netmask.c	(revision 5)
@@ -0,0 +1,395 @@
+/*
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   code to query kernel netmask
+
+   Copyright (C) Andrew Tridgell 1998
+
+   Copyright (C) 2011-2014
+   Free Software Foundation, Inc.
+
+   This file is part of the Midnight Commander.
+
+   The Midnight Commander is free software: you can redistribute it
+   and/or modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   The Midnight Commander is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* working out the netmask for an interface is an incredibly non-portable
+   thing. We have several possible implementations below, and autoconf
+   tries each of them to see what works 
+
+   Note that this file does _not_ include includes.h. That is so this code
+   can be called directly from the autoconf tests. That also means
+   this code cannot use any of the normal Samba debug stuff or defines.
+   This is standalone code.
+
+ */
+
+#ifndef AUTOCONF
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_NETMASK_IFCONF
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+/*
+ * Prototype for gcc in fussy mode.
+ */
+
+int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
+
+/****************************************************************************
+  get the netmask address for a local interface
+****************************************************************************/
+int
+get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
+{
+    struct ifconf ifc;
+    char buff[2048];
+    int fd, i, n;
+    struct ifreq *ifr = NULL;
+
+    if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "socket failed\n");
+#endif
+        return -1;
+    }
+
+    ifc.ifc_len = sizeof (buff);
+    ifc.ifc_buf = buff;
+    if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "SIOCGIFCONF failed\n");
+#endif
+        close (fd);
+        return -1;
+    }
+
+    ifr = ifc.ifc_req;
+
+    n = ifc.ifc_len / sizeof (struct ifreq);
+
+#ifdef DEBUG
+    fprintf (stderr, "%d interfaces - looking for %s\n", n, inet_ntoa (*ipaddr));
+#endif
+
+    /* Loop through interfaces, looking for given IP address */
+    for (i = n - 1; i >= 0; i--)
+    {
+        if (ioctl (fd, SIOCGIFADDR, &ifr[i]) != 0)
+        {
+#ifdef DEBUG
+            fprintf (stderr, "SIOCGIFADDR failed\n");
+#endif
+            continue;
+        }
+
+#ifdef DEBUG
+        fprintf (stderr, "interface %s\n",
+                 inet_ntoa ((*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr));
+#endif
+        if (ipaddr->s_addr != (*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr.s_addr)
+        {
+            continue;
+        }
+
+        if (ioctl (fd, SIOCGIFNETMASK, &ifr[i]) != 0)
+        {
+#ifdef DEBUG
+            fprintf (stderr, "SIOCGIFNETMASK failed\n");
+#endif
+            close (fd);
+            return -1;
+        }
+        close (fd);
+        (*nmask) = ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr;
+#ifdef DEBUG
+        fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
+#endif
+        return 0;
+    }
+
+#ifdef DEBUG
+    fprintf (stderr, "interface not found\n");
+#endif
+
+    close (fd);
+    return -1;
+}
+
+#elif defined(HAVE_NETMASK_IFREQ)
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+#ifndef I_STR
+#include <sys/stropts.h>
+#endif
+
+
+/****************************************************************************
+this should cover most of the rest of systems
+****************************************************************************/
+int
+get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
+{
+    struct ifreq ifreq;
+    struct strioctl strioctl;
+    struct ifconf *ifc;
+    char buff[2048];
+    int fd, i, n;
+    struct ifreq *ifr = NULL;
+
+    if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "socket failed\n");
+#endif
+        return -1;
+    }
+
+    ifc = (struct ifconf *) buff;
+    ifc->ifc_len = BUFSIZ - sizeof (struct ifconf);
+    strioctl.ic_cmd = SIOCGIFCONF;
+    strioctl.ic_dp = (char *) ifc;
+    strioctl.ic_len = sizeof (buff);
+    if (ioctl (fd, I_STR, &strioctl) < 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "SIOCGIFCONF failed\n");
+#endif
+        close (fd);
+        return -1;
+    }
+
+    ifr = (struct ifreq *) ifc->ifc_req;
+
+    /* Loop through interfaces, looking for given IP address */
+    n = ifc->ifc_len / sizeof (struct ifreq);
+
+    for (i = 0; i < n; i++, ifr++)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "interface %s\n",
+                 inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr));
+#endif
+        if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
+        {
+            break;
+        }
+    }
+
+#ifdef DEBUG
+    if (i == n)
+    {
+        fprintf (stderr, "interface not found\n");
+        close (fd);
+        return -1;
+    }
+#endif
+
+    ifreq = *ifr;
+
+    strioctl.ic_cmd = SIOCGIFNETMASK;
+    strioctl.ic_dp = (char *) &ifreq;
+    strioctl.ic_len = sizeof (struct ifreq);
+    if (ioctl (fd, I_STR, &strioctl) != 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "Failed SIOCGIFNETMASK\n");
+#endif
+        close (fd);
+        return -1;
+    }
+
+    close (fd);
+    *nmask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr;
+#ifdef DEBUG
+    fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
+#endif
+    return 0;
+}
+
+#elif defined(HAVE_NETMASK_AIX)
+
+#include <stdio.h>
+#include <unistd.h>             /* close() declaration for gcc in fussy mode */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+/*
+ * Prototype for gcc in fussy mode.
+ */
+
+int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
+
+/****************************************************************************
+this one is for AIX
+****************************************************************************/
+
+int
+get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
+{
+    char buff[2048];
+    int fd, i;
+    struct ifconf ifc;
+    struct ifreq *ifr = NULL;
+
+    if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "socket failed\n");
+#endif
+        return -1;
+    }
+
+
+    ifc.ifc_len = sizeof (buff);
+    ifc.ifc_buf = buff;
+
+    if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "SIOCGIFCONF failed\n");
+#endif
+        close (fd);
+        return -1;
+    }
+
+    ifr = ifc.ifc_req;
+    /* Loop through interfaces, looking for given IP address */
+    i = ifc.ifc_len;
+    while (i > 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "interface %s\n",
+                 inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr));
+#endif
+        if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
+        {
+            break;
+        }
+        i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
+        ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
+    }
+
+
+#ifdef DEBUG
+    if (i <= 0)
+    {
+        fprintf (stderr, "interface not found\n");
+        close (fd);
+        return -1;
+    }
+#endif
+
+    if (ioctl (fd, SIOCGIFNETMASK, ifr) != 0)
+    {
+#ifdef DEBUG
+        fprintf (stderr, "SIOCGIFNETMASK failed\n");
+#endif
+        close (fd);
+        return -1;
+    }
+
+    close (fd);
+
+    (*nmask) = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
+#ifdef DEBUG
+    fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
+#endif
+    return 0;
+}
+
+#else /* a dummy version */
+struct in_addr;                 /* it may not have been declared before */
+int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
+int
+get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
+{
+    return -1;
+}
+#endif
+
+
+#ifdef AUTOCONF
+/* this is the autoconf driver to test get_netmask() */
+
+int main ()
+{
+    char buf[1024];
+    struct hostent *hp;
+    struct in_addr ip, nmask;
+
+    if (gethostname (buf, sizeof (buf) - 1) != 0)
+    {
+        fprintf (stderr, "gethostname failed\n");
+        exit (1);
+    }
+
+    hp = gethostbyname (buf);
+
+    if (!hp)
+    {
+        fprintf (stderr, "gethostbyname failed\n");
+        exit (1);
+    }
+
+    memcpy ((char *) &ip, (char *) hp->h_addr, hp->h_length);
+
+    if (get_netmask (&ip, &nmask) == 0)
+        exit (0);
+
+    fprintf (stderr, "get_netmask failed\n");
+    exit (1);
+}
+#endif