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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [userland/] [route/] [lib/] [inet6_sr.c] - Blame information for rev 1767

Go to most recent revision | 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_AFINET6
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
#include <net/if.h>
17
#include <sys/ioctl.h>
18
#include <ctype.h>
19
#include <errno.h>
20
#include <netdb.h>
21
#include <resolv.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <stdio.h>
25
#include <unistd.h>
26
#ifdef __GLIBC__
27
#include <net/route.h>
28
#else
29
#include <netinet6/ipv6_route.h>        /* glibc does not have this */
30
#endif
31
#include "version.h"
32
#include "net-support.h"
33
#include "pathnames.h"
34
#include "intl.h"
35
#include "net-features.h"
36
 
37
extern struct aftype inet6_aftype;
38
 
39
static int skfd = -1;
40
 
41
 
42
static int usage(void)
43
{
44
    fprintf(stderr, _("Usage: inet6_route [-vF] del Target\n"));
45
    fprintf(stderr, _("       inet6_route [-vF] add Target [gw Gw] [metric M] [[dev] If]\n"));
46
    fprintf(stderr, _("       inet6_route [-FC] flush      NOT supported\n"));
47
    return (E_USAGE);
48
}
49
 
50
 
51
static int INET6_setroute(int action, int options, char **args)
52
{
53
    struct in6_rtmsg rt;
54
    struct ifreq ifr;
55
    struct sockaddr_in6 sa6;
56
    char target[128], gateway[128] = "NONE";
57
    int metric, prefix_len;
58
    char *devname = NULL;
59
    char *cp;
60
 
61
    if (*args == NULL)
62
        return (usage());
63
 
64
    strcpy(target, *args++);
65
    if ((cp = strchr(target, '/'))) {
66
        prefix_len = atol(cp + 1);
67
        if ((prefix_len < 0) || (prefix_len > 128))
68
            usage();
69
        *cp = 0;
70
    } else {
71
        prefix_len = 128;
72
    }
73
 
74
    /* Clean out the RTREQ structure. */
75
    memset((char *) &rt, 0, sizeof(struct in6_rtmsg));
76
 
77
    if (inet6_aftype.input(1, target, (struct sockaddr *) &sa6) < 0) {
78
        inet6_aftype.herror(target);
79
        return (1);
80
    }
81
    memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr));
82
 
83
    /* Fill in the other fields. */
84
    rt.rtmsg_flags = RTF_UP;
85
    if (prefix_len == 128)
86
        rt.rtmsg_flags |= RTF_HOST;
87
    rt.rtmsg_metric = 1;
88
    rt.rtmsg_dst_len = prefix_len;
89
 
90
    while (*args) {
91
        if (!strcmp(*args, "metric")) {
92
 
93
            args++;
94
            if (!*args || !isdigit(**args))
95
                return (usage());
96
            metric = atoi(*args);
97
            rt.rtmsg_metric = metric;
98
            args++;
99
            continue;
100
        }
101
        if (!strcmp(*args, "gw") || !strcmp(*args, "gateway")) {
102
            args++;
103
            if (!*args)
104
                return (usage());
105
            if (rt.rtmsg_flags & RTF_GATEWAY)
106
                return (usage());
107
            strcpy(gateway, *args);
108
            if (inet6_aftype.input(1, gateway,
109
                                   (struct sockaddr *) &sa6) < 0) {
110
                inet6_aftype.herror(gateway);
111
                return (E_LOOKUP);
112
            }
113
            memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr,
114
                   sizeof(struct in6_addr));
115
            rt.rtmsg_flags |= RTF_GATEWAY;
116
            args++;
117
            continue;
118
        }
119
        if (!strcmp(*args, "mod")) {
120
            args++;
121
            rt.rtmsg_flags |= RTF_MODIFIED;
122
            continue;
123
        }
124
        if (!strcmp(*args, "dyn")) {
125
            args++;
126
            rt.rtmsg_flags |= RTF_DYNAMIC;
127
            continue;
128
        }
129
        if (!strcmp(*args, "device") || !strcmp(*args, "dev")) {
130
            args++;
131
            if (!*args)
132
                return (usage());
133
        } else if (args[1])
134
            return (usage());
135
 
136
        devname = *args;
137
        args++;
138
    }
139
 
140
    /* Create a socket to the INET6 kernel. */
141
    if ((skfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
142
        perror("socket");
143
        return (E_SOCK);
144
    }
145
    if (devname) {
146
        memset(&ifr, 0, sizeof(ifr));
147
        strcpy(ifr.ifr_name, devname);
148
 
149
        if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) {
150
            perror("SIOGIFINDEX");
151
            return (E_SOCK);
152
        }
153
        rt.rtmsg_ifindex = ifr.ifr_ifindex;
154
    } else
155
        rt.rtmsg_ifindex = 0;
156
 
157
    /* Tell the kernel to accept this route. */
158
    if (action == RTACTION_DEL) {
159
        if (ioctl(skfd, SIOCDELRT, &rt) < 0) {
160
            perror("SIOCDELRT");
161
            close(skfd);
162
            return (E_SOCK);
163
        }
164
    } else {
165
        if (ioctl(skfd, SIOCADDRT, &rt) < 0) {
166
            perror("SIOCADDRT");
167
            close(skfd);
168
            return (E_SOCK);
169
        }
170
    }
171
 
172
    /* Close the socket. */
173
    (void) close(skfd);
174
    return (0);
175
}
176
 
177
int INET6_rinput(int action, int options, char **args)
178
{
179
    if (action == RTACTION_FLUSH) {
180
        fprintf(stderr, _("Flushing `inet6' routing table not supported\n"));
181
        return (usage());
182
    }
183
    if ((*args == NULL) || (action == RTACTION_HELP))
184
        return (usage());
185
 
186
    return (INET6_setroute(action, options, args));
187
}
188
#endif                          /* HAVE_AFINET6 */

powered by: WebSVN 2.1.0

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