Commit | Line | Data |
---|---|---|
b3eab9f9 | 1 | #ifndef lint |
a390ced5 | 2 | static char sccsid[] = "@(#)ifconfig.c 4.3 (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]; | |
20 | int flags; | |
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 }, | |
34 | { "arp", IFF_NOARP, setifflags }, | |
35 | { "-arp", -IFF_NOARP, setifflags }, | |
a390ced5 SL |
36 | #ifdef notdef |
37 | #define EN_SWABIPS 0x100 | |
38 | { "swabips", EN_SWABIPS, setifflags }, | |
39 | { "-swabips", -EN_SWABIPS, setifflags }, | |
40 | #endif | |
b3eab9f9 SL |
41 | { 0, 0, setifaddr }, |
42 | }; | |
43 | ||
44 | main(argc, argv) | |
45 | int argc; | |
46 | char *argv[]; | |
47 | { | |
48 | ||
49 | if (argc < 2) { | |
50 | fprintf(stderr, "usage: ifconfig interface %s %s %s\n", | |
51 | "[ address ] [ up ] [ down ]", | |
52 | "[ trailers | -trailers ]", | |
53 | "[ arp | -arp ]"); | |
54 | exit(1); | |
55 | } | |
56 | s = socket(AF_INET, SOCK_DGRAM, 0); | |
57 | if (s < 0) { | |
58 | perror("ifconfig: socket"); | |
59 | exit(1); | |
60 | } | |
61 | argc--, argv++; | |
62 | strcpy(name, *argv); | |
63 | strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); | |
64 | if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { | |
65 | Perror("ioctl (SIOCGIFFLAGS)"); | |
66 | exit(1); | |
67 | } | |
68 | flags = ifr.ifr_flags; | |
69 | argc--, argv++; | |
70 | if (argc == 0) { | |
71 | status(); | |
72 | exit(0); | |
73 | } | |
74 | while (argc > 0) { | |
75 | register struct cmd *p; | |
76 | ||
77 | for (p = cmds; p->c_name; p++) | |
78 | if (strcmp(*argv, p->c_name) == 0) | |
79 | break; | |
80 | if (p->c_func) | |
81 | (*p->c_func)(*argv, p->c_parameter); | |
82 | argc--, argv++; | |
83 | } | |
84 | exit(0); | |
85 | } | |
86 | ||
87 | /*ARGSUSED*/ | |
88 | setifaddr(addr, param) | |
89 | char *addr; | |
90 | int param; | |
91 | { | |
92 | ||
93 | getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr); | |
94 | strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); | |
95 | if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) | |
96 | Perror("ioctl (SIOCSIFADDR)"); | |
97 | } | |
98 | ||
2c4ef00e SL |
99 | setifflags(vname, value) |
100 | char *vname; | |
b3eab9f9 SL |
101 | int value; |
102 | { | |
103 | ||
104 | if (value < 0) { | |
105 | value = -value; | |
106 | ifr.ifr_flags = (flags &~ value); | |
107 | } else | |
108 | ifr.ifr_flags |= value; | |
109 | strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); | |
110 | if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) | |
2c4ef00e | 111 | Perror(vname); |
b3eab9f9 SL |
112 | } |
113 | ||
114 | status() | |
115 | { | |
116 | struct sockaddr_in *sin; | |
117 | ||
118 | strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); | |
119 | if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) | |
120 | Perror("ioctl (SIOCGIFADDR)"); | |
121 | sin = (struct sockaddr_in *)&ifr.ifr_addr; | |
122 | printf("%s: %s ", name, inet_ntoa(sin->sin_addr)); | |
123 | #define IFFBITS \ | |
124 | "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING" | |
125 | printb("flags", flags, IFFBITS); putchar('\n'); | |
126 | } | |
127 | ||
128 | Perror(cmd) | |
129 | char *cmd; | |
130 | { | |
131 | extern int errno; | |
132 | ||
133 | fprintf(stderr, "ifconfig: "); | |
134 | switch (errno) { | |
135 | ||
136 | case ENXIO: | |
137 | fprintf(stderr, "%s: ", cmd); | |
138 | fprintf(stderr, "no such interface\n"); | |
139 | break; | |
140 | ||
141 | case EPERM: | |
142 | fprintf(stderr, "%s: permission denied\n"); | |
143 | break; | |
144 | ||
145 | default: | |
146 | perror(cmd); | |
147 | } | |
148 | exit(1); | |
149 | } | |
150 | ||
151 | struct in_addr inet_makeaddr(); | |
152 | ||
153 | getaddr(s, sin) | |
154 | char *s; | |
155 | struct sockaddr_in *sin; | |
156 | { | |
157 | struct hostent *hp; | |
158 | struct netent *np; | |
159 | int val; | |
160 | ||
161 | hp = gethostbyname(s); | |
162 | if (hp) { | |
163 | sin->sin_family = hp->h_addrtype; | |
164 | bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); | |
165 | return; | |
166 | } | |
167 | np = getnetbyname(s); | |
168 | if (np) { | |
169 | sin->sin_family = np->n_addrtype; | |
170 | sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); | |
171 | return; | |
172 | } | |
173 | sin->sin_family = AF_INET; | |
174 | val = inet_addr(s); | |
175 | if (val != -1) { | |
176 | sin->sin_addr.s_addr = val; | |
177 | return; | |
178 | } | |
179 | val = inet_network(s); | |
180 | if (val != -1) { | |
181 | sin->sin_addr = inet_makeaddr(val, INADDR_ANY); | |
182 | return; | |
183 | } | |
184 | fprintf(stderr, "%s: bad value\n", s); | |
185 | exit(1); | |
186 | } | |
187 | ||
188 | /* | |
189 | * Print a value a la the %b format of the kernel's printf | |
190 | */ | |
191 | printb(s, v, bits) | |
192 | char *s; | |
193 | register char *bits; | |
194 | register unsigned short v; | |
195 | { | |
196 | register int i, any = 0; | |
197 | register char c; | |
198 | ||
199 | if (bits && *bits == 8) | |
200 | printf("%s=%o", s, v); | |
201 | else | |
202 | printf("%s=%x", s, v); | |
203 | bits++; | |
204 | if (bits) { | |
205 | putchar('<'); | |
206 | while (i = *bits++) { | |
207 | if (v & (1 << (i-1))) { | |
208 | if (any) | |
209 | putchar(','); | |
210 | any = 1; | |
211 | for (; (c = *bits) > 32; bits++) | |
212 | putchar(c); | |
213 | } else | |
214 | for (; *bits > 32; bits++) | |
215 | ; | |
216 | } | |
217 | putchar('>'); | |
218 | } | |
219 | } |