Contents of /trunk/mkinitrd-magellan/klibc/usr/kinit/ipconfig/netdev.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5094 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5094 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* |
2 | * ioctl-based device configuration |
3 | */ |
4 | #include <sys/types.h> |
5 | #include <sys/socket.h> |
6 | #include <sys/ioctl.h> |
7 | #include <errno.h> |
8 | #include <stdio.h> |
9 | #include <string.h> |
10 | #include <unistd.h> |
11 | #include <net/if.h> |
12 | #include <net/if_arp.h> |
13 | #include <netinet/in.h> |
14 | #include <linux/route.h> |
15 | |
16 | #include "netdev.h" |
17 | |
18 | static int cfd = -1; |
19 | |
20 | static void copy_name(struct netdev *dev, struct ifreq *ifr) |
21 | { |
22 | strncpy(ifr->ifr_name, dev->name, sizeof(ifr->ifr_name)); |
23 | ifr->ifr_name[sizeof(ifr->ifr_name) - 1] = '\0'; |
24 | } |
25 | |
26 | int netdev_getflags(struct netdev *dev, short *flags) |
27 | { |
28 | struct ifreq ifr; |
29 | |
30 | copy_name(dev, &ifr); |
31 | |
32 | if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) { |
33 | perror("SIOCGIFFLAGS"); |
34 | return -1; |
35 | } |
36 | |
37 | *flags = ifr.ifr_flags; |
38 | return 0; |
39 | } |
40 | |
41 | static int netdev_sif_addr(struct ifreq *ifr, int cmd, uint32_t addr) |
42 | { |
43 | struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr; |
44 | |
45 | sin->sin_family = AF_INET; |
46 | sin->sin_addr.s_addr = addr; |
47 | |
48 | return ioctl(cfd, cmd, ifr); |
49 | } |
50 | |
51 | int netdev_setaddress(struct netdev *dev) |
52 | { |
53 | struct ifreq ifr; |
54 | |
55 | copy_name(dev, &ifr); |
56 | |
57 | if (dev->ip_addr != INADDR_ANY && |
58 | netdev_sif_addr(&ifr, SIOCSIFADDR, dev->ip_addr) == -1) { |
59 | perror("SIOCSIFADDR"); |
60 | return -1; |
61 | } |
62 | |
63 | if (dev->ip_broadcast != INADDR_ANY && |
64 | netdev_sif_addr(&ifr, SIOCSIFBRDADDR, dev->ip_broadcast) == -1) { |
65 | perror("SIOCSIFBRDADDR"); |
66 | return -1; |
67 | } |
68 | |
69 | if (dev->ip_netmask != INADDR_ANY && |
70 | netdev_sif_addr(&ifr, SIOCSIFNETMASK, dev->ip_netmask) == -1) { |
71 | perror("SIOCSIFNETMASK"); |
72 | return -1; |
73 | } |
74 | |
75 | return 0; |
76 | } |
77 | |
78 | int netdev_setdefaultroute(struct netdev *dev) |
79 | { |
80 | struct rtentry r; |
81 | |
82 | if (dev->ip_gateway == INADDR_ANY) |
83 | return 0; |
84 | |
85 | memset(&r, 0, sizeof(r)); |
86 | |
87 | ((struct sockaddr_in *)&r.rt_dst)->sin_family = AF_INET; |
88 | ((struct sockaddr_in *)&r.rt_dst)->sin_addr.s_addr = INADDR_ANY; |
89 | ((struct sockaddr_in *)&r.rt_gateway)->sin_family = AF_INET; |
90 | ((struct sockaddr_in *)&r.rt_gateway)->sin_addr.s_addr = |
91 | dev->ip_gateway; |
92 | ((struct sockaddr_in *)&r.rt_genmask)->sin_family = AF_INET; |
93 | ((struct sockaddr_in *)&r.rt_genmask)->sin_addr.s_addr = INADDR_ANY; |
94 | r.rt_flags = RTF_UP | RTF_GATEWAY; |
95 | |
96 | if (ioctl(cfd, SIOCADDRT, &r) == -1 && errno != EEXIST) { |
97 | perror("SIOCADDRT"); |
98 | return -1; |
99 | } |
100 | return 0; |
101 | } |
102 | |
103 | int netdev_setmtu(struct netdev *dev) |
104 | { |
105 | struct ifreq ifr; |
106 | |
107 | copy_name(dev, &ifr); |
108 | ifr.ifr_mtu = dev->mtu; |
109 | |
110 | return ioctl(cfd, SIOCSIFMTU, &ifr); |
111 | } |
112 | |
113 | static int netdev_gif_addr(struct ifreq *ifr, int cmd, uint32_t * ptr) |
114 | { |
115 | struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr; |
116 | |
117 | if (ioctl(cfd, cmd, ifr) == -1) |
118 | return -1; |
119 | |
120 | *ptr = sin->sin_addr.s_addr; |
121 | |
122 | return 0; |
123 | } |
124 | |
125 | int netdev_up(struct netdev *dev) |
126 | { |
127 | struct ifreq ifr; |
128 | |
129 | copy_name(dev, &ifr); |
130 | |
131 | if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) { |
132 | perror("SIOCGIFFLAGS"); |
133 | return -1; |
134 | } |
135 | |
136 | ifr.ifr_flags |= IFF_UP; |
137 | |
138 | if (ioctl(cfd, SIOCSIFFLAGS, &ifr) == -1) { |
139 | perror("SIOCSIFFLAGS"); |
140 | return -1; |
141 | } |
142 | return 0; |
143 | } |
144 | |
145 | int netdev_down(struct netdev *dev) |
146 | { |
147 | struct ifreq ifr; |
148 | |
149 | copy_name(dev, &ifr); |
150 | |
151 | if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) { |
152 | perror("SIOCGIFFLAGS"); |
153 | return -1; |
154 | } |
155 | |
156 | ifr.ifr_flags &= ~IFF_UP; |
157 | |
158 | if (ioctl(cfd, SIOCSIFFLAGS, &ifr) == -1) { |
159 | perror("SIOCSIFFLAGS"); |
160 | return -1; |
161 | } |
162 | return 0; |
163 | } |
164 | |
165 | int netdev_init_if(struct netdev *dev) |
166 | { |
167 | struct ifreq ifr; |
168 | |
169 | if (cfd == -1) |
170 | cfd = socket(AF_INET, SOCK_DGRAM, 0); |
171 | if (cfd == -1) { |
172 | fprintf(stderr, "ipconfig: %s: socket(AF_INET): %s\n", |
173 | dev->name, strerror(errno)); |
174 | return -1; |
175 | } |
176 | |
177 | copy_name(dev, &ifr); |
178 | |
179 | if (ioctl(cfd, SIOCGIFINDEX, &ifr) == -1) { |
180 | fprintf(stderr, "ipconfig: %s: SIOCGIFINDEX: %s\n", |
181 | dev->name, strerror(errno)); |
182 | return -1; |
183 | } |
184 | |
185 | dev->ifindex = ifr.ifr_ifindex; |
186 | |
187 | if (ioctl(cfd, SIOCGIFMTU, &ifr) == -1) { |
188 | fprintf(stderr, "ipconfig: %s: SIOCGIFMTU: %s\n", |
189 | dev->name, strerror(errno)); |
190 | return -1; |
191 | } |
192 | |
193 | dev->mtu = ifr.ifr_mtu; |
194 | |
195 | if (ioctl(cfd, SIOCGIFHWADDR, &ifr) == -1) { |
196 | fprintf(stderr, "ipconfig: %s: SIOCGIFHWADDR: %s\n", |
197 | dev->name, strerror(errno)); |
198 | return -1; |
199 | } |
200 | |
201 | dev->hwtype = ifr.ifr_hwaddr.sa_family; |
202 | dev->hwlen = 0; |
203 | |
204 | switch (dev->hwtype) { |
205 | case ARPHRD_ETHER: |
206 | dev->hwlen = 6; |
207 | break; |
208 | case ARPHRD_EUI64: |
209 | dev->hwlen = 8; |
210 | break; |
211 | case ARPHRD_LOOPBACK: |
212 | dev->hwlen = 0; |
213 | break; |
214 | default: |
215 | return -1; |
216 | } |
217 | |
218 | memcpy(dev->hwaddr, ifr.ifr_hwaddr.sa_data, dev->hwlen); |
219 | memset(dev->hwbrd, 0xff, dev->hwlen); |
220 | |
221 | /* |
222 | * Try to get the current interface information. |
223 | */ |
224 | if (dev->ip_addr == INADDR_NONE && |
225 | netdev_gif_addr(&ifr, SIOCGIFADDR, &dev->ip_addr) == -1) { |
226 | fprintf(stderr, "ipconfig: %s: SIOCGIFADDR: %s\n", |
227 | dev->name, strerror(errno)); |
228 | dev->ip_addr = 0; |
229 | dev->ip_broadcast = 0; |
230 | dev->ip_netmask = 0; |
231 | return 0; |
232 | } |
233 | |
234 | if (dev->ip_broadcast == INADDR_NONE && |
235 | netdev_gif_addr(&ifr, SIOCGIFBRDADDR, &dev->ip_broadcast) == -1) { |
236 | fprintf(stderr, "ipconfig: %s: SIOCGIFBRDADDR: %s\n", |
237 | dev->name, strerror(errno)); |
238 | dev->ip_broadcast = 0; |
239 | } |
240 | |
241 | if (dev->ip_netmask == INADDR_NONE && |
242 | netdev_gif_addr(&ifr, SIOCGIFNETMASK, &dev->ip_netmask) == -1) { |
243 | fprintf(stderr, "ipconfig: %s: SIOCGIFNETMASK: %s\n", |
244 | dev->name, strerror(errno)); |
245 | dev->ip_netmask = 0; |
246 | } |
247 | |
248 | return 0; |
249 | } |