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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [bsd_tcpip/] [v2_0/] [src/] [sys/] [netinet6/] [dest6.c] - Blame information for rev 631

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      src/sys/netinet6/dest6.c
4
//
5
//==========================================================================
6
//####BSDCOPYRIGHTBEGIN####
7
//
8
// -------------------------------------------
9
//
10
// Portions of this software may have been derived from OpenBSD, 
11
// FreeBSD or other sources, and are covered by the appropriate
12
// copyright disclaimers included herein.
13
//
14
// Portions created by Red Hat are
15
// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
16
//
17
// -------------------------------------------
18
//
19
//####BSDCOPYRIGHTEND####
20
//==========================================================================
21
 
22
/*      $KAME: dest6.c,v 1.33 2001/10/05 10:01:32 itojun Exp $  */
23
 
24
/*
25
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
26
 * All rights reserved.
27
 *
28
 * Redistribution and use in source and binary forms, with or without
29
 * modification, are permitted provided that the following conditions
30
 * are met:
31
 * 1. Redistributions of source code must retain the above copyright
32
 *    notice, this list of conditions and the following disclaimer.
33
 * 2. Redistributions in binary form must reproduce the above copyright
34
 *    notice, this list of conditions and the following disclaimer in the
35
 *    documentation and/or other materials provided with the distribution.
36
 * 3. Neither the name of the project nor the names of its contributors
37
 *    may be used to endorse or promote products derived from this software
38
 *    without specific prior written permission.
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 */
52
 
53
#include <sys/param.h>
54
#include <sys/malloc.h>
55
#include <sys/mbuf.h>
56
#include <sys/domain.h>
57
#include <sys/protosw.h>
58
#include <sys/socket.h>
59
#include <sys/errno.h>
60
 
61
#include <net/if.h>
62
#include <net/route.h>
63
 
64
#include <netinet/in.h>
65
#include <netinet/in_var.h>
66
#include <netinet/ip6.h>
67
#include <netinet6/ip6_var.h>
68
#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__) && !(defined(__bsdi__) && _BSDI_VERSION >= 199802)
69
#include <netinet6/in6_pcb.h>
70
#endif
71
#include <netinet/icmp6.h>
72
#ifdef MIP6
73
#include <netinet6/mip6.h>
74
#endif
75
 
76
/*
77
 * Destination options header processing.
78
 */
79
int
80
dest6_input(mp, offp, proto)
81
        struct mbuf **mp;
82
        int *offp, proto;
83
{
84
        struct mbuf *m = *mp;
85
        int off = *offp, dstoptlen, optlen;
86
        struct ip6_dest *dstopts;
87
        struct mbuf *n;
88
        struct ip6_opt_home_address *haopt = NULL;
89
        struct ip6aux *ip6a = NULL;
90
        u_int8_t *opt;
91
        struct ip6_hdr *ip6;
92
 
93
        ip6 = mtod(m, struct ip6_hdr *);
94
 
95
        /* validation of the length of the header */
96
#ifndef PULLDOWN_TEST
97
        IP6_EXTHDR_CHECK(m, off, sizeof(*dstopts), IPPROTO_DONE);
98
        dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
99
#else
100
        IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts));
101
        if (dstopts == NULL)
102
                return IPPROTO_DONE;
103
#endif
104
        dstoptlen = (dstopts->ip6d_len + 1) << 3;
105
 
106
#ifndef PULLDOWN_TEST
107
        IP6_EXTHDR_CHECK(m, off, dstoptlen, IPPROTO_DONE);
108
        dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
109
#else
110
        IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen);
111
        if (dstopts == NULL)
112
                return IPPROTO_DONE;
113
#endif
114
        off += dstoptlen;
115
        dstoptlen -= sizeof(struct ip6_dest);
116
        opt = (u_int8_t *)dstopts + sizeof(struct ip6_dest);
117
 
118
        /* search header for all options. */
