2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1982, 1986, 1991, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)in.c 8.4 (Berkeley) 1/9/95
58 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.5 2001/08/13 16:26:17 ume Exp $
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/sockio.h>
64 #include <sys/socketvar.h>
65 #include <sys/malloc.h>
67 #include <sys/socket.h>
68 #include <sys/kernel.h>
69 #include <sys/sysctl.h>
70 #include <sys/kern_event.h>
73 #include <net/if_types.h>
74 #include <net/route.h>
76 #include <netinet/in.h>
77 #include <netinet/in_var.h>
78 #include <netinet/in_pcb.h>
80 #include <netinet/igmp_var.h>
83 #include <netinet/ip_var.h>
85 #include <netinet/tcp.h>
86 #include <netinet/tcp_timer.h>
87 #include <netinet/tcp_var.h>
92 static int in_mask2len
__P((struct in_addr
*));
93 static void in_len2mask
__P((struct in_addr
*, int));
94 static int in_lifaddr_ioctl
__P((struct socket
*, u_long
, caddr_t
,
95 struct ifnet
*, struct proc
*));
97 static void in_socktrim
__P((struct sockaddr_in
*));
98 static int in_ifinit
__P((struct ifnet
*,
99 struct in_ifaddr
*, struct sockaddr_in
*, int));
101 static int subnetsarelocal
= 0;
102 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
, CTLFLAG_RW
,
103 &subnetsarelocal
, 0, "");
105 struct in_multihead in_multihead
; /* XXX BSS initialization */
107 extern void arp_rtrequest();
108 extern int ether_detach_inet(struct ifnet
*ifp
);
111 extern int ip6_auto_on
;
115 * Return 1 if an internet address is for a ``local'' host
116 * (one to which we have a connection). If subnetsarelocal
117 * is true, this includes other subnets of the local net.
118 * Otherwise, it includes only the directly-connected (sub)nets.
124 register u_long i
= ntohl(in
.s_addr
);
125 register struct in_ifaddr
*ia
;
127 if (subnetsarelocal
) {
128 for (ia
= in_ifaddrhead
.tqh_first
; ia
;
129 ia
= ia
->ia_link
.tqe_next
)
130 if ((i
& ia
->ia_netmask
) == ia
->ia_net
)
133 for (ia
= in_ifaddrhead
.tqh_first
; ia
;
134 ia
= ia
->ia_link
.tqe_next
)
135 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
)
142 * Determine whether an IP address is in a reserved set of addresses
143 * that may not be forwarded, or whether datagrams to that destination
150 register u_long i
= ntohl(in
.s_addr
);
153 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
))
156 net
= i
& IN_CLASSA_NET
;
157 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
))
164 * Trim a mask in a sockaddr
168 struct sockaddr_in
*ap
;
170 register char *cplim
= (char *) &ap
->sin_addr
;
171 register char *cp
= (char *) (&ap
->sin_addr
+ 1);
174 while (--cp
>= cplim
)
176 (ap
)->sin_len
= cp
- (char *) (ap
) + 1;
183 struct in_addr
*mask
;
189 for (x
= 0; x
< sizeof(*mask
); x
++) {
194 if (x
< sizeof(*mask
)) {
195 for (y
= 0; y
< 8; y
++) {
196 if ((p
[x
] & (0x80 >> y
)) == 0)
204 in_len2mask(mask
, len
)
205 struct in_addr
*mask
;
212 bzero(mask
, sizeof(*mask
));
213 for (i
= 0; i
< len
/ 8; i
++)
216 p
[i
] = (0xff00 >> (len
% 8)) & 0xff;
219 static int in_interfaces
; /* number of external internet interfaces */
222 * Generic internet control operations (ioctl's).
223 * Ifp is 0 if not an interface-specific ioctl.
227 in_control(so
, cmd
, data
, ifp
, p
)
231 register struct ifnet
*ifp
;
234 register struct ifreq
*ifr
= (struct ifreq
*)data
;
235 register struct in_ifaddr
*ia
= 0, *iap
;
236 register struct ifaddr
*ifa
;
237 struct in_ifaddr
*oia
;
238 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)data
;
239 struct sockaddr_in oldaddr
;
240 int error
, hostIsNew
, maskIsNew
, s
;
242 struct kev_msg ev_msg
;
243 struct kev_in_data in_event_data
;
249 if (p
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)) != 0)
255 return in_lifaddr_ioctl(so
, cmd
, data
, ifp
, p
);
259 * Find address for this interface, if it exists.
261 * If an alias address was specified, find that one instead of
262 * the first one on the interface.
265 for (iap
= in_ifaddrhead
.tqh_first
; iap
;
266 iap
= iap
->ia_link
.tqe_next
)
267 if (iap
->ia_ifp
== ifp
) {
268 if (((struct sockaddr_in
*)&ifr
->ifr_addr
)->sin_addr
.s_addr
==
269 iap
->ia_addr
.sin_addr
.s_addr
) {
272 } else if (ia
== NULL
) {
274 if (ifr
->ifr_addr
.sa_family
!= AF_INET
)
281 if (p
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)) != 0)
288 return (EADDRNOTAVAIL
);
289 if (ifra
->ifra_addr
.sin_family
== AF_INET
) {
290 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
291 if (ia
->ia_ifp
== ifp
&&
292 ia
->ia_addr
.sin_addr
.s_addr
==
293 ifra
->ifra_addr
.sin_addr
.s_addr
)
296 if ((ifp
->if_flags
& IFF_POINTOPOINT
)
297 && (cmd
== SIOCAIFADDR
)
298 && (ifra
->ifra_dstaddr
.sin_addr
.s_addr
303 else if (cmd
== SIOCAIFADDR
)
305 if (cmd
== SIOCDIFADDR
&& ia
== 0)
306 return (EADDRNOTAVAIL
);
312 if ((so
->so_state
& SS_PRIV
) == 0)
315 if (p
&& (error
= suser(p
)) != 0)
320 return (EADDRNOTAVAIL
);
321 if (ifra
->ifra_addr
.sin_family
!= AF_INET
&& cmd
== SIOCSIFADDR
)
323 if (ia
== (struct in_ifaddr
*)0) {
324 ia
= (struct in_ifaddr
*)
325 _MALLOC(sizeof *ia
, M_IFADDR
, M_WAITOK
);
326 if (ia
== (struct in_ifaddr
*)NULL
)
328 bzero((caddr_t
)ia
, sizeof *ia
);
330 * Protect from ipintr() traversing address list
331 * while we're modifying it.
335 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
337 TAILQ_INSERT_TAIL(&ifp
->if_addrhead
, ifa
, ifa_link
);
340 * Temorary code for protocol attachment XXX
343 if (ifp
->if_type
== IFT_ETHER
)
344 dl_tag
= ether_attach_inet(ifp
);
346 if (ifp
->if_type
== IFT_LOOP
)
347 dl_tag
= lo_attach_inet(ifp
);
350 if (ifp
&& ifp
->if_type
== IFT_FAITH
)
351 dl_tag
= faith_attach_inet(ifp
);
355 if (ifp
&& ifp
->if_type
== IFT_GIF
)
356 dl_tag
= gif_attach_proto_family(ifp
, PF_INET
);
358 /* End of temp code */
360 ifa
->ifa_dlt
= dl_tag
;
361 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
362 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
363 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
364 ia
->ia_sockmask
.sin_len
= 8;
365 if (ifp
->if_flags
& IFF_BROADCAST
) {
366 ia
->ia_broadaddr
.sin_len
= sizeof(ia
->ia_addr
);
367 ia
->ia_broadaddr
.sin_family
= AF_INET
;
370 if (!(ifp
->if_flags
& IFF_LOOPBACK
))
376 case SIOCPROTOATTACH
:
377 case SIOCPROTODETACH
:
378 if (p
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)) != 0)
381 return (EADDRNOTAVAIL
);
382 if (strcmp(ifp
->if_name
, "en"))
388 if ((so
->so_state
& SS_PRIV
) == 0)
391 if (p
&& (error
= suser(p
)) != 0)
400 if (ia
== (struct in_ifaddr
*)0)
401 return (EADDRNOTAVAIL
);
407 return (EADDRNOTAVAIL
);
409 ifp
->if_eflags
|= IFEF_AUTOCONFIGURING
;
411 ifp
->if_eflags
&= ~IFEF_AUTOCONFIGURING
;
415 *((struct sockaddr_in
*)&ifr
->ifr_addr
) = ia
->ia_addr
;
419 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0)
421 *((struct sockaddr_in
*)&ifr
->ifr_dstaddr
) = ia
->ia_broadaddr
;
425 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0)
427 *((struct sockaddr_in
*)&ifr
->ifr_dstaddr
) = ia
->ia_dstaddr
;
431 *((struct sockaddr_in
*)&ifr
->ifr_addr
) = ia
->ia_sockmask
;
435 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0)
437 oldaddr
= ia
->ia_dstaddr
;
438 ia
->ia_dstaddr
= *(struct sockaddr_in
*)&ifr
->ifr_dstaddr
;
439 error
= dlil_ioctl(PF_INET
, ifp
, SIOCSIFDSTADDR
, (caddr_t
)ia
);
440 if (error
== EOPNOTSUPP
)
444 ia
->ia_dstaddr
= oldaddr
;
448 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
449 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
450 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
452 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
454 if (ia
->ia_ifa
.ifa_dstaddr
)
455 in_event_data
.ia_dstaddr
=
456 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
458 in_event_data
.ia_dstaddr
.s_addr
= 0;
460 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
461 in_event_data
.ia_net
= ia
->ia_net
;
462 in_event_data
.ia_netmask
= ia
->ia_netmask
;
463 in_event_data
.ia_subnet
= ia
->ia_subnet
;
464 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
465 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
466 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
467 in_event_data
.link_data
.if_family
= ifp
->if_family
;
468 in_event_data
.link_data
.if_unit
= (unsigned long) ifp
->if_unit
;
470 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
471 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
472 ev_msg
.dv
[1].data_length
= 0;
474 kev_post_msg(&ev_msg
);
477 if (ia
->ia_flags
& IFA_ROUTE
) {
478 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&oldaddr
;
479 rtinit(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
480 ia
->ia_ifa
.ifa_dstaddr
=
481 (struct sockaddr
*)&ia
->ia_dstaddr
;
482 rtinit(&(ia
->ia_ifa
), (int)RTM_ADD
, RTF_HOST
|RTF_UP
);
487 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0)
489 ia
->ia_broadaddr
= *(struct sockaddr_in
*)&ifr
->ifr_broadaddr
;
491 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
492 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
493 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
495 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
497 if (ia
->ia_ifa
.ifa_dstaddr
)
498 in_event_data
.ia_dstaddr
=
499 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
501 in_event_data
.ia_dstaddr
.s_addr
= 0;
503 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
504 in_event_data
.ia_net
= ia
->ia_net
;
505 in_event_data
.ia_netmask
= ia
->ia_netmask
;
506 in_event_data
.ia_subnet
= ia
->ia_subnet
;
507 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
508 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
509 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
510 in_event_data
.link_data
.if_family
= ifp
->if_family
;
511 in_event_data
.link_data
.if_unit
= (unsigned long) ifp
->if_unit
;
513 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
514 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
515 ev_msg
.dv
[1].data_length
= 0;
517 kev_post_msg(&ev_msg
);
522 return (in_ifinit(ifp
, ia
,
523 (struct sockaddr_in
*) &ifr
->ifr_addr
, 1));
525 case SIOCPROTOATTACH
:
526 ether_attach_inet(ifp
);
528 if (ip6_auto_on
) /* FreeBSD compat mode: Acquire linklocal addresses for IPv6 for if */
533 case SIOCPROTODETACH
:
534 // if an ip address is still present, refuse to detach
535 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
)
536 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
538 error
= ether_detach_inet(ifp
);
542 if (ip6_auto_on
) { /* if we linked ipv6 addresses to v4, remove them now */
544 error
= ether_detach_inet6(ifp
);
553 i
= ifra
->ifra_addr
.sin_addr
.s_addr
;
554 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
555 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
556 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
557 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
559 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
561 if (ia
->ia_ifa
.ifa_dstaddr
)
562 in_event_data
.ia_dstaddr
=
563 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
565 in_event_data
.ia_dstaddr
.s_addr
= 0;
567 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
568 in_event_data
.ia_net
= ia
->ia_net
;
569 in_event_data
.ia_netmask
= ia
->ia_netmask
;
570 in_event_data
.ia_subnet
= ia
->ia_subnet
;
571 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
572 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
573 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
574 in_event_data
.link_data
.if_family
= ifp
->if_family
;
575 in_event_data
.link_data
.if_unit
= (unsigned long) ifp
->if_unit
;
577 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
578 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
579 ev_msg
.dv
[1].data_length
= 0;
581 kev_post_msg(&ev_msg
);
589 if (ia
->ia_addr
.sin_family
== AF_INET
) {
590 if (ifra
->ifra_addr
.sin_len
== 0) {
591 ifra
->ifra_addr
= ia
->ia_addr
;
593 } else if (ifra
->ifra_addr
.sin_addr
.s_addr
==
594 ia
->ia_addr
.sin_addr
.s_addr
)
597 if (ifra
->ifra_mask
.sin_len
) {
599 ia
->ia_sockmask
= ifra
->ifra_mask
;
601 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
604 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
605 (ifra
->ifra_dstaddr
.sin_family
== AF_INET
)) {
607 ia
->ia_dstaddr
= ifra
->ifra_dstaddr
;
608 maskIsNew
= 1; /* We lie; but the effect's the same */
610 if (ifra
->ifra_addr
.sin_family
== AF_INET
&&
611 (hostIsNew
|| maskIsNew
)) {
612 error
= in_ifinit(ifp
, ia
, &ifra
->ifra_addr
, 0);
614 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
615 (ifra
->ifra_broadaddr
.sin_family
== AF_INET
))
616 ia
->ia_broadaddr
= ifra
->ifra_broadaddr
;
622 if ((error
== 0) || (error
== EEXIST
)) {
623 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
624 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
625 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
628 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
630 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
632 if (ia
->ia_ifa
.ifa_dstaddr
)
633 in_event_data
.ia_dstaddr
=
634 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
636 in_event_data
.ia_dstaddr
.s_addr
= 0;
638 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
639 in_event_data
.ia_net
= ia
->ia_net
;
640 in_event_data
.ia_netmask
= ia
->ia_netmask
;
641 in_event_data
.ia_subnet
= ia
->ia_subnet
;
642 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
643 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
644 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
645 in_event_data
.link_data
.if_family
= ifp
->if_family
;
646 in_event_data
.link_data
.if_unit
= (unsigned long) ifp
->if_unit
;
648 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
649 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
650 ev_msg
.dv
[1].data_length
= 0;
652 kev_post_msg(&ev_msg
);
658 error
= dlil_ioctl(PF_INET
, ifp
, SIOCDIFADDR
, (caddr_t
)ia
);
659 if (error
== EOPNOTSUPP
)
664 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
665 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
666 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
668 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
670 if (ia
->ia_ifa
.ifa_dstaddr
)
671 in_event_data
.ia_dstaddr
=
672 ((struct sockaddr_in
*)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
674 in_event_data
.ia_dstaddr
.s_addr
= 0;
676 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
677 in_event_data
.ia_net
= ia
->ia_net
;
678 in_event_data
.ia_netmask
= ia
->ia_netmask
;
679 in_event_data
.ia_subnet
= ia
->ia_subnet
;
680 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
681 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
682 strncpy(&in_event_data
.link_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
683 in_event_data
.link_data
.if_family
= ifp
->if_family
;
684 in_event_data
.link_data
.if_unit
= (unsigned long) ifp
->if_unit
;
686 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
687 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
688 ev_msg
.dv
[1].data_length
= 0;
690 kev_post_msg(&ev_msg
);
693 * in_ifscrub kills the interface route.
698 * in_ifadown gets rid of all the rest of
699 * the routes. This is not quite the right
700 * thing to do, but at least if we are running
701 * a routing process they will come back.
703 in_ifadown(&ia
->ia_ifa
, 1);
705 * XXX horrible hack to detect that we are being called
708 if (!ifnet_addrs
[ifp
->if_index
- 1]) {
709 in_pcbpurgeif0(LIST_FIRST(ripcbinfo
.listhead
), ifp
);
710 in_pcbpurgeif0(LIST_FIRST(udbinfo
.listhead
), ifp
);
715 * Protect from ipintr() traversing address list
716 * while we're modifying it.
721 TAILQ_REMOVE(&ifp
->if_addrhead
, ifa
, ifa_link
);
723 TAILQ_REMOVE(&in_ifaddrhead
, oia
, ia_link
);
724 ifafree(&oia
->ia_ifa
);
728 * If the interface supports multicast, and no address is left,
729 * remove the "all hosts" multicast group from that interface.
731 if (ifp
->if_flags
& IFF_MULTICAST
) {
733 struct in_multi
*inm
;
735 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
)
736 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
740 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
741 IN_LOOKUP_MULTI(addr
, ifp
, inm
);
753 * Inspiration from tcp_ctloutput() and ip_ctloutput()
754 * Special ioctl for OpenTransport sockets
756 struct inpcb
*inp
, *cloned_inp
;
758 int cloned_fd
= *(int *)data
;
760 s
= splnet(); /* XXX */
767 /* let's make sure it's either -1 or a valid file descriptor */
768 if (cloned_fd
!= -1) {
769 struct socket
*cloned_so
;
770 struct file
*cloned_fp
;
771 error
= getsock(p
->p_fd
, cloned_fd
, &cloned_fp
);
776 cloned_so
= (struct socket
*)cloned_fp
->f_data
;
777 cloned_inp
= sotoinpcb(cloned_so
);
782 if (cloned_inp
== NULL
) {
783 /* OT always uses IP_PORTRANGE_HIGH */
784 inp
->inp_flags
&= ~(INP_LOWPORT
);
785 inp
->inp_flags
|= INP_HIGHPORT
;
786 /* For UDP, OT allows broadcast by default */
787 if (so
->so_type
== SOCK_DGRAM
)
788 so
->so_options
|= SO_BROADCAST
;
789 /* For TCP we want to see MSG_OOB when receive urgent data */
790 else if (so
->so_type
== SOCK_STREAM
)
791 so
->so_options
|= SO_WANTOOBFLAG
;
793 inp
->inp_ip_tos
= cloned_inp
->inp_ip_tos
;
794 inp
->inp_ip_ttl
= cloned_inp
->inp_ip_ttl
;
795 inp
->inp_flags
= cloned_inp
->inp_flags
;
797 /* Multicast options */
798 if (cloned_inp
->inp_moptions
!= NULL
) {
800 struct ip_moptions
*cloned_imo
= cloned_inp
->inp_moptions
;
801 struct ip_moptions
*imo
= inp
->inp_moptions
;
805 * No multicast option buffer attached to the pcb;
809 imo
= (struct ip_moptions
*)
810 _MALLOC(sizeof(*imo
), M_IPMOPTS
, M_WAITOK
);
815 s
= splnet(); /* XXX */
816 inp
->inp_moptions
= imo
;
818 imo
->imo_multicast_ifp
= cloned_imo
->imo_multicast_ifp
;
819 imo
->imo_multicast_vif
= cloned_imo
->imo_multicast_vif
;
820 imo
->imo_multicast_ttl
= cloned_imo
->imo_multicast_ttl
;
821 imo
->imo_multicast_loop
= cloned_imo
->imo_multicast_loop
;
822 imo
->imo_num_memberships
= cloned_imo
->imo_num_memberships
;
823 for (i
= 0; i
< cloned_imo
->imo_num_memberships
; i
++) {
824 imo
->imo_membership
[i
] =
825 in_addmulti(&cloned_imo
->imo_membership
[i
]->inm_addr
,
826 cloned_imo
->imo_membership
[i
]->inm_ifp
);
827 if (imo
->imo_membership
[i
] == NULL
) {
832 if (i
< cloned_imo
->imo_num_memberships
) {
833 /* Failed, perform cleanup */
834 for (i
--; i
>= 0; i
--)
835 in_delmulti(imo
->imo_membership
[i
]);
843 #endif /* __APPLE__ */
847 /* Darwin: dlil_ioctl called from ifioctl */
849 return ((*ifp
->if_ioctl
)(ifp
, cmd
, data
));
857 * SIOCGLIFADDR: get first address. (?!?)
858 * SIOCGLIFADDR with IFLR_PREFIX:
859 * get first address that matches the specified prefix.
860 * SIOCALIFADDR: add the specified address.
861 * SIOCALIFADDR with IFLR_PREFIX:
862 * EINVAL since we can't deduce hostid part of the address.
863 * SIOCDLIFADDR: delete the specified address.
864 * SIOCDLIFADDR with IFLR_PREFIX:
865 * delete the first address that matches the specified prefix.
867 * EINVAL on invalid parameters
868 * EADDRNOTAVAIL on prefix match failed/specified address not found
869 * other values may be returned from in_ioctl()
872 in_lifaddr_ioctl(so
, cmd
, data
, ifp
, p
)
879 struct if_laddrreq
*iflr
= (struct if_laddrreq
*)data
;
884 panic("invalid argument to in_lifaddr_ioctl");
890 /* address must be specified on GET with IFLR_PREFIX */
891 if ((iflr
->flags
& IFLR_PREFIX
) == 0)
896 /* address must be specified on ADD and DELETE */
897 if (iflr
->addr
.ss_family
!= AF_INET
)
899 if (iflr
->addr
.ss_len
!= sizeof(struct sockaddr_in
))
901 /* XXX need improvement */
902 if (iflr
->dstaddr
.ss_family
903 && iflr
->dstaddr
.ss_family
!= AF_INET
)
905 if (iflr
->dstaddr
.ss_family
906 && iflr
->dstaddr
.ss_len
!= sizeof(struct sockaddr_in
))
909 default: /*shouldn't happen*/
912 if (sizeof(struct in_addr
) * 8 < iflr
->prefixlen
)
918 struct in_aliasreq ifra
;
920 if (iflr
->flags
& IFLR_PREFIX
)
923 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
924 bzero(&ifra
, sizeof(ifra
));
925 bcopy(iflr
->iflr_name
, ifra
.ifra_name
,
926 sizeof(ifra
.ifra_name
));
928 bcopy(&iflr
->addr
, &ifra
.ifra_addr
, iflr
->addr
.ss_len
);
930 if (iflr
->dstaddr
.ss_family
) { /*XXX*/
931 bcopy(&iflr
->dstaddr
, &ifra
.ifra_dstaddr
,
932 iflr
->dstaddr
.ss_len
);
935 ifra
.ifra_mask
.sin_family
= AF_INET
;
936 ifra
.ifra_mask
.sin_len
= sizeof(struct sockaddr_in
);
937 in_len2mask(&ifra
.ifra_mask
.sin_addr
, iflr
->prefixlen
);
939 return in_control(so
, SIOCAIFADDR
, (caddr_t
)&ifra
, ifp
, p
);
944 struct in_ifaddr
*ia
;
945 struct in_addr mask
, candidate
, match
;
946 struct sockaddr_in
*sin
;
949 bzero(&mask
, sizeof(mask
));
950 if (iflr
->flags
& IFLR_PREFIX
) {
951 /* lookup a prefix rather than address. */
952 in_len2mask(&mask
, iflr
->prefixlen
);
954 sin
= (struct sockaddr_in
*)&iflr
->addr
;
955 match
.s_addr
= sin
->sin_addr
.s_addr
;
956 match
.s_addr
&= mask
.s_addr
;
958 /* if you set extra bits, that's wrong */
959 if (match
.s_addr
!= sin
->sin_addr
.s_addr
)
964 if (cmd
== SIOCGLIFADDR
) {
965 /* on getting an address, take the 1st match */
968 /* on deleting an address, do exact match */
969 in_len2mask(&mask
, 32);
970 sin
= (struct sockaddr_in
*)&iflr
->addr
;
971 match
.s_addr
= sin
->sin_addr
.s_addr
;
977 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
978 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
)
982 candidate
.s_addr
= ((struct sockaddr_in
*)&ifa
->ifa_addr
)->sin_addr
.s_addr
;
983 candidate
.s_addr
&= mask
.s_addr
;
984 if (candidate
.s_addr
== match
.s_addr
)
988 return EADDRNOTAVAIL
;
989 ia
= (struct in_ifaddr
*)ifa
;
991 if (cmd
== SIOCGLIFADDR
) {
992 /* fill in the if_laddrreq structure */
993 bcopy(&ia
->ia_addr
, &iflr
->addr
, ia
->ia_addr
.sin_len
);
995 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0) {
996 bcopy(&ia
->ia_dstaddr
, &iflr
->dstaddr
,
997 ia
->ia_dstaddr
.sin_len
);
999 bzero(&iflr
->dstaddr
, sizeof(iflr
->dstaddr
));
1002 in_mask2len(&ia
->ia_sockmask
.sin_addr
);
1004 iflr
->flags
= 0; /*XXX*/
1008 struct in_aliasreq ifra
;
1010 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1011 bzero(&ifra
, sizeof(ifra
));
1012 bcopy(iflr
->iflr_name
, ifra
.ifra_name
,
1013 sizeof(ifra
.ifra_name
));
1015 bcopy(&ia
->ia_addr
, &ifra
.ifra_addr
,
1016 ia
->ia_addr
.sin_len
);
1017 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0) {
1018 bcopy(&ia
->ia_dstaddr
, &ifra
.ifra_dstaddr
,
1019 ia
->ia_dstaddr
.sin_len
);
1021 bcopy(&ia
->ia_sockmask
, &ifra
.ifra_dstaddr
,
1022 ia
->ia_sockmask
.sin_len
);
1024 return in_control(so
, SIOCDIFADDR
, (caddr_t
)&ifra
,
1030 return EOPNOTSUPP
; /*just for safety*/
1034 * Delete any existing route for an interface.
1038 register struct ifnet
*ifp
;
1039 register struct in_ifaddr
*ia
;
1042 if ((ia
->ia_flags
& IFA_ROUTE
) == 0)
1044 if (ifp
->if_flags
& (IFF_LOOPBACK
|IFF_POINTOPOINT
))
1045 rtinit(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1047 rtinit(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1048 ia
->ia_flags
&= ~IFA_ROUTE
;
1052 * Initialize an interface's internet address
1053 * and routing table entry.
1056 in_ifinit(ifp
, ia
, sin
, scrub
)
1057 register struct ifnet
*ifp
;
1058 register struct in_ifaddr
*ia
;
1059 struct sockaddr_in
*sin
;
1062 register u_long i
= ntohl(sin
->sin_addr
.s_addr
);
1063 struct sockaddr_in oldaddr
;
1064 int s
= splimp(), flags
= RTF_UP
, error
;
1067 oldaddr
= ia
->ia_addr
;
1071 * Give the interface a chance to initialize
1072 * if this is its first address,
1073 * and to validate the address if necessary.
1075 error
= dlil_ioctl(PF_INET
, ifp
, SIOCSIFADDR
, (caddr_t
)ia
);
1076 if (error
== EOPNOTSUPP
)
1080 ia
->ia_addr
= oldaddr
;
1085 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1086 in_ifscrub(ifp
, ia
);
1087 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1090 ia
->ia_netmask
= IN_CLASSA_NET
;
1091 else if (IN_CLASSB(i
))
1092 ia
->ia_netmask
= IN_CLASSB_NET
;
1094 ia
->ia_netmask
= IN_CLASSC_NET
;
1096 * The subnet mask usually includes at least the standard network part,
1097 * but may may be smaller in the case of supernetting.
1098 * If it is set, we believe it.
1100 if (ia
->ia_subnetmask
== 0) {
1101 ia
->ia_subnetmask
= ia
->ia_netmask
;
1102 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1104 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1105 ia
->ia_net
= i
& ia
->ia_netmask
;
1106 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1107 in_socktrim(&ia
->ia_sockmask
);
1109 * Add route for the network.
1111 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1112 if (ifp
->if_flags
& IFF_BROADCAST
) {
1113 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1114 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1115 ia
->ia_netbroadcast
.s_addr
=
1116 htonl(ia
->ia_net
| ~ ia
->ia_netmask
);
1117 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1118 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1120 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1121 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
)
1125 if ((error
= rtinit(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0)
1126 ia
->ia_flags
|= IFA_ROUTE
;
1127 /* XXX check if the subnet route points to the same interface */
1128 if (error
== EEXIST
)
1132 * If the interface supports multicast, join the "all hosts"
1133 * multicast group on that interface.
1135 if (ifp
->if_flags
& IFF_MULTICAST
) {
1136 struct in_multi
*inm
;
1137 struct in_addr addr
;
1139 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1140 IN_LOOKUP_MULTI(addr
, ifp
, inm
);
1142 in_addmulti(&addr
, ifp
);
1149 * Return 1 if the address might be a local broadcast address.
1152 in_broadcast(in
, ifp
)
1156 register struct ifaddr
*ifa
;
1159 if (in
.s_addr
== INADDR_BROADCAST
||
1160 in
.s_addr
== INADDR_ANY
)
1162 if ((ifp
->if_flags
& IFF_BROADCAST
) == 0)
1164 t
= ntohl(in
.s_addr
);
1166 * Look through the list of addresses for a match
1167 * with a broadcast address.
1169 #define ia ((struct in_ifaddr *)ifa)
1170 for (ifa
= ifp
->if_addrhead
.tqh_first
; ifa
;
1171 ifa
= ifa
->ifa_link
.tqe_next
) {
1172 if (ifa
->ifa_addr
== NULL
)
1174 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
1175 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
1176 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
1178 * Check for old-style (host 0) broadcast.
1180 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
1182 * Check for an all one subnetmask. These
1183 * only exist when an interface gets a secondary
1186 ia
->ia_subnetmask
!= (u_long
)0xffffffff)
1193 * Add an address to the list of IP multicast addresses for a given interface.
1196 in_addmulti(ap
, ifp
)
1197 register struct in_addr
*ap
;
1198 register struct ifnet
*ifp
;
1200 register struct in_multi
*inm
;
1202 struct sockaddr_in sin
;
1203 struct ifmultiaddr
*ifma
;
1207 * Call generic routine to add membership or increment
1208 * refcount. It wants addresses in the form of a sockaddr,
1209 * so we build one here (being careful to zero the unused bytes).
1211 bzero(&sin
, sizeof sin
);
1212 sin
.sin_family
= AF_INET
;
1213 sin
.sin_len
= sizeof sin
;
1215 error
= if_addmulti(ifp
, (struct sockaddr
*)&sin
, &ifma
);
1222 * If ifma->ifma_protospec is null, then if_addmulti() created
1223 * a new record. Otherwise, we are done.
1225 if (ifma
->ifma_protospec
!= 0) {
1227 return ifma
->ifma_protospec
;
1230 inm
= (struct in_multi
*) _MALLOC(sizeof(*inm
), M_IPMADDR
, M_WAITOK
);
1236 bzero(inm
, sizeof *inm
);
1237 inm
->inm_addr
= *ap
;
1239 inm
->inm_ifma
= ifma
;
1240 ifma
->ifma_protospec
= inm
;
1241 LIST_INSERT_HEAD(&in_multihead
, inm
, inm_link
);
1244 * Let IGMP know that we have joined a new IP multicast group.
1246 igmp_joingroup(inm
);
1252 * Delete a multicast address record.
1256 register struct in_multi
*inm
;
1258 struct ifmultiaddr
*ifma
= inm
->inm_ifma
;
1261 /* We intentionally do this a bit differently than BSD */
1263 if (ifma
->ifma_refcount
== 1) {
1265 * No remaining claims to this record; let IGMP know that
1266 * we are leaving the multicast group.
1268 igmp_leavegroup(inm
);
1269 ifma
->ifma_protospec
= 0;
1270 LIST_REMOVE(inm
, inm_link
);
1271 FREE(inm
, M_IPMADDR
);
1273 /* XXX - should be separate API for when we have an ifma? */
1274 if_delmulti(ifma
->ifma_ifp
, ifma
->ifma_addr
);