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

« back to all changes in this revision

Viewing changes to 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
 
}