]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/in.c
xnu-1486.2.11.tar.gz
[apple/xnu.git] / bsd / netinet / in.c
1 /*
2 * Copyright (c) 2000-2008 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 #include <kern/zalloc.h>
76
77 #include <pexpert/pexpert.h>
78
79 #include <net/if.h>
80 #include <net/if_types.h>
81 #include <net/route.h>
82 #include <net/kpi_protocol.h>
83
84 #include <netinet/in.h>
85 #include <netinet/in_var.h>
86 #include <netinet/in_pcb.h>
87
88 #include <netinet/igmp_var.h>
89 #include <net/dlil.h>
90
91 #include <netinet/ip_var.h>
92
93 #include <netinet/tcp.h>
94 #include <netinet/tcp_timer.h>
95 #include <netinet/tcp_var.h>
96
97 #include <sys/file.h>
98
99 #if PF
100 #include <net/pfvar.h>
101 #endif /* PF */
102
103 static int in_mask2len(struct in_addr *);
104 static void in_len2mask(struct in_addr *, int);
105 static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t,
106 struct ifnet *, struct proc *);
107
108 static void in_socktrim(struct sockaddr_in *);
109 static int in_ifinit(struct ifnet *,
110 struct in_ifaddr *, struct sockaddr_in *, int);
111
112 #define IA_HASH_INIT(ia) { \
113 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \
114 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \
115 }
116
117 #define IA_IS_HASHED(ia) \
118 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \
119 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1))
120
121 static void in_iahash_remove(struct in_ifaddr *);
122 static void in_iahash_insert(struct in_ifaddr *);
123 static void in_iahash_insert_ptp(struct in_ifaddr *);
124 static struct in_ifaddr *in_ifaddr_alloc(int);
125 static void in_ifaddr_free(struct ifaddr *);
126 static void in_ifaddr_trace(struct ifaddr *, int);
127
128 static int subnetsarelocal = 0;
129 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
130 &subnetsarelocal, 0, "");
131
132 struct in_multihead in_multihead; /* XXX BSS initialization */
133
134 /* Track whether or not the SIOCARPIPLL ioctl has been called */
135 __private_extern__ u_int32_t ipv4_ll_arp_aware = 0;
136
137 struct in_ifaddr_dbg {
138 struct in_ifaddr inifa; /* in_ifaddr */
139 struct in_ifaddr inifa_old; /* saved in_ifaddr */
140 u_int16_t inifa_refhold_cnt; /* # of ifaref */
141 u_int16_t inifa_refrele_cnt; /* # of ifafree */
142 /*
143 * Alloc and free callers.
144 */
145 ctrace_t inifa_alloc;
146 ctrace_t inifa_free;
147 /*
148 * Circular lists of ifaref and ifafree callers.
149 */
150 ctrace_t inifa_refhold[CTRACE_HIST_SIZE];
151 ctrace_t inifa_refrele[CTRACE_HIST_SIZE];
152 };
153
154 static unsigned int inifa_debug; /* debug flags */
155 static unsigned int inifa_size; /* size of zone element */
156 static struct zone *inifa_zone; /* zone for in_ifaddr */
157
158 #define INIFA_ZONE_MAX 64 /* maximum elements in zone */
159 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
160
161 int
162 inaddr_local(struct in_addr in)
163 {
164 struct rtentry *rt;
165 struct sockaddr_in sin;
166 int local = 0;
167
168 sin.sin_family = AF_INET;
169 sin.sin_len = sizeof (sin);
170 sin.sin_addr = in;
171 rt = rtalloc1((struct sockaddr *)&sin, 0, 0);
172
173 if (rt != NULL) {
174 RT_LOCK_SPIN(rt);
175 if (rt->rt_gateway->sa_family == AF_LINK ||
176 (rt->rt_ifp->if_flags & IFF_LOOPBACK))
177 local = 1;
178 RT_UNLOCK(rt);
179 rtfree(rt);
180 } else {
181 local = in_localaddr(in);
182 }
183 return (local);
184 }
185
186 /*
187 * Return 1 if an internet address is for a ``local'' host
188 * (one to which we have a connection). If subnetsarelocal
189 * is true, this includes other subnets of the local net.
190 * Otherwise, it includes only the directly-connected (sub)nets.
191 */
192 int
193 in_localaddr(struct in_addr in)
194 {
195 u_int32_t i = ntohl(in.s_addr);
196 struct in_ifaddr *ia;
197
198 if (subnetsarelocal) {
199 lck_rw_lock_shared(in_ifaddr_rwlock);
200 for (ia = in_ifaddrhead.tqh_first; ia;
201 ia = ia->ia_link.tqe_next)
202 if ((i & ia->ia_netmask) == ia->ia_net) {
203 lck_rw_done(in_ifaddr_rwlock);
204 return (1);
205 }
206 lck_rw_done(in_ifaddr_rwlock);
207 } else {
208 lck_rw_lock_shared(in_ifaddr_rwlock);
209 for (ia = in_ifaddrhead.tqh_first; ia;
210 ia = ia->ia_link.tqe_next)
211 if ((i & ia->ia_subnetmask) == ia->ia_subnet) {
212 lck_rw_done(in_ifaddr_rwlock);
213 return (1);
214 }
215 lck_rw_done(in_ifaddr_rwlock);
216 }
217 return (0);
218 }
219
220 /*
221 * Determine whether an IP address is in a reserved set of addresses
222 * that may not be forwarded, or whether datagrams to that destination
223 * may be forwarded.
224 */
225 int
226 in_canforward(struct in_addr in)
227 {
228 u_int32_t i = ntohl(in.s_addr);
229 u_int32_t net;
230
231 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
232 return (0);
233 if (IN_CLASSA(i)) {
234 net = i & IN_CLASSA_NET;
235 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
236 return (0);
237 }
238 return (1);
239 }
240
241 /*
242 * Trim a mask in a sockaddr
243 */
244 static void
245 in_socktrim(struct sockaddr_in *ap)
246 {
247 char *cplim = (char *) &ap->sin_addr;
248 char *cp = (char *) (&ap->sin_addr + 1);
249
250 ap->sin_len = 0;
251 while (--cp >= cplim)
252 if (*cp) {
253 (ap)->sin_len = cp - (char *) (ap) + 1;
254 break;
255 }
256 }
257
258 static int
259 in_mask2len(struct in_addr *mask)
260 {
261 size_t x, y;
262 u_char *p;
263
264 p = (u_char *)mask;
265 for (x = 0; x < sizeof(*mask); x++) {
266 if (p[x] != 0xff)
267 break;
268 }
269 y = 0;
270 if (x < sizeof(*mask)) {
271 for (y = 0; y < 8; y++) {
272 if ((p[x] & (0x80 >> y)) == 0)
273 break;
274 }
275 }
276 return x * 8 + y;
277 }
278
279 static void
280 in_len2mask(struct in_addr *mask, int len)
281 {
282 int i;
283 u_char *p;
284
285 p = (u_char *)mask;
286 bzero(mask, sizeof(*mask));
287 for (i = 0; i < len / 8; i++)
288 p[i] = 0xff;
289 if (len % 8)
290 p[i] = (0xff00 >> (len % 8)) & 0xff;
291 }
292
293 static int in_interfaces; /* number of external internet interfaces */
294
295 /*
296 * Generic internet control operations (ioctl's).
297 * Ifp is 0 if not an interface-specific ioctl.
298 *
299 * Returns: 0 Success
300 * EINVAL
301 * EADDRNOTAVAIL
302 * EDESTADDRREQ
303 * EPERM
304 * ENOBUFS
305 * EBUSY
306 * EOPNOTSUPP
307 * proc_suser:EPERM
308 * suser:EPERM
309 * in_lifaddr_ioctl:???
310 * dlil_ioctl:???
311 * in_ifinit:???
312 * dlil_plumb_protocol:???
313 * dlil_unplumb_protocol:???
314 */
315 /* ARGSUSED */
316 int
317 in_control(
318 struct socket *so,
319 u_long cmd,
320 caddr_t data,
321 struct ifnet *ifp,
322 struct proc *p)
323 {
324 struct ifreq *ifr = (struct ifreq *)data;
325 struct in_ifaddr *ia = NULL, *iap;
326 struct ifaddr *ifa;
327 struct in_aliasreq *ifra = (struct in_aliasreq *)data;
328 struct sockaddr_in oldaddr;
329 int error = 0;
330 int hostIsNew, maskIsNew;
331 struct kev_msg ev_msg;
332 struct kev_in_data in_event_data;
333
334 switch (cmd) {
335 case SIOCALIFADDR:
336 case SIOCDLIFADDR:
337 if ((error = proc_suser(p)) != 0)
338 return error;
339 /*fall through*/
340 case SIOCGLIFADDR:
341 if (!ifp)
342 return EINVAL;
343 return in_lifaddr_ioctl(so, cmd, data, ifp, p);
344 }
345
346 /*
347 * Find address for this interface, if it exists.
348 *
349 * If an alias address was specified, find that one instead of
350 * the first one on the interface.
351 */
352 if (ifp) {
353 lck_rw_lock_shared(in_ifaddr_rwlock);
354 for (iap = in_ifaddrhead.tqh_first; iap;
355 iap = iap->ia_link.tqe_next)
356 if (iap->ia_ifp == ifp) {
357 if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr ==
358 iap->ia_addr.sin_addr.s_addr) {
359 ia = iap;
360 break;
361 } else if (ia == NULL) {
362 ia = iap;
363 if (ifr->ifr_addr.sa_family != AF_INET)
364 break;
365 }
366 }
367 /* take a reference on ia before releasing lock */
368 if (ia != NULL) {
369 ifaref(&ia->ia_ifa);
370 }
371 lck_rw_done(in_ifaddr_rwlock);
372 }
373 switch (cmd) {
374 case SIOCAUTOADDR:
375 case SIOCARPIPLL:
376 if ((error = proc_suser(p)) != 0) {
377 goto done;
378 }
379 if (ifp == 0) {
380 error = EADDRNOTAVAIL;
381 goto done;
382 }
383 break;
384
385 case SIOCAIFADDR:
386 case SIOCDIFADDR:
387 if (ifp == 0) {
388 error = EADDRNOTAVAIL;
389 goto done;
390 }
391 if (ifra->ifra_addr.sin_family == AF_INET) {
392 struct in_ifaddr *oia;
393
394 lck_rw_lock_shared(in_ifaddr_rwlock);
395 for (oia = ia; ia; ia = ia->ia_link.tqe_next) {
396 if (ia->ia_ifp == ifp &&
397 ia->ia_addr.sin_addr.s_addr ==
398 ifra->ifra_addr.sin_addr.s_addr)
399 break;
400 }
401 /* take a reference on ia before releasing lock */
402 if (ia != NULL && ia != oia) {
403 ifaref(&ia->ia_ifa);
404 }
405 lck_rw_done(in_ifaddr_rwlock);
406 if (oia != NULL && oia != ia) {
407 ifafree(&oia->ia_ifa);
408 }
409 if ((ifp->if_flags & IFF_POINTOPOINT)
410 && (cmd == SIOCAIFADDR)
411 && (ifra->ifra_dstaddr.sin_addr.s_addr
412 == INADDR_ANY)) {
413 error = EDESTADDRREQ;
414 goto done;
415 }
416 }
417 else if (cmd == SIOCAIFADDR) {
418 error = EINVAL;
419 goto done;
420 }
421 if (cmd == SIOCDIFADDR && ia == 0) {
422 error = EADDRNOTAVAIL;
423 goto done;
424 }
425 /* FALLTHROUGH */
426 case SIOCSIFADDR:
427 case SIOCSIFNETMASK:
428 case SIOCSIFDSTADDR:
429 if ((so->so_state & SS_PRIV) == 0) {
430 error = EPERM;
431 goto done;
432 }
433 if (ifp == 0) {
434 error = EADDRNOTAVAIL;
435 goto done;
436 }
437 if (ifra->ifra_addr.sin_family != AF_INET
438 && cmd == SIOCSIFADDR) {
439 error = EINVAL;
440 goto done;
441 }
442 if (ia == (struct in_ifaddr *)0) {
443 ia = in_ifaddr_alloc(M_WAITOK);
444 if (ia == (struct in_ifaddr *)NULL) {
445 error = ENOBUFS;
446 goto done;
447 }
448 IA_HASH_INIT(ia);
449 ifa = &ia->ia_ifa;
450 /* Hold a reference for this routine */
451 ifaref(ifa);
452 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
453 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
454 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
455 ia->ia_sockmask.sin_len = 8;
456 ifnet_lock_exclusive(ifp);
457 if (ifp->if_flags & IFF_BROADCAST) {
458 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
459 ia->ia_broadaddr.sin_family = AF_INET;
460 }
461 ia->ia_ifp = ifp;
462 if (!(ifp->if_flags & IFF_LOOPBACK))
463 in_interfaces++;
464 /* if_attach_ifa() holds a reference for ifa_link */
465 if_attach_ifa(ifp, ifa);
466 ifnet_lock_done(ifp);
467 lck_rw_lock_exclusive(in_ifaddr_rwlock);
468 /* Hold a reference for ia_link */
469 ifaref(ifa);
470 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
471 lck_rw_done(in_ifaddr_rwlock);
472
473 /* Generic protocol plumbing */
474
475 if ((error = proto_plumb(PF_INET, ifp))) {
476 if (error != EEXIST) {
477 kprintf("in.c: warning can't plumb proto if=%s%d type %d error=%d\n",
478 ifp->if_name, ifp->if_unit, ifp->if_type, error);
479 }
480 error = 0; /*discard error, can be cold with unsupported interfaces */
481 }
482 }
483 break;
484
485 case SIOCPROTOATTACH:
486 case SIOCPROTODETACH:
487 if ((error = proc_suser(p)) != 0) {
488 goto done;
489 }
490 if (ifp == 0) {
491 error = EADDRNOTAVAIL;
492 goto done;
493 }
494 break;
495
496 case SIOCSIFBRDADDR:
497 if ((so->so_state & SS_PRIV) == 0) {
498 error = EPERM;
499 goto done;
500 }
501 /* FALLTHROUGH */
502
503 case SIOCGIFADDR:
504 case SIOCGIFNETMASK:
505 case SIOCGIFDSTADDR:
506 case SIOCGIFBRDADDR:
507 if (ia == (struct in_ifaddr *)0) {
508 error = EADDRNOTAVAIL;
509 goto done;
510 }
511 break;
512 }
513 switch (cmd) {
514 case SIOCAUTOADDR:
515 ifnet_lock_exclusive(ifp);
516 if (ifr->ifr_intval)
517 ifp->if_eflags |= IFEF_AUTOCONFIGURING;
518 else
519 ifp->if_eflags &= ~IFEF_AUTOCONFIGURING;
520 ifnet_lock_done(ifp);
521 break;
522
523 case SIOCARPIPLL:
524 ipv4_ll_arp_aware = 1;
525 ifnet_lock_exclusive(ifp);
526 if (ifr->ifr_data)
527 ifp->if_eflags |= IFEF_ARPLL;
528 else
529 ifp->if_eflags &= ~IFEF_ARPLL;
530 ifnet_lock_done(ifp);
531 break;
532
533 case SIOCGIFADDR:
534 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
535 break;
536
537 case SIOCGIFBRDADDR:
538 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
539 error = EINVAL;
540 break;
541 }
542 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
543 break;
544
545 case SIOCGIFDSTADDR:
546 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
547 error = EINVAL;
548 break;
549 }
550 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
551 break;
552
553 case SIOCGIFNETMASK:
554 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
555 break;
556
557 case SIOCSIFDSTADDR:
558 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
559 error = EINVAL;
560 break;
561 }
562 oldaddr = ia->ia_dstaddr;
563 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
564 if (ia->ia_dstaddr.sin_family == AF_INET)
565 ia->ia_dstaddr.sin_len = sizeof (struct sockaddr_in);
566 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia);
567 if (error == EOPNOTSUPP) {
568 error = 0;
569 }
570 if (error) {
571 ia->ia_dstaddr = oldaddr;
572 break;
573 }
574
575 ev_msg.vendor_code = KEV_VENDOR_APPLE;
576 ev_msg.kev_class = KEV_NETWORK_CLASS;
577 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
578
579 ev_msg.event_code = KEV_INET_SIFDSTADDR;
580
581 if (ia->ia_ifa.ifa_dstaddr)
582 in_event_data.ia_dstaddr =
583 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
584 else
585 in_event_data.ia_dstaddr.s_addr = 0;
586
587 in_event_data.ia_addr = ia->ia_addr.sin_addr;
588 in_event_data.ia_net = ia->ia_net;
589 in_event_data.ia_netmask = ia->ia_netmask;
590 in_event_data.ia_subnet = ia->ia_subnet;
591 in_event_data.ia_subnetmask = ia->ia_subnetmask;
592 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
593 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
594 in_event_data.link_data.if_family = ifp->if_family;
595 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
596
597 ev_msg.dv[0].data_ptr = &in_event_data;
598 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
599 ev_msg.dv[1].data_length = 0;
600
601 kev_post_msg(&ev_msg);
602
603
604 if (ia->ia_flags & IFA_ROUTE) {
605 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
606 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
607 ia->ia_ifa.ifa_dstaddr =
608 (struct sockaddr *)&ia->ia_dstaddr;
609 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
610 }
611 break;
612
613 case SIOCSIFBRDADDR:
614 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
615 error = EINVAL;
616 break;
617 }
618 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
619
620 ev_msg.vendor_code = KEV_VENDOR_APPLE;
621 ev_msg.kev_class = KEV_NETWORK_CLASS;
622 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
623
624 ev_msg.event_code = KEV_INET_SIFBRDADDR;
625
626 if (ia->ia_ifa.ifa_dstaddr)
627 in_event_data.ia_dstaddr =
628 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
629 else
630 in_event_data.ia_dstaddr.s_addr = 0;
631
632 in_event_data.ia_addr = ia->ia_addr.sin_addr;
633 in_event_data.ia_net = ia->ia_net;
634 in_event_data.ia_netmask = ia->ia_netmask;
635 in_event_data.ia_subnet = ia->ia_subnet;
636 in_event_data.ia_subnetmask = ia->ia_subnetmask;
637 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
638 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
639 in_event_data.link_data.if_family = ifp->if_family;
640 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
641
642 ev_msg.dv[0].data_ptr = &in_event_data;
643 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
644 ev_msg.dv[1].data_length = 0;
645
646 kev_post_msg(&ev_msg);
647
648 break;
649
650 case SIOCSIFADDR:
651 /*
652 * If this is a new address, the reference count for the
653 * hash table has been taken at creation time above.
654 */
655 error = in_ifinit(ifp, ia,
656 (struct sockaddr_in *)&ifr->ifr_addr, 1);
657 #if PF
658 if (!error)
659 (void) pf_ifaddr_hook(ifp, cmd);
660 #endif /* PF */
661 break;
662
663 case SIOCPROTOATTACH:
664 error = proto_plumb(PF_INET, ifp);
665 break;
666
667 case SIOCPROTODETACH:
668 // if an ip address is still present, refuse to detach
669 ifnet_lock_shared(ifp);
670 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
671 if (ifa->ifa_addr->sa_family == AF_INET)
672 break;
673 ifnet_lock_done(ifp);
674 if (ifa != 0) {
675 error = EBUSY;
676 break;
677 }
678
679 error = proto_unplumb(PF_INET, ifp);
680 break;
681
682
683 case SIOCSIFNETMASK: {
684 u_long i;
685
686 i = ifra->ifra_addr.sin_addr.s_addr;
687 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
688 ev_msg.vendor_code = KEV_VENDOR_APPLE;
689 ev_msg.kev_class = KEV_NETWORK_CLASS;
690 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
691
692 ev_msg.event_code = KEV_INET_SIFNETMASK;
693
694 if (ia->ia_ifa.ifa_dstaddr)
695 in_event_data.ia_dstaddr =
696 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
697 else
698 in_event_data.ia_dstaddr.s_addr = 0;
699
700 in_event_data.ia_addr = ia->ia_addr.sin_addr;
701 in_event_data.ia_net = ia->ia_net;
702 in_event_data.ia_netmask = ia->ia_netmask;
703 in_event_data.ia_subnet = ia->ia_subnet;
704 in_event_data.ia_subnetmask = ia->ia_subnetmask;
705 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
706 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
707 in_event_data.link_data.if_family = ifp->if_family;
708 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
709
710 ev_msg.dv[0].data_ptr = &in_event_data;
711 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
712 ev_msg.dv[1].data_length = 0;
713
714 kev_post_msg(&ev_msg);
715
716 break;
717 }
718 case SIOCAIFADDR:
719 maskIsNew = 0;
720 hostIsNew = 1;
721 error = 0;
722
723 if (ia->ia_addr.sin_family == AF_INET) {
724 if (ifra->ifra_addr.sin_len == 0) {
725 ifra->ifra_addr = ia->ia_addr;
726 hostIsNew = 0;
727 } else if (ifra->ifra_addr.sin_addr.s_addr ==
728 ia->ia_addr.sin_addr.s_addr)
729 hostIsNew = 0;
730 }
731 if (ifra->ifra_mask.sin_len) {
732 in_ifscrub(ifp, ia, 0);
733 ia->ia_sockmask = ifra->ifra_mask;
734 ia->ia_subnetmask =
735 ntohl(ia->ia_sockmask.sin_addr.s_addr);
736 maskIsNew = 1;
737 }
738 if ((ifp->if_flags & IFF_POINTOPOINT) &&
739 (ifra->ifra_dstaddr.sin_family == AF_INET)) {
740 in_ifscrub(ifp, ia, 0);
741 ia->ia_dstaddr = ifra->ifra_dstaddr;
742 ia->ia_dstaddr.sin_len = sizeof (struct sockaddr_in);
743 maskIsNew = 1; /* We lie; but the effect's the same */
744 }
745 if (ifra->ifra_addr.sin_family == AF_INET &&
746 (hostIsNew || maskIsNew)) {
747 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
748 }
749 #if PF
750 if (!error)
751 (void) pf_ifaddr_hook(ifp, cmd);
752 #endif /* PF */
753 if ((ifp->if_flags & IFF_BROADCAST) &&
754 (ifra->ifra_broadaddr.sin_family == AF_INET))
755 ia->ia_broadaddr = ifra->ifra_broadaddr;
756
757 /*
758 * Report event.
759 */
760
761 if ((error == 0) || (error == EEXIST)) {
762 ev_msg.vendor_code = KEV_VENDOR_APPLE;
763 ev_msg.kev_class = KEV_NETWORK_CLASS;
764 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
765
766 if (hostIsNew)
767 ev_msg.event_code = KEV_INET_NEW_ADDR;
768 else
769 ev_msg.event_code = KEV_INET_CHANGED_ADDR;
770
771 if (ia->ia_ifa.ifa_dstaddr)
772 in_event_data.ia_dstaddr =
773 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
774 else
775 in_event_data.ia_dstaddr.s_addr = 0;
776
777 in_event_data.ia_addr = ia->ia_addr.sin_addr;
778 in_event_data.ia_net = ia->ia_net;
779 in_event_data.ia_netmask = ia->ia_netmask;
780 in_event_data.ia_subnet = ia->ia_subnet;
781 in_event_data.ia_subnetmask = ia->ia_subnetmask;
782 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
783 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
784 in_event_data.link_data.if_family = ifp->if_family;
785 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
786
787 ev_msg.dv[0].data_ptr = &in_event_data;
788 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
789 ev_msg.dv[1].data_length = 0;
790
791 kev_post_msg(&ev_msg);
792 }
793 break;
794
795 case SIOCDIFADDR:
796 error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia);
797 if (error == EOPNOTSUPP)
798 error = 0;
799 if (error != 0) {
800 break;
801 }
802
803 /* Fill out the kernel event information */
804 ev_msg.vendor_code = KEV_VENDOR_APPLE;
805 ev_msg.kev_class = KEV_NETWORK_CLASS;
806 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
807
808 ev_msg.event_code = KEV_INET_ADDR_DELETED;
809
810 if (ia->ia_ifa.ifa_dstaddr)
811 in_event_data.ia_dstaddr =
812 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
813 else
814 in_event_data.ia_dstaddr.s_addr = 0;
815
816 in_event_data.ia_addr = ia->ia_addr.sin_addr;
817 in_event_data.ia_net = ia->ia_net;
818 in_event_data.ia_netmask = ia->ia_netmask;
819 in_event_data.ia_subnet = ia->ia_subnet;
820 in_event_data.ia_subnetmask = ia->ia_subnetmask;
821 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
822 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
823 in_event_data.link_data.if_family = ifp->if_family;
824 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
825
826 ev_msg.dv[0].data_ptr = &in_event_data;
827 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
828 ev_msg.dv[1].data_length = 0;
829
830 ifa = &ia->ia_ifa;
831 lck_rw_lock_exclusive(in_ifaddr_rwlock);
832 /* Release ia_link reference */
833 ifafree(ifa);
834 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
835 if (IA_IS_HASHED(ia))
836 in_iahash_remove(ia);
837 lck_rw_done(in_ifaddr_rwlock);
838
839 /*
840 * in_ifscrub kills the interface route.
841 */
842 in_ifscrub(ifp, ia, 0);
843 ifnet_lock_exclusive(ifp);
844 /* if_detach_ifa() releases ifa_link reference */
845 if_detach_ifa(ifp, ifa);
846 #ifdef __APPLE__
847 /*
848 * If the interface supports multicast, and no address is left,
849 * remove the "all hosts" multicast group from that interface.
850 */
851 if (ifp->if_flags & IFF_MULTICAST) {
852 struct in_addr addr;
853 struct in_multi *inm = NULL;
854
855 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
856 if (ifa->ifa_addr->sa_family == AF_INET)
857 break;
858
859 if (ifa == 0) {
860 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
861 IN_LOOKUP_MULTI(addr, ifp, inm);
862 }
863 ifnet_lock_done(ifp);
864 if (inm)
865 in_delmulti(&inm);
866 } else
867 ifnet_lock_done(ifp);
868 #endif
869
870 /* Post the kernel event */
871 kev_post_msg(&ev_msg);
872
873 /*
874 * See if there is any IPV4 address left and if so,
875 * reconfigure KDP to use current primary address.
876 */
877 ifa = ifa_ifpgetprimary(ifp, AF_INET);
878 if (ifa != NULL) {
879 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa);
880 if (error == EOPNOTSUPP)
881 error = 0;
882
883 /* Release reference from ifa_ifpgetprimary() */
884 ifafree(ifa);
885 }
886 #if PF
887 (void) pf_ifaddr_hook(ifp, cmd);
888 #endif /* PF */
889 break;
890
891 #ifdef __APPLE__
892 case SIOCSETOT: {
893 /*
894 * Inspiration from tcp_ctloutput() and ip_ctloutput()
895 * Special ioctl for OpenTransport sockets
896 */
897 struct inpcb *inp, *cloned_inp;
898 int error2 = 0;
899 int cloned_fd = *(int *)data;
900
901 inp = sotoinpcb(so);
902 if (inp == NULL) {
903 break;
904 }
905
906 /* let's make sure it's either -1 or a valid file descriptor */
907 if (cloned_fd != -1) {
908 struct socket *cloned_so;
909 error2 = file_socket(cloned_fd, &cloned_so);
910 if (error2){
911 break;
912 }
913 cloned_inp = sotoinpcb(cloned_so);
914 file_drop(cloned_fd);
915 } else {
916 cloned_inp = NULL;
917 }
918
919 if (cloned_inp == NULL) {
920 /* OT always uses IP_PORTRANGE_HIGH */
921 inp->inp_flags &= ~(INP_LOWPORT);
922 inp->inp_flags |= INP_HIGHPORT;
923 /* For UDP, OT allows broadcast by default */
924 if (so->so_type == SOCK_DGRAM)
925 so->so_options |= SO_BROADCAST;
926 /* For TCP we want to see MSG_OOB when receive urgent data */
927 else if (so->so_type == SOCK_STREAM)
928 so->so_options |= SO_WANTOOBFLAG;
929 } else {
930 inp->inp_ip_tos = cloned_inp->inp_ip_tos;
931 inp->inp_ip_ttl = cloned_inp->inp_ip_ttl;
932 inp->inp_flags = cloned_inp->inp_flags;
933
934 /* Multicast options */
935 if (cloned_inp->inp_moptions != NULL) {
936 int i;
937 struct ip_moptions *cloned_imo = cloned_inp->inp_moptions;
938 struct ip_moptions *imo = inp->inp_moptions;
939
940 if (imo == NULL) {
941 /*
942 * No multicast option buffer attached to the pcb;
943 * allocate one.
944 */
945 imo = (struct ip_moptions*)
946 _MALLOC(sizeof(*imo), M_IPMOPTS, M_WAITOK);
947 if (imo == NULL) {
948 error2 = ENOBUFS;
949 break;
950 }
951 inp->inp_moptions = imo;
952 }
953 imo->imo_multicast_ifp = cloned_imo->imo_multicast_ifp;
954 imo->imo_multicast_vif = cloned_imo->imo_multicast_vif;
955 imo->imo_multicast_ttl = cloned_imo->imo_multicast_ttl;
956 imo->imo_multicast_loop = cloned_imo->imo_multicast_loop;
957 imo->imo_num_memberships = cloned_imo->imo_num_memberships;
958 for (i = 0; i < cloned_imo->imo_num_memberships; i++) {
959 imo->imo_membership[i] =
960 in_addmulti(&cloned_imo->imo_membership[i]->inm_addr,
961 cloned_imo->imo_membership[i]->inm_ifp);
962 if (imo->imo_membership[i] == NULL) {
963 error2 = ENOBUFS;
964 break;
965 }
966 }
967 if (i < cloned_imo->imo_num_memberships) {
968 /* Failed, perform cleanup */
969 for (i--; i >= 0; i--)
970 in_delmulti(&imo->imo_membership[i]);
971 imo->imo_num_memberships = 0;
972 break;
973 }
974 }
975 }
976 break;
977 }
978 #endif /* __APPLE__ */
979
980 default:
981 error = EOPNOTSUPP;
982 }
983 done:
984 if (ia != NULL) {
985 ifafree(&ia->ia_ifa);
986 }
987 return (error);
988 }
989
990 /*
991 * SIOC[GAD]LIFADDR.
992 * SIOCGLIFADDR: get first address. (?!?)
993 * SIOCGLIFADDR with IFLR_PREFIX:
994 * get first address that matches the specified prefix.
995 * SIOCALIFADDR: add the specified address.
996 * SIOCALIFADDR with IFLR_PREFIX:
997 * EINVAL since we can't deduce hostid part of the address.
998 * SIOCDLIFADDR: delete the specified address.
999 * SIOCDLIFADDR with IFLR_PREFIX:
1000 * delete the first address that matches the specified prefix.
1001 * return values:
1002 * EINVAL on invalid parameters
1003 * EADDRNOTAVAIL on prefix match failed/specified address not found
1004 * other values may be returned from in_ioctl()
1005 */
1006 static int
1007 in_lifaddr_ioctl(
1008 struct socket *so,
1009 u_long cmd,
1010 caddr_t data,
1011 struct ifnet *ifp,
1012 struct proc *p)
1013 {
1014 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
1015 struct ifaddr *ifa;
1016
1017 /* sanity checks */
1018 if (!data || !ifp) {
1019 panic("invalid argument to in_lifaddr_ioctl");
1020 /*NOTRECHED*/
1021 }
1022
1023 switch (cmd) {
1024 case SIOCGLIFADDR:
1025 /* address must be specified on GET with IFLR_PREFIX */
1026 if ((iflr->flags & IFLR_PREFIX) == 0)
1027 break;
1028 /*FALLTHROUGH*/
1029 case SIOCALIFADDR:
1030 case SIOCDLIFADDR:
1031 /* address must be specified on ADD and DELETE */
1032 if (iflr->addr.ss_family != AF_INET)
1033 return EINVAL;
1034 if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
1035 return EINVAL;
1036 /* XXX need improvement */
1037 if (iflr->dstaddr.ss_family
1038 && iflr->dstaddr.ss_family != AF_INET)
1039 return EINVAL;
1040 if (iflr->dstaddr.ss_family
1041 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
1042 return EINVAL;
1043 break;
1044 default: /*shouldn't happen*/
1045 return EOPNOTSUPP;
1046 }
1047 if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
1048 return EINVAL;
1049
1050 switch (cmd) {
1051 case SIOCALIFADDR:
1052 {
1053 struct in_aliasreq ifra;
1054
1055 if (iflr->flags & IFLR_PREFIX)
1056 return EINVAL;
1057
1058 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1059 bzero(&ifra, sizeof(ifra));
1060 bcopy(iflr->iflr_name, ifra.ifra_name,
1061 sizeof(ifra.ifra_name));
1062
1063 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
1064
1065 if (iflr->dstaddr.ss_family) { /*XXX*/
1066 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1067 iflr->dstaddr.ss_len);
1068 }
1069
1070 ifra.ifra_mask.sin_family = AF_INET;
1071 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
1072 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
1073
1074 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p);
1075 }
1076 case SIOCGLIFADDR:
1077 case SIOCDLIFADDR:
1078 {
1079 struct in_ifaddr *ia;
1080 struct in_addr mask, candidate;
1081 struct in_addr match = { 0 };
1082 struct sockaddr_in *sin;
1083 int cmp;
1084
1085 bzero(&mask, sizeof(mask));
1086 if (iflr->flags & IFLR_PREFIX) {
1087 /* lookup a prefix rather than address. */
1088 in_len2mask(&mask, iflr->prefixlen);
1089
1090 sin = (struct sockaddr_in *)&iflr->addr;
1091 match.s_addr = sin->sin_addr.s_addr;
1092 match.s_addr &= mask.s_addr;
1093
1094 /* if you set extra bits, that's wrong */
1095 if (match.s_addr != sin->sin_addr.s_addr)
1096 return EINVAL;
1097
1098 cmp = 1;
1099 } else {
1100 if (cmd == SIOCGLIFADDR) {
1101 /* on getting an address, take the 1st match */
1102 cmp = 0; /*XXX*/
1103 } else {
1104 /* on deleting an address, do exact match */
1105 in_len2mask(&mask, 32);
1106 sin = (struct sockaddr_in *)&iflr->addr;
1107 match.s_addr = sin->sin_addr.s_addr;
1108
1109 cmp = 1;
1110 }
1111 }
1112
1113 ifnet_lock_shared(ifp);
1114 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1115 if (ifa->ifa_addr->sa_family != AF_INET6)
1116 continue;
1117 if (!cmp)
1118 break;
1119 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
1120 candidate.s_addr &= mask.s_addr;
1121 if (candidate.s_addr == match.s_addr)
1122 break;
1123 }
1124 ifnet_lock_done(ifp);
1125 if (!ifa)
1126 return EADDRNOTAVAIL;
1127 ia = (struct in_ifaddr *)ifa;
1128
1129 if (cmd == SIOCGLIFADDR) {
1130 /* fill in the if_laddrreq structure */
1131 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
1132
1133 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1134 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1135 ia->ia_dstaddr.sin_len);
1136 } else
1137 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1138
1139 iflr->prefixlen =
1140 in_mask2len(&ia->ia_sockmask.sin_addr);
1141
1142 iflr->flags = 0; /*XXX*/
1143
1144 return 0;
1145 } else {
1146 struct in_aliasreq ifra;
1147
1148 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1149 bzero(&ifra, sizeof(ifra));
1150 bcopy(iflr->iflr_name, ifra.ifra_name,
1151 sizeof(ifra.ifra_name));
1152
1153 bcopy(&ia->ia_addr, &ifra.ifra_addr,
1154 ia->ia_addr.sin_len);
1155 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1156 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1157 ia->ia_dstaddr.sin_len);
1158 }
1159 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
1160 ia->ia_sockmask.sin_len);
1161
1162 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
1163 ifp, p);
1164 }
1165 }
1166 }
1167
1168 return EOPNOTSUPP; /*just for safety*/
1169 }
1170
1171 /*
1172 * Delete any existing route for an interface.
1173 */
1174 void
1175 in_ifscrub(
1176 struct ifnet *ifp,
1177 struct in_ifaddr *ia,
1178 int locked)
1179 {
1180
1181 if ((ia->ia_flags & IFA_ROUTE) == 0)
1182 return;
1183 if (!locked)
1184 lck_mtx_lock(rnh_lock);
1185 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
1186 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1187 else
1188 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1189 ia->ia_flags &= ~IFA_ROUTE;
1190 if (!locked)
1191 lck_mtx_unlock(rnh_lock);
1192 }
1193
1194 /*
1195 * Caller must hold in_ifaddr_rwlock as writer.
1196 */
1197 static void
1198 in_iahash_remove(struct in_ifaddr *ia)
1199 {
1200 if (!IA_IS_HASHED(ia))
1201 panic("attempt to remove wrong ia %p from hash table\n", ia);
1202
1203 TAILQ_REMOVE(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1204 IA_HASH_INIT(ia);
1205 ifafree(&ia->ia_ifa);
1206 }
1207
1208 /*
1209 * Caller must hold in_ifaddr_rwlock as writer.
1210 */
1211 static void
1212 in_iahash_insert(struct in_ifaddr *ia)
1213 {
1214 if (ia->ia_addr.sin_family != AF_INET)
1215 panic("attempt to insert wrong ia %p into hash table\n", ia);
1216 else if (IA_IS_HASHED(ia))
1217 panic("attempt to double-insert ia %p into hash table\n", ia);
1218
1219 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1220 ifaref(&ia->ia_ifa);
1221 }
1222
1223 /*
1224 * Some point to point interfaces that are tunnels
1225 * borrow the address from an underlying interface (e.g.
1226 * VPN server). In order for source address selection logic to
1227 * find the underlying interface first, we add the address
1228 * of borrowing point to point interfaces at the end of the list.
1229 * (see rdar://6733789)
1230 *
1231 * Caller must hold in_ifaddr_rwlock as writer.
1232 */
1233 static void
1234 in_iahash_insert_ptp(struct in_ifaddr *ia)
1235 {
1236 struct in_ifaddr *tmp_ifa;
1237 struct ifnet *tmp_ifp;
1238
1239 if (ia->ia_addr.sin_family != AF_INET)
1240 panic("attempt to insert wrong ia %p into hash table\n", ia);
1241 else if (IA_IS_HASHED(ia))
1242 panic("attempt to double-insert ia %p into hash table\n", ia);
1243
1244 TAILQ_FOREACH(tmp_ifa, INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia_hash)
1245 if (IA_SIN(tmp_ifa)->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
1246 break;
1247 tmp_ifp = (tmp_ifa == NULL) ? NULL : tmp_ifa->ia_ifp;
1248
1249 if (tmp_ifp == NULL)
1250 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1251 else
1252 TAILQ_INSERT_TAIL(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1253
1254 ifaref(&ia->ia_ifa);
1255 }
1256
1257 /*
1258 * Initialize an interface's internet address
1259 * and routing table entry.
1260 */
1261 static int
1262 in_ifinit(
1263 struct ifnet *ifp,
1264 struct in_ifaddr *ia,
1265 struct sockaddr_in *sin,
1266 int scrub)
1267 {
1268 u_int32_t i = ntohl(sin->sin_addr.s_addr);
1269 struct sockaddr_in oldaddr;
1270 int flags = RTF_UP, error;
1271 struct ifaddr *ifa0;
1272 unsigned int cmd;
1273 int oldremoved = 0;
1274
1275 /* Take an extra reference for this routine */
1276 ifaref(&ia->ia_ifa);
1277
1278 lck_rw_lock_exclusive(in_ifaddr_rwlock);
1279 oldaddr = ia->ia_addr;
1280 if (IA_IS_HASHED(ia)) {
1281 oldremoved = 1;
1282 in_iahash_remove(ia);
1283 }
1284 ia->ia_addr = *sin;
1285 ia->ia_addr.sin_len = sizeof (*sin);
1286 if ((ifp->if_flags & IFF_POINTOPOINT))
1287 in_iahash_insert_ptp(ia);
1288 else
1289 in_iahash_insert(ia);
1290 lck_rw_done(in_ifaddr_rwlock);
1291
1292 /*
1293 * Give the interface a chance to initialize if this is its first
1294 * address, and to validate the address if necessary. Send down
1295 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1296 * We find the first IPV4 address assigned to it and check if this
1297 * is the same as the one passed into this routine.
1298 */
1299 ifa0 = ifa_ifpgetprimary(ifp, AF_INET);
1300 cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR;
1301 error = ifnet_ioctl(ifp, PF_INET, cmd, ia);
1302 if (error == EOPNOTSUPP)
1303 error = 0;
1304 /*
1305 * If we've just sent down SIOCAIFADDR, send another ioctl down
1306 * for SIOCSIFADDR for the first IPV4 address of the interface,
1307 * because an address change on one of the addresses will result
1308 * in the removal of the previous first IPV4 address. KDP needs
1309 * be reconfigured with the current primary IPV4 address.
1310 */
1311 if (error == 0 && cmd == SIOCAIFADDR) {
1312 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0);
1313 if (error == EOPNOTSUPP)
1314 error = 0;
1315 }
1316
1317 /* Release reference from ifa_ifpgetprimary() */
1318 ifafree(ifa0);
1319
1320 if (error) {
1321 lck_rw_lock_exclusive(in_ifaddr_rwlock);
1322 if (IA_IS_HASHED(ia))
1323 in_iahash_remove(ia);
1324 ia->ia_addr = oldaddr;
1325 if (oldremoved) {
1326 if ((ifp->if_flags & IFF_POINTOPOINT))
1327 in_iahash_insert_ptp(ia);
1328 else
1329 in_iahash_insert(ia);
1330 }
1331 lck_rw_done(in_ifaddr_rwlock);
1332 /* Release extra reference taken above */
1333 ifafree(&ia->ia_ifa);
1334 return (error);
1335 }
1336 lck_mtx_lock(rnh_lock);
1337 if (scrub) {
1338 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1339 in_ifscrub(ifp, ia, 1);
1340 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1341 }
1342 if (IN_CLASSA(i))
1343 ia->ia_netmask = IN_CLASSA_NET;
1344 else if (IN_CLASSB(i))
1345 ia->ia_netmask = IN_CLASSB_NET;
1346 else
1347 ia->ia_netmask = IN_CLASSC_NET;
1348 /*
1349 * The subnet mask usually includes at least the standard network part,
1350 * but may may be smaller in the case of supernetting.
1351 * If it is set, we believe it.
1352 */
1353 if (ia->ia_subnetmask == 0) {
1354 ia->ia_subnetmask = ia->ia_netmask;
1355 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
1356 } else
1357 ia->ia_netmask &= ia->ia_subnetmask;
1358 ia->ia_net = i & ia->ia_netmask;
1359 ia->ia_subnet = i & ia->ia_subnetmask;
1360 in_socktrim(&ia->ia_sockmask);
1361 /*
1362 * Add route for the network.
1363 */
1364 ia->ia_ifa.ifa_metric = ifp->if_metric;
1365 if (ifp->if_flags & IFF_BROADCAST) {
1366 ia->ia_broadaddr.sin_addr.s_addr =
1367 htonl(ia->ia_subnet | ~ia->ia_subnetmask);
1368 ia->ia_netbroadcast.s_addr =
1369 htonl(ia->ia_net | ~ ia->ia_netmask);
1370 } else if (ifp->if_flags & IFF_LOOPBACK) {
1371 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1372 flags |= RTF_HOST;
1373 } else if (ifp->if_flags & IFF_POINTOPOINT) {
1374 if (ia->ia_dstaddr.sin_family != AF_INET) {
1375 lck_mtx_unlock(rnh_lock);
1376 /* Release extra reference taken above */
1377 ifafree(&ia->ia_ifa);
1378 return (0);
1379 }
1380 ia->ia_dstaddr.sin_len = sizeof (*sin);
1381 flags |= RTF_HOST;
1382 }
1383 if ((error = rtinit_locked(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
1384 ia->ia_flags |= IFA_ROUTE;
1385 lck_mtx_unlock(rnh_lock);
1386
1387 /* XXX check if the subnet route points to the same interface */
1388 if (error == EEXIST)
1389 error = 0;
1390
1391 /*
1392 * If the interface supports multicast, join the "all hosts"
1393 * multicast group on that interface.
1394 */
1395 if (ifp->if_flags & IFF_MULTICAST) {
1396 struct in_multi *inm;
1397 struct in_addr addr;
1398
1399 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
1400 ifnet_lock_shared(ifp);
1401 IN_LOOKUP_MULTI(addr, ifp, inm);
1402 ifnet_lock_done(ifp);
1403 if (inm == 0)
1404 in_addmulti(&addr, ifp);
1405 }
1406
1407 /* Release extra reference taken above */
1408 ifafree(&ia->ia_ifa);
1409 return (error);
1410 }
1411
1412
1413 /*
1414 * Return 1 if the address might be a local broadcast address.
1415 */
1416 int
1417 in_broadcast(
1418 struct in_addr in,
1419 struct ifnet *ifp)
1420 {
1421 struct ifaddr *ifa;
1422 u_int32_t t;
1423
1424 if (in.s_addr == INADDR_BROADCAST ||
1425 in.s_addr == INADDR_ANY)
1426 return 1;
1427 if ((ifp->if_flags & IFF_BROADCAST) == 0)
1428 return 0;
1429 t = ntohl(in.s_addr);
1430 /*
1431 * Look through the list of addresses for a match
1432 * with a broadcast address.
1433 */
1434 #define ia ((struct in_ifaddr *)ifa)
1435 ifnet_lock_shared(ifp);
1436 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1437 if (ifa->ifa_addr == NULL) {
1438 ifnet_lock_done(ifp);
1439 return (0);
1440 }
1441 if (ifa->ifa_addr->sa_family == AF_INET &&
1442 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
1443 in.s_addr == ia->ia_netbroadcast.s_addr ||
1444 /*
1445 * Check for old-style (host 0) broadcast.
1446 */
1447 t == ia->ia_subnet || t == ia->ia_net) &&
1448 /*
1449 * Check for an all one subnetmask. These
1450 * only exist when an interface gets a secondary
1451 * address.
1452 */
1453 ia->ia_subnetmask != (u_int32_t)0xffffffff) {
1454 ifnet_lock_done(ifp);
1455 return 1;
1456 }
1457 }
1458 ifnet_lock_done(ifp);
1459 return (0);
1460 #undef ia
1461 }
1462
1463 static void
1464 in_free_inm(
1465 void* ifma_protospec)
1466 {
1467 struct in_multi *inm = ifma_protospec;
1468
1469 /*
1470 * No remaining claims to this record; let IGMP know that
1471 * we are leaving the multicast group.
1472 */
1473 igmp_leavegroup(inm);
1474 lck_mtx_lock(rnh_lock);
1475 LIST_REMOVE(inm, inm_link);
1476 lck_mtx_unlock(rnh_lock);
1477 FREE(inm, M_IPMADDR);
1478 }
1479
1480 /*
1481 * Add an address to the list of IP multicast addresses for a given interface.
1482 */
1483 struct in_multi *
1484 in_addmulti(
1485 struct in_addr *ap,
1486 struct ifnet *ifp)
1487 {
1488 struct in_multi *inm;
1489 int error;
1490 struct sockaddr_in sin;
1491 struct ifmultiaddr *ifma;
1492
1493 /*
1494 * Call generic routine to add membership or increment
1495 * refcount. It wants addresses in the form of a sockaddr,
1496 * so we build one here (being careful to zero the unused bytes).
1497 */
1498 bzero(&sin, sizeof sin);
1499 sin.sin_family = AF_INET;
1500 sin.sin_len = sizeof sin;
1501 sin.sin_addr = *ap;
1502 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
1503 if (error) {
1504 return 0;
1505 }
1506
1507 /*
1508 * If ifma->ifma_protospec is null, then if_addmulti() created
1509 * a new record. Otherwise, we are done.
1510 */
1511 if (ifma->ifma_protospec != 0) {
1512 return ifma->ifma_protospec;
1513 }
1514
1515 inm = (struct in_multi *) _MALLOC(sizeof(*inm), M_IPMADDR, M_WAITOK);
1516 if (inm == NULL) {
1517 return (NULL);
1518 }
1519
1520 bzero(inm, sizeof *inm);
1521 inm->inm_addr = *ap;
1522 inm->inm_ifp = ifp;
1523 inm->inm_ifma = ifma;
1524 lck_mtx_lock(rnh_lock);
1525 if (ifma->ifma_protospec == NULL) {
1526 ifma->ifma_protospec = inm;
1527 ifma->ifma_free = in_free_inm;
1528 LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
1529 }
1530 lck_mtx_unlock(rnh_lock);
1531
1532 if (ifma->ifma_protospec != inm) {
1533 _FREE(inm, M_IPMADDR);
1534 return ifma->ifma_protospec;
1535 }
1536
1537 /*
1538 * Let IGMP know that we have joined a new IP multicast group.
1539 */
1540 error = igmp_joingroup(inm);
1541 if (error) {
1542 char addrbuf[16];
1543
1544 /*
1545 * We can't free the inm because someone else may already be
1546 * using it. Once we put it in to ifma->ifma_protospec, it
1547 * must exist as long as the ifma does. Might be nice to flag
1548 * the error so we can try igmp_joingroup the next time through.
1549 */
1550 log(LOG_ERR, "igmp_joingroup error %d joining multicast %s on %s%d\n",
1551 error, inet_ntop(AF_INET, &sin.sin_addr, addrbuf, sizeof(addrbuf)),
1552 ifp->if_name, ifp->if_unit);
1553 }
1554
1555 return (inm);
1556 }
1557
1558 /*
1559 * Delete a multicast address record.
1560 */
1561 void
1562 in_delmulti(
1563 struct in_multi **inm)
1564 {
1565 struct in_multi *inm2;
1566
1567 lck_mtx_lock(rnh_lock);
1568 LIST_FOREACH(inm2, &in_multihead, inm_link) {
1569 if (inm2 == *inm)
1570 break;
1571 }
1572 if (inm2 != *inm) {
1573 lck_mtx_unlock(rnh_lock);
1574 printf("in_delmulti - ignoring invalid inm (%p)\n", *inm);
1575 return;
1576 }
1577 lck_mtx_unlock(rnh_lock);
1578
1579 /* We intentionally do this a bit differently than BSD */
1580 if ((*inm)->inm_ifma) {
1581 if_delmultiaddr((*inm)->inm_ifma, 0);
1582 ifma_release((*inm)->inm_ifma);
1583 }
1584 *inm = NULL;
1585 }
1586
1587 #if !NFSCLIENT
1588 int inet_aton(char *cp, struct in_addr *pin);
1589 int
1590 inet_aton(char * cp, struct in_addr * pin)
1591 {
1592 u_char * b = (unsigned char *)pin;
1593 int i;
1594 char * p;
1595
1596 for (p = cp, i = 0; i < 4; i++) {
1597 u_int32_t l = strtoul(p, 0, 0);
1598 if (l > 255)
1599 return (FALSE);
1600 b[i] = l;
1601 p = strchr(p, '.');
1602 if (i < 3 && p == NULL)
1603 return (FALSE);
1604 p++;
1605 }
1606 return (TRUE);
1607 }
1608 #endif
1609
1610 /*
1611 * Called as part of ip_init
1612 */
1613 void
1614 in_ifaddr_init(void)
1615 {
1616 PE_parse_boot_argn("ifa_debug", &inifa_debug, sizeof (inifa_debug));
1617
1618 inifa_size = (inifa_debug == 0) ? sizeof (struct in_ifaddr) :
1619 sizeof (struct in_ifaddr_dbg);
1620
1621 inifa_zone = zinit(inifa_size, INIFA_ZONE_MAX * inifa_size,
1622 0, INIFA_ZONE_NAME);
1623 if (inifa_zone == NULL)
1624 panic("%s: failed allocating %s", __func__, INIFA_ZONE_NAME);
1625
1626 zone_change(inifa_zone, Z_EXPAND, TRUE);
1627 }
1628
1629 static struct in_ifaddr *
1630 in_ifaddr_alloc(int how)
1631 {
1632 struct in_ifaddr *inifa;
1633
1634 inifa = (how == M_WAITOK) ? zalloc(inifa_zone) :
1635 zalloc_noblock(inifa_zone);
1636 if (inifa != NULL) {
1637 bzero(inifa, inifa_size);
1638 inifa->ia_ifa.ifa_free = in_ifaddr_free;
1639 inifa->ia_ifa.ifa_debug |= IFD_ALLOC;
1640 if (inifa_debug != 0) {
1641 struct in_ifaddr_dbg *inifa_dbg =
1642 (struct in_ifaddr_dbg *)inifa;
1643 inifa->ia_ifa.ifa_debug |= IFD_DEBUG;
1644 inifa->ia_ifa.ifa_trace = in_ifaddr_trace;
1645 ctrace_record(&inifa_dbg->inifa_alloc);
1646 }
1647 }
1648 return (inifa);
1649 }
1650
1651 static void
1652 in_ifaddr_free(struct ifaddr *ifa)
1653 {
1654 if (ifa->ifa_refcnt != 0)
1655 panic("%s: ifa %p bad ref cnt", __func__, ifa);
1656 if (!(ifa->ifa_debug & IFD_ALLOC))
1657 panic("%s: ifa %p cannot be freed", __func__, ifa);
1658
1659 if (ifa->ifa_debug & IFD_DEBUG) {
1660 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
1661 ctrace_record(&inifa_dbg->inifa_free);
1662 bcopy(&inifa_dbg->inifa, &inifa_dbg->inifa_old,
1663 sizeof (struct in_ifaddr));
1664 }
1665 bzero(ifa, sizeof (struct in_ifaddr));
1666 zfree(inifa_zone, ifa);
1667 }
1668
1669 static void
1670 in_ifaddr_trace(struct ifaddr *ifa, int refhold)
1671 {
1672 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
1673 ctrace_t *tr;
1674 u_int32_t idx;
1675 u_int16_t *cnt;
1676
1677 if (!(ifa->ifa_debug & IFD_DEBUG))
1678 panic("%s: ifa %p has no debug structure", __func__, ifa);
1679
1680 if (refhold) {
1681 cnt = &inifa_dbg->inifa_refhold_cnt;
1682 tr = inifa_dbg->inifa_refhold;
1683 } else {
1684 cnt = &inifa_dbg->inifa_refrele_cnt;
1685 tr = inifa_dbg->inifa_refrele;
1686 }
1687
1688 idx = OSAddAtomic16(1, (volatile SInt16 *)cnt) % CTRACE_HIST_SIZE;
1689 ctrace_record(&tr[idx]);
1690 }