re-add wrongly disappered IPV6_CHECKSUM stuff by introducing

ip6_raw_ctloutput().

Obtained from:	KAME
This commit is contained in:
Hajimu UMEMOTO 2003-10-26 18:17:01 +00:00
parent 06f544b2d6
commit 02b9a2066e
3 changed files with 83 additions and 0 deletions

View File

@ -2118,6 +2118,82 @@ do { \
return (error);
}
int
ip6_raw_ctloutput(so, sopt)
struct socket *so;
struct sockopt *sopt;
{
int error = 0, optval, optlen;
const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
struct in6pcb *in6p = sotoin6pcb(so);
int level, op, optname;
if (sopt) {
level = sopt->sopt_level;
op = sopt->sopt_dir;
optname = sopt->sopt_name;
optlen = sopt->sopt_valsize;
} else
panic("ip6_raw_ctloutput: arg soopt is NULL");
if (level != IPPROTO_IPV6) {
return (EINVAL);
}
switch (optname) {
case IPV6_CHECKSUM:
/*
* For ICMPv6 sockets, no modification allowed for checksum
* offset, permit "no change" values to help existing apps.
*
* XXX 2292bis says: "An attempt to set IPV6_CHECKSUM
* for an ICMPv6 socket will fail."
* The current behavior does not meet 2292bis.
*/
switch (op) {
case SOPT_SET:
if (optlen != sizeof(int)) {
error = EINVAL;
break;
}
error = sooptcopyin(sopt, &optval, sizeof(optval),
sizeof(optval));
if (error)
break;
if ((optval % 2) != 0) {
/* the API assumes even offset values */
error = EINVAL;
} else if (so->so_proto->pr_protocol ==
IPPROTO_ICMPV6) {
if (optval != icmp6off)
error = EINVAL;
} else
in6p->in6p_cksum = optval;
break;
case SOPT_GET:
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
optval = icmp6off;
else
optval = in6p->in6p_cksum;
error = sooptcopyout(sopt, &optval, sizeof(optval));
break;
default:
error = EINVAL;
break;
}
break;
default:
error = ENOPROTOOPT;
break;
}
return (error);
}
/*
* Set up IP6 options in pcb for insertion in output packets or
* specifying behavior of outgoing packets.

View File

@ -367,6 +367,7 @@ int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
struct ip6_moptions *, struct ifnet **,
struct inpcb *));
int ip6_ctloutput __P((struct socket *, struct sockopt *));
int ip6_raw_ctloutput __P((struct socket *, struct sockopt *));
void init_ip6pktopts __P((struct ip6_pktopts *));
int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *,
struct ip6_pktopts *, int, int, int));

View File

@ -527,6 +527,9 @@ rip6_ctloutput(so, sopt)
case MRT6_PIM:
error = ip6_mrouter_get(so, sopt);
break;
case IPV6_CHECKSUM:
error = ip6_raw_ctloutput(so, sopt);
break;
default:
error = ip6_ctloutput(so, sopt);
break;
@ -544,6 +547,9 @@ rip6_ctloutput(so, sopt)
case MRT6_PIM:
error = ip6_mrouter_set(so, sopt);
break;
case IPV6_CHECKSUM:
error = ip6_raw_ctloutput(so, sopt);
break;
default:
error = ip6_ctloutput(so, sopt);
break;