119
        for (optlen = 0; dstoptlen > 0; dstoptlen -= optlen, opt += optlen) {
120
                if (*opt != IP6OPT_PAD1 &&
121
                    (dstoptlen < IP6OPT_MINLEN || *(opt + 1) + 2 > dstoptlen)) {
122
                        ip6stat.ip6s_toosmall++;
123
                        goto bad;
124
                }
125
 
126
                switch (*opt) {
127
                case IP6OPT_PAD1:
128
                        optlen = 1;
129
                        break;
130
                case IP6OPT_PADN:
131
                        optlen = *(opt + 1) + 2;
132
                        break;
133
                case IP6OPT_HOME_ADDRESS:
134
                        /*
135
                         * XXX we assume that home address option appear after
136
                         * AH.  if the assumption does not hold, the validation
137
                         * of AH will fail due to the address swap.
138
                         */
139
#if 0
140
                        /* be picky about alignment: 8n+6 */
141
                        if ((opt - (u_int8_t *)dstopts) % 8 != 6)
142
                                goto bad;
143
#endif
144
 
145
                        /* HA option must appear only once */
146
                        n = ip6_addaux(m);
147
                        if (!n) {
148
                                /* not enough core */
149
                                goto bad;
150
                        }
151
                        ip6a = mtod(n, struct ip6aux *);
152
                        if ((ip6a->ip6a_flags & IP6A_HASEEN) != 0) {
153
                                /* XXX icmp6 paramprob? */
154
                                goto bad;
155
                        }
156
 
157
                        haopt = (struct ip6_opt_home_address *)opt;
158
                        optlen = haopt->ip6oh_len + 2;
159
 
160
                        /*
161
                         * don't complain even if it is larger,
162
                         * we don't support suboptions at this moment.
163
                         */
164
                        if (optlen < sizeof(*haopt)) {
165
                                ip6stat.ip6s_toosmall++;
166
                                goto bad;
167
                        }
168
 
169
                        /* XXX check header ordering */
170
 
171
                        bcopy(haopt->ip6oh_addr, &ip6a->ip6a_home,
172
                            sizeof(ip6a->ip6a_home));
173
                        bcopy(&ip6->ip6_src, &ip6a->ip6a_careof,
174
                            sizeof(ip6a->ip6a_careof));
175
                        ip6a->ip6a_flags |= IP6A_HASEEN;
176
 
177
                        /*
178
                         * reject invalid home-addresses
179
                         */
180
                        /* XXX linklocal-address is not supported */
181
                        if (IN6_IS_ADDR_MULTICAST(&ip6a->ip6a_home) ||
182
                            IN6_IS_ADDR_LINKLOCAL(&ip6a->ip6a_home) ||
183
                            IN6_IS_ADDR_V4MAPPED(&ip6a->ip6a_home)  ||
184
                            IN6_IS_ADDR_UNSPECIFIED(&ip6a->ip6a_home) ||
185
                            IN6_IS_ADDR_LOOPBACK(&ip6a->ip6a_home)) {
186
                                ip6stat.ip6s_badscope++;
187
                                goto bad;
188
                        }
189
 
190
                        /*
191
                         * Currently, no valid sub-options are
192
                         * defined for use in a Home Address option.
193
                         */
194
 
195
                        break;
196
 
197
#ifdef MIP6
198
                case IP6OPT_BINDING_UPDATE:
199
                case IP6OPT_BINDING_ACK:
200
                case IP6OPT_BINDING_REQ:
201
                        if (mip6_process_destopt(m, dstopts, opt, dstoptlen)
202
                            == -1)
203
                                goto bad;
204
                        optlen = *(opt + 1) + 2;
205
                        break;
206
#endif /* MIP6 */
207
 
208
                default:                /* unknown option */
209
                        optlen = ip6_unknown_opt(opt, m,
210
                            opt - mtod(m, u_int8_t *));
211
                        if (optlen == -1)
212
                                return (IPPROTO_DONE);
213
                        optlen += 2;
214
                        break;
215
                }
216
        }
217
 
218
        /* if haopt is non-NULL, we are sure we have seen fresh HA option */
219
        if (haopt && ip6a &&
220
            (ip6a->ip6a_flags & (IP6A_HASEEN | IP6A_SWAP)) == IP6A_HASEEN) {
221
                /* XXX should we do this at all?  do it now or later? */
222
                /* XXX interaction with 2292bis IPV6_RECVDSTOPT */
223
                /* XXX interaction with ipsec - should be okay */
224
                /* XXX icmp6 responses is modified - which is bad */
225
                bcopy(&ip6a->ip6a_careof, haopt->ip6oh_addr,
226
                    sizeof(haopt->ip6oh_addr));
227
                bcopy(&ip6a->ip6a_home, &ip6->ip6_src,
228
                    sizeof(ip6->ip6_src));
229
#if 0
230
                /* XXX linklocal address is (currently) not supported */
231
                if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
232
                        ip6->ip6_src.s6_addr16[1]
233
                                = htons(m->m_pkthdr.rcvif->if_index);
234
#endif
235
                ip6a->ip6a_flags |= IP6A_SWAP;
236
        }
237
 
238
        *offp = off;
239
        return (dstopts->ip6d_nxt);
240
 
241
  bad:
242
        m_freem(m);
243
        return (IPPROTO_DONE);
244
}

powered by: WebSVN 2.1.0

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