xref: /netbsd-src/sys/netinet/in.c (revision 6ea46cb5e46c49111a6ecf3bcbe3c7e2730fe9f6)
1 /*	$NetBSD: in.c,v 1.14 1994/06/29 06:38:00 cgd Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)in.c	8.2 (Berkeley) 11/15/93
36  */
37 
38 #include <sys/param.h>
39 #include <sys/ioctl.h>
40 #include <sys/errno.h>
41 #include <sys/malloc.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 
45 #include <net/if.h>
46 #include <net/route.h>
47 
48 #include <netinet/in_systm.h>
49 #include <netinet/in.h>
50 #include <netinet/in_var.h>
51 #include <netinet/if_ether.h>
52 
53 #include "ether.h"
54 
55 #ifdef INET
56 /*
57  * Return the network number from an internet address.
58  */
59 u_long
60 in_netof(in)
61 	struct in_addr in;
62 {
63 	register u_long i = ntohl(in.s_addr);
64 	register u_long net;
65 	register struct in_ifaddr *ia;
66 
67 	if (IN_CLASSA(i))
68 		net = i & IN_CLASSA_NET;
69 	else if (IN_CLASSB(i))
70 		net = i & IN_CLASSB_NET;
71 	else if (IN_CLASSC(i))
72 		net = i & IN_CLASSC_NET;
73 	else if (IN_CLASSD(i))
74 		net = i & IN_CLASSD_NET;
75 	else
76 		return (0);
77 
78 	/*
79 	 * Check whether network is a subnet;
80 	 * if so, return subnet number.
81 	 */
82 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
83 		if (net == ia->ia_net)
84 			return (i & ia->ia_subnetmask);
85 	return (net);
86 }
87 
88 #ifndef SUBNETSARELOCAL
89 #define	SUBNETSARELOCAL	1
90 #endif
91 int subnetsarelocal = SUBNETSARELOCAL;
92 /*
93  * Return 1 if an internet address is for a ``local'' host
94  * (one to which we have a connection).  If subnetsarelocal
95  * is true, this includes other subnets of the local net.
96  * Otherwise, it includes only the directly-connected (sub)nets.
97  */
98 int
99 in_localaddr(in)
100 	struct in_addr in;
101 {
102 	register u_long i = ntohl(in.s_addr);
103 	register struct in_ifaddr *ia;
104 
105 	if (subnetsarelocal) {
106 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
107 			if ((i & ia->ia_netmask) == ia->ia_net)
108 				return (1);
109 	} else {
110 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
111 			if ((i & ia->ia_subnetmask) == ia->ia_subnet)
112 				return (1);
113 	}
114 	return (0);
115 }
116 
117 /*
118  * Determine whether an IP address is in a reserved set of addresses
119  * that may not be forwarded, or whether datagrams to that destination
120  * may be forwarded.
121  */
122 int
123 in_canforward(in)
124 	struct in_addr in;
125 {
126 	register u_long i = ntohl(in.s_addr);
127 	register u_long net;
128 
129 	if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
130 		return (0);
131 	if (IN_CLASSA(i)) {
132 		net = i & IN_CLASSA_NET;
133 		if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
134 			return (0);
135 	}
136 	return (1);
137 }
138 
139 /*
140  * Trim a mask in a sockaddr
141  */
142 void
143 in_socktrim(ap)
144 	struct sockaddr_in *ap;
145 {
146 	register char *cplim = (char *) &ap->sin_addr;
147 	register char *cp = (char *) (&ap->sin_addr + 1);
148 
149 	ap->sin_len = 0;
150 	while (--cp > cplim)
151 		if (*cp) {
152 			(ap)->sin_len = cp - (char *) (ap) + 1;
153 			break;
154 		}
155 }
156 
157 int	in_interfaces;		/* number of external internet interfaces */
158 extern	struct ifnet loif;
159 
160 /*
161  * Generic internet control operations (ioctl's).
162  * Ifp is 0 if not an interface-specific ioctl.
163  */
164 /* ARGSUSED */
165 int
166 in_control(so, cmd, data, ifp)
167 	struct socket *so;
168 	int cmd;
169 	caddr_t data;
170 	register struct ifnet *ifp;
171 {
172 	register struct ifreq *ifr = (struct ifreq *)data;
173 	register struct in_ifaddr *ia = 0;
174 	register struct ifaddr *ifa;
175 	struct in_ifaddr *oia;
176 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
177 	struct sockaddr_in oldaddr;
178 	int error, hostIsNew, maskIsNew;
179 	u_long i;
180 
181 	/*
182 	 * Find address for this interface, if it exists.
183 	 */
184 	if (ifp)
185 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
186 			if (ia->ia_ifp == ifp)
187 				break;
188 
189 	switch (cmd) {
190 
191 	case SIOCAIFADDR:
192 	case SIOCDIFADDR:
193 		if (ifra->ifra_addr.sin_family == AF_INET)
194 		    for (oia = ia; ia; ia = ia->ia_next) {
195 			if (ia->ia_ifp == ifp  &&
196 			    ia->ia_addr.sin_addr.s_addr ==
197 				ifra->ifra_addr.sin_addr.s_addr)
198 			    break;
199 		}
200 		if (cmd == SIOCDIFADDR && ia == 0)
201 			return (EADDRNOTAVAIL);
202 		/* FALLTHROUGH */
203 	case SIOCSIFADDR:
204 	case SIOCSIFNETMASK:
205 	case SIOCSIFDSTADDR:
206 		if ((so->so_state & SS_PRIV) == 0)
207 			return (EPERM);
208 
209 		if (ifp == 0)
210 			panic("in_control");
211 		if (ia == (struct in_ifaddr *)0) {
212 			oia = (struct in_ifaddr *)
213 				malloc(sizeof *oia, M_IFADDR, M_WAITOK);
214 			if (oia == (struct in_ifaddr *)NULL)
215 				return (ENOBUFS);
216 			bzero((caddr_t)oia, sizeof *oia);
217 			if (ia = in_ifaddr) {
218 				for ( ; ia->ia_next; ia = ia->ia_next)
219 					continue;
220 				ia->ia_next = oia;
221 			} else
222 				in_ifaddr = oia;
223 			ia = oia;
224 			if (ifa = ifp->if_addrlist) {
225 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
226 					continue;
227 				ifa->ifa_next = (struct ifaddr *) ia;
228 			} else
229 				ifp->if_addrlist = (struct ifaddr *) ia;
230 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
231 			ia->ia_ifa.ifa_dstaddr
232 					= (struct sockaddr *)&ia->ia_dstaddr;
233 			ia->ia_ifa.ifa_netmask
234 					= (struct sockaddr *)&ia->ia_sockmask;
235 			ia->ia_sockmask.sin_len = 8;
236 			if (ifp->if_flags & IFF_BROADCAST) {
237 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
238 				ia->ia_broadaddr.sin_family = AF_INET;
239 			}
240 			ia->ia_ifp = ifp;
241 			if (ifp != &loif)
242 				in_interfaces++;
243 		}
244 		break;
245 
246 	case SIOCSIFBRDADDR:
247 		if ((so->so_state & SS_PRIV) == 0)
248 			return (EPERM);
249 		/* FALLTHROUGH */
250 
251 	case SIOCGIFADDR:
252 	case SIOCGIFNETMASK:
253 	case SIOCGIFDSTADDR:
254 	case SIOCGIFBRDADDR:
255 		if (ia == (struct in_ifaddr *)0)
256 			return (EADDRNOTAVAIL);
257 		break;
258 	}
259 	switch (cmd) {
260 
261 	case SIOCGIFADDR:
262 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
263 		break;
264 
265 	case SIOCGIFBRDADDR:
266 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
267 			return (EINVAL);
268 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
269 		break;
270 
271 	case SIOCGIFDSTADDR:
272 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
273 			return (EINVAL);
274 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
275 		break;
276 
277 	case SIOCGIFNETMASK:
278 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
279 		break;
280 
281 	case SIOCSIFDSTADDR:
282 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
283 			return (EINVAL);
284 		oldaddr = ia->ia_dstaddr;
285 		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
286 		if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
287 					(ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
288 			ia->ia_dstaddr = oldaddr;
289 			return (error);
290 		}
291 		if (ia->ia_flags & IFA_ROUTE) {
292 			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
293 			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
294 			ia->ia_ifa.ifa_dstaddr =
295 					(struct sockaddr *)&ia->ia_dstaddr;
296 			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
297 		}
298 		break;
299 
300 	case SIOCSIFBRDADDR:
301 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
302 			return (EINVAL);
303 		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
304 		break;
305 
306 	case SIOCSIFADDR:
307 		return (in_ifinit(ifp, ia,
308 		    (struct sockaddr_in *) &ifr->ifr_addr, 1));
309 
310 	case SIOCSIFNETMASK:
311 		i = ifra->ifra_addr.sin_addr.s_addr;
312 		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
313 		break;
314 
315 	case SIOCAIFADDR:
316 		maskIsNew = 0;
317 		hostIsNew = 1;
318 		error = 0;
319 		if (ia->ia_addr.sin_family == AF_INET) {
320 			if (ifra->ifra_addr.sin_len == 0) {
321 				ifra->ifra_addr = ia->ia_addr;
322 				hostIsNew = 0;
323 			} else if (ifra->ifra_addr.sin_addr.s_addr ==
324 					       ia->ia_addr.sin_addr.s_addr)
325 				hostIsNew = 0;
326 		}
327 		if (ifra->ifra_mask.sin_len) {
328 			in_ifscrub(ifp, ia);
329 			ia->ia_sockmask = ifra->ifra_mask;
330 			ia->ia_subnetmask =
331 			     ntohl(ia->ia_sockmask.sin_addr.s_addr);
332 			maskIsNew = 1;
333 		}
334 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
335 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
336 			in_ifscrub(ifp, ia);
337 			ia->ia_dstaddr = ifra->ifra_dstaddr;
338 			maskIsNew  = 1; /* We lie; but the effect's the same */
339 		}
340 		if (ifra->ifra_addr.sin_family == AF_INET &&
341 		    (hostIsNew || maskIsNew))
342 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
343 		if ((ifp->if_flags & IFF_BROADCAST) &&
344 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
345 			ia->ia_broadaddr = ifra->ifra_broadaddr;
346 		return (error);
347 
348 	case SIOCDIFADDR:
349 		in_ifscrub(ifp, ia);
350 		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
351 			ifp->if_addrlist = ifa->ifa_next;
352 		else {
353 			while (ifa->ifa_next &&
354 			       (ifa->ifa_next != (struct ifaddr *)ia))
355 				    ifa = ifa->ifa_next;
356 			if (ifa->ifa_next)
357 				ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
358 			else
359 				printf("Couldn't unlink inifaddr from ifp\n");
360 		}
361 		oia = ia;
362 		if (oia == (ia = in_ifaddr))
363 			in_ifaddr = ia->ia_next;
364 		else {
365 			while (ia->ia_next && (ia->ia_next != oia))
366 				ia = ia->ia_next;
367 			if (ia->ia_next)
368 				ia->ia_next = oia->ia_next;
369 			else
370 				printf("Didn't unlink inifadr from list\n");
371 		}
372 		IFAFREE((&oia->ia_ifa));
373 		break;
374 
375 	default:
376 		if (ifp == 0 || ifp->if_ioctl == 0)
377 			return (EOPNOTSUPP);
378 		return ((*ifp->if_ioctl)(ifp, cmd, data));
379 	}
380 	return (0);
381 }
382 
383 /*
384  * Delete any existing route for an interface.
385  */
386 void
387 in_ifscrub(ifp, ia)
388 	register struct ifnet *ifp;
389 	register struct in_ifaddr *ia;
390 {
391 
392 	if ((ia->ia_flags & IFA_ROUTE) == 0)
393 		return;
394 	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
395 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
396 	else
397 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
398 	ia->ia_flags &= ~IFA_ROUTE;
399 }
400 
401 /*
402  * Initialize an interface's internet address
403  * and routing table entry.
404  */
405 int
406 in_ifinit(ifp, ia, sin, scrub)
407 	register struct ifnet *ifp;
408 	register struct in_ifaddr *ia;
409 	struct sockaddr_in *sin;
410 	int scrub;
411 {
412 	register u_long i = ntohl(sin->sin_addr.s_addr);
413 	struct sockaddr_in oldaddr;
414 	int s = splimp(), flags = RTF_UP, error, ether_output();
415 
416 	oldaddr = ia->ia_addr;
417 	ia->ia_addr = *sin;
418 	/*
419 	 * Give the interface a chance to initialize
420 	 * if this is its first address,
421 	 * and to validate the address if necessary.
422 	 */
423 	if (ifp->if_ioctl &&
424 	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
425 		splx(s);
426 		ia->ia_addr = oldaddr;
427 		return (error);
428 	}
429 #if NETHER > 0
430 	if (ifp->if_output == ether_output) { /* XXX: Another Kludge */
431 		ia->ia_ifa.ifa_rtrequest = arp_rtrequest;
432 		ia->ia_ifa.ifa_flags |= RTF_CLONING;
433 	}
434 #endif
435 	splx(s);
436 	if (scrub) {
437 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
438 		in_ifscrub(ifp, ia);
439 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
440 	}
441 	if (IN_CLASSA(i))
442 		ia->ia_netmask = IN_CLASSA_NET;
443 	else if (IN_CLASSB(i))
444 		ia->ia_netmask = IN_CLASSB_NET;
445 	else
446 		ia->ia_netmask = IN_CLASSC_NET;
447 	/*
448 	 * The subnet mask usually includes at least the standard network part,
449 	 * but may may be smaller in the case of supernetting.
450 	 * If it is set, we believe it.
451 	 */
452 	if (ia->ia_subnetmask == 0) {
453 		ia->ia_subnetmask = ia->ia_netmask;
454 		ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
455 	} else
456 		ia->ia_netmask &= ia->ia_subnetmask;
457 	ia->ia_net = i & ia->ia_netmask;
458 	ia->ia_subnet = i & ia->ia_subnetmask;
459 	in_socktrim(&ia->ia_sockmask);
460 	/*
461 	 * Add route for the network.
462 	 */
463 	ia->ia_ifa.ifa_metric = ifp->if_metric;
464 	if (ifp->if_flags & IFF_BROADCAST) {
465 		ia->ia_broadaddr.sin_addr.s_addr =
466 			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
467 		ia->ia_netbroadcast.s_addr =
468 			htonl(ia->ia_net | ~ ia->ia_netmask);
469 	} else if (ifp->if_flags & IFF_LOOPBACK) {
470 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
471 		flags |= RTF_HOST;
472 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
473 		if (ia->ia_dstaddr.sin_family != AF_INET)
474 			return (0);
475 		flags |= RTF_HOST;
476 	}
477 	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
478 		ia->ia_flags |= IFA_ROUTE;
479 	/*
480 	 * If the interface supports multicast, join the "all hosts"
481 	 * multicast group on that interface.
482 	 */
483 	if (ifp->if_flags & IFF_MULTICAST) {
484 		struct in_addr addr;
485 
486 		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
487 		in_addmulti(&addr, ifp);
488 	}
489 	return (error);
490 }
491 
492 
493 /*
494  * Return 1 if the address might be a local broadcast address.
495  */
496 int
497 in_broadcast(in, ifp)
498 	struct in_addr in;
499 	struct ifnet *ifp;
500 {
501 	register struct ifaddr *ifa;
502 	u_long t;
503 
504 	if (in.s_addr == INADDR_BROADCAST ||
505 	    in.s_addr == INADDR_ANY)
506 		return 1;
507 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
508 		return 0;
509 	t = ntohl(in.s_addr);
510 	/*
511 	 * Look through the list of addresses for a match
512 	 * with a broadcast address.
513 	 */
514 #define ia ((struct in_ifaddr *)ifa)
515 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
516 		if (ifa->ifa_addr->sa_family == AF_INET &&
517 		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
518 		     in.s_addr == ia->ia_netbroadcast.s_addr ||
519 		     /*
520 		      * Check for old-style (host 0) broadcast.
521 		      */
522 		     t == ia->ia_subnet || t == ia->ia_net))
523 			    return 1;
524 	return (0);
525 #undef ia
526 }
527 
528 /*
529  * Add an address to the list of IP multicast addresses for a given interface.
530  */
531 struct in_multi *
532 in_addmulti(ap, ifp)
533 	register struct in_addr *ap;
534 	register struct ifnet *ifp;
535 {
536 	register struct in_multi *inm;
537 	struct ifreq ifr;
538 	struct in_ifaddr *ia;
539 	int s = splnet();
540 
541 	/*
542 	 * See if address already in list.
543 	 */
544 	IN_LOOKUP_MULTI(*ap, ifp, inm);
545 	if (inm != NULL) {
546 		/*
547 		 * Found it; just increment the reference count.
548 		 */
549 		++inm->inm_refcount;
550 	}
551 	else {
552 		/*
553 		 * New address; allocate a new multicast record
554 		 * and link it into the interface's multicast list.
555 		 */
556 		inm = (struct in_multi *)malloc(sizeof(*inm),
557 		    M_IPMADDR, M_NOWAIT);
558 		if (inm == NULL) {
559 			splx(s);
560 			return (NULL);
561 		}
562 		inm->inm_addr = *ap;
563 		inm->inm_ifp = ifp;
564 		inm->inm_refcount = 1;
565 		IFP_TO_IA(ifp, ia);
566 		if (ia == NULL) {
567 			free(inm, M_IPMADDR);
568 			splx(s);
569 			return (NULL);
570 		}
571 		inm->inm_ia = ia;
572 		inm->inm_next = ia->ia_multiaddrs;
573 		ia->ia_multiaddrs = inm;
574 		/*
575 		 * Ask the network driver to update its multicast reception
576 		 * filter appropriately for the new address.
577 		 */
578 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
579 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;
580 		if ((ifp->if_ioctl == NULL) ||
581 		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
582 			ia->ia_multiaddrs = inm->inm_next;
583 			free(inm, M_IPMADDR);
584 			splx(s);
585 			return (NULL);
586 		}
587 		/*
588 		 * Let IGMP know that we have joined a new IP multicast group.
589 		 */
590 		igmp_joingroup(inm);
591 	}
592 	splx(s);
593 	return (inm);
594 }
595 
596 /*
597  * Delete a multicast address record.
598  */
599 int
600 in_delmulti(inm)
601 	register struct in_multi *inm;
602 {
603 	register struct in_multi **p;
604 	struct ifreq ifr;
605 	int s = splnet();
606 
607 	if (--inm->inm_refcount == 0) {
608 		/*
609 		 * No remaining claims to this record; let IGMP know that
610 		 * we are leaving the multicast group.
611 		 */
612 		igmp_leavegroup(inm);
613 		/*
614 		 * Unlink from list.
615 		 */
616 		for (p = &inm->inm_ia->ia_multiaddrs;
617 		     *p != inm;
618 		     p = &(*p)->inm_next)
619 			 continue;
620 		*p = (*p)->inm_next;
621 		/*
622 		 * Notify the network driver to update its multicast reception
623 		 * filter.
624 		 */
625 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
626 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =
627 								inm->inm_addr;
628 		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
629 							     (caddr_t)&ifr);
630 		free(inm, M_IPMADDR);
631 	}
632 	splx(s);
633 }
634 #endif
635