Commit | Line | Data |
---|---|---|
b3eab9f9 | 1 | #ifndef lint |
9f1b5d96 | 2 | static char sccsid[] = "@(#)ifconfig.c 4.8 (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 | ||
17 | struct ifreq ifr; | |
18 | struct sockaddr_in sin = { AF_INET }; | |
19 | char name[30]; | |
dea973a0 | 20 | int setaddr; |
b3eab9f9 SL |
21 | int s; |
22 | ||
23 | int setifflags(), setifaddr(); | |
24 | ||
25 | struct 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 | ||
48 | main(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*/ | |
97 | setifaddr(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 |
111 | setifflags(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 | ||
126 | status() | |
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 | ||
142 | Perror(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: | |
9f1b5d96 | 156 | fprintf(stderr, "%s: permission denied\n", cmd); |
b3eab9f9 SL |
157 | break; |
158 | ||
159 | default: | |
160 | perror(cmd); | |
161 | } | |
162 | exit(1); | |
163 | } | |
164 | ||
165 | struct in_addr inet_makeaddr(); | |
166 | ||
167 | getaddr(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 | */ | |
205 | printb(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 | } |