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 ---