OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [userland/] [route/] [lib/] [inet_sr.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 745 simons
/*
2
   Modifications:
3
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
4
 */
5
 
6
#include "config.h"
7
 
8
#if HAVE_AFINET
9
#include <asm/types.h>
10
#include <sys/param.h>
11
#include <sys/types.h>
12
#include <sys/socket.h>
13
#include <netinet/in.h>
14
#include <arpa/inet.h>
15
#include <arpa/nameser.h>
16
#ifdef EMBED
17
#include <gnu/types.h>
18
#include <asm/atomic.h>
19
#include <linux/if_arp.h>
20
#include <linux/route.h>
21
#else
22
#include <net/route.h> /* realy broken */
23
#endif
24
#include <sys/ioctl.h>
25
#include <ctype.h>
26
#include <errno.h>
27
#include <netdb.h>
28
#include <resolv.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <stdio.h>
32
#include <unistd.h>
33
#include "version.h"
34
#include "net-support.h"
35
#include "pathnames.h"
36
#include "intl.h"
37
#include "net-features.h"
38
#include "util.h"
39
 
40
#if HAVE_NEW_ADDRT
41
#define mask_in_addr(x) (((struct sockaddr_in *)&((x).rt_genmask))->sin_addr.s_addr)
42
#define full_mask(x) (x)
43
#else
44
#define mask_in_addr(x) ((x).rt_genmask)
45
#define full_mask(x) (((struct sockaddr_in *)&(x))->sin_addr.s_addr)
46
#endif
47
 
48
extern struct aftype inet_aftype;
49
 
50
static int skfd = -1;
51
 
52
 
53
static int usage(void)
54
{
55
    fprintf(stderr, _("Usage: inet_route [-vF] del {-host|-net} Target[/prefix] [gw Gw] [metric M] [[dev] If]\n"));
56
    fprintf(stderr, _("       inet_route [-vF] add {-host|-net} Target[/prefix] [gw Gw] [metric M]\n"));
57
    fprintf(stderr, _("                              [netmask N] [mss Mss] [window W] [irtt I]\n"));
58
    fprintf(stderr, _("                              [mod] [dyn] [reinstate] [[dev] If]\n"));
59
    fprintf(stderr, _("       inet_route [-vF] add {-host|-net} Target[/prefix] [metric M] reject\n"));
60
    fprintf(stderr, _("       inet_route [-FC] flush      NOT supported\n"));
61
    return (E_USAGE);
62
}
63
 
64
static int INET_setroute(int action, int options, char **args)
65
{
66
    struct rtentry rt;
67
    char target[128], gateway[128] = "NONE", netmask[128] = "default";
68
    int xflag, isnet;
69
 
70
    xflag = 0;
71
 
72
    if (!strcmp(*args, "#net")) {
73
        xflag = 1;
74
        args++;
75
    } else if (!strcmp(*args, "#host")) {
76
        xflag = 2;
77
        args++;
78
    }
79
    if (*args == NULL)
80
        return (usage());
81
 
82
    safe_strncpy(target, *args++, (sizeof target));
83
 
84
    /* Clean out the RTREQ structure. */
85
    memset((char *) &rt, 0, sizeof(struct rtentry));
86
 
87
    /* Special hack for /prefix syntax */
88
    {
89
        union {
90
            struct sockaddr_in m;
91
            struct sockaddr d;
92
        } mask;
93
        int n;
94
 
95
        n = inet_aftype.getmask(target, &mask.d, netmask);
96
        if (n < 0)
97
            return usage();
98
        else if (n)
99
            rt.rt_genmask = full_mask(mask.d);
100
    }
101
 
102
    if ((isnet = inet_aftype.input(0, target, &rt.rt_dst)) < 0) {
103
        inet_aftype.herror(target);
104
        return (1);
105
    }
106
    switch (xflag) {
107
    case 1:
108
        isnet = 1;
109
        break;
110
 
111
    case 2:
112
        isnet = 0;
113
        break;
114
 
115
    default:
116
        break;
117
    }
118
 
119
    /* Fill in the other fields. */
120
    rt.rt_flags = (RTF_UP | RTF_HOST);
121
    if (isnet)
122
        rt.rt_flags &= ~RTF_HOST;
123
 
124
    while (*args) {
125
        if (!strcmp(*args, "metric")) {
126
            int metric;
127
 
128
            args++;
129
            if (!*args || !isdigit(**args))
130
                return (usage());
131
            metric = atoi(*args);
132
#if HAVE_NEW_ADDRT
133
            rt.rt_metric = metric + 1;
134
#else
135
            ENOSUPP("inet_setroute", "NEW_ADDRT (metric)");
136
#endif
137
            args++;
138
            continue;
139
        }
140
        if (!strcmp(*args, "netmask")) {
141
            struct sockaddr mask;
142
 
143
            args++;
144
            if (!*args || mask_in_addr(rt))
145
                return (usage());
146
            safe_strncpy(netmask, *args, (sizeof netmask));
147
            if ((isnet = inet_aftype.input(0, netmask, &mask)) < 0) {
148
                inet_aftype.herror(netmask);
149
                return (E_LOOKUP);
150
            }
151
            rt.rt_genmask = full_mask(mask);
152
            args++;
153
            continue;
154
        }
155
        if (!strcmp(*args, "gw") || !strcmp(*args, "gateway")) {
156
            args++;
157
            if (!*args)
158
                return (usage());
159
            if (rt.rt_flags & RTF_GATEWAY)
160
                return (usage());
161
            safe_strncpy(gateway, *args, (sizeof gateway));
162
            if ((isnet = inet_aftype.input(0, gateway, &rt.rt_gateway)) < 0) {
163
                inet_aftype.herror(gateway);
164
                return (E_LOOKUP);
165
            }
166
            if (isnet) {
167
                fprintf(stderr, _("route: %s: cannot use a NETWORK as gateway!\n"),
168
                        gateway);
169
                return (E_OPTERR);
170
            }
171
            rt.rt_flags |= RTF_GATEWAY;
172
            args++;
173
            continue;
174
        }
175
        if (!strcmp(*args, "mss")) {
176
            args++;
177
            rt.rt_flags |= RTF_MSS;
178
            if (!*args)
179
                return (usage());
180
            rt.rt_mss = atoi(*args);
181
            args++;
182
            if (rt.rt_mss < 64 || rt.rt_mss > 32768) {
183
                fprintf(stderr, _("route: Invalid MSS.\n"));
184
                return (E_OPTERR);
185
            }
186
            continue;
187
        }
188
        if (!strcmp(*args, "window")) {
189
            args++;
190
            if (!*args)
191
                return (usage());
192
            rt.rt_flags |= RTF_WINDOW;
193
            rt.rt_window = atoi(*args);
194
            args++;
195
            if (rt.rt_window < 128) {
196
                fprintf(stderr, _("route: Invalid window.\n"));
197
                return (E_OPTERR);
198
            }
199
            continue;
200
        }
201
        if (!strcmp(*args, "irtt")) {
202
            args++;
203
            if (!*args)
204
                return (usage());
205
            args++;
206
#if HAVE_RTF_IRTT
207
            rt.rt_flags |= RTF_IRTT;
208
            rt.rt_irtt = atoi(*(args - 1));
209
            rt.rt_irtt *= (HZ / 100);   /* FIXME */
210
#if 0                           /* FIXME: do we need to check anything of this? */
211
            if (rt.rt_irtt < 1 || rt.rt_irtt > (120 * HZ)) {
212
                fprintf(stderr, _("route: Invalid initial rtt.\n"));
213
                return (E_OPTERR);
214
            }
215
#endif
216
#else
217
            ENOSUPP("inet_setroute", "RTF_IRTT");
218
#endif
219
            continue;
220
        }
221
        if (!strcmp(*args, "reject")) {
222
            args++;
223
#if HAVE_RTF_REJECT
224
            rt.rt_flags |= RTF_REJECT;
225
#else
226
            ENOSUPP("inet_setroute", "RTF_REJECT");
227
#endif
228
            continue;
229
        }
230
        if (!strcmp(*args, "mod")) {
231
            args++;
232
            rt.rt_flags |= RTF_MODIFIED;
233
            continue;
234
        }
235
        if (!strcmp(*args, "dyn")) {
236
            args++;
237
            rt.rt_flags |= RTF_DYNAMIC;
238
            continue;
239
        }
240
        if (!strcmp(*args, "reinstate")) {
241
            args++;
242
            rt.rt_flags |= RTF_REINSTATE;
243
            continue;
244
        }
245
        if (!strcmp(*args, "device") || !strcmp(*args, "dev")) {
246
            args++;
247
            if (rt.rt_dev || *args == NULL)
248
                return usage();
249
            rt.rt_dev = *args++;
250
            continue;
251
        }
252
        /* nothing matches */
253
        if (!rt.rt_dev) {
254
            rt.rt_dev = *args++;
255
            if (*args)
256
                return usage(); /* must be last to catch typos */
257
        } else
258
            return usage();
259
    }
260
 
261
#if HAVE_RTF_REJECT
262
    if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev)
263
        rt.rt_dev = "lo";
264
#endif
265
 
266
    /* sanity checks.. */
267
    if (mask_in_addr(rt)) {
268
        __u32 mask = ~ntohl(mask_in_addr(rt));
269
        if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) {
270
            fprintf(stderr, _("route: netmask %.8x doesn't make sense with host route\n"), mask);
271
            return (E_OPTERR);
272
        }
273
        if (mask & (mask + 1)) {
274
            fprintf(stderr, _("route: bogus netmask %s\n"), netmask);
275
            return (E_OPTERR);
276
        }
277
        mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr;
278
        if (mask & ~mask_in_addr(rt)) {
279
            fprintf(stderr, _("route: netmask doesn't match route address\n"));
280
            return (E_OPTERR);
281
        }
282
    }
