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