Deleted Added
full compact
raw_ip6.c (190964) raw_ip6.c (191672)
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>
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 190964 2009-04-12 13:22:33Z rwatson $");
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/*
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 forwarding.
131 * Hooks for multicast routing. They all default to NULL, so leave them not
132 * initialized and rely on BSS being set to 0.
132 */
133 */
133struct socket *ip6_mrouter = NULL;
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 */
134int (*ip6_mrouter_set)(struct socket *, struct sockopt *);
135int (*ip6_mrouter_get)(struct socket *, struct sockopt *);
136int (*ip6_mrouter_done)(void);
137int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *);
138int (*mrt6_ioctl)(int, caddr_t);
139
140/*
141 * Setup generic address and protocol structures for raw_input routine, then
142 * pass them along with mbuf chain.
143 */
144int
145rip6_input(struct mbuf **mp, int *offp, int proto)
146{
147 INIT_VNET_INET(curvnet);
148 INIT_VNET_INET6(curvnet);
149#ifdef IPSEC
150 INIT_VNET_IPSEC(curvnet);
151#endif
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;
152 struct mbuf *m = *mp;
153 register struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
154 register struct inpcb *in6p;
155 struct inpcb *last = 0;
156 struct mbuf *opts = NULL;
157 struct sockaddr_in6 fromsa;
158
159 V_rip6stat.rip6s_ipackets++;
160
161 if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) {
162 /* XXX Send icmp6 host/port unreach? */
163 m_freem(m);
164 return (IPPROTO_DONE);
165 }
166
167 init_sin6(&fromsa, m); /* general init */
168
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
169 INP_INFO_RLOCK(&V_ripcbinfo);
170 LIST_FOREACH(in6p, &V_ripcb, inp_list) {
171 /* XXX inp locking */
172 if ((in6p->inp_vflag & INP_IPV6) == 0)
173 continue;
174 if (in6p->inp_ip_p &&
175 in6p->inp_ip_p != proto)
176 continue;
177 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
178 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
179 continue;
180 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
181 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
182 continue;
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;
183 if (prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst) != 0)
184 continue;
185 INP_RLOCK(in6p);
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 }
186 if (in6p->in6p_cksum != -1) {
187 V_rip6stat.rip6s_isum++;
188 if (in6_cksum(m, proto, *offp,
189 m->m_pkthdr.len - *offp)) {
190 INP_RUNLOCK(in6p);
191 V_rip6stat.rip6s_badsum++;
192 continue;
193 }
194 }
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 }
195 if (last != NULL) {
196 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
197
198#ifdef IPSEC
199 /*
200 * Check AH/ESP integrity.
201 */
202 if (n && ipsec6_in_reject(n, last)) {

--- 396 unchanged lines hidden (view full) ---

599 ICMP6_FILTER_SETPASSALL(inp->in6p_icmp6filt);
600 INP_WUNLOCK(inp);
601 return (0);
602}
603
604static void
605rip6_detach(struct socket *so)
606{
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{
607 INIT_VNET_INET(so->so_vnet);
654 INIT_VNET_INET6(so->so_vnet);
608 struct inpcb *inp;
609
610 inp = sotoinpcb(so);
611 KASSERT(inp != NULL, ("rip6_detach: inp == NULL"));
612
655 struct inpcb *inp;
656
657 inp = sotoinpcb(so);
658 KASSERT(inp != NULL, ("rip6_detach: inp == NULL"));
659
613 if (so == ip6_mrouter && ip6_mrouter_done)
660 if (so == V_ip6_mrouter && ip6_mrouter_done)
614 ip6_mrouter_done();
615 /* xxx: RSVP */
616 INP_INFO_WLOCK(&V_ripcbinfo);
617 INP_WLOCK(inp);
618 free(inp->in6p_icmp6filt, M_PCB);
619 in_pcbdetach(inp);
620 in_pcbfree(inp);
621 INP_INFO_WUNLOCK(&V_ripcbinfo);

--- 228 unchanged lines hidden ---
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 ---