283
    /* Fill out netmask if still unset */
284
    if ((action == RTACTION_ADD) && rt.rt_flags & RTF_HOST)
285
        mask_in_addr(rt) = 0xffffffff;
286
 
287
    /* Create a socket to the INET kernel. */
288
    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
289
        perror("socket");
290
        return (E_SOCK);
291
    }
292
    /* Tell the kernel to accept this route. */
293
    if (action == RTACTION_DEL) {
294
        if (ioctl(skfd, SIOCDELRT, &rt) < 0) {
295
            perror("SIOCDELRT");
296
            close(skfd);
297
            return (E_SOCK);
298
        }
299
    } else {
300
        if (ioctl(skfd, SIOCADDRT, &rt) < 0) {
301
            perror("SIOCADDRT");
302
            close(skfd);
303
            return (E_SOCK);
304
        }
305
    }
306
 
307
    /* Close the socket. */
308
    (void) close(skfd);
309
    return (0);
310
}
311
 
312
int INET_rinput(int action, int options, char **args)
313
{
314
    if (action == RTACTION_FLUSH) {
315
        fprintf(stderr, _("Flushing `inet' routing table not supported\n"));
316
        return (usage());
317
    }
318
    if (options & FLAG_CACHE) {
319
        fprintf(stderr, _("Modifying `inet' routing cache not supported\n"));
320
        return (usage());
321
    }
322
    if ((*args == NULL) || (action == RTACTION_HELP))
323
        return (usage());
324
 
325
    return (INET_setroute(action, options, args));
326
}
327
#endif                          /* HAVE_AFINET */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.