1 /* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <fcntl.h> 35 #include <kvm.h> 36 #include <nlist.h> 37 #include <string.h> 38 #include <limits.h> 39 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <net/if.h> 43 #include <net/if_var.h> 44 #include <net/if_types.h> 45 #include <net/if_dl.h> 46 #include <netinet/in.h> 47 #define _KERNEL 48 #include <netinet/if_ether.h> 49 #undef _KERNEL 50 #include <netinet/in_var.h> 51 #include <arpa/inet.h> 52 53 kvm_t *kvmd; 54 55 struct nlist nl[] = { 56 #define N_IFNET 0 57 { "_ifnet" }, 58 { "" }, 59 }; 60 61 const char *inet6_n2a __P((struct in6_addr *)); 62 int main __P((void)); 63 char *ifname __P((struct ifnet *)); 64 void kread __P((u_long, void *, int)); 65 void if6_addrlist __P((struct ifaddr *)); 66 void in6_multilist __P((struct in6_multi *)); 67 void in6_multientry __P((struct in6_multi *)); 68 69 #define KREAD(addr, buf, type) \ 70 kread((u_long)addr, (void *)buf, sizeof(type)) 71 72 const char *inet6_n2a(p) 73 struct in6_addr *p; 74 { 75 static char buf[BUFSIZ]; 76 77 if (IN6_IS_ADDR_UNSPECIFIED(p)) 78 return "*"; 79 return inet_ntop(AF_INET6, (void *)p, buf, sizeof(buf)); 80 } 81 82 int main() 83 { 84 char buf[_POSIX2_LINE_MAX], ifname[IFNAMSIZ]; 85 struct ifnet *ifp, *nifp, ifnet; 86 struct arpcom arpcom; 87 88 if ((kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf)) == NULL) { 89 perror("kvm_openfiles"); 90 exit(1); 91 } 92 if (kvm_nlist(kvmd, nl) < 0) { 93 perror("kvm_nlist"); 94 exit(1); 95 } 96 if (nl[N_IFNET].n_value == 0) { 97 printf("symbol %s not found\n", nl[N_IFNET].n_name); 98 exit(1); 99 } 100 KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *); 101 while (ifp) { 102 KREAD(ifp, &ifnet, struct ifnet); 103 printf("%s:\n", if_indextoname(ifnet.if_index, ifname)); 104 if6_addrlist(TAILQ_FIRST(&ifnet.if_addrhead)); 105 ifp = TAILQ_NEXT(&ifnet, if_link); 106 } 107 108 exit(0); 109 /*NOTREACHED*/ 110 } 111 112 char *ifname(ifp) 113 struct ifnet *ifp; 114 { 115 static char buf[BUFSIZ]; 116 117 KREAD(ifp->if_name, buf, IFNAMSIZ); 118 return buf; 119 } 120 121 void kread(addr, buf, len) 122 u_long addr; 123 void *buf; 124 int len; 125 { 126 if (kvm_read(kvmd, addr, buf, len) != len) { 127 perror("kvm_read"); 128 exit(1); 129 } 130 } 131 132 void 133 if6_addrlist(ifap) 134 struct ifaddr *ifap; 135 { 136 static char in6buf[BUFSIZ]; 137 struct ifnet ifnet; 138 struct ifaddr ifa; 139 struct ifaddr *ifap0; 140 struct ifmultiaddr ifm, *ifmp = 0; 141 struct in6_ifaddr if6a; 142 struct in6_multi *mc = 0, in6m; 143 int in6_multilist_done = 0; 144 struct sockaddr sa; 145 struct sockaddr_in6 sin6; 146 struct sockaddr_dl sdl; 147 148 if (ifap == NULL) 149 return; 150 ifap0 = ifap; 151 152 do { 153 KREAD(ifap, &ifa, struct ifaddr); 154 if (ifa.ifa_addr == NULL) 155 continue; 156 KREAD(ifa.ifa_addr, &sa, struct sockaddr); 157 if (sa.sa_family != PF_INET6) 158 continue; 159 KREAD(ifap, &if6a, struct in6_ifaddr); 160 printf("\tinet6 %s\n", 161 inet_ntop(AF_INET6, 162 (const void *)&if6a.ia_addr.sin6_addr, 163 in6buf, sizeof(in6buf))); 164 } while ((ifap = TAILQ_NEXT(&ifa, ifa_link)) != NULL); 165 166 KREAD(ifap0, &ifa, struct ifaddr); 167 KREAD(ifa.ifa_ifp, &ifnet, struct ifnet); 168 if (ifnet.if_multiaddrs.lh_first) 169 ifmp = ifnet.if_multiaddrs.lh_first; 170 if (ifmp == NULL) 171 return; 172 do { 173 KREAD(ifmp, &ifm, struct ifmultiaddr); 174 if (ifm.ifma_addr == NULL) 175 continue; 176 KREAD(ifm.ifma_addr, &sa, struct sockaddr); 177 if (sa.sa_family != AF_INET6) 178 continue; 179 in6_multientry((struct in6_multi *)ifm.ifma_protospec); 180 if (ifm.ifma_lladdr == 0) 181 continue; 182 KREAD(ifm.ifma_lladdr, &sdl, struct sockaddr_dl); 183 printf("\t\t\tmcast-macaddr %s multicnt %d\n", 184 ether_ntoa((struct ether_addr *)LLADDR(&sdl)), 185 ifm.ifma_refcount); 186 } while ((ifmp = LIST_NEXT(&ifm, ifma_link)) != NULL); 187 } 188 189 void 190 in6_multientry(mc) 191 struct in6_multi *mc; 192 { 193 static char mcbuf[BUFSIZ]; 194 struct in6_multi multi; 195 196 KREAD(mc, &multi, struct in6_multi); 197 printf("\t\tgroup %s\n", inet_ntop(AF_INET6, 198 (const void *)&multi.in6m_addr, 199 mcbuf, sizeof(mcbuf))); 200 } 201