From: Klaas Freitag Date: Sat, 11 Dec 1999 13:35:53 +0000 (+0000) Subject: Some patches from Kurt Garloff to handle /etc/networks correctly X-Git-Tag: v1.60~72 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=11e66d4103f90b958c8dee4c8de522aff12ac21c;p=platform%2Fupstream%2Fnet-tools.git 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 :-) --- diff --git a/ifconfig.c b/ifconfig.c index 8bf86ff..1027c72 100644 --- a/ifconfig.c +++ b/ifconfig.c @@ -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, * and others. Copyright 1993 MicroWalt Corporation @@ -41,6 +41,7 @@ /* Ugh. But libc5 doesn't provide POSIX types. */ #include + #ifdef HAVE_HWSLIP #include #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); diff --git a/include/interface.h b/include/interface.h index 133b7d6..8894fca 100644 --- a/include/interface.h +++ b/include/interface.h @@ -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); 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, * 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 + * 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, * 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 - 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);