summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2004-08-09 03:13:57 +0000
committeryongari <yongari@FreeBSD.org>2004-08-09 03:13:57 +0000
commit2b707fbd8fb9f2858a26eea1d2962ad18c405966 (patch)
treec6d723e3cdd89b4887f0502ec0743f3cab225991 /sbin/ifconfig
parent2f658d62e3282352e7af9201055c13e8ce625da6 (diff)
downloadFreeBSD-src-2b707fbd8fb9f2858a26eea1d2962ad18c405966.zip
FreeBSD-src-2b707fbd8fb9f2858a26eea1d2962ad18c405966.tar.gz
Fix long standing mediaopt setting bugs seen on sparc64. Though
the bug exists in little-endian machine, it was not triggered due to the difference of memory ordering between little/big endian machines. Instead of relying on possibly modified value during function invokcations, use saved copy of ifr.ifr_addr.sa_family. Also add a comment at the top of ifconfig.c clarifying the issue so the bug won't re-appear. Approved by: jake Reviewed by: yar
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r--sbin/ifconfig/ifconfig.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 8070bfe..64e8882 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -94,6 +94,11 @@ static const char rcsid[] =
#define NI_WITHSCOPEID 0
#endif
+/*
+ * Since "struct ifreq" is composed of various union members, callers
+ * should pay special attention to interprete the value.
+ * (.e.g. little/big endian difference in the structure.)
+ */
struct ifreq ifr, ridreq;
struct ifaliasreq addreq;
#ifdef INET6
@@ -653,14 +658,15 @@ end:
int
ifconfig(int argc, char *const *argv, const struct afswtch *afp)
{
- int s;
+ int af, s;
if (afp == NULL)
afp = &afs[0];
- ifr.ifr_addr.sa_family = afp->af_af == AF_LINK ? AF_INET : afp->af_af;
+ af = afp->af_af == AF_LINK ? AF_INET : afp->af_af;
+ ifr.ifr_addr.sa_family = af;
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
- if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+ if ((s = socket(af, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
while (argc > 0) {
@@ -690,7 +696,7 @@ ifconfig(int argc, char *const *argv, const struct afswtch *afp)
argc--, argv++;
}
#ifdef INET6
- if (ifr.ifr_addr.sa_family == AF_INET6 && explicit_prefix == 0) {
+ if (af == AF_INET6 && explicit_prefix == 0) {
/* Aggregatable address architecture defines all prefixes
are 64. So, it is convenient to set prefixlen to 64 if
it is not specified. */
@@ -699,7 +705,7 @@ ifconfig(int argc, char *const *argv, const struct afswtch *afp)
}
#endif
#ifndef NO_IPX
- if (setipdst && ifr.ifr_addr.sa_family == AF_IPX) {
+ if (setipdst && af == AF_IPX) {
struct ipxip_req rq;
int size = sizeof(rq);
@@ -710,7 +716,7 @@ ifconfig(int argc, char *const *argv, const struct afswtch *afp)
Perror("Encapsulation Routing");
}
#endif
- if (ifr.ifr_addr.sa_family == AF_APPLETALK)
+ if (af == AF_APPLETALK)
checkatrange((struct sockaddr_at *) &addreq.ifra_addr);
if (clearaddr) {
if (afp->af_ridreq == NULL || afp->af_difaddr == 0) {
OpenPOWER on IntegriCloud