|
|
Power 6/32 Unix version 1.21
#ifndef lint
static char sccsid[] = "@(#)ifconfig.c 4.5 (Berkeley) 11/2/83";
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <strings.h>
struct ifreq ifr;
struct sockaddr_in sin = { AF_INET };
char name[30];
int flags;
int s;
int setifflags(), setifaddr();
struct cmd {
char *c_name;
int c_parameter;
int (*c_func)();
} cmds[] = {
{ "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 },
#ifdef notdef
#define EN_SWABIPS 0x100
{ "swabips", EN_SWABIPS, setifflags },
{ "-swabips", -EN_SWABIPS, setifflags },
#endif
{ 0, 0, setifaddr },
};
char *malloc();
/*--------------------------------------------------------
Changes:
. reget the interface flag before setting it (in case
ioctl(SIOCSIFADDR) has already changed the flag.
. add the interface to set the Ethernet station address.
If the interface address is not recognized symbolically
and it is not Internet numeric address and its
syntax is "Ex.x.x.x.x.x", then the address is Ethernet
station address. Also enhance the parsing of Ethernet address.
. fix the format error in Perror().
--------------------------------------------------------*/
main(argc, argv)
int argc;
char *argv[];
{
if (argc < 2) {
fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
"[ address ] [ up ] [ down ]",
"[ trailers | -trailers ]",
"[ arp | -arp ]");
exit(1);
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
perror("ifconfig: socket");
exit(1);
}
argc--, argv++;
strcpy(name, *argv);
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
exit(1);
}
flags = ifr.ifr_flags;
argc--, argv++;
if (argc == 0) {
status();
exit(0);
}
while (argc > 0) {
register struct cmd *p;
for (p = cmds; p->c_name; p++)
if (strcmp(*argv, p->c_name) == 0)
break;
if (p->c_func)
(*p->c_func)(*argv, p->c_parameter);
argc--, argv++;
}
exit(0);
}
/*ARGSUSED*/
setifaddr(addr, param)
char *addr;
int param;
{
register long val;
val = getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr);
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
if (val != 2) {
if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
Perror("ioctl (SIOCSIFADDR)");
}
else { /* Set Ethernet station address */
if (ioctl(s, SIOCSETETADDR, (caddr_t)&ifr) < 0)
Perror("ioctl (SIOCSETADDR)");
}
}
setifflags(vname, value)
char *vname;
int value;
{
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
exit(1);
}
flags = ifr.ifr_flags;
if (value < 0) {
value = -value;
flags &= ~value;
} else
flags |= value;
ifr.ifr_flags = flags;
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
Perror(vname);
}
status()
{
struct sockaddr_in *sin;
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
Perror("ioctl (SIOCGIFADDR)");
sin = (struct sockaddr_in *)&ifr.ifr_addr;
printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
#define IFFBITS \
"\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP"
printb("flags", flags, IFFBITS); putchar('\n');
}
Perror(cmd)
char *cmd;
{
extern int errno;
fprintf(stderr, "ifconfig: ");
switch (errno) {
case ENXIO:
fprintf(stderr, "%s: ", cmd);
fprintf(stderr, "no such interface\n");
break;
case EPERM:
fprintf(stderr, "%s: permission denied\n", cmd);
break;
default:
perror(cmd);
}
exit(1);
}
struct in_addr inet_makeaddr();
getaddr(s, sin)
char *s;
struct sockaddr_in *sin;
{
struct hostent *hp;
struct netent *np;
char *s1;
int val;
hp = gethostbyname(s);
if (hp) {
sin->sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
return(1);
}
np = getnetbyname(s);
if (np) {
sin->sin_family = np->n_addrtype;
sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
return(1);
}
sin->sin_family = AF_INET;
val = inet_addr(s);
if (val != -1) {
sin->sin_addr.s_addr = val;
return(1);
}
val = inet_network(s);
if (val != -1) {
sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
return(1);
}
if ((s[0] == 'E') && (index(s,'.'))) {
char *nxtc;
long lno, ix;
/* Get Ethernet station address */
s1 = malloc((unsigned)(strlen(s)+1));
if (!s1) {
fprintf(stderr,"%s: Ethernet address too long\n",s);
exit(1);
}
strcpy(s1,s); /* save original address for error message */
/* Transform Ea.b.c.d.e.f to a.b.c.d.e.f. for ease of
parsing
*/
strncpy(s,s+1,strlen(s)-1);
s[strlen(s)-1]='.';
for (ix=2; ix<8; ix++) {
char *t;
nxtc = index(s,'.');
if (!nxtc || nxtc==s) {
fprintf(stderr,"%s: bad Ethernet address\n",s1);
exit(1);
}
*nxtc++ = NULL;
for (t=s;*t && t<nxtc; t++) {
if ( !(*t>='0' && *t<='9') &&
!(*t>='a' && *t<='f') &&
!(*t>='A' && *t<='F')) {
fprintf(stderr,
"%s: bad1 Ethernet address\n",s1);
exit(1);
}
}
sscanf(s,"%x",&lno);
sin->sin_zero[ix]=(char)(~(lno & 0xff));
s = nxtc;
}
if (*s) {
fprintf(stderr,"%s: Ethernet address too long\n",s1);
exit(1);
}
#ifdef DEBUG
printf("\nEthernet station address : ");
printf("%x.%x.%x.%x.%x.%x\n",sin->sin_zero[2]&0xff,
sin->sin_zero[3]&0xff,sin->sin_zero[4]&0xff,
sin->sin_zero[5]&0xff,
sin->sin_zero[6]&0xff,sin->sin_zero[7]&0xff);
#endif DEBUG
return(2);
}
fprintf(stderr, "%s: bad value\n", s);
exit(1);
}
/*
* Print a value a la the %b format of the kernel's printf
*/
printb(s, v, bits)
char *s;
register char *bits;
register unsigned short v;
{
register int i, any = 0;
register char c;
if (bits && *bits == 8)
printf("%s=%o", s, v);
else
printf("%s=%x", s, v);
bits++;
if (bits) {
putchar('<');
while (i = *bits++) {
if (v & (1 << (i-1))) {
if (any)
putchar(',');
any = 1;
for (; (c = *bits) > 32; bits++)
putchar(c);
} else
for (; *bits > 32; bits++)
;
}
putchar('>');
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.