1 /* $NetBSD: ifmcstat.c,v 1.9 2004/11/16 05:59:32 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include <sys/types.h>
41 #include <sys/socket.h>
43 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
44 # include <net/if_var.h>
46 #include <net/if_types.h>
47 #include <net/if_dl.h>
48 #include <netinet/in.h>
53 # include <netinet/if_ether.h>
58 # include <net/if_ether.h>
60 #include <netinet/in_var.h>
61 #include <arpa/inet.h>
69 { "_ifnet", 0, 0, 0, 0 },
70 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
72 { "_in6_mk", 0, 0, 0, 0 },
77 const char *inet6_n2a
__P((struct in6_addr
*));
79 char *ifname
__P((struct ifnet
*));
80 void kread
__P((u_long
, void *, int));
81 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
82 void acmc
__P((struct ether_multi
*));
84 void if6_addrlist
__P((struct ifaddr
*));
85 void in6_multilist
__P((struct in6_multi
*));
86 struct in6_multi
* in6_multientry
__P((struct in6_multi
*));
88 #if !defined(__NetBSD__) && !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__)
91 u_int8_t ether_addr_octet
[6];
94 static char *ether_ntoa
__P((struct ether_addr
*));
97 #define KREAD(addr, buf, type) \
98 kread((u_long)addr, (void *)buf, sizeof(type))
101 struct multi6_kludge
{
102 LIST_ENTRY(multi6_kludge
) mk_entry
;
103 struct ifnet
*mk_ifp
;
104 struct in6_multihead mk_head
;
108 const char *inet6_n2a(p
)
111 static char buf
[NI_MAXHOST
];
112 struct sockaddr_in6 sin6
;
114 const int niflags
= NI_NUMERICHOST
;
116 memset(&sin6
, 0, sizeof(sin6
));
117 sin6
.sin6_family
= AF_INET6
;
118 sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
120 if (IN6_IS_ADDR_LINKLOCAL(p
) || IN6_IS_ADDR_MC_LINKLOCAL(p
)) {
121 scopeid
= ntohs(*(u_int16_t
*)&sin6
.sin6_addr
.s6_addr
[2]);
123 sin6
.sin6_scope_id
= scopeid
;
124 sin6
.sin6_addr
.s6_addr
[2] = 0;
125 sin6
.sin6_addr
.s6_addr
[3] = 0;
128 if (getnameinfo((struct sockaddr
*)&sin6
, sin6
.sin6_len
,
129 buf
, sizeof(buf
), NULL
, 0, niflags
) == 0)
137 char buf
[_POSIX2_LINE_MAX
], ifnam
[IFNAMSIZ
];
138 struct ifnet
*ifp
, *nifp
, ifnet
;
140 struct arpcom arpcom
;
143 struct sockaddr_dl sdl
;
146 if ((kvmd
= kvm_openfiles(NULL
, NULL
, NULL
, O_RDONLY
, buf
)) == NULL
) {
147 perror("kvm_openfiles");
150 if (kvm_nlist(kvmd
, nl
) < 0) {
154 if (nl
[N_IFNET
].n_value
== 0) {
155 printf("symbol %s not found\n", nl
[N_IFNET
].n_name
);
158 KREAD(nl
[N_IFNET
].n_value
, &ifp
, struct ifnet
*);
160 KREAD(ifp
, &ifnet
, struct ifnet
);
161 printf("%s:\n", if_indextoname(ifnet
.if_index
, ifnam
));
163 #if defined(__NetBSD__) || defined(__OpenBSD__)
164 if6_addrlist(ifnet
.if_addrlist
.tqh_first
);
165 nifp
= ifnet
.if_list
.tqe_next
;
166 #elif defined(__FreeBSD__) && __FreeBSD__ >= 3
167 if6_addrlist(TAILQ_FIRST(&ifnet
.if_addrhead
));
168 nifp
= ifnet
.if_link
.tqe_next
;
170 if6_addrlist(ifnet
.if_addrlist
);
171 nifp
= ifnet
.if_next
;
175 KREAD(ifnet
.if_sadl
, &sdl
, struct sockaddr_dl
);
176 if (sdl
.sdl_type
== IFT_ETHER
) {
177 printf("\tenaddr %s",
178 ether_ntoa((struct ether_addr
*)LLADDR(&sdl
)));
179 KREAD(ifp
, &ec
, struct ethercom
);
180 printf(" multicnt %d", ec
.ec_multicnt
);
181 acmc(ec
.ec_multiaddrs
.lh_first
);
184 #elif defined(__FreeBSD__) && __FreeBSD__ >= 3
187 if (ifnet
.if_type
== IFT_ETHER
) {
188 KREAD(ifp
, &arpcom
, struct arpcom
);
189 printf("\tenaddr %s",
190 ether_ntoa((struct ether_addr
*)arpcom
.ac_enaddr
));
191 KREAD(ifp
, &arpcom
, struct arpcom
);
192 printf(" multicnt %d", arpcom
.ac_multicnt
);
194 acmc(arpcom
.ac_multiaddrs
.lh_first
);
196 acmc(arpcom
.ac_multiaddrs
);
212 static char buf
[BUFSIZ
];
213 #if defined(__NetBSD__) || defined(__OpenBSD__)
217 #if defined(__NetBSD__) || defined(__OpenBSD__)
218 KREAD(ifp
, &ifnet
, struct ifnet
);
219 strncpy(buf
, ifnet
.if_xname
, BUFSIZ
);
221 KREAD(ifp
->if_name
, buf
, IFNAMSIZ
);
226 void kread(addr
, buf
, len
)
231 if (kvm_read(kvmd
, addr
, buf
, len
) != len
) {
237 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
239 struct ether_multi
*am
;
241 struct ether_multi em
;
244 KREAD(am
, &em
, struct ether_multi
);
247 printf("%s -- ", ether_ntoa((struct ether_addr
*)em
.enm_addrlo
));
248 printf("%s ", ether_ntoa((struct ether_addr
*)&em
.enm_addrhi
));
249 printf("%d", em
.enm_refcount
);
250 #if !defined(__NetBSD__) && !defined(__OpenBSD__)
253 am
= em
.enm_list
.le_next
;
265 struct in6_ifaddr if6a
;
266 struct in6_multi
*mc
= 0;
267 struct ifaddr
*ifap0
;
271 KREAD(ifap
, &ifa
, struct ifaddr
);
272 if (ifa
.ifa_addr
== NULL
)
274 KREAD(ifa
.ifa_addr
, &sa
, struct sockaddr
);
275 if (sa
.sa_family
!= PF_INET6
)
277 KREAD(ifap
, &if6a
, struct in6_ifaddr
);
278 printf("\tinet6 %s\n", inet6_n2a(&if6a
.ia_addr
.sin6_addr
));
279 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
280 mc
= mc
? mc
: if6a
.ia6_multiaddrs
.lh_first
;
283 #if defined(__NetBSD__) || defined(__OpenBSD__)
284 ifap
= ifa
.ifa_list
.tqe_next
;
285 #elif defined(__FreeBSD__) && __FreeBSD__ >= 3
286 ifap
= ifa
.ifa_link
.tqe_next
;
289 #endif /* __FreeBSD__ >= 3 */
291 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
294 struct ifmultiaddr ifm
, *ifmp
= 0;
295 struct sockaddr_in6 sin6
;
296 struct in6_multi in6m
;
297 struct sockaddr_dl sdl
;
298 int in6_multilist_done
= 0;
300 KREAD(ifap0
, &ifa
, struct ifaddr
);
301 KREAD(ifa
.ifa_ifp
, &ifnet
, struct ifnet
);
302 if (ifnet
.if_multiaddrs
.lh_first
)
303 ifmp
= ifnet
.if_multiaddrs
.lh_first
;
305 KREAD(ifmp
, &ifm
, struct ifmultiaddr
);
306 if (ifm
.ifma_addr
== NULL
)
308 KREAD(ifm
.ifma_addr
, &sa
, struct sockaddr
);
309 if (sa
.sa_family
!= AF_INET6
)
311 (void)in6_multientry((struct in6_multi
*)
313 if (ifm
.ifma_lladdr
== 0)
315 KREAD(ifm
.ifma_lladdr
, &sdl
, struct sockaddr_dl
);
316 printf("\t\t\tmcast-macaddr %s multicnt %d\n",
317 ether_ntoa((struct ether_addr
*)LLADDR(&sdl
)),
320 ifmp
= ifm
.ifma_link
.le_next
;
328 if (nl
[N_IN6_MK
].n_value
!= 0) {
329 LIST_HEAD(in6_mktype
, multi6_kludge
) in6_mk
;
330 struct multi6_kludge
*mkp
, mk
;
333 KREAD(nl
[N_IN6_MK
].n_value
, &in6_mk
, struct in6_mktype
);
334 KREAD(ifap0
, &ifa
, struct ifaddr
);
336 nam
= strdup(ifname(ifa
.ifa_ifp
));
338 for (mkp
= in6_mk
.lh_first
; mkp
; mkp
= mk
.mk_entry
.le_next
) {
339 KREAD(mkp
, &mk
, struct multi6_kludge
);
340 if (strcmp(nam
, ifname(mk
.mk_ifp
)) == 0 &&
341 mk
.mk_head
.lh_first
) {
342 printf("\t(on kludge entry for %s)\n", nam
);
343 in6_multilist(mk
.mk_head
.lh_first
);
354 struct in6_multi
*mc
;
356 struct in6_multi multi
;
358 KREAD(mc
, &multi
, struct in6_multi
);
359 printf("\t\tgroup %s", inet6_n2a(&multi
.in6m_addr
));
360 printf(" refcnt %u\n", multi
.in6m_refcount
);
361 return(multi
.in6m_entry
.le_next
);
366 struct in6_multi
*mc
;
369 mc
= in6_multientry(mc
);
372 #if !defined(__NetBSD__) && !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(__OpenBSD__)
375 struct ether_addr
*e
;
382 snprintf(buf
, sizeof(buf
), "%02x:%02x:%02x:%02x:%02x:%02x",
383 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5]);