Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/kinit/ipconfig/netdev.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide 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)
-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 niro 532 /*
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     }