]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/in.c
xnu-517.9.4.tar.gz
[apple/xnu.git] / bsd / netinet / in.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1982, 1986, 1991, 1993
24 * The Regents of the University of California. All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 *
54 * @(#)in.c 8.4 (Berkeley) 1/9/95
55 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.5 2001/08/13 16:26:17 ume Exp $
56 */
57
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/sockio.h>
61 #include <sys/socketvar.h>
62 #include <sys/malloc.h>
63 #include <sys/proc.h>
64 #include <sys/socket.h>
65 #include <sys/kernel.h>
66 #include <sys/sysctl.h>
67 #include <sys/kern_event.h>
68
69 #include <net/if.h>
70 #include <net/if_types.h>
71 #include <net/route.h>
72
73 #include <netinet/in.h>
74 #include <netinet/in_var.h>
75 #include <netinet/in_pcb.h>
76
77 #include <netinet/igmp_var.h>
78 #include <net/dlil.h>
79
80 #include <netinet/ip_var.h>
81
82 #include <netinet/tcp.h>
83 #include <netinet/tcp_timer.h>
84 #include <netinet/tcp_var.h>
85
86 #include <sys/file.h>
87
88
89 static int in_mask2len __P((struct in_addr *));
90 static void in_len2mask __P((struct in_addr *, int));
91 static int in_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
92 struct ifnet *, struct proc *));
93
94 static void in_socktrim __P((struct sockaddr_in *));
95 static int in_ifinit __P((struct ifnet *,
96 struct in_ifaddr *, struct sockaddr_in *, int));
97
98 static int subnetsarelocal = 0;
99 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
100 &subnetsarelocal, 0, "");
101
102 struct in_multihead in_multihead; /* XXX BSS initialization */
103
104 extern void arp_rtrequest();
105
106 /*
107 * Return 1 if an internet address is for a ``local'' host
108 * (one to which we have a connection). If subnetsarelocal
109 * is true, this includes other subnets of the local net.
110 * Otherwise, it includes only the directly-connected (sub)nets.
111 */
112 int
113 in_localaddr(in)
114 struct in_addr in;
115 {
116 register u_long i = ntohl(in.s_addr);
117 register struct in_ifaddr *ia;
118
119 if (subnetsarelocal) {
120 for (ia = in_ifaddrhead.tqh_first; ia;
121 ia = ia->ia_link.tqe_next)
122 if ((i & ia->ia_netmask) == ia->ia_net)
123 return (1);
124 } else {
125 for (ia = in_ifaddrhead.tqh_first; ia;
126 ia = ia->ia_link.tqe_next)
127 if ((i & ia->ia_subnetmask) == ia->ia_subnet)
128 return (1);
129 }
130 return (0);
131 }
132
133 /*
134 * Determine whether an IP address is in a reserved set of addresses
135 * that may not be forwarded, or whether datagrams to that destination
136 * may be forwarded.
137 */
138 int
139 in_canforward(in)
140 struct in_addr in;
141 {
142 register u_long i = ntohl(in.s_addr);
143 register u_long net;
144
145 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
146 return (0);
147 if (IN_CLASSA(i)) {
148 net = i & IN_CLASSA_NET;
149 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
150 return (0);
151 }
152 return (1);
153 }
154
155 /*
156 * Trim a mask in a sockaddr
157 */
158 static void
159 in_socktrim(ap)
160 struct sockaddr_in *ap;
161 {
162 register char *cplim = (char *) &ap->sin_addr;
163 register char *cp = (char *) (&ap->sin_addr + 1);
164
165 ap->sin_len = 0;
166 while (--cp >= cplim)
167 if (*cp) {
168 (ap)->sin_len = cp - (char *) (ap) + 1;
169 break;
170 }
171 }
172
173 static int
174 in_mask2len(mask)
175 struct in_addr *mask;
176 {
177 int x, y;
178 u_char *p;
179
180 p = (u_char *)mask;
181 for (x = 0; x < sizeof(*mask); x++) {
182 if (p[x] != 0xff)
183 break;
184 }
185 y = 0;
186 if (x < sizeof(*mask)) {
187 for (y = 0; y < 8; y++) {
188 if ((p[x] & (0x80 >> y)) == 0)
189 break;
190 }
191 }
192 return x * 8 + y;
193 }
194
195 static void
196 in_len2mask(mask, len)
197 struct in_addr *mask;
198 int len;
199 {
200 int i;
201 u_char *p;
202
203 p = (u_char *)mask;
204 bzero(mask, sizeof(*mask));
205 for (i = 0; i < len / 8; i++)
206 p[i] = 0xff;
207 if (len % 8)
208 p[i] = (0xff00 >> (len % 8)) & 0xff;
209 }
210
211 static int in_interfaces; /* number of external internet interfaces */
212
213 /*
214 * Generic internet control operations (ioctl's).
215 * Ifp is 0 if not an interface-specific ioctl.
216 */
217 /* ARGSUSED */
218 int
219 in_control(so, cmd, data, ifp, p)
220 struct socket *so;
221 u_long cmd;
222 caddr_t data;
223 register struct ifnet *ifp;
224 struct proc *p;
225 {
226 register struct ifreq *ifr = (struct ifreq *)data;
227 register struct in_ifaddr *ia = 0, *iap;
228 register struct ifaddr *ifa;
229 struct in_ifaddr *oia;
230 struct in_aliasreq *ifra = (struct in_aliasreq *)data;
231 struct sockaddr_in oldaddr;
232 int error, hostIsNew, maskIsNew, s;
233 u_long i, dl_tag;
234 struct kev_msg ev_msg;
235 struct kev_in_data in_event_data;
236
237
238 switch (cmd) {
239 case SIOCALIFADDR:
240 case SIOCDLIFADDR:
241 if (p && (error = suser(p->p_ucred, &p->p_acflag)) != 0)
242 return error;
243 /*fall through*/
244 case SIOCGLIFADDR:
245 if (!ifp)
246 return EINVAL;
247 return in_lifaddr_ioctl(so, cmd, data, ifp, p);
248 }
249
250 /*
251 * Find address for this interface, if it exists.
252 *
253 * If an alias address was specified, find that one instead of
254 * the first one on the interface.
255 */
256 if (ifp)
257 for (iap = in_ifaddrhead.tqh_first; iap;
258 iap = iap->ia_link.tqe_next)
259 if (iap->ia_ifp == ifp) {
260 if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr ==
261 iap->ia_addr.sin_addr.s_addr) {
262 ia = iap;
263 break;
264 } else if (ia == NULL) {
265 ia = iap;
266 if (ifr->ifr_addr.sa_family != AF_INET)
267 break;
268 }
269 }
270
271 switch (cmd) {
272 case SIOCAUTOADDR:
273 if (p && (error = suser(p->p_ucred, &p->p_acflag)) != 0)
274 return error;
275 break;
276
277 case SIOCAIFADDR:
278 case SIOCDIFADDR:
279 if (ifp == 0)
280 return (EADDRNOTAVAIL);
281 if (ifra->ifra_addr.sin_family == AF_INET) {
282 for (oia = ia; ia; ia = ia->ia_link.tqe_next) {
283 if (ia->ia_ifp == ifp &&
284 ia->ia_addr.sin_addr.s_addr ==
285 ifra->ifra_addr.sin_addr.s_addr)
286 break;
287 }
288 if ((ifp->if_flags & IFF_POINTOPOINT)
289 && (cmd == SIOCAIFADDR)
290 && (ifra->ifra_dstaddr.sin_addr.s_addr
291 == INADDR_ANY)) {
292 return EDESTADDRREQ;
293 }
294 }
295 else if (cmd == SIOCAIFADDR)
296 return (EINVAL);
297 if (cmd == SIOCDIFADDR && ia == 0)
298 return (EADDRNOTAVAIL);
299 /* FALLTHROUGH */
300 case SIOCSIFADDR:
301 case SIOCSIFNETMASK:
302 case SIOCSIFDSTADDR:
303 #ifdef __APPLE__
304 if ((so->so_state & SS_PRIV) == 0)
305 return (EPERM);
306 #else
307 if (p && (error = suser(p)) != 0)
308 return error;
309 #endif
310
311 if (ifp == 0)
312 return (EADDRNOTAVAIL);
313 if (ifra->ifra_addr.sin_family != AF_INET && cmd == SIOCSIFADDR)
314 return (EINVAL);
315 if (ia == (struct in_ifaddr *)0) {
316 ia = (struct in_ifaddr *)
317 _MALLOC(sizeof *ia, M_IFADDR, M_WAITOK);
318 if (ia == (struct in_ifaddr *)NULL)
319 return (ENOBUFS);
320 bzero((caddr_t)ia, sizeof *ia);
321 /*
322 * Protect from ipintr() traversing address list
323 * while we're modifying it.
324 */
325 s = splnet();
326
327 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
328 ifa = &ia->ia_ifa;
329 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
330
331 /*
332 * Temorary code for protocol attachment XXX
333 */
334
335 /* Generic protocol plumbing */
336
337 if (error = dlil_plumb_protocol(PF_INET, ifp, &dl_tag)) {
338 kprintf("in.c: warning can't plumb proto if=%s%n type %d error=%d\n",
339 ifp->if_name, ifp->if_unit, ifp->if_type, error);
340 error = 0; /*discard error, can be cold with unsupported interfaces */
341 }
342 /* End of temp code */
343
344 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
345 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
346 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
347 ia->ia_sockmask.sin_len = 8;
348 if (ifp->if_flags & IFF_BROADCAST) {
349 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
350 ia->ia_broadaddr.sin_family = AF_INET;
351 }
352 ia->ia_ifp = ifp;
353 if (!(ifp->if_flags & IFF_LOOPBACK))
354 in_interfaces++;
355 splx(s);
356 }
357 break;
358
359 case SIOCPROTOATTACH:
360 case SIOCPROTODETACH:
361 if (p && (error = suser(p->p_ucred, &p->p_acflag)) != 0)
362 return error;
363 if (ifp == 0)
364 return (EADDRNOTAVAIL);
365 break;
366
367 case SIOCSIFBRDADDR:
368 #ifdef __APPLE__
369 if ((so->so_state & SS_PRIV) == 0)
370 return (EPERM);
371 #else
372 if (p && (error = suser(p)) != 0)
373 return error;
374 #endif
375 /* FALLTHROUGH */
376
377 case SIOCGIFADDR:
378 case SIOCGIFNETMASK:
379 case SIOCGIFDSTADDR:
380 case SIOCGIFBRDADDR:
381 if (ia == (struct in_ifaddr *)0)
382 return (EADDRNOTAVAIL);
383 break;
384 }
385 switch (cmd) {
386 case SIOCAUTOADDR:
387 if (ifp == 0)
388 return (EADDRNOTAVAIL);
389 if (ifr->ifr_data)
390 ifp->if_eflags |= IFEF_AUTOCONFIGURING;
391 else
392 ifp->if_eflags &= ~IFEF_AUTOCONFIGURING;
393 break;
394
395 case SIOCGIFADDR:
396 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
397 break;
398
399 case SIOCGIFBRDADDR:
400 if ((ifp->if_flags & IFF_BROADCAST) == 0)
401 return (EINVAL);
402 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
403 break;
404
405 case SIOCGIFDSTADDR:
406 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
407 return (EINVAL);
408 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
409 break;
410
411 case SIOCGIFNETMASK:
412 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
413 break;
414
415 case SIOCSIFDSTADDR:
416 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
417 return (EINVAL);
418 oldaddr = ia->ia_dstaddr;
419 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
420 error = dlil_ioctl(PF_INET, ifp, SIOCSIFDSTADDR, (caddr_t)ia);
421 if (error == EOPNOTSUPP)
422 error = 0;
423
424 if (error) {
425 ia->ia_dstaddr = oldaddr;
426 return error;
427 }
428
429 ev_msg.vendor_code = KEV_VENDOR_APPLE;
430 ev_msg.kev_class = KEV_NETWORK_CLASS;
431 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
432
433 ev_msg.event_code = KEV_INET_SIFDSTADDR;
434
435 if (ia->ia_ifa.ifa_dstaddr)
436 in_event_data.ia_dstaddr =
437 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
438 else
439 in_event_data.ia_dstaddr.s_addr = 0;
440
441 in_event_data.ia_addr = ia->ia_addr.sin_addr;
442 in_event_data.ia_net = ia->ia_net;
443 in_event_data.ia_netmask = ia->ia_netmask;
444 in_event_data.ia_subnet = ia->ia_subnet;
445 in_event_data.ia_subnetmask = ia->ia_subnetmask;
446 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
447 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
448 in_event_data.link_data.if_family = ifp->if_family;
449 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
450
451 ev_msg.dv[0].data_ptr = &in_event_data;
452 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
453 ev_msg.dv[1].data_length = 0;
454
455 kev_post_msg(&ev_msg);
456
457
458 if (ia->ia_flags & IFA_ROUTE) {
459 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
460 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
461 ia->ia_ifa.ifa_dstaddr =
462 (struct sockaddr *)&ia->ia_dstaddr;
463 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
464 }
465 break;
466
467 case SIOCSIFBRDADDR:
468 if ((ifp->if_flags & IFF_BROADCAST) == 0)
469 return (EINVAL);
470 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
471
472 ev_msg.vendor_code = KEV_VENDOR_APPLE;
473 ev_msg.kev_class = KEV_NETWORK_CLASS;
474 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
475
476 ev_msg.event_code = KEV_INET_SIFBRDADDR;
477
478 if (ia->ia_ifa.ifa_dstaddr)
479 in_event_data.ia_dstaddr =
480 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
481 else
482 in_event_data.ia_dstaddr.s_addr = 0;
483
484 in_event_data.ia_addr = ia->ia_addr.sin_addr;
485 in_event_data.ia_net = ia->ia_net;
486 in_event_data.ia_netmask = ia->ia_netmask;
487 in_event_data.ia_subnet = ia->ia_subnet;
488 in_event_data.ia_subnetmask = ia->ia_subnetmask;
489 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
490 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
491 in_event_data.link_data.if_family = ifp->if_family;
492 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
493
494 ev_msg.dv[0].data_ptr = &in_event_data;
495 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
496 ev_msg.dv[1].data_length = 0;
497
498 kev_post_msg(&ev_msg);
499
500 break;
501
502 case SIOCSIFADDR:
503 return (in_ifinit(ifp, ia,
504 (struct sockaddr_in *) &ifr->ifr_addr, 1));
505
506 case SIOCPROTOATTACH:
507 error = dlil_plumb_protocol(PF_INET, ifp, &dl_tag);
508 if (error)
509 return(error);
510 break;
511
512 case SIOCPROTODETACH:
513 // if an ip address is still present, refuse to detach
514 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
515 if (ifa->ifa_addr->sa_family == AF_INET)
516 return EBUSY;
517
518 error = dlil_unplumb_protocol(PF_INET, ifp);
519 if (error)
520 return(error);
521 break;
522
523
524 case SIOCSIFNETMASK:
525 i = ifra->ifra_addr.sin_addr.s_addr;
526 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
527 ev_msg.vendor_code = KEV_VENDOR_APPLE;
528 ev_msg.kev_class = KEV_NETWORK_CLASS;
529 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
530
531 ev_msg.event_code = KEV_INET_SIFNETMASK;
532
533 if (ia->ia_ifa.ifa_dstaddr)
534 in_event_data.ia_dstaddr =
535 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
536 else
537 in_event_data.ia_dstaddr.s_addr = 0;
538
539 in_event_data.ia_addr = ia->ia_addr.sin_addr;
540 in_event_data.ia_net = ia->ia_net;
541 in_event_data.ia_netmask = ia->ia_netmask;
542 in_event_data.ia_subnet = ia->ia_subnet;
543 in_event_data.ia_subnetmask = ia->ia_subnetmask;
544 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
545 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
546 in_event_data.link_data.if_family = ifp->if_family;
547 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
548
549 ev_msg.dv[0].data_ptr = &in_event_data;
550 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
551 ev_msg.dv[1].data_length = 0;
552
553 kev_post_msg(&ev_msg);
554
555 break;
556
557 case SIOCAIFADDR:
558 maskIsNew = 0;
559 hostIsNew = 1;
560 error = 0;
561 if (ia->ia_addr.sin_family == AF_INET) {
562 if (ifra->ifra_addr.sin_len == 0) {
563 ifra->ifra_addr = ia->ia_addr;
564 hostIsNew = 0;
565 } else if (ifra->ifra_addr.sin_addr.s_addr ==
566 ia->ia_addr.sin_addr.s_addr)
567 hostIsNew = 0;
568 }
569 if (ifra->ifra_mask.sin_len) {
570 in_ifscrub(ifp, ia);
571 ia->ia_sockmask = ifra->ifra_mask;
572 ia->ia_subnetmask =
573 ntohl(ia->ia_sockmask.sin_addr.s_addr);
574 maskIsNew = 1;
575 }
576 if ((ifp->if_flags & IFF_POINTOPOINT) &&
577 (ifra->ifra_dstaddr.sin_family == AF_INET)) {
578 in_ifscrub(ifp, ia);
579 ia->ia_dstaddr = ifra->ifra_dstaddr;
580 maskIsNew = 1; /* We lie; but the effect's the same */
581 }
582 if (ifra->ifra_addr.sin_family == AF_INET &&
583 (hostIsNew || maskIsNew)) {
584 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
585 }
586 if ((ifp->if_flags & IFF_BROADCAST) &&
587 (ifra->ifra_broadaddr.sin_family == AF_INET))
588 ia->ia_broadaddr = ifra->ifra_broadaddr;
589
590 /*
591 * Report event.
592 */
593
594 if ((error == 0) || (error == EEXIST)) {
595 ev_msg.vendor_code = KEV_VENDOR_APPLE;
596 ev_msg.kev_class = KEV_NETWORK_CLASS;
597 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
598
599 if (hostIsNew)
600 ev_msg.event_code = KEV_INET_NEW_ADDR;
601 else
602 ev_msg.event_code = KEV_INET_CHANGED_ADDR;
603
604 if (ia->ia_ifa.ifa_dstaddr)
605 in_event_data.ia_dstaddr =
606 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
607 else
608 in_event_data.ia_dstaddr.s_addr = 0;
609
610 in_event_data.ia_addr = ia->ia_addr.sin_addr;
611 in_event_data.ia_net = ia->ia_net;
612 in_event_data.ia_netmask = ia->ia_netmask;
613 in_event_data.ia_subnet = ia->ia_subnet;
614 in_event_data.ia_subnetmask = ia->ia_subnetmask;
615 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
616 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
617 in_event_data.link_data.if_family = ifp->if_family;
618 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
619
620 ev_msg.dv[0].data_ptr = &in_event_data;
621 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
622 ev_msg.dv[1].data_length = 0;
623
624 kev_post_msg(&ev_msg);
625 }
626
627 return (error);
628
629 case SIOCDIFADDR:
630 error = dlil_ioctl(PF_INET, ifp, SIOCDIFADDR, (caddr_t)ia);
631 if (error == EOPNOTSUPP)
632 error = 0;
633 if (error)
634 return error;
635
636 ev_msg.vendor_code = KEV_VENDOR_APPLE;
637 ev_msg.kev_class = KEV_NETWORK_CLASS;
638 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
639
640 ev_msg.event_code = KEV_INET_ADDR_DELETED;
641
642 if (ia->ia_ifa.ifa_dstaddr)
643 in_event_data.ia_dstaddr =
644 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
645 else
646 in_event_data.ia_dstaddr.s_addr = 0;
647
648 in_event_data.ia_addr = ia->ia_addr.sin_addr;
649 in_event_data.ia_net = ia->ia_net;
650 in_event_data.ia_netmask = ia->ia_netmask;
651 in_event_data.ia_subnet = ia->ia_subnet;
652 in_event_data.ia_subnetmask = ia->ia_subnetmask;
653 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
654 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
655 in_event_data.link_data.if_family = ifp->if_family;
656 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit;
657
658 ev_msg.dv[0].data_ptr = &in_event_data;
659 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
660 ev_msg.dv[1].data_length = 0;
661
662 kev_post_msg(&ev_msg);
663
664 /*
665 * in_ifscrub kills the interface route.
666 */
667 in_ifscrub(ifp, ia);
668 #ifndef __APPLE__
669 /*
670 * in_ifadown gets rid of all the rest of
671 * the routes. This is not quite the right
672 * thing to do, but at least if we are running
673 * a routing process they will come back.
674 */
675 in_ifadown(&ia->ia_ifa, 1);
676 /*
677 * XXX horrible hack to detect that we are being called
678 * from if_detach()
679 */
680 if (!ifnet_addrs[ifp->if_index - 1]) {
681 in_pcbpurgeif0(LIST_FIRST(ripcbinfo.listhead), ifp);
682 in_pcbpurgeif0(LIST_FIRST(udbinfo.listhead), ifp);
683 }
684 #endif
685
686 /*
687 * Protect from ipintr() traversing address list
688 * while we're modifying it.
689 */
690 s = splnet();
691
692 ifa = &ia->ia_ifa;
693 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
694 oia = ia;
695 TAILQ_REMOVE(&in_ifaddrhead, oia, ia_link);
696 ifafree(&oia->ia_ifa);
697
698 #ifdef __APPLE__
699 /*
700 * If the interface supports multicast, and no address is left,
701 * remove the "all hosts" multicast group from that interface.
702 */
703 if (ifp->if_flags & IFF_MULTICAST) {
704 struct in_addr addr;
705 struct in_multi *inm;
706
707 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
708 if (ifa->ifa_addr->sa_family == AF_INET)
709 break;
710
711 if (ifa == 0) {
712 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
713 IN_LOOKUP_MULTI(addr, ifp, inm);
714 if (inm)
715 in_delmulti(inm);
716 }
717 }
718 #endif
719 splx(s);
720 break;
721
722 #ifdef __APPLE__
723 case SIOCSETOT: {
724 /*
725 * Inspiration from tcp_ctloutput() and ip_ctloutput()
726 * Special ioctl for OpenTransport sockets
727 */
728 struct inpcb *inp, *cloned_inp;
729 int error = 0;
730 int cloned_fd = *(int *)data;
731
732 s = splnet(); /* XXX */
733 inp = sotoinpcb(so);
734 if (inp == NULL) {
735 splx(s);
736 break;
737 }
738
739 /* let's make sure it's either -1 or a valid file descriptor */
740 if (cloned_fd != -1) {
741 struct socket *cloned_so;
742 struct file *cloned_fp;
743 error = getsock(p->p_fd, cloned_fd, &cloned_fp);
744 if (error){
745 splx(s);
746 break;
747 }
748 cloned_so = (struct socket *)cloned_fp->f_data;
749 cloned_inp = sotoinpcb(cloned_so);
750 } else {
751 cloned_inp = NULL;
752 }
753
754 if (cloned_inp == NULL) {
755 /* OT always uses IP_PORTRANGE_HIGH */
756 inp->inp_flags &= ~(INP_LOWPORT);
757 inp->inp_flags |= INP_HIGHPORT;
758 /* For UDP, OT allows broadcast by default */
759 if (so->so_type == SOCK_DGRAM)
760 so->so_options |= SO_BROADCAST;
761 /* For TCP we want to see MSG_OOB when receive urgent data */
762 else if (so->so_type == SOCK_STREAM)
763 so->so_options |= SO_WANTOOBFLAG;
764 } else {
765 inp->inp_ip_tos = cloned_inp->inp_ip_tos;
766 inp->inp_ip_ttl = cloned_inp->inp_ip_ttl;
767 inp->inp_flags = cloned_inp->inp_flags;
768
769 /* Multicast options */
770 if (cloned_inp->inp_moptions != NULL) {
771 int i;
772 struct ip_moptions *cloned_imo = cloned_inp->inp_moptions;
773 struct ip_moptions *imo = inp->inp_moptions;
774
775 if (imo == NULL) {
776 /*
777 * No multicast option buffer attached to the pcb;
778 * allocate one.
779 */
780 splx();
781 imo = (struct ip_moptions*)
782 _MALLOC(sizeof(*imo), M_IPMOPTS, M_WAITOK);
783 if (imo == NULL) {
784 error = ENOBUFS;
785 break;
786 }
787 s = splnet(); /* XXX */
788 inp->inp_moptions = imo;
789 }
790 imo->imo_multicast_ifp = cloned_imo->imo_multicast_ifp;
791 imo->imo_multicast_vif = cloned_imo->imo_multicast_vif;
792 imo->imo_multicast_ttl = cloned_imo->imo_multicast_ttl;
793 imo->imo_multicast_loop = cloned_imo->imo_multicast_loop;
794 imo->imo_num_memberships = cloned_imo->imo_num_memberships;
795 for (i = 0; i < cloned_imo->imo_num_memberships; i++) {
796 imo->imo_membership[i] =
797 in_addmulti(&cloned_imo->imo_membership[i]->inm_addr,
798 cloned_imo->imo_membership[i]->inm_ifp);
799 if (imo->imo_membership[i] == NULL) {
800 error = ENOBUFS;
801 break;
802 }
803 }
804 if (i < cloned_imo->imo_num_memberships) {
805 /* Failed, perform cleanup */
806 for (i--; i >= 0; i--)
807 in_delmulti(imo->imo_membership[i]);
808 break;
809 }
810 }
811 }
812 splx(s);
813 break;
814 }
815 #endif /* __APPLE__ */
816
817 default:
818 return EOPNOTSUPP;
819 /* Darwin: dlil_ioctl called from ifioctl */
820 #ifndef __APPLE__
821 return ((*ifp->if_ioctl)(ifp, cmd, data));
822 #endif
823 }
824 return (0);
825 }
826
827 /*
828 * SIOC[GAD]LIFADDR.
829 * SIOCGLIFADDR: get first address. (?!?)
830 * SIOCGLIFADDR with IFLR_PREFIX:
831 * get first address that matches the specified prefix.
832 * SIOCALIFADDR: add the specified address.
833 * SIOCALIFADDR with IFLR_PREFIX:
834 * EINVAL since we can't deduce hostid part of the address.
835 * SIOCDLIFADDR: delete the specified address.
836 * SIOCDLIFADDR with IFLR_PREFIX:
837 * delete the first address that matches the specified prefix.
838 * return values:
839 * EINVAL on invalid parameters
840 * EADDRNOTAVAIL on prefix match failed/specified address not found
841 * other values may be returned from in_ioctl()
842 */
843 static int
844 in_lifaddr_ioctl(so, cmd, data, ifp, p)
845 struct socket *so;
846 u_long cmd;
847 caddr_t data;
848 struct ifnet *ifp;
849 struct proc *p;
850 {
851 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
852 struct ifaddr *ifa;
853
854 /* sanity checks */
855 if (!data || !ifp) {
856 panic("invalid argument to in_lifaddr_ioctl");
857 /*NOTRECHED*/
858 }
859
860 switch (cmd) {
861 case SIOCGLIFADDR:
862 /* address must be specified on GET with IFLR_PREFIX */
863 if ((iflr->flags & IFLR_PREFIX) == 0)
864 break;
865 /*FALLTHROUGH*/
866 case SIOCALIFADDR:
867 case SIOCDLIFADDR:
868 /* address must be specified on ADD and DELETE */
869 if (iflr->addr.ss_family != AF_INET)
870 return EINVAL;
871 if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
872 return EINVAL;
873 /* XXX need improvement */
874 if (iflr->dstaddr.ss_family
875 && iflr->dstaddr.ss_family != AF_INET)
876 return EINVAL;
877 if (iflr->dstaddr.ss_family
878 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
879 return EINVAL;
880 break;
881 default: /*shouldn't happen*/
882 return EOPNOTSUPP;
883 }
884 if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
885 return EINVAL;
886
887 switch (cmd) {
888 case SIOCALIFADDR:
889 {
890 struct in_aliasreq ifra;
891
892 if (iflr->flags & IFLR_PREFIX)
893 return EINVAL;
894
895 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
896 bzero(&ifra, sizeof(ifra));
897 bcopy(iflr->iflr_name, ifra.ifra_name,
898 sizeof(ifra.ifra_name));
899
900 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
901
902 if (iflr->dstaddr.ss_family) { /*XXX*/
903 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
904 iflr->dstaddr.ss_len);
905 }
906
907 ifra.ifra_mask.sin_family = AF_INET;
908 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
909 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
910
911 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p);
912 }
913 case SIOCGLIFADDR:
914 case SIOCDLIFADDR:
915 {
916 struct in_ifaddr *ia;
917 struct in_addr mask, candidate, match;
918 struct sockaddr_in *sin;
919 int cmp;
920
921 bzero(&mask, sizeof(mask));
922 if (iflr->flags & IFLR_PREFIX) {
923 /* lookup a prefix rather than address. */
924 in_len2mask(&mask, iflr->prefixlen);
925
926 sin = (struct sockaddr_in *)&iflr->addr;
927 match.s_addr = sin->sin_addr.s_addr;
928 match.s_addr &= mask.s_addr;
929
930 /* if you set extra bits, that's wrong */
931 if (match.s_addr != sin->sin_addr.s_addr)
932 return EINVAL;
933
934 cmp = 1;
935 } else {
936 if (cmd == SIOCGLIFADDR) {
937 /* on getting an address, take the 1st match */
938 cmp = 0; /*XXX*/
939 } else {
940 /* on deleting an address, do exact match */
941 in_len2mask(&mask, 32);
942 sin = (struct sockaddr_in *)&iflr->addr;
943 match.s_addr = sin->sin_addr.s_addr;
944
945 cmp = 1;
946 }
947 }
948
949 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
950 if (ifa->ifa_addr->sa_family != AF_INET6)
951 continue;
952 if (!cmp)
953 break;
954 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
955 candidate.s_addr &= mask.s_addr;
956 if (candidate.s_addr == match.s_addr)
957 break;
958 }
959 if (!ifa)
960 return EADDRNOTAVAIL;
961 ia = (struct in_ifaddr *)ifa;
962
963 if (cmd == SIOCGLIFADDR) {
964 /* fill in the if_laddrreq structure */
965 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
966
967 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
968 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
969 ia->ia_dstaddr.sin_len);
970 } else
971 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
972
973 iflr->prefixlen =
974 in_mask2len(&ia->ia_sockmask.sin_addr);
975
976 iflr->flags = 0; /*XXX*/
977
978 return 0;
979 } else {
980 struct in_aliasreq ifra;
981
982 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
983 bzero(&ifra, sizeof(ifra));
984 bcopy(iflr->iflr_name, ifra.ifra_name,
985 sizeof(ifra.ifra_name));
986
987 bcopy(&ia->ia_addr, &ifra.ifra_addr,
988 ia->ia_addr.sin_len);
989 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
990 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
991 ia->ia_dstaddr.sin_len);
992 }
993 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
994 ia->ia_sockmask.sin_len);
995
996 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
997 ifp, p);
998 }
999 }
1000 }
1001
1002 return EOPNOTSUPP; /*just for safety*/
1003 }
1004
1005 /*
1006 * Delete any existing route for an interface.
1007 */
1008 void
1009 in_ifscrub(ifp, ia)
1010 register struct ifnet *ifp;
1011 register struct in_ifaddr *ia;
1012 {
1013
1014 if ((ia->ia_flags & IFA_ROUTE) == 0)
1015 return;
1016 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
1017 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1018 else
1019 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1020 ia->ia_flags &= ~IFA_ROUTE;
1021 }
1022
1023 /*
1024 * Initialize an interface's internet address
1025 * and routing table entry.
1026 */
1027 static int
1028 in_ifinit(ifp, ia, sin, scrub)
1029 register struct ifnet *ifp;
1030 register struct in_ifaddr *ia;
1031 struct sockaddr_in *sin;
1032 int scrub;
1033 {
1034 register u_long i = ntohl(sin->sin_addr.s_addr);
1035 struct sockaddr_in oldaddr;
1036 int s = splimp(), flags = RTF_UP, error;
1037
1038 oldaddr = ia->ia_addr;
1039 ia->ia_addr = *sin;
1040
1041 /*
1042 * Give the interface a chance to initialize
1043 * if this is its first address,
1044 * and to validate the address if necessary.
1045 */
1046 error = dlil_ioctl(PF_INET, ifp, SIOCSIFADDR, (caddr_t)ia);
1047 if (error == EOPNOTSUPP)
1048 error = 0;
1049 if (error) {
1050 splx(s);
1051 ia->ia_addr = oldaddr;
1052 return (error);
1053 }
1054 splx(s);
1055 if (scrub) {
1056 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1057 in_ifscrub(ifp, ia);
1058 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1059 }
1060 if (IN_CLASSA(i))
1061 ia->ia_netmask = IN_CLASSA_NET;
1062 else if (IN_CLASSB(i))
1063 ia->ia_netmask = IN_CLASSB_NET;
1064 else
1065 ia->ia_netmask = IN_CLASSC_NET;
1066 /*
1067 * The subnet mask usually includes at least the standard network part,
1068 * but may may be smaller in the case of supernetting.
1069 * If it is set, we believe it.
1070 */
1071 if (ia->ia_subnetmask == 0) {
1072 ia->ia_subnetmask = ia->ia_netmask;
1073 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
1074 } else
1075 ia->ia_netmask &= ia->ia_subnetmask;
1076 ia->ia_net = i & ia->ia_netmask;
1077 ia->ia_subnet = i & ia->ia_subnetmask;
1078 in_socktrim(&ia->ia_sockmask);
1079 /*
1080 * Add route for the network.
1081 */
1082 ia->ia_ifa.ifa_metric = ifp->if_metric;
1083 if (ifp->if_flags & IFF_BROADCAST) {
1084 ia->ia_broadaddr.sin_addr.s_addr =
1085 htonl(ia->ia_subnet | ~ia->ia_subnetmask);
1086 ia->ia_netbroadcast.s_addr =
1087 htonl(ia->ia_net | ~ ia->ia_netmask);
1088 } else if (ifp->if_flags & IFF_LOOPBACK) {
1089 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1090 flags |= RTF_HOST;
1091 } else if (ifp->if_flags & IFF_POINTOPOINT) {
1092 if (ia->ia_dstaddr.sin_family != AF_INET)
1093 return (0);
1094 flags |= RTF_HOST;
1095 }
1096 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
1097 ia->ia_flags |= IFA_ROUTE;
1098 /* XXX check if the subnet route points to the same interface */
1099 if (error == EEXIST)
1100 error = 0;
1101
1102 /*
1103 * If the interface supports multicast, join the "all hosts"
1104 * multicast group on that interface.
1105 */
1106 if (ifp->if_flags & IFF_MULTICAST) {
1107 struct in_multi *inm;
1108 struct in_addr addr;
1109
1110 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
1111 IN_LOOKUP_MULTI(addr, ifp, inm);
1112 if (inm == 0)
1113 in_addmulti(&addr, ifp);
1114 }
1115 return (error);
1116 }
1117
1118
1119 /*
1120 * Return 1 if the address might be a local broadcast address.
1121 */
1122 int
1123 in_broadcast(in, ifp)
1124 struct in_addr in;
1125 struct ifnet *ifp;
1126 {
1127 register struct ifaddr *ifa;
1128 u_long t;
1129
1130 if (in.s_addr == INADDR_BROADCAST ||
1131 in.s_addr == INADDR_ANY)
1132 return 1;
1133 if ((ifp->if_flags & IFF_BROADCAST) == 0)
1134 return 0;
1135 t = ntohl(in.s_addr);
1136 /*
1137 * Look through the list of addresses for a match
1138 * with a broadcast address.
1139 */
1140 #define ia ((struct in_ifaddr *)ifa)
1141 for (ifa = ifp->if_addrhead.tqh_first; ifa;
1142 ifa = ifa->ifa_link.tqe_next) {
1143 if (ifa->ifa_addr == NULL)
1144 return (0);
1145 if (ifa->ifa_addr->sa_family == AF_INET &&
1146 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
1147 in.s_addr == ia->ia_netbroadcast.s_addr ||
1148 /*
1149 * Check for old-style (host 0) broadcast.
1150 */
1151 t == ia->ia_subnet || t == ia->ia_net) &&
1152 /*
1153 * Check for an all one subnetmask. These
1154 * only exist when an interface gets a secondary
1155 * address.
1156 */
1157 ia->ia_subnetmask != (u_long)0xffffffff)
1158 return 1;
1159 }
1160 return (0);
1161 #undef ia
1162 }
1163 /*
1164 * Add an address to the list of IP multicast addresses for a given interface.
1165 */
1166 struct in_multi *
1167 in_addmulti(ap, ifp)
1168 register struct in_addr *ap;
1169 register struct ifnet *ifp;
1170 {
1171 register struct in_multi *inm;
1172 int error;
1173 struct sockaddr_in sin;
1174 struct ifmultiaddr *ifma;
1175 int s = splnet();
1176
1177 /*
1178 * Call generic routine to add membership or increment
1179 * refcount. It wants addresses in the form of a sockaddr,
1180 * so we build one here (being careful to zero the unused bytes).
1181 */
1182 bzero(&sin, sizeof sin);
1183 sin.sin_family = AF_INET;
1184 sin.sin_len = sizeof sin;
1185 sin.sin_addr = *ap;
1186 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
1187 if (error) {
1188 splx(s);
1189 return 0;
1190 }
1191
1192 /*
1193 * If ifma->ifma_protospec is null, then if_addmulti() created
1194 * a new record. Otherwise, we are done.
1195 */
1196 if (ifma->ifma_protospec != 0) {
1197 splx(s);
1198 return ifma->ifma_protospec;
1199 }
1200
1201 inm = (struct in_multi *) _MALLOC(sizeof(*inm), M_IPMADDR, M_WAITOK);
1202 if (inm == NULL) {
1203 splx(s);
1204 return (NULL);
1205 }
1206
1207 bzero(inm, sizeof *inm);
1208 inm->inm_addr = *ap;
1209 inm->inm_ifp = ifp;
1210 inm->inm_ifma = ifma;
1211 ifma->ifma_protospec = inm;
1212 LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
1213
1214 /*
1215 * Let IGMP know that we have joined a new IP multicast group.
1216 */
1217 error = igmp_joingroup(inm);
1218 if (error) {
1219 if_delmultiaddr(ifma);
1220 LIST_REMOVE(inm, inm_link);
1221 _FREE(inm, M_IPMADDR);
1222 inm = NULL;
1223 }
1224 splx(s);
1225 return (inm);
1226 }
1227
1228 /*
1229 * Delete a multicast address record.
1230 */
1231 void
1232 in_delmulti(inm)
1233 register struct in_multi *inm;
1234 {
1235 struct ifmultiaddr *ifma = inm->inm_ifma;
1236 int s = splnet();
1237
1238 /* We intentionally do this a bit differently than BSD */
1239
1240 if (ifma && ifma->ifma_refcount == 1) {
1241 /*
1242 * No remaining claims to this record; let IGMP know that
1243 * we are leaving the multicast group.
1244 */
1245 igmp_leavegroup(inm);
1246 ifma->ifma_protospec = 0;
1247 LIST_REMOVE(inm, inm_link);
1248 FREE(inm, M_IPMADDR);
1249 }
1250 /* XXX - should be separate API for when we have an ifma? */
1251 if (ifma)
1252 if_delmultiaddr(ifma);
1253 splx(s);
1254 }