version 1.39.6.1, 2007/09/03 16:49:08 |
version 1.44, 2008/04/15 03:57:04 |
Line 125 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 125 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <netinet6/ip6_var.h> |
#include <netinet6/ip6_var.h> |
#include <netinet6/scope6_var.h> |
#include <netinet6/scope6_var.h> |
#include <netinet/icmp6.h> |
#include <netinet/icmp6.h> |
|
#include <netinet6/icmp6_private.h> |
#include <netinet6/mld6_var.h> |
#include <netinet6/mld6_var.h> |
|
|
#include <net/net_osdep.h> |
#include <net/net_osdep.h> |
Line 163 static struct mld_hdr * mld_allocbuf(str |
|
Line 164 static struct mld_hdr * mld_allocbuf(str |
|
static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *); |
static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *); |
static void mld_starttimer(struct in6_multi *); |
static void mld_starttimer(struct in6_multi *); |
static void mld_stoptimer(struct in6_multi *); |
static void mld_stoptimer(struct in6_multi *); |
static void mld_timeo(struct in6_multi *); |
|
static u_long mld_timerresid(struct in6_multi *); |
static u_long mld_timerresid(struct in6_multi *); |
|
|
void |
void |
mld_init() |
mld_init(void) |
{ |
{ |
static u_int8_t hbh_buf[8]; |
static u_int8_t hbh_buf[8]; |
struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; |
struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; |
Line 203 mld_starttimer(struct in6_multi *in6m) |
|
Line 203 mld_starttimer(struct in6_multi *in6m) |
|
} |
} |
|
|
/* start or restart the timer */ |
/* start or restart the timer */ |
callout_reset(in6m->in6m_timer_ch, in6m->in6m_timer, |
callout_schedule(&in6m->in6m_timer_ch, in6m->in6m_timer); |
(void (*) __P((void *)))mld_timeo, in6m); |
|
} |
} |
|
|
static void |
static void |
Line 213 mld_stoptimer(struct in6_multi *in6m) |
|
Line 212 mld_stoptimer(struct in6_multi *in6m) |
|
if (in6m->in6m_timer == IN6M_TIMER_UNDEF) |
if (in6m->in6m_timer == IN6M_TIMER_UNDEF) |
return; |
return; |
|
|
callout_stop(in6m->in6m_timer_ch); |
callout_stop(&in6m->in6m_timer_ch); |
|
|
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
} |
} |
|
|
static void |
static void |
mld_timeo(struct in6_multi *in6m) |
mld_timeo(void *arg) |
{ |
{ |
|
struct in6_multi *in6m = arg; |
int s = splsoftnet(); |
int s = splsoftnet(); |
|
|
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
|
|
callout_stop(in6m->in6m_timer_ch); |
|
|
|
switch (in6m->in6m_state) { |
switch (in6m->in6m_state) { |
case MLD_REPORTPENDING: |
case MLD_REPORTPENDING: |
mld_start_listening(in6m); |
mld_start_listening(in6m); |
Line 332 mld_input(struct mbuf *m, int off) |
|
Line 330 mld_input(struct mbuf *m, int off) |
|
|
|
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) { |
icmp6stat.icp6s_tooshort++; |
ICMP6_STATINC(ICMP6_STAT_TOOSHORT); |
return; |
return; |
} |
} |
|
|
Line 539 mld_sendpkt(struct in6_multi *in6m, int |
|
Line 537 mld_sendpkt(struct in6_multi *in6m, int |
|
im6o.im6o_multicast_loop = (ip6_mrouter != NULL); |
im6o.im6o_multicast_loop = (ip6_mrouter != NULL); |
|
|
/* increment output statictics */ |
/* increment output statictics */ |
icmp6stat.icp6s_outhist[type]++; |
ICMP6_STATINC(ICMP6_STAT_OUTHIST + type); |
icmp6_ifstat_inc(ifp, ifs6_out_msg); |
icmp6_ifstat_inc(ifp, ifs6_out_msg); |
switch (type) { |
switch (type) { |
case MLD_LISTENER_QUERY: |
case MLD_LISTENER_QUERY: |
Line 647 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 645 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; |
in6m->in6m_timer_ch = |
|
malloc(sizeof(*in6m->in6m_timer_ch), M_IPMADDR, M_NOWAIT); |
|
if (in6m->in6m_timer_ch == NULL) { |
|
free(in6m, M_IPMADDR); |
|
splx(s); |
|
return (NULL); |
|
} |
|
IFP_TO_IA6(ifp, ia); |
IFP_TO_IA6(ifp, ia); |
if (ia == NULL) { |
if (ia == NULL) { |
/* leaks in6m_timer_ch */ |
|
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
splx(s); |
splx(s); |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
Line 678 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 668 in6_addmulti(struct in6_addr *maddr6, st |
|
(void *)&ifr); |
(void *)&ifr); |
if (*errorp) { |
if (*errorp) { |
LIST_REMOVE(in6m, in6m_entry); |
LIST_REMOVE(in6m, in6m_entry); |
/* leaks in6m_timer_ch */ |
|
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
IFAFREE(&ia->ia_ifa); |
IFAFREE(&ia->ia_ifa); |
splx(s); |
splx(s); |
return (NULL); |
return (NULL); |
} |
} |
|
|
callout_init(in6m->in6m_timer_ch, 0); |
callout_init(&in6m->in6m_timer_ch, 0); |
|
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 752 in6_delmulti(struct in6_multi *in6m) |
|
Line 742 in6_delmulti(struct in6_multi *in6m) |
|
sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); |
sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); |
(*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, |
(*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, |
SIOCDELMULTI, (void *)&ifr); |
SIOCDELMULTI, (void *)&ifr); |
free(in6m->in6m_timer_ch, M_IPMADDR); |
callout_destroy(&in6m->in6m_timer_ch); |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
} |
} |
splx(s); |
splx(s); |