Some patches from Kurt Garloff to handle /etc/networks correctly
authorKlaas Freitag <freitag@suse.de>
Sat, 11 Dec 1999 13:35:53 +0000 (13:35 +0000)
committerKlaas Freitag <freitag@suse.de>
Sat, 11 Dec 1999 13:35:53 +0000 (13:35 +0000)
Make ifconfig more forgiving when /proc is not mounted

Avoid endless recursion when /proc/net/dev is empty :-)

ifconfig.c
include/interface.h
lib/inet.c
lib/inet6.c
lib/inet6_sr.c
lib/inet_gr.c
lib/inet_sr.c
lib/interface.c

index 8bf86ff..1027c72 100644 (file)
@@ -3,7 +3,7 @@
  *              that either displays or sets the characteristics of
  *              one or more of the system's networking interfaces.
  *
- * Version:     $Id: ifconfig.c,v 1.32 1999/09/28 09:01:49 philip Exp $
+ * Version:     $Id: ifconfig.c,v 1.33 1999/12/11 13:35:53 freitag Exp $
  *
  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  *              and others.  Copyright 1993 MicroWalt Corporation
@@ -41,6 +41,7 @@
 /* Ugh.  But libc5 doesn't provide POSIX types.  */
 #include <asm/types.h>
 
+
 #ifdef HAVE_HWSLIP
 #include <linux/if_slip.h>
 #endif
@@ -364,7 +365,7 @@ static int if_print(char *ifname)
     } else {
        struct interface *ife;
 
-       ife = lookup_interface(ifname);
+       ife = lookup_interface(ifname,1);
        res = do_if_fetch(ife); 
        if (res >= 0) 
            ife_print(ife);
index 133b7d6..8894fca 100644 (file)
@@ -66,7 +66,7 @@ extern int if_fetch(struct interface *ife);
 
 extern int for_all_interfaces(int (*)(struct interface *, void *), void *);
 extern int free_interface_list(void);
-extern struct interface *lookup_interface(char *name);
+extern struct interface *lookup_interface(char *name, int readlist);
 extern int if_readlist(void);
 
 extern int do_if_fetch(struct interface *ife);
index 29a2969..ae90664 100644 (file)
@@ -3,7 +3,7 @@
  *              support functions for the net-tools.
  *              (NET-3 base distribution).
  *
- * Version:    $Id: inet.c,v 1.12 1999/06/12 23:04:18 philip Exp $
+ * Version:    $Id: inet.c,v 1.13 1999/12/11 13:35:56 freitag Exp $
  *
  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  *              Copyright 1993 MicroWalt Corporation
@@ -17,6 +17,8 @@
  *960329 {1.26} Bernd Eckenfels :       resolve 255.255.255.255 
  *980101 {1.27} Bernd Eckenfels :      resolve raw sockets in /etc/protocols
  *990302 {1.28} Phil Blundell   :       add netmask to INET_rresolve
+ *991007        Kurt Garloff   :       rresolve, resolve: may be hosts
+ *             <garloff@suse.de>       store type (host?) in cache 
  *
  *              This program is free software; you can redistribute it
  *              and/or  modify it under  the terms of  the GNU General
 
 extern int h_errno;            /* some netdb.h versions don't export this */
 
+/* cache */
 struct addr {
     struct sockaddr_in addr;
     char *name;
+    int host;
     struct addr *next;
 };
 
@@ -70,7 +74,7 @@ static struct service *tcp_name = NULL, *udp_name = NULL, *raw_name = NULL;
 static struct addr *INET_nn = NULL;    /* addr-to-name cache           */
 
 
-static int INET_resolve(char *name, struct sockaddr_in *sin)
+static int INET_resolve(char *name, struct sockaddr_in *sin, int hostfirst)
 {
     struct hostent *hp;
     struct netent *np;
@@ -88,16 +92,37 @@ static int INET_resolve(char *name, struct sockaddr_in *sin)
     if (inet_aton(name, &sin->sin_addr)) {
        return 0;
     }
+    /* If we expect this to be a hostname, try hostname database first */
+#ifdef DEBUG
+    if (hostfirst) fprintf (stderr, "gethostbyname (%s)\n", name);
+#endif
+    if (hostfirst && 
+       (hp = gethostbyname(name)) != (struct hostent *) NULL) {
+       memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], 
+               sizeof(struct in_addr));
+       return 0;
+    }
     /* Try the NETWORKS database to see if this is a known network. */
+#ifdef DEBUG
+    fprintf (stderr, "getnetbyname (%s)\n", name);
+#endif
     if ((np = getnetbyname(name)) != (struct netent *) NULL) {
        sin->sin_addr.s_addr = htonl(np->n_net);
        return 1;
     }
+    if (hostfirst) {
+       /* Don't try again */
+       errno = h_errno;
+       return -1;
+    }
 #ifdef DEBUG
     res_init();
     _res.options |= RES_DEBUG;
 #endif
 
