mld6.c (ec002fee9957c147af90cc5159ef6d2f5538dc73) | mld6.c (1272577e22d8f1c1c5b5e88f2624836e93aecb17) |
---|---|
1/* $FreeBSD$ */ 2/* $KAME: mld6.c,v 1.27 2001/04/04 05:17:30 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 96 unchanged lines hidden (view full) --- 105 106static void mld6_sendpkt(struct in6_multi *, int, const struct in6_addr *); 107static void mld_starttimer(struct in6_multi *); 108static void mld_stoptimer(struct in6_multi *); 109static void mld_timeo(struct in6_multi *); 110static u_long mld_timerresid(struct in6_multi *); 111 112void | 1/* $FreeBSD$ */ 2/* $KAME: mld6.c,v 1.27 2001/04/04 05:17:30 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 96 unchanged lines hidden (view full) --- 105 106static void mld6_sendpkt(struct in6_multi *, int, const struct in6_addr *); 107static void mld_starttimer(struct in6_multi *); 108static void mld_stoptimer(struct in6_multi *); 109static void mld_timeo(struct in6_multi *); 110static u_long mld_timerresid(struct in6_multi *); 111 112void |
113mld6_init() | 113mld6_init(void) |
114{ 115 static u_int8_t hbh_buf[8]; 116 struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; 117 u_int16_t rtalert_code = htons((u_int16_t)IP6OPT_RTALERT_MLD); 118 119 /* ip6h_nxt will be fill in later */ 120 hbh->ip6h_len = 0; /* (8 >> 3) - 1 */ 121 --- 4 unchanged lines hidden (view full) --- 126 hbh_buf[5] = IP6OPT_RTALERT_LEN - 2; 127 bcopy((caddr_t)&rtalert_code, &hbh_buf[6], sizeof(u_int16_t)); 128 129 ip6_initpktopts(&ip6_opts); 130 ip6_opts.ip6po_hbh = hbh; 131} 132 133static void | 114{ 115 static u_int8_t hbh_buf[8]; 116 struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; 117 u_int16_t rtalert_code = htons((u_int16_t)IP6OPT_RTALERT_MLD); 118 119 /* ip6h_nxt will be fill in later */ 120 hbh->ip6h_len = 0; /* (8 >> 3) - 1 */ 121 --- 4 unchanged lines hidden (view full) --- 126 hbh_buf[5] = IP6OPT_RTALERT_LEN - 2; 127 bcopy((caddr_t)&rtalert_code, &hbh_buf[6], sizeof(u_int16_t)); 128 129 ip6_initpktopts(&ip6_opts); 130 ip6_opts.ip6po_hbh = hbh; 131} 132 133static void |
134mld_starttimer(in6m) 135 struct in6_multi *in6m; | 134mld_starttimer(struct in6_multi *in6m) |
136{ 137 struct timeval now; 138 139 microtime(&now); 140 in6m->in6m_timer_expire.tv_sec = now.tv_sec + in6m->in6m_timer / hz; 141 in6m->in6m_timer_expire.tv_usec = now.tv_usec + 142 (in6m->in6m_timer % hz) * (1000000 / hz); 143 if (in6m->in6m_timer_expire.tv_usec > 1000000) { 144 in6m->in6m_timer_expire.tv_sec++; 145 in6m->in6m_timer_expire.tv_usec -= 1000000; 146 } 147 148 /* start or restart the timer */ 149 callout_reset(in6m->in6m_timer_ch, in6m->in6m_timer, 150 (void (*) __P((void *)))mld_timeo, in6m); 151} 152 153static void | 135{ 136 struct timeval now; 137 138 microtime(&now); 139 in6m->in6m_timer_expire.tv_sec = now.tv_sec + in6m->in6m_timer / hz; 140 in6m->in6m_timer_expire.tv_usec = now.tv_usec + 141 (in6m->in6m_timer % hz) * (1000000 / hz); 142 if (in6m->in6m_timer_expire.tv_usec > 1000000) { 143 in6m->in6m_timer_expire.tv_sec++; 144 in6m->in6m_timer_expire.tv_usec -= 1000000; 145 } 146 147 /* start or restart the timer */ 148 callout_reset(in6m->in6m_timer_ch, in6m->in6m_timer, 149 (void (*) __P((void *)))mld_timeo, in6m); 150} 151 152static void |
154mld_stoptimer(in6m) 155 struct in6_multi *in6m; | 153mld_stoptimer(struct in6_multi *in6m) |
156{ 157 if (in6m->in6m_timer == IN6M_TIMER_UNDEF) 158 return; 159 160 callout_stop(in6m->in6m_timer_ch); 161 in6m->in6m_timer = IN6M_TIMER_UNDEF; 162} 163 164static void | 154{ 155 if (in6m->in6m_timer == IN6M_TIMER_UNDEF) 156 return; 157 158 callout_stop(in6m->in6m_timer_ch); 159 in6m->in6m_timer = IN6M_TIMER_UNDEF; 160} 161 162static void |
165mld_timeo(in6m) 166 struct in6_multi *in6m; | 163mld_timeo(struct in6_multi *in6m) |
167{ 168 int s = splnet(); 169 170 in6m->in6m_timer = IN6M_TIMER_UNDEF; 171 172 callout_stop(in6m->in6m_timer_ch); 173 174 switch (in6m->in6m_state) { --- 4 unchanged lines hidden (view full) --- 179 mld6_sendpkt(in6m, MLD_LISTENER_REPORT, NULL); 180 break; 181 } 182 183 splx(s); 184} 185 186static u_long | 164{ 165 int s = splnet(); 166 167 in6m->in6m_timer = IN6M_TIMER_UNDEF; 168 169 callout_stop(in6m->in6m_timer_ch); 170 171 switch (in6m->in6m_state) { --- 4 unchanged lines hidden (view full) --- 176 mld6_sendpkt(in6m, MLD_LISTENER_REPORT, NULL); 177 break; 178 } 179 180 splx(s); 181} 182 183static u_long |
187mld_timerresid(in6m) 188 struct in6_multi *in6m; | 184mld_timerresid(struct in6_multi *in6m) |
189{ 190 struct timeval now, diff; 191 192 microtime(&now); 193 194 if (now.tv_sec > in6m->in6m_timer_expire.tv_sec || 195 (now.tv_sec == in6m->in6m_timer_expire.tv_sec && 196 now.tv_usec > in6m->in6m_timer_expire.tv_usec)) { --- 7 unchanged lines hidden (view full) --- 204 diff.tv_usec += 1000000; 205 } 206 207 /* return the remaining time in milliseconds */ 208 return (((u_long)(diff.tv_sec * 1000000 + diff.tv_usec)) / 1000); 209} 210 211void | 185{ 186 struct timeval now, diff; 187 188 microtime(&now); 189 190 if (now.tv_sec > in6m->in6m_timer_expire.tv_sec || 191 (now.tv_sec == in6m->in6m_timer_expire.tv_sec && 192 now.tv_usec > in6m->in6m_timer_expire.tv_usec)) { --- 7 unchanged lines hidden (view full) --- 200 diff.tv_usec += 1000000; 201 } 202 203 /* return the remaining time in milliseconds */ 204 return (((u_long)(diff.tv_sec * 1000000 + diff.tv_usec)) / 1000); 205} 206 207void |
212mld6_start_listening(in6m) 213 struct in6_multi *in6m; | 208mld6_start_listening(struct in6_multi *in6m) |
214{ 215 struct in6_addr all_in6; 216 int s = splnet(); 217 218 /* 219 * RFC2710 page 10: 220 * The node never sends a Report or Done for the link-scope all-nodes 221 * address. --- 18 unchanged lines hidden (view full) --- 240 in6m->in6m_state = MLD_IREPORTEDLAST; 241 242 mld_starttimer(in6m); 243 } 244 splx(s); 245} 246 247void | 209{ 210 struct in6_addr all_in6; 211 int s = splnet(); 212 213 /* 214 * RFC2710 page 10: 215 * The node never sends a Report or Done for the link-scope all-nodes 216 * address. --- 18 unchanged lines hidden (view full) --- 235 in6m->in6m_state = MLD_IREPORTEDLAST; 236 237 mld_starttimer(in6m); 238 } 239 splx(s); 240} 241 242void |
248mld6_stop_listening(in6m) 249 struct in6_multi *in6m; | 243mld6_stop_listening(struct in6_multi *in6m) |
250{ 251 struct in6_addr allnode, allrouter; 252 253 allnode = in6addr_linklocal_allnodes; 254 if (in6_setscope(&allnode, in6m->in6m_ifp, NULL)) { 255 /* XXX: this should not happen! */ 256 return; 257 } --- 6 unchanged lines hidden (view full) --- 264 !IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &allnode) && 265 IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > 266 IPV6_ADDR_SCOPE_INTFACELOCAL) { 267 mld6_sendpkt(in6m, MLD_LISTENER_DONE, &allrouter); 268 } 269} 270 271void | 244{ 245 struct in6_addr allnode, allrouter; 246 247 allnode = in6addr_linklocal_allnodes; 248 if (in6_setscope(&allnode, in6m->in6m_ifp, NULL)) { 249 /* XXX: this should not happen! */ 250 return; 251 } --- 6 unchanged lines hidden (view full) --- 258 !IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &allnode) && 259 IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > 260 IPV6_ADDR_SCOPE_INTFACELOCAL) { 261 mld6_sendpkt(in6m, MLD_LISTENER_DONE, &allrouter); 262 } 263} 264 265void |
272mld6_input(m, off) 273 struct mbuf *m; 274 int off; | 266mld6_input(struct mbuf *m, int off) |
275{ 276 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 277 struct mld_hdr *mldh; 278 struct ifnet *ifp = m->m_pkthdr.rcvif; 279 struct in6_multi *in6m; 280 struct in6_addr mld_addr, all_in6; 281 struct in6_ifaddr *ia; 282 struct ifmultiaddr *ifma; --- 153 unchanged lines hidden (view full) --- 436 log(LOG_ERR, "mld6_input: illegal type(%d)", mldh->mld_type); 437 break; 438 } 439 440 m_freem(m); 441} 442 443static void | 267{ 268 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 269 struct mld_hdr *mldh; 270 struct ifnet *ifp = m->m_pkthdr.rcvif; 271 struct in6_multi *in6m; 272 struct in6_addr mld_addr, all_in6; 273 struct in6_ifaddr *ia; 274 struct ifmultiaddr *ifma; --- 153 unchanged lines hidden (view full) --- 428 log(LOG_ERR, "mld6_input: illegal type(%d)", mldh->mld_type); 429 break; 430 } 431 432 m_freem(m); 433} 434 435static void |
444mld6_sendpkt(in6m, type, dst) 445 struct in6_multi *in6m; 446 int type; 447 const struct in6_addr *dst; | 436mld6_sendpkt(struct in6_multi *in6m, int type, const struct in6_addr *dst) |
448{ 449 struct mbuf *mh, *md; 450 struct mld_hdr *mldh; 451 struct ip6_hdr *ip6; 452 struct ip6_moptions im6o; 453 struct in6_ifaddr *ia; 454 struct ifnet *ifp = in6m->in6m_ifp; 455 struct ifnet *outif = NULL; --- 83 unchanged lines hidden (view full) --- 539} 540 541/* 542 * Add an address to the list of IP6 multicast addresses for a given interface. 543 * Add source addresses to the list also, if upstream router is MLDv2 capable 544 * and the number of source is not 0. 545 */ 546struct in6_multi * | 437{ 438 struct mbuf *mh, *md; 439 struct mld_hdr *mldh; 440 struct ip6_hdr *ip6; 441 struct ip6_moptions im6o; 442 struct in6_ifaddr *ia; 443 struct ifnet *ifp = in6m->in6m_ifp; 444 struct ifnet *outif = NULL; --- 83 unchanged lines hidden (view full) --- 528} 529 530/* 531 * Add an address to the list of IP6 multicast addresses for a given interface. 532 * Add source addresses to the list also, if upstream router is MLDv2 capable 533 * and the number of source is not 0. 534 */ 535struct in6_multi * |
547in6_addmulti(maddr6, ifp, errorp, delay) 548 struct in6_addr *maddr6; 549 struct ifnet *ifp; 550 int *errorp, delay; | 536in6_addmulti(struct in6_addr *maddr6, struct ifnet *ifp, 537 int *errorp, int delay) |
551{ 552 struct in6_multi *in6m; 553 554 *errorp = 0; 555 in6m = NULL; 556 557 IFF_LOCKGIANT(ifp); 558 /*IN6_MULTI_LOCK();*/ --- 103 unchanged lines hidden --- | 538{ 539 struct in6_multi *in6m; 540 541 *errorp = 0; 542 in6m = NULL; 543 544 IFF_LOCKGIANT(ifp); 545 /*IN6_MULTI_LOCK();*/ --- 103 unchanged lines hidden --- |