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