]> granicus.if.org Git - sudo/commitdiff
Initial revision
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 2 May 1995 03:31:59 +0000 (03:31 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 2 May 1995 03:31:59 +0000 (03:31 +0000)
interfaces.c [new file with mode: 0644]

diff --git a/interfaces.c b/interfaces.c
new file mode 100644 (file)
index 0000000..530331f
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  CU sudo version 1.3.1
+ *
+ *  This program 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 1, or (at your option)
+ *  any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Please send bugs, changes, problems to sudo-bugs@cs.colorado.edu
+ *
+ *******************************************************************
+ *
+ *  This module contains XXX
+ *
+ *  Todd C. Miller  Mon May  1 20:48:43 MDT 1995
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id$";
+#endif /* lint */
+
+#define MAIN
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif /* STDC_HEADERS */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_MALLOC_H 
+#include <malloc.h>   
+#endif /* HAVE_MALLOC_H */ 
+#include <netdb.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#else
+#include <sys/ioctl.h>
+#endif /* HAVE_SYS_SOCKIO_H */
+#ifdef _ISC
+#include <sys/stream.h>
+#include <sys/sioctl.h>
+#include <sys/stropts.h>
+#include <net/errno.h>
+#define STRSET(cmd, param, len) {strioctl.ic_cmd=(cmd);\
+                  strioctl.ic_dp=(param);\
+                    strioctl.ic_len=(len);}
+#endif /* _ISC */
+#ifdef _MIPS
+#include <net/soioctl.h>
+#endif /* _MIPS */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <sys/param.h>
+
+#include "sudo.h"
+#include "options.h"
+#include "version.h"
+
+#if !defined(STDC_HEADERS) && !defined(__GNUC__)
+extern char *malloc    __P((size_t));
+#endif /* !STDC_HEADERS && !__GNUC__ */
+
+/*
+ * Globals
+ */
+struct interface *interfaces;
+int num_interfaces;
+extern int Argc;
+extern char **Argv;
+
+
+/**********************************************************************
+ *
+ *  load_interfaces()
+ *
+ *  This function sets the interfaces global variable
+ *  and sets the constituent ip addrs and netmasks.
+ */
+
+void load_interfaces()
+{
+    unsigned long localhost_mask;
+    struct ifconf ifconf;
+    struct ifreq ifreq;
+    struct sockaddr_in *sin;
+    char buf[BUFSIZ];
+    int sock, i, j;
+#ifdef _ISC
+    struct ifreq *ifr;
+    struct ifconf *ifc;
+    struct strioctl strioctl;
+#endif /* _ISC */
+
+    /* so we can skip localhost and its ilk */
+    localhost_mask = inet_addr("127.0.0.0");
+
+    sock = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sock < 0) {
+       perror("socket");
+       exit(1);
+    }
+
+    /*
+     * get interface configuration or return (leaving interfaces NULL)
+     */
+    ifconf.ifc_len = sizeof(buf);
+    ifconf.ifc_buf = buf;
+#ifdef _ISC
+    ifc = (struct ifconf *)buf;
+    ifc->ifc_len = sizeof (buf) - sizeof(struct ifconf);
+    STRSET(SIOCGIFCONF, (caddr_t)ifc, sizeof(buf));
+    if (ioctl(sock, I_STR, &strioctl) < 0) {
+       /* networking probably not installed in kernel */
+       return;
+    }
+    ifconf = *ifc;
+
+#else
+    if (ioctl(sock, SIOCGIFCONF, (char *)(&ifconf)) < 0) {
+       /* networking probably not installed in kernel */
+       return;
+    }
+#endif /* _ISC */
+
+    /*
+     * find out how many interfaces exist
+     */
+    num_interfaces = ifconf.ifc_len / sizeof(struct ifreq);
+
+    /*
+     * malloc() space for interfaces array
+     */
+    interfaces = (struct interface *) malloc(sizeof(struct interface) *
+       num_interfaces);
+    if (interfaces == NULL) {
+       perror("malloc");
+       (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+       exit(1);
+    }
+
+    /*
+     * for each interface, get the ip address and netmask
+     */
+#ifdef _ISC
+    ifr = (struct ifreq *)(ifc->ifc_req);
+    for (i = 0, j = 0; i < num_interfaces; i++, ifr++) {
+       (void) strncpy(ifreq.ifr_name, ifr->ifr_name,
+           sizeof(ifr->ifr_name));
+
+       /* get the ip address */
+       STRSET(SIOCGIFADDR, (caddr_t)ifr, sizeof(ifreq));
+       if (ioctl(sock, I_STR, &strioctl) < 0) {
+           /* non-fatal error if interface is down or not supported */
+           if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
+               continue;
+
+           (void) fprintf(stderr, "%s: Error, ioctl: SIOCGIFADDR ", Argv[0]);
+           perror("");
+           exit(1);
+       }
+       sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#else
+    for (i = 0, j = 0; i < num_interfaces; i++) {
+       (void) strncpy(ifreq.ifr_name, ifconf.ifc_req[i].ifr_name,
+           sizeof(ifreq.ifr_name));
+
+       /* get the ip address */
+       if (ioctl(sock, SIOCGIFADDR, (caddr_t)(&ifreq))) {
+           /* non-fatal error if interface is down or not supported */
+           if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
+               continue;
+
+           (void) fprintf(stderr, "%s: Error, ioctl: SIOCGIFADDR ", Argv[0]);
+           perror("");
+           exit(1);
+       }
+       sin = (struct sockaddr_in *)&ifreq.ifr_addr;
+#endif /* _ISC */
+
+       /* make sure we don't have a dupe (usually consecutive) */
+       if (j > 0 && memcmp(&interfaces[j-1].addr, &(sin->sin_addr),
+           sizeof(sin->sin_addr)) == 0)
+           continue;
+
+       /* store the ip address */
+       (void) memcpy(&interfaces[j].addr, &(sin->sin_addr),
+           sizeof(struct in_addr));
+
+       /* get the netmask */
+#ifdef SIOCGIFNETMASK
+       (void) strncpy(ifreq.ifr_name, ifconf.ifc_req[i].ifr_name,
+           sizeof(ifreq.ifr_name));
+       if (ioctl(sock, SIOCGIFNETMASK, (char *)(&ifreq)) == 0) {
+           /* store the netmask */
+           (void) memcpy(&interfaces[j].netmask, &(sin->sin_addr),
+               sizeof(struct in_addr));
+       } else {
+#else
+       {
+#endif /* SIOCGIFNETMASK */
+           if (IN_CLASSC(interfaces[j].addr.s_addr))
+               interfaces[j].netmask.s_addr = htonl(IN_CLASSC_NET);
+           else if (IN_CLASSB(interfaces[j].addr.s_addr))
+               interfaces[j].netmask.s_addr = htonl(IN_CLASSB_NET);
+           else
+               interfaces[j].netmask.s_addr = htonl(IN_CLASSA_NET);
+       }
+
+       /* avoid localhost and friends */
+       if ((interfaces[j].addr.s_addr & interfaces[j].netmask.s_addr) ==
+           localhost_mask)
+           continue;
+
+       ++j;
+    }
+
+    /* if there were bogus entries, realloc the array */
+    if (i != j) {
+       num_interfaces = j;
+       interfaces = (struct interface *) realloc(interfaces,
+           sizeof(struct interface) * num_interfaces);
+       if (interfaces == NULL) {
+           perror("realloc");
+           (void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
+           exit(1);
+       }
+    }
+}