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