add EGP
[unix-history] / usr / src / sbin / ifconfig / ifconfig.c
CommitLineData
b3eab9f9 1#ifndef lint
dea973a0 2static char sccsid[] = "@(#)ifconfig.c 4.7 (Berkeley) %G%";
b3eab9f9
SL
3#endif
4
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <sys/ioctl.h>
8
9#include <netinet/in.h>
10#include <net/if.h>
11
12#include <stdio.h>
13#include <errno.h>
14#include <ctype.h>
15#include <netdb.h>
16
17struct ifreq ifr;
18struct sockaddr_in sin = { AF_INET };
19char name[30];
dea973a0 20int setaddr;
b3eab9f9
SL
21int s;
22
23int setifflags(), setifaddr();
24
25struct cmd {
26 char *c_name;
27 int c_parameter;
28 int (*c_func)();
29} cmds[] = {
30 { "up", IFF_UP, setifflags } ,
31 { "down", -IFF_UP, setifflags },
32 { "trailers", -IFF_NOTRAILERS,setifflags },
33 { "-trailers", IFF_NOTRAILERS, setifflags },
1095926d
MK
34 { "arp", -IFF_NOARP, setifflags },
35 { "-arp", IFF_NOARP, setifflags },
dea973a0
MK
36 { "local", IFF_LOCAL, setifflags },
37 { "-local", -IFF_LOCAL, setifflags },
717eb130
CL
38 { "debug", IFF_DEBUG, setifflags },
39 { "-debug", -IFF_DEBUG, setifflags },
a390ced5
SL
40#ifdef notdef
41#define EN_SWABIPS 0x100
42 { "swabips", EN_SWABIPS, setifflags },
43 { "-swabips", -EN_SWABIPS, setifflags },
44#endif
b3eab9f9
SL
45 { 0, 0, setifaddr },
46};
47
48main(argc, argv)
49 int argc;
50 char *argv[];
51{
52
53 if (argc < 2) {
54 fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
55 "[ address ] [ up ] [ down ]",
56 "[ trailers | -trailers ]",
57 "[ arp | -arp ]");
58 exit(1);
59 }
60 s = socket(AF_INET, SOCK_DGRAM, 0);
61 if (s < 0) {
62 perror("ifconfig: socket");
63 exit(1);
64 }
65 argc--, argv++;
66 strcpy(name, *argv);
67 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
68 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
69 Perror("ioctl (SIOCGIFFLAGS)");
70 exit(1);
71 }
b3eab9f9
SL
72 argc--, argv++;
73 if (argc == 0) {
74 status();
75 exit(0);
76 }
77 while (argc > 0) {
78 register struct cmd *p;
79
80 for (p = cmds; p->c_name; p++)
81 if (strcmp(*argv, p->c_name) == 0)
82 break;
83 if (p->c_func)
84 (*p->c_func)(*argv, p->c_parameter);
85 argc--, argv++;
86 }
dea973a0
MK
87 if (setaddr) {
88 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
89 ifr.ifr_addr = *(struct sockaddr *) &sin;
90 if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
91 Perror("ioctl (SIOCSIFADDR)");
92 }
b3eab9f9
SL
93 exit(0);
94}
95
96/*ARGSUSED*/
97setifaddr(addr, param)
98 char *addr;
99 int param;
100{
101
dea973a0
MK
102 getaddr(addr, &sin);
103 /*
104 * Delay the ioctl to set the interface addr until flags are all set.
105 * The address interpretation may depend on the flags,
106 * and the flags may change when the address is set.
a9575a9a 107 */
dea973a0 108 setaddr++;
b3eab9f9
SL
109}
110
2c4ef00e
SL
111setifflags(vname, value)
112 char *vname;
b3eab9f9
SL
113 int value;
114{
115
116 if (value < 0) {
117 value = -value;
dea973a0 118 ifr.ifr_flags &= ~value;
b3eab9f9 119 } else
dea973a0 120 ifr.ifr_flags |= value;
b3eab9f9
SL
121 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
122 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
2c4ef00e 123 Perror(vname);
b3eab9f9
SL
124}
125
126status()
127{
128 struct sockaddr_in *sin;
dea973a0 129 int flags = ifr.ifr_flags;
b3eab9f9
SL
130
131 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
132 if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
133 Perror("ioctl (SIOCGIFADDR)");
134 sin = (struct sockaddr_in *)&ifr.ifr_addr;
135 printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
136#define IFFBITS \
dea973a0
MK
137"\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
138\11LOCAL"
b3eab9f9
SL
139 printb("flags", flags, IFFBITS); putchar('\n');
140}
141
142Perror(cmd)
143 char *cmd;
144{
145 extern int errno;
146
147 fprintf(stderr, "ifconfig: ");
148 switch (errno) {
149
150 case ENXIO:
151 fprintf(stderr, "%s: ", cmd);
152 fprintf(stderr, "no such interface\n");
153 break;
154
155 case EPERM:
156 fprintf(stderr, "%s: permission denied\n");
157 break;
158
159 default:
160 perror(cmd);
161 }
162 exit(1);
163}
164
165struct in_addr inet_makeaddr();
166
167getaddr(s, sin)
168 char *s;
169 struct sockaddr_in *sin;
170{
171 struct hostent *hp;
172 struct netent *np;
173 int val;
174
175 hp = gethostbyname(s);
176 if (hp) {
177 sin->sin_family = hp->h_addrtype;
178 bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
179 return;
180 }
181 np = getnetbyname(s);
182 if (np) {
183 sin->sin_family = np->n_addrtype;
184 sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
185 return;
186 }
187 sin->sin_family = AF_INET;
188 val = inet_addr(s);
189 if (val != -1) {
190 sin->sin_addr.s_addr = val;
191 return;
192 }
193 val = inet_network(s);
194 if (val != -1) {
195 sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
196 return;
197 }
198 fprintf(stderr, "%s: bad value\n", s);
199 exit(1);
200}
201
202/*
203 * Print a value a la the %b format of the kernel's printf
204 */
205printb(s, v, bits)
206 char *s;
207 register char *bits;
208 register unsigned short v;
209{
210 register int i, any = 0;
211 register char c;
212
213 if (bits && *bits == 8)
214 printf("%s=%o", s, v);
215 else
216 printf("%s=%x", s, v);
217 bits++;
218 if (bits) {
219 putchar('<');
220 while (i = *bits++) {
221 if (v & (1 << (i-1))) {
222 if (any)
223 putchar(',');
224 any = 1;
225 for (; (c = *bits) > 32; bits++)
226 putchar(c);
227 } else
228 for (; *bits > 32; bits++)
229 ;
230 }
231 putchar('>');
232 }
233}