version 1.63, 2015/08/24 22:21:27 |
version 1.68, 2016/06/21 03:28:27 |
Line 336 mld_input(struct mbuf *m, int off) |
|
Line 336 mld_input(struct mbuf *m, int off) |
|
{ |
{ |
struct ip6_hdr *ip6; |
struct ip6_hdr *ip6; |
struct mld_hdr *mldh; |
struct mld_hdr *mldh; |
struct ifnet *ifp = m->m_pkthdr.rcvif; |
struct ifnet *ifp; |
struct in6_multi *in6m = NULL; |
struct in6_multi *in6m = NULL; |
struct in6_addr mld_addr, all_in6; |
struct in6_addr mld_addr, all_in6; |
struct in6_ifaddr *ia; |
struct in6_ifaddr *ia; |
u_long timer = 0; /* timer value in the MLD query header */ |
u_long timer = 0; /* timer value in the MLD query header */ |
|
int s; |
|
|
|
ifp = m_get_rcvif(m, &s); |
IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh)); |
IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh)); |
if (mldh == NULL) { |
if (mldh == NULL) { |
ICMP6_STATINC(ICMP6_STAT_TOOSHORT); |
ICMP6_STATINC(ICMP6_STAT_TOOSHORT); |
return; |
goto out_nodrop; |
} |
} |
|
|
/* source address validation */ |
/* source address validation */ |
Line 375 mld_input(struct mbuf *m, int off) |
|
Line 377 mld_input(struct mbuf *m, int off) |
|
"mld_input: src %s is not link-local (grp=%s)\n", |
"mld_input: src %s is not link-local (grp=%s)\n", |
ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&mldh->mld_addr)); |
ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&mldh->mld_addr)); |
#endif |
#endif |
m_freem(m); |
goto out; |
return; |
|
} |
} |
|
|
/* |
/* |
Line 385 mld_input(struct mbuf *m, int off) |
|
Line 386 mld_input(struct mbuf *m, int off) |
|
mld_addr = mldh->mld_addr; |
mld_addr = mldh->mld_addr; |
if (in6_setscope(&mld_addr, ifp, NULL)) { |
if (in6_setscope(&mld_addr, ifp, NULL)) { |
/* XXX: this should not happen! */ |
/* XXX: this should not happen! */ |
m_free(m); |
goto out; |
return; |
|
} |
} |
|
|
/* |
/* |
Line 497 mld_input(struct mbuf *m, int off) |
|
Line 497 mld_input(struct mbuf *m, int off) |
|
break; |
break; |
} |
} |
|
|
|
out: |
m_freem(m); |
m_freem(m); |
|
out_nodrop: |
|
m_put_rcvif(ifp, &s); |
} |
} |
|
|
static void |
static void |
Line 541 mld_sendpkt(struct in6_multi *in6m, int |
|
Line 544 mld_sendpkt(struct in6_multi *in6m, int |
|
|
|
/* construct multicast option */ |
/* construct multicast option */ |
memset(&im6o, 0, sizeof(im6o)); |
memset(&im6o, 0, sizeof(im6o)); |
im6o.im6o_multicast_ifp = ifp; |
im6o.im6o_multicast_if_index = if_get_index(ifp); |
im6o.im6o_multicast_hlim = 1; |
im6o.im6o_multicast_hlim = 1; |
|
|
/* |
/* |
Line 594 mld_allocbuf(struct mbuf **mh, int len, |
|
Line 597 mld_allocbuf(struct mbuf **mh, int len, |
|
(*mh)->m_next = md; |
(*mh)->m_next = md; |
md->m_next = NULL; |
md->m_next = NULL; |
|
|
(*mh)->m_pkthdr.rcvif = NULL; |
m_reset_rcvif((*mh)); |
(*mh)->m_pkthdr.len = sizeof(struct ip6_hdr) + len; |
(*mh)->m_pkthdr.len = sizeof(struct ip6_hdr) + len; |
(*mh)->m_len = sizeof(struct ip6_hdr); |
(*mh)->m_len = sizeof(struct ip6_hdr); |
MH_ALIGN(*mh, sizeof(struct ip6_hdr)); |
MH_ALIGN(*mh, sizeof(struct ip6_hdr)); |
Line 658 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 661 in6_addmulti(struct in6_addr *maddr6, st |
|
in6m->in6m_ifp = ifp; |
in6m->in6m_ifp = ifp; |
in6m->in6m_refcount = 1; |
in6m->in6m_refcount = 1; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
|
callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE); |
|
callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m); |
|
|
IFP_TO_IA6(ifp, ia); |
IFP_TO_IA6(ifp, ia); |
if (ia == NULL) { |
if (ia == NULL) { |
|
callout_destroy(&in6m->in6m_timer_ch); |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
splx(s); |
splx(s); |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
Line 676 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 683 in6_addmulti(struct in6_addr *maddr6, st |
|
sockaddr_in6_init(&sin6, maddr6, 0, 0, 0); |
sockaddr_in6_init(&sin6, maddr6, 0, 0, 0); |
*errorp = if_mcast_op(ifp, SIOCADDMULTI, sin6tosa(&sin6)); |
*errorp = if_mcast_op(ifp, SIOCADDMULTI, sin6tosa(&sin6)); |
if (*errorp) { |
if (*errorp) { |
|
callout_destroy(&in6m->in6m_timer_ch); |
LIST_REMOVE(in6m, in6m_entry); |
LIST_REMOVE(in6m, in6m_entry); |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
ifafree(&ia->ia_ifa); |
ifafree(&ia->ia_ifa); |
Line 683 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 691 in6_addmulti(struct in6_addr *maddr6, st |
|
return (NULL); |
return (NULL); |
} |
} |
|
|
callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE); |
|
callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m); |
|
in6m->in6m_timer = timer; |
in6m->in6m_timer = timer; |
if (in6m->in6m_timer > 0) { |
if (in6m->in6m_timer > 0) { |
in6m->in6m_state = MLD_REPORTPENDING; |
in6m->in6m_state = MLD_REPORTPENDING; |
Line 976 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
Line 982 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
uint32_t tmp; |
uint32_t tmp; |
int error; |
int error; |
size_t written; |
size_t written; |
|
struct psref psref; |
|
int bound; |
|
|
if (namelen != 1) |
if (namelen != 1) |
return EINVAL; |
return EINVAL; |
|
|
ifp = if_byindex(name[0]); |
bound = curlwp_bind(); |
if (ifp == NULL) |
ifp = if_get_byindex(name[0], &psref); |
|
if (ifp == NULL) { |
|
curlwp_bindx(bound); |
return ENODEV; |
return ENODEV; |
|
} |
|
|
if (oldp == NULL) { |
if (oldp == NULL) { |
*oldlenp = 0; |
*oldlenp = 0; |
Line 997 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
Line 1008 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
sizeof(uint32_t); |
sizeof(uint32_t); |
} |
} |
} |
} |
|
if_put(ifp, &psref); |
|
curlwp_bindx(bound); |
return 0; |
return 0; |
} |
} |
|
|
Line 1033 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
Line 1046 in6_multicast_sysctl(SYSCTLFN_ARGS) |
|
} |
} |
} |
} |
done: |
done: |
|
if_put(ifp, &psref); |
|
curlwp_bindx(bound); |
*oldlenp = written; |
*oldlenp = written; |
return error; |
return error; |
} |
} |