1127043Sjhb/*-
2127043Sjhb * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3127043Sjhb * All rights reserved.
4127043Sjhb *
5127043Sjhb * Redistribution and use in source and binary forms, with or without
6127043Sjhb * modification, are permitted provided that the following conditions
7127043Sjhb * are met:
8127043Sjhb * 1. Redistributions of source code must retain the above copyright
9127043Sjhb *    notice, this list of conditions and the following disclaimer.
10127043Sjhb * 2. Redistributions in binary form must reproduce the above copyright
11127043Sjhb *    notice, this list of conditions and the following disclaimer in the
12127043Sjhb *    documentation and/or other materials provided with the distribution.
13127043Sjhb * 3. Neither the name of the project nor the names of its contributors
14127043Sjhb *    may be used to endorse or promote products derived from this software
15127043Sjhb *    without specific prior written permission.
16127043Sjhb *
17127043Sjhb * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18127043Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19127043Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20127043Sjhb * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21127043Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22127043Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23127043Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24127043Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25127043Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26127043Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27127043Sjhb * SUCH DAMAGE.
28127043Sjhb *
29127043Sjhb *	$KAME: route6.c,v 1.24 2001/03/14 03:07:05 itojun Exp $
30127043Sjhb */
31240336Sobrien
32136224Smtm#include <sys/cdefs.h>
33127043Sjhb__FBSDID("$FreeBSD$");
34127043Sjhb
35127043Sjhb#include "opt_inet.h"
36127043Sjhb#include "opt_inet6.h"
37298514Slme
38163063Sflz#include <sys/param.h>
39127043Sjhb#include <sys/mbuf.h>
40127043Sjhb#include <sys/socket.h>
41127043Sjhb#include <sys/systm.h>
42127043Sjhb#include <sys/queue.h>
43127043Sjhb
44127043Sjhb#include <net/if.h>
45127043Sjhb
46127043Sjhb#include <netinet/in.h>
47127043Sjhb#include <netinet6/in6_var.h>
48127043Sjhb#include <netinet/ip6.h>
49127043Sjhb#include <netinet6/ip6_var.h>
50127043Sjhb#include <netinet6/scope6_var.h>
51127043Sjhb
52127043Sjhb#include <netinet/icmp6.h>
53127043Sjhb
54127043Sjhb/*
55127043Sjhb * proto - is unused
56127043Sjhb */
57127478Sdougb
58127043Sjhbint
59127043Sjhbroute6_input(struct mbuf **mp, int *offp, int proto)
60127043Sjhb{
61127478Sdougb	struct ip6_hdr *ip6;
62127043Sjhb	struct mbuf *m = *mp;
63127043Sjhb	struct ip6_rthdr *rh;
64127043Sjhb	int off = *offp, rhlen;
65127043Sjhb#ifdef __notyet__
66127043Sjhb	struct ip6aux *ip6a;
67127043Sjhb
68127043Sjhb	ip6a = ip6_findaux(m);
69127043Sjhb	if (ip6a) {
70127043Sjhb		/* XXX reject home-address option before rthdr */
71127043Sjhb		if (ip6a->ip6a_flags & IP6A_SWAP) {
72127043Sjhb			IP6STAT_INC(ip6s_badoptions);
73127478Sdougb			m_freem(m);
74127043Sjhb			return IPPROTO_DONE;
75127043Sjhb		}
76127043Sjhb	}
77127043Sjhb#endif
78127043Sjhb
79127043Sjhb#ifndef PULLDOWN_TEST
80127043Sjhb	IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE);
81127043Sjhb	ip6 = mtod(m, struct ip6_hdr *);
82127043Sjhb	rh = (struct ip6_rthdr *)((caddr_t)ip6 + off);
83127043Sjhb#else
84127043Sjhb	ip6 = mtod(m, struct ip6_hdr *);
85127043Sjhb	IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh));
86127043Sjhb	if (rh == NULL) {
87127043Sjhb		IP6STAT_INC(ip6s_tooshort);
88127043Sjhb		return IPPROTO_DONE;
89127043Sjhb	}
90127043Sjhb#endif
91127043Sjhb
92127043Sjhb	/*
93127043Sjhb	 * While this switch may look gratuitous, leave it in
94127043Sjhb	 * in favour of RH2 implementations, etc.
95127043Sjhb	 */
96127043Sjhb	switch (rh->ip6r_type) {
97127043Sjhb	default:
98127043Sjhb		/* Unknown routing header type. */
99127043Sjhb		if (rh->ip6r_segleft == 0) {
100127043Sjhb			rhlen = (rh->ip6r_len + 1) << 3;
101127043Sjhb			break;	/* Final dst. Just ignore the header. */
102127043Sjhb		}
103127043Sjhb		IP6STAT_INC(ip6s_badoptions);
104127043Sjhb		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
105			    (caddr_t)&rh->ip6r_type - (caddr_t)ip6);
106		return (IPPROTO_DONE);
107	}
108
109	*offp += rhlen;
110	return (rh->ip6r_nxt);
111}
112