diff --git a/include/libbb.h b/include/libbb.h index 632ed937d..9ea9f5ae6 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -129,8 +129,8 @@ struct aftype { int af; int alen; char *(*print) (unsigned char *); - char *(*sprint) (struct sockaddr *, int numeric); - int (*input) (int type, char *bufp, struct sockaddr *); + const char *(*sprint) (struct sockaddr *, int numeric); + int (*input) (/*int type,*/ const char *bufp, struct sockaddr *); void (*herror) (char *text); int (*rprint) (int options); int (*rinput) (int typ, int ext, char **argv); @@ -149,7 +149,7 @@ struct hwtype { int type; int alen; char *(*print) (unsigned char *); - int (*input) (char *, struct sockaddr *); + int (*input) (const char *, struct sockaddr *); int (*activate) (int fd); int suppress_null_addr; }; diff --git a/networking/arp.c b/networking/arp.c index 2af6bc970..7a36f44bb 100644 --- a/networking/arp.c +++ b/networking/arp.c @@ -27,8 +27,6 @@ #define DFLT_AF "inet" #define DFLT_HW "ether" -#define _PATH_PROCNET_ARP "/proc/net/arp" - #define ARP_OPT_A (0x1) #define ARP_OPT_p (0x2) #define ARP_OPT_H (0x4) @@ -64,7 +62,7 @@ static const char *const options[] = { /* Called only from main, once */ static int arp_del(char **args) { - char host[128]; + char *host; struct arpreq req; struct sockaddr sa; int flags = 0; @@ -73,8 +71,8 @@ static int arp_del(char **args) memset(&req, 0, sizeof(req)); /* Resolve the host name. */ - safe_strncpy(host, *args, 128); - if (ap->input(0, host, &sa) < 0) { + host = *args; + if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } @@ -130,8 +128,8 @@ static int arp_del(char **args) if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { - safe_strncpy(host, *args, 128); - if (ap->input(0, host, &sa) < 0) { + host = *args; + if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); @@ -213,15 +211,15 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa, /* Called only from main, once */ static int arp_set(char **args) { - char host[128]; + char *host; struct arpreq req; struct sockaddr sa; int flags; memset(&req, 0, sizeof(req)); - safe_strncpy(host, *args++, 128); - if (ap->input(0, host, &sa) < 0) { + host = *args++; + if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } /* If a host has more than one address, use the correct one! */ @@ -285,8 +283,8 @@ static int arp_set(char **args) if (*++args == NULL) bb_show_usage(); if (strcmp(*args, "255.255.255.255") != 0) { - safe_strncpy(host, *args++, 128); - if (ap->input(0, host, &sa) < 0) { + host = *args; + if (ap->input(host, &sa) < 0) { bb_herror_msg_and_die("%s", host); } memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); @@ -362,82 +360,82 @@ arp_disp(const char *name, char *ip, int type, int arp_flags, /* Called only from main, once */ static int arp_show(char *name) { - char host[100]; - struct sockaddr sa; - char ip[100]; - char hwa[100]; - char mask[100]; - char line[200]; - char dev[100]; - int type, flags; - FILE *fp; + const char *host; const char *hostname; + FILE *fp; + struct sockaddr sa; + int type, flags; int num; unsigned entries = 0, shown = 0; + char ip[128]; + char hwa[128]; + char mask[128]; + char line[128]; + char dev[128]; - host[0] = '\0'; - + host = NULL; if (name != NULL) { /* Resolve the host name. */ - safe_strncpy(host, name, (sizeof host)); - if (ap->input(0, host, &sa) < 0) { - bb_herror_msg_and_die("%s", host); + if (ap->input(name, &sa) < 0) { + bb_herror_msg_and_die("%s", name); } - safe_strncpy(host, ap->sprint(&sa, 1), sizeof(host)); + host = xstrdup(ap->sprint(&sa, 1)); } - /* Open the PROCps kernel table. */ - fp = xfopen(_PATH_PROCNET_ARP, "r"); - /* Bypass header -- read until newline */ - if (fgets(line, sizeof(line), fp) != (char *) NULL) { + fp = xfopen("/proc/net/arp", "r"); + /* Bypass header -- read one line */ + fgets(line, sizeof(line), fp); + + /* Read the ARP cache entries. */ + while (fgets(line, sizeof(line), fp)) { + mask[0] = '-'; mask[1] = '\0'; dev[0] = '-'; dev[1] = '\0'; - /* Read the ARP cache entries. */ - for (; fgets(line, sizeof(line), fp);) { - num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n", - ip, &type, &flags, hwa, mask, dev); - if (num < 4) - break; + /* All these strings can't overflow + * because fgets above reads limited amount of data */ + num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n", + ip, &type, &flags, hwa, mask, dev); + if (num < 4) + break; - entries++; - /* if the user specified hw-type differs, skip it */ - if (hw_set && (type != hw->type)) - continue; + entries++; + /* if the user specified hw-type differs, skip it */ + if (hw_set && (type != hw->type)) + continue; - /* if the user specified address differs, skip it */ - if (host[0] && strcmp(ip, host) != 0) - continue; + /* if the user specified address differs, skip it */ + if (host && strcmp(ip, host) != 0) + continue; - /* if the user specified device differs, skip it */ - if (device[0] && strcmp(dev, device) != 0) - continue; + /* if the user specified device differs, skip it */ + if (device[0] && strcmp(dev, device) != 0) + continue; - shown++; - /* This IS ugly but it works -be */ - if (option_mask32 & ARP_OPT_n) + shown++; + /* This IS ugly but it works -be */ + hostname = "?"; + if (!(option_mask32 & ARP_OPT_n)) { + if (ap->input(ip, &sa) < 0) + hostname = ip; + else + hostname = ap->sprint(&sa, (option_mask32 & ARP_OPT_n) | 0x8000); + if (strcmp(hostname, ip) == 0) hostname = "?"; - else { - if (ap->input(0, ip, &sa) < 0) - hostname = ip; - else - hostname = ap->sprint(&sa, (option_mask32 & ARP_OPT_n) | 0x8000); - if (strcmp(hostname, ip) == 0) - hostname = "?"; - } - - arp_disp(hostname, ip, type, flags, hwa, mask, dev); } + + arp_disp(hostname, ip, type, flags, hwa, mask, dev); } if (option_mask32 & ARP_OPT_v) printf("Entries: %d\tSkipped: %d\tFound: %d\n", entries, entries - shown, shown); if (!shown) { - if (hw_set || host[0] || device[0]) + if (hw_set || host || device[0]) printf("No match found in %d entries\n", entries); } - - fclose(fp); - + if (ENABLE_FEATURE_CLEAN_UP) { + free((char*)host); + fclose(fp); + } return 0; } diff --git a/networking/interface.c b/networking/interface.c index c03471238..262b97879 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -82,12 +82,12 @@ struct in6_ifreq { #endif /* Display an Internet socket address. */ -static char *INET_sprint(struct sockaddr *sap, int numeric) +static const char *INET_sprint(struct sockaddr *sap, int numeric) { static char buff[128]; if (sap->sa_family == 0xFFFF || sap->sa_family == 0) - return safe_strncpy(buff, "[NONE SET]", sizeof(buff)); + return "[NONE SET]"; if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, numeric, 0xffffff00) != 0) @@ -96,6 +96,7 @@ static char *INET_sprint(struct sockaddr *sap, int numeric) return buff; } +#ifdef UNUSED_AND_BUGGY static int INET_getsock(char *bufp, struct sockaddr *sap) { char *sp = bufp, *bp; @@ -136,9 +137,12 @@ static int INET_getsock(char *bufp, struct sockaddr *sap) return (sp - bufp); } +#endif -static int INET_input(int type, char *bufp, struct sockaddr *sap) +static int INET_input(/*int type,*/ const char *bufp, struct sockaddr *sap) { + return INET_resolve(bufp, (struct sockaddr_in *) sap, 0); +/* switch (type) { case 1: return (INET_getsock(bufp, sap)); @@ -147,6 +151,7 @@ static int INET_input(int type, char *bufp, struct sockaddr *sap) default: return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0)); } +*/ } static struct aftype inet_aftype = { @@ -163,17 +168,18 @@ static struct aftype inet_aftype = { /* Display an Internet socket address. */ /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ -static char *INET6_sprint(struct sockaddr *sap, int numeric) +static const char *INET6_sprint(struct sockaddr *sap, int numeric) { static char buff[128]; if (sap->sa_family == 0xFFFF || sap->sa_family == 0) - return safe_strncpy(buff, "[NONE SET]", sizeof(buff)); + return "[NONE SET]"; if (INET6_rresolve(buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric)) - return safe_strncpy(buff, "[UNKNOWN]", sizeof(buff)); + return "[UNKNOWN]"; return buff; } +#ifdef UNUSED static int INET6_getsock(char *bufp, struct sockaddr *sap) { struct sockaddr_in6 *sin6; @@ -187,15 +193,19 @@ static int INET6_getsock(char *bufp, struct sockaddr *sap) return 16; /* ?;) */ } +#endif -static int INET6_input(int type, char *bufp, struct sockaddr *sap) +static int INET6_input(/*int type,*/ const char *bufp, struct sockaddr *sap) { + return INET6_resolve(bufp, (struct sockaddr_in6 *) sap); +/* switch (type) { case 1: return (INET6_getsock(bufp, sap)); default: return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap)); } +*/ } static struct aftype inet6_aftype = { @@ -229,12 +239,10 @@ static char *UNSPEC_print(unsigned char *ptr) } /* Display an UNSPEC socket address. */ -static char *UNSPEC_sprint(struct sockaddr *sap, int numeric) +static const char *UNSPEC_sprint(struct sockaddr *sap, int numeric) { - static char buf[64]; - if (sap->sa_family == 0xFFFF || sap->sa_family == 0) - return safe_strncpy(buf, "[NONE SET]", sizeof(buf)); + return "[NONE SET]"; return UNSPEC_print((unsigned char *)sap->sa_data); } @@ -809,7 +817,7 @@ static char *pr_ether(unsigned char *ptr) return buff; } -static int in_ether(char *bufp, struct sockaddr *sap); +static int in_ether(const char *bufp, struct sockaddr *sap); static struct hwtype ether_hwtype = { .name = "ether", @@ -831,10 +839,10 @@ static unsigned hexchar2int(char c) } /* Input an Ethernet address and convert to binary. */ -static int in_ether(char *bufp, struct sockaddr *sap) +static int in_ether(const char *bufp, struct sockaddr *sap) { unsigned char *ptr; - char c, *orig; + char c; int i; unsigned val; @@ -842,7 +850,6 @@ static int in_ether(char *bufp, struct sockaddr *sap) ptr = (unsigned char*) sap->sa_data; i = 0; - orig = bufp; while ((*bufp != '\0') && (i < ETH_ALEN)) { val = hexchar2int(*bufp++) * 0x10; if (val > 0xff) {