1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 46 unchanged lines hidden (view full) --- 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58 * 59 * @(#)raw_ip.c 8.2 (Berkeley) 1/4/94 60 */ 61 62#include <sys/cdefs.h> |
63__FBSDID("$FreeBSD: head/sys/netinet6/raw_ip6.c 191672 2009-04-29 19:19:13Z bms $"); |
64 65#include "opt_ipsec.h" 66#include "opt_inet6.h" 67#include "opt_route.h" 68 69#include <sys/param.h> 70#include <sys/errno.h> 71#include <sys/jail.h> --- 51 unchanged lines hidden (view full) --- 123extern struct inpcbinfo ripcbinfo; 124struct rip6stat rip6stat; 125#endif 126 127extern u_long rip_sendspace; 128extern u_long rip_recvspace; 129 130/* |
131 * Hooks for multicast routing. They all default to NULL, so leave them not 132 * initialized and rely on BSS being set to 0. |
133 */ |
134 135/* 136 * The socket used to communicate with the multicast routing daemon. 137 */ 138#ifdef VIMAGE_GLOBALS 139struct socket *ip6_mrouter; 140#endif 141 142/* 143 * The various mrouter functions. 144 */ |
145int (*ip6_mrouter_set)(struct socket *, struct sockopt *); 146int (*ip6_mrouter_get)(struct socket *, struct sockopt *); 147int (*ip6_mrouter_done)(void); 148int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *); 149int (*mrt6_ioctl)(int, caddr_t); 150 151/* 152 * Setup generic address and protocol structures for raw_input routine, then 153 * pass them along with mbuf chain. 154 */ 155int 156rip6_input(struct mbuf **mp, int *offp, int proto) 157{ 158 INIT_VNET_INET(curvnet); 159 INIT_VNET_INET6(curvnet); 160#ifdef IPSEC 161 INIT_VNET_IPSEC(curvnet); 162#endif |
163 struct ifnet *ifp; |
164 struct mbuf *m = *mp; 165 register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 166 register struct inpcb *in6p; 167 struct inpcb *last = 0; 168 struct mbuf *opts = NULL; 169 struct sockaddr_in6 fromsa; 170 171 V_rip6stat.rip6s_ipackets++; 172 173 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { 174 /* XXX Send icmp6 host/port unreach? */ 175 m_freem(m); 176 return (IPPROTO_DONE); 177 } 178 179 init_sin6(&fromsa, m); /* general init */ 180 |
181 ifp = m->m_pkthdr.rcvif; 182 |
183 INP_INFO_RLOCK(&V_ripcbinfo); 184 LIST_FOREACH(in6p, &V_ripcb, inp_list) { 185 /* XXX inp locking */ 186 if ((in6p->inp_vflag & INP_IPV6) == 0) 187 continue; 188 if (in6p->inp_ip_p && 189 in6p->inp_ip_p != proto) 190 continue; 191 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 192 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) 193 continue; 194 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && 195 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) 196 continue; |
197 if (jailed(in6p->inp_cred)) { 198 /* 199 * Allow raw socket in jail to receive multicast; 200 * assume process had PRIV_NETINET_RAW at attach, 201 * and fall through into normal filter path if so. 202 */ 203 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && 204 prison_check_ip6(in6p->inp_cred, 205 &ip6->ip6_dst) != 0) 206 continue; 207 } |
208 if (in6p->in6p_cksum != -1) { 209 V_rip6stat.rip6s_isum++; 210 if (in6_cksum(m, proto, *offp, 211 m->m_pkthdr.len - *offp)) { 212 INP_RUNLOCK(in6p); 213 V_rip6stat.rip6s_badsum++; 214 continue; 215 } 216 } |
217 INP_RLOCK(in6p); 218 /* 219 * If this raw socket has multicast state, and we 220 * have received a multicast, check if this socket 221 * should receive it, as multicast filtering is now 222 * the responsibility of the transport layer. 223 */ 224 if (in6p->in6p_moptions && 225 IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 226 struct sockaddr_in6 mcaddr; 227 int blocked; 228 229 bzero(&mcaddr, sizeof(struct sockaddr_in6)); 230 mcaddr.sin6_len = sizeof(struct sockaddr_in6); 231 mcaddr.sin6_family = AF_INET6; 232 mcaddr.sin6_addr = ip6->ip6_dst; 233 234 blocked = im6o_mc_filter(in6p->in6p_moptions, ifp, 235 (struct sockaddr *)&mcaddr, 236 (struct sockaddr *)&fromsa); 237 if (blocked != MCAST_PASS) { 238 IP6STAT_INC(ip6s_notmember); 239 continue; 240 } 241 } |
242 if (last != NULL) { 243 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); 244 245#ifdef IPSEC 246 /* 247 * Check AH/ESP integrity. 248 */ 249 if (n && ipsec6_in_reject(n, last)) { --- 396 unchanged lines hidden (view full) --- 646 ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt); 647 INP_WUNLOCK(inp); 648 return (0); 649} 650 651static void 652rip6_detach(struct socket *so) 653{ |
654 INIT_VNET_INET6(so->so_vnet); |
655 struct inpcb *inp; 656 657 inp = sotoinpcb(so); 658 KASSERT(inp != NULL, ("rip6_detach: inp == NULL")); 659 |
660 if (so == V_ip6_mrouter && ip6_mrouter_done) |
661 ip6_mrouter_done(); 662 /* xxx: RSVP */ 663 INP_INFO_WLOCK(&V_ripcbinfo); 664 INP_WLOCK(inp); 665 free(inp->in6p_icmp6filt, M_PCB); 666 in_pcbdetach(inp); 667 in_pcbfree(inp); 668 INP_INFO_WUNLOCK(&V_ripcbinfo); --- 228 unchanged lines hidden --- |