]>
git.saurik.com Git - apple/network_cmds.git/blob - netstat.tproj/mcast.c
2 * Copyright (c) 2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 2007 Bruce M. Simpson <bms@FreeBSD.org>
30 * All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
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.
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 #include <sys/cdefs.h>
58 * Print the running system's current multicast group memberships.
59 * As this relies on getifmaddrs(), it may not be used with a core file.
62 #include <sys/types.h>
63 #include <sys/param.h>
64 #include <sys/sysctl.h>
65 #include <sys/ioctl.h>
66 #include <sys/socket.h>
67 #include <sys/errno.h>
70 #include <net/if_var.h>
71 #include <net/if_mib.h>
72 #include <net/if_types.h>
73 #include <net/if_dl.h>
74 #include <net/route.h>
75 #include <netinet/in.h>
76 #include <netinet/if_ether.h>
77 #include <arpa/inet.h>
97 struct sockaddr_storage ss
;
99 struct sockaddr_dl sdl
;
100 struct sockaddr_in sin
;
101 struct sockaddr_in6 sin6
;
103 typedef union sockunion sockunion_t
;
106 * This may have been defined in <net/if.h>. Note that if <net/if.h> is
107 * to be included it must be included before this header file.
109 #ifndef ifa_broadaddr
110 #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
114 struct ifmaddrs
*ifma_next
;
115 struct sockaddr
*ifma_name
;
116 struct sockaddr
*ifma_addr
;
117 struct sockaddr
*ifma_lladdr
;
120 void ifmalist_dump_af(const struct ifmaddrs
* const ifmap
, int const af
);
122 #define SALIGN (sizeof(uint32_t) - 1)
123 #define SA_RLEN(sa) (sa ? ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \
125 #define MAX_SYSCTL_TRY 5
126 #define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA)
128 int getifmaddrs(struct ifmaddrs
**);
129 void freeifmaddrs(struct ifmaddrs
*);
133 getifmaddrs(struct ifmaddrs
**pif
)
146 struct ifma_msghdr2
*ifmam
;
147 struct ifmaddrs
*ifa
, *ift
;
148 struct rt_msghdr
*rtm
;
153 mib
[2] = 0; /* protocol */
154 mib
[3] = 0; /* wildcard address family */
155 mib
[4] = NET_RT_IFLIST2
;
156 mib
[5] = 0; /* no flags */
158 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
160 if ((buf
= malloc(needed
)) == NULL
)
162 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0) {
163 if (errno
!= ENOMEM
|| ++ntry
>= MAX_SYSCTL_TRY
) {
170 } while (buf
== NULL
);
172 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
173 rtm
= (struct rt_msghdr
*)(void *)next
;
174 if (rtm
->rtm_version
!= RTM_VERSION
)
176 switch (rtm
->rtm_type
) {
178 ifmam
= (struct ifma_msghdr2
*)(void *)rtm
;
179 if ((ifmam
->ifmam_addrs
& RTA_IFA
) == 0)
182 p
= (char *)(ifmam
+ 1);
183 for (i
= 0; i
< RTAX_MAX
; i
++) {
184 if ((RTA_MASKS
& ifmam
->ifmam_addrs
&
187 sa
= (struct sockaddr
*)(void *)p
;
196 data
= malloc(sizeof(struct ifmaddrs
) * icnt
+ dcnt
);
202 ifa
= (struct ifmaddrs
*)(void *)data
;
203 data
+= sizeof(struct ifmaddrs
) * icnt
;
205 memset(ifa
, 0, sizeof(struct ifmaddrs
) * icnt
);
208 for (next
= buf
; next
< buf
+ needed
; next
+= rtm
->rtm_msglen
) {
209 rtm
= (struct rt_msghdr
*)(void *)next
;
210 if (rtm
->rtm_version
!= RTM_VERSION
)
213 switch (rtm
->rtm_type
) {
215 ifmam
= (struct ifma_msghdr2
*)(void *)rtm
;
216 if ((ifmam
->ifmam_addrs
& RTA_IFA
) == 0)
219 p
= (char *)(ifmam
+ 1);
220 for (i
= 0; i
< RTAX_MAX
; i
++) {
221 if ((RTA_MASKS
& ifmam
->ifmam_addrs
&
224 sa
= (struct sockaddr
*)(void *)p
;
229 (struct sockaddr
*)(void *)data
;
230 memcpy(data
, p
, len
);
236 (struct sockaddr
*)(void *)data
;
237 memcpy(data
, p
, len
);
243 (struct sockaddr
*)(void *)data
;
244 memcpy(data
, p
, len
);
254 ift
->ifma_next
= ift
+ 1;
255 ift
= ift
->ifma_next
;
264 ift
->ifma_next
= NULL
;
274 freeifmaddrs(struct ifmaddrs
*ifmp
)
281 ifmalist_dump_af(const struct ifmaddrs
* const ifmap
, int const af
)
283 const struct ifmaddrs
*ifma
;
285 char myifname
[IFNAMSIZ
];
287 char addrbuf
[INET6_ADDRSTRLEN
];
290 char *pafname
, *pifname
, *plladdr
= NULL
, *pgroup
= NULL
;
305 pafname
= "Link-layer";
311 fprintf(stdout
, "%s Multicast Group Memberships\n", pafname
);
312 fprintf(stdout
, "%-20s\t%-16s\t%s\n", "Group", "Link-layer Address",
315 for (ifma
= ifmap
; ifma
; ifma
= ifma
->ifma_next
) {
317 if (ifma
->ifma_name
== NULL
|| ifma
->ifma_addr
== NULL
)
321 psa
= (sockunion_t
*)ifma
->ifma_addr
;
322 if (psa
->sa
.sa_family
!= af
)
325 switch (psa
->sa
.sa_family
) {
327 pgroup
= inet_ntoa(psa
->sin
.sin_addr
);
331 in6addr
= &psa
->sin6
.sin6_addr
;
332 inet_ntop(psa
->sa
.sa_family
, in6addr
, addrbuf
,
338 if ((psa
->sdl
.sdl_alen
== ETHER_ADDR_LEN
) ||
339 (psa
->sdl
.sdl_type
== IFT_ETHER
)) {
341 ether_ntoa((struct ether_addr
*)&psa
->sdl
.sdl_data
);
344 pgroup
= addr2ascii(AF_LINK
,
346 sizeof(struct sockaddr_dl
),
355 /* Link-layer mapping, if any */
356 psa
= (sockunion_t
*)ifma
->ifma_lladdr
;
358 if (psa
->sa
.sa_family
== AF_LINK
) {
359 if ((psa
->sdl
.sdl_alen
== ETHER_ADDR_LEN
) ||
360 (psa
->sdl
.sdl_type
== IFT_ETHER
)) {
363 ether_ntoa((struct ether_addr
*)&psa
->sdl
.sdl_data
);
366 /* something more exotic */
367 plladdr
= addr2ascii(AF_LINK
,
369 sizeof(struct sockaddr_dl
),
376 /* not a link-layer address */
377 plladdr
= "<invalid>";
379 for (i
= 0; psa
->sa
.sa_len
> 2 && i
< psa
->sa
.sa_len
- 2; i
++)
380 printf("0x%x ", psa
->sa
.sa_data
[i
]);
387 /* Interface upon which the membership exists */
388 psa
= (sockunion_t
*)ifma
->ifma_name
;
389 if (psa
!= NULL
&& psa
->sa
.sa_family
== AF_LINK
) {
390 strlcpy(myifname
, link_ntoa(&psa
->sdl
), IFNAMSIZ
);
391 pcolon
= strchr(myifname
, ':');
399 fprintf(stdout
, "%-20s\t%-16s\t%s\n", pgroup
, plladdr
, pifname
);
406 struct ifmaddrs
*ifmap
;
408 if (getifmaddrs(&ifmap
))
409 err(EX_OSERR
, "getifmaddrs");
411 ifmalist_dump_af(ifmap
, AF_LINK
);
413 ifmalist_dump_af(ifmap
, AF_INET
);
416 ifmalist_dump_af(ifmap
, AF_INET6
);