aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKlaas Freitag <freitag@suse.de>1999-12-11 13:35:53 +0000
committerKlaas Freitag <freitag@suse.de>1999-12-11 13:35:53 +0000
commit11e66d4103f90b958c8dee4c8de522aff12ac21c (patch)
treecc7d339357462b6892bcc74e1c1f4abe6588c61f /lib
parentSupport new token ring ARP type (diff)
downloadnet-tools-11e66d4103f90b958c8dee4c8de522aff12ac21c.tar.gz
net-tools-11e66d4103f90b958c8dee4c8de522aff12ac21c.tar.bz2
net-tools-11e66d4103f90b958c8dee4c8de522aff12ac21c.zip
Some patches from Kurt Garloff to handle /etc/networks correctly
Make ifconfig more forgiving when /proc is not mounted Avoid endless recursion when /proc/net/dev is empty :-)
Diffstat (limited to 'lib')
-rw-r--r--lib/inet.c62
-rw-r--r--lib/inet6.c10
-rw-r--r--lib/inet6_sr.c2
-rw-r--r--lib/inet_gr.c8
-rw-r--r--lib/inet_sr.c16
-rw-r--r--lib/interface.c23
6 files changed, 89 insertions, 32 deletions
diff --git a/lib/inet.c b/lib/inet.c
index 29a2969..ae90664 100644
--- a/lib/inet.c
+++ b/lib/inet.c
@@ -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
@@ -51,9 +53,11 @@
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));
}
}
diff --git a/lib/inet6.c b/lib/inet6.c
index 33364b4..26e42c1 100644
--- a/lib/inet6.c
+++ b/lib/inet6.c
@@ -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)
{
diff --git a/lib/inet6_sr.c b/lib/inet6_sr.c
index 84d9cf9..4a0c70e 100644
--- a/lib/inet6_sr.c
+++ b/lib/inet6_sr.c
@@ -34,6 +34,8 @@
#include "intl.h"
#include "net-features.h"
+
+
extern struct aftype inet6_aftype;
static int skfd = -1;
diff --git a/lib/inet_gr.c b/lib/inet_gr.c
index d58fa26..5b7a22a 100644
--- a/lib/inet_gr.c
+++ b/lib/inet_gr.c
@@ -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));
diff --git a/lib/inet_sr.c b/lib/inet_sr.c
index bae2437..3dfa66f 100644
--- a/lib/inet_sr.c
+++ b/lib/inet_sr.c
@@ -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);
}
diff --git a/lib/interface.c b/lib/interface.c
index 57813a9..4c97818 100644
--- a/lib/interface.c
+++ b/lib/interface.c
@@ -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);