version 1.35, 2001/07/25 23:28:03 |
version 1.36, 2001/10/18 07:44:35 |
Line 157 rip6_input(mp, offp, proto) |
|
Line 157 rip6_input(mp, offp, proto) |
|
bzero(&rip6src, sizeof(rip6src)); |
bzero(&rip6src, sizeof(rip6src)); |
rip6src.sin6_len = sizeof(struct sockaddr_in6); |
rip6src.sin6_len = sizeof(struct sockaddr_in6); |
rip6src.sin6_family = AF_INET6; |
rip6src.sin6_family = AF_INET6; |
#if 0 /*XXX inbound flowlabel */ |
#if 0 /* XXX inbound flowlabel */ |
rip6src.sin6_flowinfo = ip6->ip6_flow & IPV6_FLOWINFO_MASK; |
rip6src.sin6_flowinfo = ip6->ip6_flow & IPV6_FLOWINFO_MASK; |
#endif |
#endif |
/* KAME hack: recover scopeid */ |
/* KAME hack: recover scopeid */ |
Line 527 rip6_output(m, va_alist) |
|
Line 527 rip6_output(m, va_alist) |
|
return(error); |
return(error); |
} |
} |
|
|
/* |
/* |
* Raw IPv6 socket option processing. |
* Raw IPv6 socket option processing. |
*/ |
*/ |
int |
int |
rip6_ctloutput(op, so, level, optname, m) |
rip6_ctloutput(op, so, level, optname, mp) |
int op; |
int op; |
struct socket *so; |
struct socket *so; |
int level, optname; |
int level, optname; |
struct mbuf **m; |
struct mbuf **mp; |
{ |
{ |
int error = 0; |
int error = 0; |
|
int optval; |
|
struct in6pcb *in6p; |
|
struct mbuf *m; |
|
const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum); |
|
|
switch (level) { |
switch (level) { |
case IPPROTO_IPV6: |
case IPPROTO_IPV6: |
Line 550 rip6_ctloutput(op, so, level, optname, m |
|
Line 554 rip6_ctloutput(op, so, level, optname, m |
|
case MRT6_DEL_MFC: |
case MRT6_DEL_MFC: |
case MRT6_PIM: |
case MRT6_PIM: |
if (op == PRCO_SETOPT) { |
if (op == PRCO_SETOPT) { |
error = ip6_mrouter_set(optname, so, *m); |
error = ip6_mrouter_set(optname, so, *mp); |
if (*m) |
if (*mp) |
(void)m_free(*m); |
(void)m_free(*mp); |
|
} else if (op == PRCO_GETOPT) |
|
error = ip6_mrouter_get(optname, so, mp); |
|
else |
|
error = EINVAL; |
|
return (error); |
|
case IPV6_CHECKSUM: |
|
/* |
|
* for ICMPv6 sockets, no modification allowed for |
|
* checksum offset, permit "no change" values to |
|
* help existing apps. |
|
*/ |
|
in6p = sotoin6pcb(so); |
|
error = 0; |
|
if (op == PRCO_SETOPT) { |
|
m = *mp; |
|
if (m && m->m_len == sizeof(int)) { |
|
optval = *mtod(m, int *); |
|
if (so->so_proto->pr_protocol == |
|
IPPROTO_ICMPV6) { |
|
if (optval != icmp6off) |
|
error = EINVAL; |
|
} else |
|
in6p->in6p_cksum = optval; |
|
} else |
|
error = EINVAL; |
|
if (m) |
|
m_free(m); |
} else if (op == PRCO_GETOPT) { |
} else if (op == PRCO_GETOPT) { |
error = ip6_mrouter_get(optname, so, m); |
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) |
|
optval = icmp6off; |
|
else |
|
optval = in6p->in6p_cksum; |
|
*mp = m = m_get(M_WAIT, MT_SOOPTS); |
|
m->m_len = sizeof(int); |
|
*mtod(m, int *) = optval; |
} else |
} else |
error = EINVAL; |
error = EINVAL; |
return (error); |
return error; |
|
default: |
|
return (ip6_ctloutput(op, so, level, optname, mp)); |
} |
} |
return (ip6_ctloutput(op, so, level, optname, m)); |
|
/* NOTREACHED */ |
|
|
|
case IPPROTO_ICMPV6: |
case IPPROTO_ICMPV6: |
/* |
/* |
* XXX: is it better to call icmp6_ctloutput() directly |
* XXX: is it better to call icmp6_ctloutput() directly |
* from protosw? |
* from protosw? |
*/ |
*/ |
return(icmp6_ctloutput(op, so, level, optname, m)); |
return(icmp6_ctloutput(op, so, level, optname, mp)); |
|
|
default: |
default: |
if (op == PRCO_SETOPT && *m) |
if (op == PRCO_SETOPT && *mp) |
(void)m_free(*m); |
m_free(*mp); |
return(EINVAL); |
return EINVAL; |
} |
} |
} |
} |
|
|
Line 698 rip6_usrreq(so, req, m, nam, control, p) |
|
Line 735 rip6_usrreq(so, req, m, nam, control, p) |
|
error = EADDRNOTAVAIL; |
error = EADDRNOTAVAIL; |
break; |
break; |
} |
} |
/* |
|
* Currently, ifa_ifwithaddr tends to fail for a link-local |
|
* address, since it implicitly expects that the link ID |
|
* for the address is embedded in the sin6_addr part. |
|
* For now, we'd rather keep this "as is". We'll eventually fix |
|
* this in a more natural way. |
|
*/ |
|
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && |
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && |
(ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0) { |
(ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0) { |
error = EADDRNOTAVAIL; |
error = EADDRNOTAVAIL; |
Line 720 rip6_usrreq(so, req, m, nam, control, p) |
|
Line 750 rip6_usrreq(so, req, m, nam, control, p) |
|
in6p->in6p_laddr = addr->sin6_addr; |
in6p->in6p_laddr = addr->sin6_addr; |
break; |
break; |
} |
} |
|
|
case PRU_CONNECT: |
case PRU_CONNECT: |
{ |
{ |
struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *); |
struct sockaddr_in6 *addr = mtod(nam, struct sockaddr_in6 *); |