* Copyright (c) 1983 Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)ifconfig.c 4.29 (Berkeley) %G%";
#include <netiso/iso_var.h>
struct ifreq ifr
, ridreq
;
struct ifaliasreq addreq
;
struct iso_ifreq iso_ridreq
;
struct iso_aliasreq iso_addreq
;
struct sockaddr_in netmask
;
int setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
int setifmetric(), setifbroadaddr(), setifipdst();
int notealias(), setsnpaoffset(), setnsellength();
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
},
{ "alias", IFF_UP
, notealias
},
{ "-alias", -IFF_UP
, notealias
},
{ "delete", -IFF_UP
, notealias
},
#define EN_SWABIPS 0x1000
{ "swabips", EN_SWABIPS
, setifflags
},
{ "-swabips", -EN_SWABIPS
, setifflags
},
{ "netmask", NEXTARG
, setifnetmask
},
{ "metric", NEXTARG
, setifmetric
},
{ "broadcast", NEXTARG
, setifbroadaddr
},
{ "ipdst", NEXTARG
, setifipdst
},
{ "snpaoffset", NEXTARG
, setsnpaoffset
},
{ "nsellength", NEXTARG
, setnsellength
},
* 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();
int iso_status(), iso_getaddr();
/* Known address families */
#define C(x) ((caddr_t) &x)
{ "inet", AF_INET
, in_status
, in_getaddr
,
SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
{ "ns", AF_NS
, xns_status
, xns_getaddr
,
SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
{ "iso", AF_ISO
, iso_status
, iso_getaddr
,
SIOCDIFADDR_ISO
, SIOCAIFADDR_ISO
, C(iso_ridreq
), C(iso_addreq
) },
struct afswtch
*afp
; /*the address family being set or asked about*/
register struct afswtch
*rafp
;
fprintf(stderr
, "usage: ifconfig interface\n%s%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 (afp
= rafp
= afs
; rafp
->af_name
; rafp
++)
if (strcmp(rafp
->af_name
, *argv
) == 0) {
afp
= rafp
; argc
--; argv
++;
af
= ifr
.ifr_addr
.sa_family
= rafp
->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 (setipdst
&& af
==AF_NS
) {
rq
.rq_ns
= addreq
.ifra_addr
;
rq
.rq_ip
= addreq
.ifra_dstaddr
;
if (setsockopt(s
, 0, SO_NSIP_ROUTE
, &rq
, size
) < 0)
Perror("Encapsulation Routing");
strncpy(rafp
->af_ridreq
, name
, sizeof ifr
.ifr_name
);
if ((ret
= ioctl(s
, rafp
->af_difaddr
, rafp
->af_ridreq
)) < 0) {
if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
/* means no previous address for interface */
Perror("ioctl (SIOCDIFADDR)");
strncpy(rafp
->af_addreq
, name
, sizeof ifr
.ifr_name
);
if (ioctl(s
, rafp
->af_aifaddr
, rafp
->af_addreq
) < 0)
Perror("ioctl (SIOCAIFADDR)");
* 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
, (doalias
>= 0 ? ADDR
: RIDADDR
));
(*afp
->af_getaddr
)(addr
, MASK
);
(*afp
->af_getaddr
)(addr
, DSTADDR
);
in_getaddr(addr
, DSTADDR
);
#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
if (setaddr
&& doalias
== 0 && param
< 0)
bcopy((caddr_t
)rqtosa(af_addreq
),
(caddr_t
)rqtosa(af_ridreq
),
rqtosa(af_addreq
)->sa_len
);
setifdstaddr(addr
, param
)
(*afp
->af_getaddr
)(addr
, DSTADDR
);
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)");
iso_addreq
.ifra_snpaoffset
= atoi(val
);
"\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
== EPROTONOSUPPORT
)
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
));
struct sockaddr_iso
*siso
;
s
= socket(AF_ISO
, SOCK_DGRAM
, 0);
if (errno
== EPROTONOSUPPORT
)
perror("ifconfig: socket");
bzero((caddr_t
)&ifr
, sizeof(ifr
));
strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
if (ioctl(s
, SIOCGIFADDR_ISO
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
bzero((char *)&ifr
.ifr_Addr
, sizeof(ifr
.ifr_Addr
));
perror("ioctl (SIOCGIFADDR_ISO)");
strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
printf("\tiso %s ", iso_ntoa(&siso
->siso_addr
));
if (ioctl(s
, SIOCGIFNETMASK_ISO
, (caddr_t
)&ifr
) < 0) {
if (errno
!= EADDRNOTAVAIL
)
perror("ioctl (SIOCGIFNETMASK_ISO)");
printf(" netmask %s ", iso_ntoa(&siso
->siso_addr
));
if (flags
& IFF_POINTOPOINT
) {
if (ioctl(s
, SIOCGIFDSTADDR_ISO
, (caddr_t
)&ifr
) < 0) {
if (errno
== EADDRNOTAVAIL
)
bzero((char *)&ifr
.ifr_Addr
, sizeof(ifr
.ifr_Addr
));
Perror("ioctl (SIOCGIFDSTADDR_ISO)");
strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
printf("--> %s ", iso_ntoa(&siso
->siso_addr
));
fprintf(stderr
, "ifconfig: ");
fprintf(stderr
, "%s: no such interface\n", cmd
);
fprintf(stderr
, "%s: permission denied\n", cmd
);
struct in_addr
inet_makeaddr();
#define SIN(x) ((struct sockaddr_in *) &(x))
struct sockaddr_in
*sintab
[] = {
SIN(ridreq
.ifr_addr
), SIN(addreq
.ifra_addr
),
SIN(addreq
.ifra_mask
), SIN(addreq
.ifra_broadaddr
)};
register struct sockaddr_in
*sin
= sintab
[which
];
sin
->sin_len
= sizeof(*sin
);
sin
->sin_family
= AF_INET
;
if ((val
= inet_addr(s
)) != -1)
sin
->sin_addr
.s_addr
= val
;
else if (hp
= gethostbyname(s
))
bcopy(hp
->h_addr
, (char *)&sin
->sin_addr
, hp
->h_length
);
else if (np
= getnetbyname(s
))
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
++)
#define SNS(x) ((struct sockaddr_ns *) &(x))
struct sockaddr_ns
*snstab
[] = {
SNS(ridreq
.ifr_addr
), SNS(addreq
.ifra_addr
),
SNS(addreq
.ifra_mask
), SNS(addreq
.ifra_broadaddr
)};
struct sockaddr_ns
*sns
= snstab
[which
];
struct ns_addr
ns_addr();
sns
->sns_len
= sizeof(*sns
);
sns
->sns_addr
= ns_addr(addr
);
printf("Attempt to set XNS netmask will be ineffectual\n");
#define SISO(x) ((struct sockaddr_iso *) &(x))
struct sockaddr_iso
*sisotab
[] = {
SISO(iso_ridreq
.ifr_Addr
), SISO(iso_addreq
.ifra_addr
),
SISO(iso_addreq
.ifra_mask
), SISO(iso_addreq
.ifra_dstaddr
)};
register struct sockaddr_iso
*siso
= sisotab
[which
];
struct iso_addr
*iso_addr();
siso
->siso_addr
= *iso_addr(addr
);
siso
->siso_len
= TSEL(siso
) - (caddr_t
)(siso
);
siso
->siso_len
= sizeof(*siso
);
siso
->siso_family
= AF_ISO
;
fprintf(stderr
, "Negative NSEL length is absurd\n");
if (afp
== 0 || afp
->af_af
!= AF_ISO
) {
fprintf(stderr
, "Setting NSEL length valid only for iso\n");
register struct sockaddr_iso
*s
;
s
->siso_nlen
-= nsellength
;
s
->siso_tlen
= nsellength
;
fixnsel(sisotab
[RIDADDR
]);
fixnsel(sisotab
[DSTADDR
]);