| version 1.103.6.2, 2008/09/28 10:40:58 |
version 1.104, 2008/04/07 06:31:28 |
| Line 86 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| Line 86 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| #include <netinet/in_systm.h> |
#include <netinet/in_systm.h> |
| #include <netinet/ip.h> |
#include <netinet/ip.h> |
| #include <netinet/ip_var.h> |
#include <netinet/ip_var.h> |
| #include <netinet/ip_private.h> |
|
| #include <netinet/ip_mroute.h> |
#include <netinet/ip_mroute.h> |
| #include <netinet/ip_icmp.h> |
#include <netinet/ip_icmp.h> |
| #include <netinet/in_pcb.h> |
#include <netinet/in_pcb.h> |
| Line 97 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| Line 96 __KERNEL_RCSID(0, "$NetBSD$"); |
|
| |
|
| #ifdef IPSEC |
#ifdef IPSEC |
| #include <netinet6/ipsec.h> |
#include <netinet6/ipsec.h> |
| #include <netinet6/ipsec_private.h> |
#endif /*IPSEC*/ |
| #endif /* IPSEC */ |
|
| |
|
| #ifdef FAST_IPSEC |
#ifdef FAST_IPSEC |
| #include <netipsec/ipsec.h> |
#include <netipsec/ipsec.h> |
| #include <netipsec/ipsec_var.h> |
#include <netipsec/ipsec_var.h> /* XXX ipsecstat namespace */ |
| #include <netipsec/ipsec_private.h> |
#endif /* FAST_IPSEC*/ |
| #endif /* FAST_IPSEC */ |
|
| |
|
| struct inpcbtable rawcbtable; |
struct inpcbtable rawcbtable; |
| |
|
| Line 202 rip_input(struct mbuf *m, ...) |
|
| Line 199 rip_input(struct mbuf *m, ...) |
|
| #if defined(IPSEC) || defined(FAST_IPSEC) |
#if defined(IPSEC) || defined(FAST_IPSEC) |
| /* check AH/ESP integrity. */ |
/* check AH/ESP integrity. */ |
| else if (ipsec4_in_reject_so(m, last->inp_socket)) { |
else if (ipsec4_in_reject_so(m, last->inp_socket)) { |
| IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); |
ipsecstat.in_polvio++; |
| /* do not inject data to pcb */ |
/* do not inject data to pcb */ |
| } |
} |
| #endif /*IPSEC*/ |
#endif /*IPSEC*/ |
| Line 217 rip_input(struct mbuf *m, ...) |
|
| Line 214 rip_input(struct mbuf *m, ...) |
|
| /* check AH/ESP integrity. */ |
/* check AH/ESP integrity. */ |
| if (last != NULL && ipsec4_in_reject_so(m, last->inp_socket)) { |
if (last != NULL && ipsec4_in_reject_so(m, last->inp_socket)) { |
| m_freem(m); |
m_freem(m); |
| IPSEC_STATINC(IPSEC_STAT_IN_POLVIO); |
ipsecstat.in_polvio++; |
| IP_STATDEC(IP_STAT_DELIVERED); |
ipstat[IP_STAT_DELIVERED]--; |
| /* do not inject data to pcb */ |
/* do not inject data to pcb */ |
| } else |
} else |
| #endif /*IPSEC*/ |
#endif /*IPSEC*/ |
| if (last != NULL) |
if (last != NULL) |
| rip_sbappendaddr(last, ip, sintosa(&ripsrc), hlen, opts, m); |
rip_sbappendaddr(last, ip, sintosa(&ripsrc), hlen, opts, m); |
| else if (inetsw[ip_protox[ip->ip_p]].pr_input == rip_input) { |
else if (inetsw[ip_protox[ip->ip_p]].pr_input == rip_input) { |
| uint64_t *ips; |
|
| |
|
| icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, |
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, |
| 0, 0); |
0, 0); |
| ips = IP_STAT_GETREF(); |
ipstat[IP_STAT_NOPROTO]++; |
| ips[IP_STAT_NOPROTO]++; |
ipstat[IP_STAT_DELIVERED]--; |
| ips[IP_STAT_DELIVERED]--; |
|
| IP_STAT_PUTREF(); |
|
| } else |
} else |
| m_freem(m); |
m_freem(m); |
| return; |
return; |
| Line 370 rip_output(struct mbuf *m, ...) |
|
| Line 363 rip_output(struct mbuf *m, ...) |
|
| opts = NULL; |
opts = NULL; |
| /* XXX prevent ip_output from overwriting header fields */ |
/* XXX prevent ip_output from overwriting header fields */ |
| flags |= IP_RAWOUTPUT; |
flags |= IP_RAWOUTPUT; |
| IP_STATINC(IP_STAT_RAWOUT); |
ipstat[IP_STAT_RAWOUT]++; |
| } |
} |
| return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, |
return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, |
| inp->inp_socket, &inp->inp_errormtu)); |
inp->inp_socket, &inp->inp_errormtu)); |
| Line 380 rip_output(struct mbuf *m, ...) |
|
| Line 373 rip_output(struct mbuf *m, ...) |
|
| * Raw IP socket option processing. |
* Raw IP socket option processing. |
| */ |
*/ |
| int |
int |
| rip_ctloutput(int op, struct socket *so, struct sockopt *sopt) |
rip_ctloutput(int op, struct socket *so, int level, int optname, |
| |
struct mbuf **m) |
| { |
{ |
| struct inpcb *inp = sotoinpcb(so); |
struct inpcb *inp = sotoinpcb(so); |
| int error = 0; |
int error = 0; |
| int optval; |
|
| |
|
| if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) { |
if (level == SOL_SOCKET && optname == SO_NOHEADER) { |
| if (op == PRCO_GETOPT) { |
if (op == PRCO_GETOPT) { |
| optval = (inp->inp_flags & INP_NOHEADER) ? 1 : 0; |
*m = m_intopt(so, |
| error = sockopt_set(sopt, &optval, sizeof(optval)); |
(inp->inp_flags & INP_NOHEADER) ? 1 : 0); |
| } else if (op == PRCO_SETOPT) { |
return 0; |
| error = sockopt_getint(sopt, &optval); |
} else if (*m == NULL || (*m)->m_len != sizeof(int)) |
| if (error) |
error = EINVAL; |
| goto out; |
else if (*mtod(*m, int *)) { |
| if (optval) { |
inp->inp_flags &= ~INP_HDRINCL; |
| inp->inp_flags &= ~INP_HDRINCL; |
inp->inp_flags |= INP_NOHEADER; |
| inp->inp_flags |= INP_NOHEADER; |
} else |
| } else |
inp->inp_flags &= ~INP_NOHEADER; |
| inp->inp_flags &= ~INP_NOHEADER; |
goto free_m; |
| } |
} else if (level != IPPROTO_IP) |
| goto out; |
return ip_ctloutput(op, so, level, optname, m); |
| } else if (sopt->sopt_level != IPPROTO_IP) |
|
| return ip_ctloutput(op, so, sopt); |
|
| |
|
| switch (op) { |
switch (op) { |
| |
|
| case PRCO_SETOPT: |
case PRCO_SETOPT: |
| switch (sopt->sopt_name) { |
switch (optname) { |
| case IP_HDRINCL: |
case IP_HDRINCL: |
| error = sockopt_getint(sopt, &optval); |
if (*m == NULL || (*m)->m_len != sizeof(int)) |
| if (error) |
error = EINVAL; |
| break; |
else if (*mtod(*m, int *)) |
| if (optval) |
|
| inp->inp_flags |= INP_HDRINCL; |
inp->inp_flags |= INP_HDRINCL; |
| else |
else |
| inp->inp_flags &= ~INP_HDRINCL; |
inp->inp_flags &= ~INP_HDRINCL; |
| break; |
goto free_m; |
| |
|
| #ifdef MROUTING |
#ifdef MROUTING |
| case MRT_INIT: |
case MRT_INIT: |
| Line 429 rip_ctloutput(int op, struct socket *so, |
|
| Line 419 rip_ctloutput(int op, struct socket *so, |
|
| case MRT_API_CONFIG: |
case MRT_API_CONFIG: |
| case MRT_ADD_BW_UPCALL: |
case MRT_ADD_BW_UPCALL: |
| case MRT_DEL_BW_UPCALL: |
case MRT_DEL_BW_UPCALL: |
| error = ip_mrouter_set(so, sopt); |
error = ip_mrouter_set(so, optname, m); |
| break; |
break; |
| #endif |
#endif |
| |
|
| default: |
default: |
| error = ip_ctloutput(op, so, sopt); |
error = ip_ctloutput(op, so, level, optname, m); |
| break; |
break; |
| } |
} |
| break; |
break; |
| |
|
| case PRCO_GETOPT: |
case PRCO_GETOPT: |
| switch (sopt->sopt_name) { |
switch (optname) { |
| case IP_HDRINCL: |
case IP_HDRINCL: |
| optval = inp->inp_flags & INP_HDRINCL; |
*m = m_intopt(so, inp->inp_flags & INP_HDRINCL ? 1 : 0); |
| error = sockopt_set(sopt, &optval, sizeof(optval)); |
|
| break; |
break; |
| |
|
| #ifdef MROUTING |
#ifdef MROUTING |
| Line 451 rip_ctloutput(int op, struct socket *so, |
|
| Line 440 rip_ctloutput(int op, struct socket *so, |
|
| case MRT_ASSERT: |
case MRT_ASSERT: |
| case MRT_API_SUPPORT: |
case MRT_API_SUPPORT: |
| case MRT_API_CONFIG: |
case MRT_API_CONFIG: |
| error = ip_mrouter_get(so, sopt); |
error = ip_mrouter_get(so, optname, m); |
| break; |
break; |
| #endif |
#endif |
| |
|
| default: |
default: |
| error = ip_ctloutput(op, so, sopt); |
error = ip_ctloutput(op, so, level, optname, m); |
| break; |
break; |
| } |
} |
| break; |
break; |
| } |
} |
| out: |
return error; |
| |
free_m: |
| |
if (op == PRCO_SETOPT && *m != NULL) |
| |
(void)m_free(*m); |
| return error; |
return error; |
| } |
} |
| |
|
| Line 529 rip_usrreq(struct socket *so, int req, |
|
| Line 521 rip_usrreq(struct socket *so, int req, |
|
| s = splsoftnet(); |
s = splsoftnet(); |
| |
|
| if (req == PRU_PURGEIF) { |
if (req == PRU_PURGEIF) { |
| mutex_enter(softnet_lock); |
|
| in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control); |
in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control); |
| in_purgeif((struct ifnet *)control); |
in_purgeif((struct ifnet *)control); |
| in_pcbpurgeif(&rawcbtable, (struct ifnet *)control); |
in_pcbpurgeif(&rawcbtable, (struct ifnet *)control); |
| mutex_exit(softnet_lock); |
|
| splx(s); |
splx(s); |
| return (0); |
return (0); |
| } |
} |
| Line 551 rip_usrreq(struct socket *so, int req, |
|
| Line 541 rip_usrreq(struct socket *so, int req, |
|
| switch (req) { |
switch (req) { |
| |
|
| case PRU_ATTACH: |
case PRU_ATTACH: |
| sosetlock(so); |
|
| if (inp != 0) { |
if (inp != 0) { |
| error = EISCONN; |
error = EISCONN; |
| break; |
break; |