~ubuntu-branches/ubuntu/hardy/klibc/hardy-updates

« back to all changes in this revision

Viewing changes to usr/kinit/ipconfig/netdev.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeff Bailey
  • Date: 2006-01-04 20:24:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060104202452-ec4v3n829rymukuv
Tags: 1.1.15-0ubuntu1
* New upstream version.

* Patch to fix compilation on parisc64 kernels.

Show diffs side-by-side

added added

removed removed

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