Add copyright
[unix-history] / usr / src / sbin / ifconfig / ifconfig.c
CommitLineData
b3eab9f9 1#ifndef lint
375a8436 2static char sccsid[] = "@(#)ifconfig.c 4.10 (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
40a42b7f 23int setifflags(), setifaddr(), setifdstaddr();
b3eab9f9
SL
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 45 { 0, 0, setifaddr },
40a42b7f 46 { 0, 0, setifdstaddr },
b3eab9f9
SL
47};
48
49main(argc, argv)
50 int argc;
51 char *argv[];
52{
53
54 if (argc < 2) {
55 fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
40a42b7f 56 "[ address [ dest_addr ] ] [ up ] [ down ]",
b3eab9f9
SL
57 "[ trailers | -trailers ]",
58 "[ arp | -arp ]");
59 exit(1);
60 }
61 s = socket(AF_INET, SOCK_DGRAM, 0);
62 if (s < 0) {
63 perror("ifconfig: socket");
64 exit(1);
65 }
66 argc--, argv++;
67 strcpy(name, *argv);
68 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
69 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
70 Perror("ioctl (SIOCGIFFLAGS)");
71 exit(1);
72 }
b3eab9f9
SL
73 argc--, argv++;
74 if (argc == 0) {
75 status();
76 exit(0);
77 }
78 while (argc > 0) {
79 register struct cmd *p;
80
81 for (p = cmds; p->c_name; p++)
82 if (strcmp(*argv, p->c_name) == 0)
83 break;
40a42b7f
TF
84 if (p->c_name == 0 && setaddr)
85 p++; /* got src, do dst */
b3eab9f9
SL
86 if (p->c_func)
87 (*p->c_func)(*argv, p->c_parameter);
88 argc--, argv++;
89 }
dea973a0
MK
90 if (setaddr) {
91 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
92 ifr.ifr_addr = *(struct sockaddr *) &sin;
93 if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
94 Perror("ioctl (SIOCSIFADDR)");
95 }
b3eab9f9
SL
96 exit(0);
97}
98
99/*ARGSUSED*/
100setifaddr(addr, param)
101 char *addr;
102 int param;
103{
104
dea973a0
MK
105 getaddr(addr, &sin);
106 /*
107 * Delay the ioctl to set the interface addr until flags are all set.
108 * The address interpretation may depend on the flags,
109 * and the flags may change when the address is set.
a9575a9a 110 */
dea973a0 111 setaddr++;
b3eab9f9
SL
112}
113
40a42b7f
TF
114/*ARGSUSED*/
115setifdstaddr(addr, param)
116 char *addr;
117 int param;
118{
375a8436 119 int flags = ifr.ifr_flags;
40a42b7f
TF
120
121 getaddr(addr, (struct sockaddr_in *)&ifr.ifr_dstaddr);
122 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
123 if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
124 Perror("ioctl (SIOCSIFDSTADDR)");
375a8436 125 ifr.ifr_flags = flags;
40a42b7f
TF
126}
127
2c4ef00e
SL
128setifflags(vname, value)
129 char *vname;
b3eab9f9
SL
130 int value;
131{
132
133 if (value < 0) {
134 value = -value;
dea973a0 135 ifr.ifr_flags &= ~value;
b3eab9f9 136 } else
dea973a0 137 ifr.ifr_flags |= value;
b3eab9f9
SL
138 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
139 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
2c4ef00e 140 Perror(vname);
b3eab9f9
SL
141}
142
143status()
144{
145 struct sockaddr_in *sin;
dea973a0 146 int flags = ifr.ifr_flags;
b3eab9f9
SL
147
148 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
149 if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
150 Perror("ioctl (SIOCGIFADDR)");
151 sin = (struct sockaddr_in *)&ifr.ifr_addr;
152 printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
40a42b7f
TF
153 if (flags & IFF_POINTOPOINT) {
154 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
155 if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0)
156 Perror("ioctl (SIOCGIFDSTADDR)");
157 sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
158 printf("--> %s ", inet_ntoa(sin->sin_addr));
159 }
b3eab9f9 160#define IFFBITS \
dea973a0
MK
161"\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
162\11LOCAL"
b3eab9f9
SL
163 printb("flags", flags, IFFBITS); putchar('\n');
164}
165
166Perror(cmd)
167 char *cmd;
168{
169 extern int errno;
170
171 fprintf(stderr, "ifconfig: ");
172 switch (errno) {
173
174 case ENXIO:
175 fprintf(stderr, "%s: ", cmd);
176 fprintf(stderr, "no such interface\n");
177 break;
178
179 case EPERM:
9f1b5d96 180 fprintf(stderr, "%s: permission denied\n", cmd);
b3eab9f9
SL
181 break;
182
183 default:
184 perror(cmd);
185 }
186 exit(1);
187}
188
189struct in_addr inet_makeaddr();
190
191getaddr(s, sin)
192 char *s;
193 struct sockaddr_in *sin;
194{
195 struct hostent *hp;
196 struct netent *np;
197 int val;
198
199 hp = gethostbyname(s);
200 if (hp) {
201 sin->sin_family = hp->h_addrtype;
202 bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
203 return;
204 }
205 np = getnetbyname(s);
206 if (np) {
207 sin->sin_family = np->n_addrtype;
208 sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
209 return;
210 }
211 sin->sin_family = AF_INET;
212 val = inet_addr(s);
213 if (val != -1) {
214 sin->sin_addr.s_addr = val;
215 return;
216 }
217 val = inet_network(s);
218 if (val != -1) {
219 sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
220 return;
221 }
222 fprintf(stderr, "%s: bad value\n", s);
223 exit(1);
224}
225
226/*
227 * Print a value a la the %b format of the kernel's printf
228 */
229printb(s, v, bits)
230 char *s;
231 register char *bits;
232 register unsigned short v;
233{
234 register int i, any = 0;
235 register char c;
236
237 if (bits && *bits == 8)
238 printf("%s=%o", s, v);
239 else
240 printf("%s=%x", s, v);
241 bits++;
242 if (bits) {
243 putchar('<');
244 while (i = *bits++) {
245 if (v & (1 << (i-1))) {
246 if (any)
247 putchar(',');
248 any = 1;
249 for (; (c = *bits) > 32; bits++)
250 putchar(c);
251 } else
252 for (; *bits > 32; bits++)
253 ;
254 }
255 putchar('>');
256 }
257}