* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)ifconfig.c 4.18 (Berkeley) %G%";
struct sockaddr_in sin
= { AF_INET
};
struct sockaddr_in broadaddr
;
struct sockaddr_in netmask
= { AF_INET
};
struct sockaddr_in ipdst
= { AF_INET
};
int setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
int setifmetric(), setifbroadaddr(), setifipdst();
int c_parameter
; /* NEXTARG means next argv */
{ "up", IFF_UP
, setifflags
} ,
{ "down", -IFF_UP
, setifflags
},
{ "trailers", -IFF_NOTRAILERS
,setifflags
},
{ "-trailers", IFF_NOTRAILERS
, setifflags
},
{ "arp", -IFF_NOARP
, setifflags
},
{ "-arp", IFF_NOARP
, setifflags
},
{ "debug", IFF_DEBUG
, setifflags
},
{ "-debug", -IFF_DEBUG
, setifflags
},
#define EN_SWABIPS 0x1000
{ "swabips", EN_SWABIPS
, setifflags
},
{ "-swabips", -EN_SWABIPS
, setifflags
},
{ "netmask", NEXTARG
, setifnetmask
},
{ "metric", NEXTARG
, setifmetric
},
{ "broadcast", NEXTARG
, setifbroadaddr
},
{ "ipdst", NEXTARG
, setifipdst
},
* XNS support liberally adapted from
* code written at the University of Maryland
* principally by James O'Toole and Chris Torek.
int in_status(), in_getaddr();
int xns_status(), xns_getaddr();
/* Known address families */
{ "inet", AF_INET
, in_status
, in_getaddr
},
{ "ns", AF_NS
, xns_status
, xns_getaddr
},
struct afswtch
*afp
; /*the address family being set or asked about*/
fprintf(stderr
, "usage: ifconfig interface\n%s%s%s%s",
"\t[ af [ address [ dest_addr ] ] [ up ] [ down ]",
"\t[ trailers | -trailers ]\n",
strncpy(name
, *argv
, sizeof(name
));
strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
for (myafp
= afp
= afs
; myafp
->af_name
; myafp
++)
if (strcmp(myafp
->af_name
, *argv
) == 0) {
afp
= myafp
; argc
--; argv
++;
af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
s
= socket(af
, SOCK_DGRAM
, 0);
perror("ifconfig: socket");
if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
if (ioctl(s
, SIOCGIFMETRIC
, (caddr_t
)&ifr
) < 0)
perror("ioctl (SIOCGIFMETRIC)");
for (p
= cmds
; p
->c_name
; p
++)
if (strcmp(*argv
, p
->c_name
) == 0)
if (p
->c_name
== 0 && setaddr
)
p
++; /* got src, do dst */
if (p
->c_parameter
== NEXTARG
) {
(*p
->c_func
)(*argv
, p
->c_parameter
);
if ((setmask
|| setaddr
) && (af
== AF_INET
)) {
* If setting the address and not the mask,
* clear any existing mask and the kernel will then
* assign the default. If setting both,
* set the mask first, so the address will be
ifr
.ifr_addr
= *(struct sockaddr
*)&netmask
;
if (ioctl(s
, SIOCSIFNETMASK
, (caddr_t
)&ifr
) < 0)
Perror("ioctl (SIOCSIFNETMASK)");
if (setipdst
&& af
==AF_NS
) {
rq
.rq_ns
= *(struct sockaddr
*) &sin
;
rq
.rq_ip
= *(struct sockaddr
*) &ipdst
;
if (setsockopt(s
, 0, SO_NSIP_ROUTE
, &rq
, size
) < 0)
Perror("Encapsulation Routing");
ifr
.ifr_addr
= *(struct sockaddr
*) &sin
;
if (ioctl(s
, SIOCSIFADDR
, (caddr_t
)&ifr
) < 0)
Perror("ioctl (SIOCSIFADDR)");
ifr
.ifr_addr
= *(struct sockaddr
*)&broadaddr
;
if (ioctl(s
, SIOCSIFBRDADDR
, (caddr_t
)&ifr
) < 0)
Perror("ioctl (SIOCSIFBRDADDR)");
* Delay the ioctl to set the interface addr until flags are all set.
* The address interpretation may depend on the flags,
* and the flags may change when the address is set.
(*afp
->af_getaddr
)(addr
, &sin
);
in_getaddr(addr
, &netmask
);
(*afp
->af_getaddr
)(addr
, &broadaddr
);
in_getaddr(addr
, &ipdst
);
setifdstaddr(addr
, param
)
(*afp
->af_getaddr
)(addr
, &ifr
.ifr_addr
);
if (ioctl(s
, SIOCSIFDSTADDR
, (caddr_t
)&ifr
) < 0)
Perror("ioctl (SIOCSIFDSTADDR)");
if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
if (ioctl(s
, SIOCSIFFLAGS
, (caddr_t
)&ifr
) < 0)
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
ifr
.ifr_metric
= atoi(val
);
if (ioctl(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
perror("ioctl (set metric)");
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
* Print the status of the interface. If an address family was
* specified, show it and it only; otherwise, show them all.
register struct afswtch
*p
= afp
;
short af
= ifr
.ifr_addr
.sa_family
;
printb("flags", flags
, IFFBITS
);
printf(" metric %d", metric
);
} else for (p
= afs
; p
->af_name
; p
++) {
ifr
.ifr_addr
.sa_family
= p
->af_af
;
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
if (ioctl(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
perror("ioctl (SIOCGIFADDR)");
sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
printf("\tinet %s ", inet_ntoa(sin
->sin_addr
));
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
if (ioctl(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
if (errno
!= EADDRNOTAVAIL
)
perror("ioctl (SIOCGIFNETMASK)");
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
((struct sockaddr_in
*)&ifr
.ifr_addr
)->sin_addr
;
if (flags
& IFF_POINTOPOINT
) {
if (ioctl(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
)
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
perror("ioctl (SIOCGIFDSTADDR)");
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
sin
= (struct sockaddr_in
*)&ifr
.ifr_dstaddr
;
printf("--> %s ", inet_ntoa(sin
->sin_addr
));
printf("netmask %x ", ntohl(netmask
.sin_addr
.s_addr
));
if (flags
& IFF_BROADCAST
) {
if (ioctl(s
, SIOCGIFBRDADDR
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
)
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
perror("ioctl (SIOCGIFADDR)");
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
if (sin
->sin_addr
.s_addr
!= 0)
printf("broadcast %s", inet_ntoa(sin
->sin_addr
));
s
= socket(AF_NS
, SOCK_DGRAM
, 0);
if (errno
== EAFNOSUPPORT
)
perror("ifconfig: socket");
if (ioctl(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
perror("ioctl (SIOCGIFADDR)");
strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
sns
= (struct sockaddr_ns
*)&ifr
.ifr_addr
;
printf("\tns %s ", ns_ntoa(sns
->sns_addr
));
if (flags
& IFF_POINTOPOINT
) { /* by W. Nesheim@Cornell */
if (ioctl(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
)
bzero((char *)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
Perror("ioctl (SIOCGIFDSTADDR)");
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
sns
= (struct sockaddr_ns
*)&ifr
.ifr_dstaddr
;
printf("--> %s ", ns_ntoa(sns
->sns_addr
));
fprintf(stderr
, "ifconfig: ");
fprintf(stderr
, "%s: no such interface\n", cmd
);
fprintf(stderr
, "%s: permission denied\n", cmd
);
struct in_addr
inet_makeaddr();
register struct sockaddr_in
*sin
= (struct sockaddr_in
*)saddr
;
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= val
;
sin
->sin_family
= hp
->h_addrtype
;
bcopy(hp
->h_addr
, (char *)&sin
->sin_addr
, hp
->h_length
);
sin
->sin_family
= np
->n_addrtype
;
sin
->sin_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
fprintf(stderr
, "%s: bad value\n", s
);
* Print a value a la the %b format of the kernel's printf
register unsigned short v
;
for (; (c
= *bits
) > 32; bits
++)
for (; *bits
> 32; bits
++)
struct sockaddr_ns
*sns
= (struct sockaddr_ns
*)saddr
;
struct ns_addr
ns_addr();
sns
->sns_addr
= ns_addr(addr
);