+#ifdef DEBUG
+    fprintf (stderr, "gethostbyname (%s)\n", name);
+#endif
     if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
        errno = h_errno;
        return -1;
@@ -109,6 +134,10 @@ static int INET_resolve(char *name, struct sockaddr_in *sin)
 }
 
 
+/* numeric: & 0x8000: default instead of *, 
+ *         & 0x4000: host instead of net, 
+ *         & 0x0fff: don't resolve
+ */
 static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin, 
                         int numeric, unsigned int netmask)
 {
@@ -116,6 +145,7 @@ static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
     struct netent *np;
     struct addr *pn;
     unsigned long ad, host_ad;
+    int host = 0;
 
     /* Grmpf. -FvK */
     if (sin->sin_family != AF_INET) {
@@ -126,8 +156,11 @@ static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
        return (-1);
     }
     ad = (unsigned long) sin->sin_addr.s_addr;
+#ifdef DEBUG
+    fprintf (stderr, "rresolve: %08lx, mask %08x, num %08x \n", ad, netmask, numeric);
+#endif
     if (ad == INADDR_ANY) {
-       if ((numeric & 0x7FFF) == 0) {
+       if ((numeric & 0x0FFF) == 0) {
            if (numeric & 0x8000)
                safe_strncpy(name, "default", len);
            else
@@ -135,17 +168,23 @@ static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
            return (0);
        }
     }
-    if (numeric & 0x7FFF) {
+    if (numeric & 0x0FFF) {
         safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
        return (0);
     }
+
+    if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
+       host = 1;
 #if 0
     INET_nn = NULL;
 #endif
     pn = INET_nn;
     while (pn != NULL) {
-       if (pn->addr.sin_addr.s_addr == ad) {
+       if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
            safe_strncpy(name, pn->name, len);
+#ifdef DEBUG
+           fprintf (stderr, "rresolve: found %s %08lx in cache\n", (host? "host": "net"), ad);
+#endif
            return (0);
        }
        pn = pn->next;
@@ -154,11 +193,17 @@ static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
     host_ad = ntohl(ad);
     np = NULL;
     ent = NULL;
-    if ((ad & (~ netmask)) != 0) {
+    if (host) {
+#ifdef DEBUG
+       fprintf (stderr, "gethostbyaddr (%08lx)\n", ad);
+#endif
        ent = gethostbyaddr((char *) &ad, 4, AF_INET);
        if (ent != NULL)
            safe_strncpy(name, ent->h_name, len);
     } else {
+#ifdef DEBUG
+       fprintf (stderr, "getnetbyaddr (%08lx)\n", host_ad);
+#endif
        np = getnetbyaddr(host_ad, AF_INET);
        if (np != NULL)
            safe_strncpy(name, np->n_name, len);
@@ -168,6 +213,7 @@ static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
     pn = (struct addr *) malloc(sizeof(struct addr));
     pn->addr = *sin;
     pn->next = INET_nn;
+    pn->host = host;
     pn->name = (char *) malloc(strlen(name) + 1);
     strcpy(pn->name, name);
     INET_nn = pn;
@@ -264,8 +310,10 @@ static int INET_input(int type, char *bufp, struct sockaddr *sap)
     switch (type) {
     case 1:
        return (INET_getsock(bufp, sap));
+    case 256:
+       return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
     default:
-       return (INET_resolve(bufp, (struct sockaddr_in *) sap));
+       return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
     }
 }
 
index 33364b4..26e42c1 100644 (file)
@@ -3,7 +3,7 @@
  *              support functions for the net-tools.
  *              (most of it copied from lib/inet.c 1.26).
  *
- * Version:     $Id: inet6.c,v 1.8 1999/08/24 16:47:24 ecki Exp $
+ * Version:     $Id: inet6.c,v 1.9 1999/12/11 13:35:57 freitag Exp $
  *
  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  *              Copyright 1993 MicroWalt Corporation
@@ -52,7 +52,7 @@ static int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
     memset (&req, '\0', sizeof req);
     req.ai_family = AF_INET6;
     if ((s = getaddrinfo(name, NULL, &req, &ai))) {
-       fprintf(stderr, "getaddrinfo: %s: %s\n", name, gai_strerror(s));
+       fprintf(stderr, "getaddrinfo: %s: %d\n", name, s);
        return -1;
     }
     memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
@@ -62,6 +62,12 @@ static int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
     return (0);
 }
 
+#ifndef IN6_IS_ADDR_UNSPECIFIED
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+        (((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
+         ((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
+#endif
+
 
 static int INET6_rresolve(char *name, struct sockaddr_in6 *sin6, int numeric)
 {
index 84d9cf9..4a0c70e 100644 (file)
@@ -34,6 +34,8 @@
 #include "intl.h"
 #include "net-features.h"
 
+
+
 extern struct aftype inet6_aftype;
 
 static int skfd = -1;
index d58fa26..5b7a22a 100644 (file)
@@ -1,9 +1,11 @@
 /*
-   $Id: inet_gr.c,v 1.11 1999/03/02 21:09:15 philip Exp $
+   $Id: inet_gr.c,v 1.12 1999/12/11 13:35:58 freitag Exp $
 
    Modifications:
    1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
    1999-01-01 - Bernd Eckenfels          - fixed the routing cache printouts
+   1999-10-07 - Kurt Garloff <garloff@suse.de> - do host (instead of network) name
+                                               lookup for gws and hosts
  */
 
 #include "config.h"
@@ -105,11 +107,11 @@ int rprint_fib(int ext, int numeric)
        
        sin_netmask = (struct sockaddr_in *)&snet_mask;
        strcpy(net_addr, INET_sprintmask(&snet_target, 
-                                        (numeric | 0x8000),
+                                        (numeric | 0x8000 | (iflags & RTF_HOST? 0x4000: 0)),
                                         sin_netmask->sin_addr.s_addr));
        net_addr[15] = '\0';
 
-       strcpy(gate_addr, inet_aftype.sprint(&snet_gateway, numeric));
+       strcpy(gate_addr, inet_aftype.sprint(&snet_gateway, numeric | 0x4000));
        gate_addr[15] = '\0';
 
        strcpy(mask_addr, inet_aftype.sprint(&snet_mask, 1));
index bae2437..3dfa66f 100644 (file)
@@ -1,6 +1,8 @@
 /*
    Modifications:
    1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
+   1999-10-07 - Kurt Garloff            - for -host and gws: prefer host names
+                                               over networks (or even reject)
  */
 
 #include "config.h"
@@ -92,21 +94,17 @@ static int INET_setroute(int action, int options, char **args)
            rt.rt_genmask = full_mask(mask.d);
     }
 
-    if ((isnet = inet_aftype.input(0, target, &rt.rt_dst)) < 0) {
+    /* Prefer hostname lookup is -host flag was given */
+    if ((isnet = inet_aftype.input((xflag!=2? 0: 256), target, &rt.rt_dst)) < 0) {
        inet_aftype.herror(target);
        return (1);
     }
     switch (xflag) {
     case 1:
-       isnet = 1;
-       break;
-
+       isnet = 1; break;
     case 2:
-       isnet = 0;
-       break;
-
+       isnet = 0; break;
     default:
-       break;
     }
 
     /* Fill in the other fields. */
@@ -152,7 +150,7 @@ static int INET_setroute(int action, int options, char **args)
            if (rt.rt_flags & RTF_GATEWAY)
                return (usage());
            safe_strncpy(gateway, *args, (sizeof gateway));
-           if ((isnet = inet_aftype.input(0, gateway, &rt.rt_gateway)) < 0) {
+           if ((isnet = inet_aftype.input(256, gateway, &rt.rt_gateway)) < 0) {
                inet_aftype.herror(gateway);
                return (E_LOOKUP);
            }
index 57813a9..4c97818 100644 (file)
@@ -4,7 +4,7 @@
    10/1998 partly rewriten by Andi Kleen to support an interface list.   
    I don't claim that the list operations are efficient @).  
 
-   $Id: interface.c,v 1.6 1999/09/27 00:36:16 freitag Exp $
+   $Id: interface.c,v 1.7 1999/12/11 13:35:59 freitag Exp $
  */
 
 #include "config.h"
@@ -65,15 +65,15 @@ void add_interface(struct interface *n)
     (*pp) = n;
 }
 
-struct interface *lookup_interface(char *name)
+struct interface *lookup_interface(char *name, int readlist)
 {
     struct interface *ife = NULL;
 
-    if (int_list || if_readlist() >= 0) { 
-       for (ife = int_list; ife; ife = ife->next) {
-           if (!strcmp(ife->name, name))
-               break;
-       }
+    if (int_list || (readlist && if_readlist() >= 0)) {
+               for (ife = int_list; ife; ife = ife->next) {
+               if (!strcmp(ife->name, name))
+                       break;
+               }
     }
 
     if (!ife) { 
@@ -148,7 +148,7 @@ static int if_readconf(void)
 
     ifr = ifc.ifc_req;
     for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
-       lookup_interface(ifr->ifr_name);
+       lookup_interface(ifr->ifr_name,0);
        ifr++;
     }
     err = 0;
@@ -267,9 +267,10 @@ int if_readlist(void)
 
     fh = fopen(_PATH_PROCNET_DEV, "r");
     if (!fh) {
-       perror(_PATH_PROCNET_DEV);
-       return -1;
-    }
+               fprintf(stderr, _("Warning: cannot open %s (%s). Limited output.\n"),
+                       _PATH_PROCNET_DEV, strerror(errno)); 
+               return if_readconf();
+       }       
     fgets(buf, sizeof buf, fh);        /* eat line */
     fgets(buf, sizeof buf, fh);