1251881Speter/*- 2251881Speter * Copyright (c) 2012 maksim yevmenkin <emax@freebsd.org> 3251881Speter * All rights reserved. 4251881Speter * 5251881Speter * Redistribution and use in source and binary forms, with or without 6251881Speter * modification, are permitted providing that the following conditions 7251881Speter * are met: 8251881Speter * 1. Redistributions of source code must retain the above copyright 9251881Speter * notice, this list of conditions and the following disclaimer. 10251881Speter * 2. Redistributions in binary form must reproduce the above copyright 11251881Speter * notice, this list of conditions and the following disclaimer in the 12251881Speter * documentation and/or other materials provided with the distribution. 13251881Speter * 14251881Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15251881Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16251881Speter * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17251881Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18251881Speter * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19251881Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20251881Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21251881Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22251881Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23251881Speter * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24251881Speter * POSSIBILITY OF SUCH DAMAGE. 25251881Speter */ 26251881Speter 27251881Speter/* gcc -Wall -ggdb ifpifa.c -lkvm -o ifpifa */ 28251881Speter 29251881Speter#include <sys/types.h> 30251881Speter#include <sys/callout.h> 31251881Speter#include <sys/cdefs.h> 32251881Speter#include <sys/param.h> 33251881Speter#include <sys/protosw.h> 34251881Speter#include <sys/queue.h> 35251881Speter#include <sys/socket.h> 36251881Speter#include <sys/socketvar.h> 37251881Speter 38251881Speter#include <net/if.h> 39251881Speter#include <net/if_var.h> 40251881Speter#include <net/if_dl.h> 41251881Speter#include <net/if_types.h> 42251881Speter#include <net/ethernet.h> 43251881Speter#include <netinet/in.h> 44251881Speter#include <netinet/in_var.h> 45251881Speter#include <arpa/inet.h> 46251881Speter 47251881Speter#include <err.h> 48251881Speter#include <fcntl.h> 49251881Speter#include <kvm.h> 50251881Speter#include <limits.h> 51251881Speter#include <nlist.h> 52251881Speter#include <stdio.h> 53251881Speter#include <stdlib.h> 54251881Speter#include <string.h> 55251881Speter 56251881Speter__FBSDID("$FreeBSD: releng/10.3/tools/tools/ifpifa/ifpifa.c 236645 2012-06-05 22:02:27Z emax $"); 57251881Speter 58251881Speterstatic struct nlist nl[] = { 59251881Speter#define N_IFNET 0 60251881Speter { .n_name = "_ifnet", }, 61251881Speter { .n_name = NULL, }, 62251881Speter}; 63251881Speter 64251881Speterstatic int 65251881Speterkread(kvm_t *kd, u_long addr, char *buffer, int size) 66251881Speter{ 67251881Speter if (kd == NULL || buffer == NULL) 68251881Speter return (-1); 69251881Speter 70251881Speter if (kvm_read(kd, addr, buffer, size) != size) { 71251881Speter warnx("kvm_read: %s", kvm_geterr(kd)); 72251881Speter return (-1); 73251881Speter } 74251881Speter 75251881Speter return (0); 76251881Speter} 77251881Speter 78251881Speterint 79251881Spetermain(void) 80251881Speter{ 81251881Speter kvm_t *kd; 82251881Speter char errbuf[_POSIX2_LINE_MAX]; 83251881Speter u_long ifnetaddr, ifnetaddr_next; 84251881Speter u_long ifaddraddr, ifaddraddr_next; 85251881Speter struct ifnet ifnet; 86251881Speter struct ifnethead ifnethead; 87251881Speter union { 88251881Speter struct ifaddr ifa; 89251881Speter struct in_ifaddr in; 90251881Speter struct in6_ifaddr in6; 91251881Speter } ifaddr; 92251881Speter union { 93251881Speter struct sockaddr *sa; 94251881Speter struct sockaddr_dl *sal; 95251881Speter struct sockaddr_in *sa4; 96251881Speter struct sockaddr_in6 *sa6; 97251881Speter } sa; 98251881Speter char addr[INET6_ADDRSTRLEN]; 99251881Speter 100251881Speter kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); 101251881Speter if (kd == NULL) { 102251881Speter warnx("kvm_openfiles: %s", errbuf); 103251881Speter exit(0); 104251881Speter } 105251881Speter 106251881Speter if (kvm_nlist(kd, nl) < 0) { 107251881Speter warnx("kvm_nlist: %s", kvm_geterr(kd)); 108251881Speter goto out; 109251881Speter } 110251881Speter 111251881Speter if (nl[N_IFNET].n_type == 0) { 112251881Speter warnx("kvm_nlist: no namelist"); 113251881Speter goto out; 114251881Speter } 115251881Speter 116251881Speter if (kread(kd, nl[N_IFNET].n_value, 117251881Speter (char *) &ifnethead, sizeof(ifnethead)) != 0) 118251881Speter goto out; 119251881Speter 120251881Speter for (ifnetaddr = (u_long) TAILQ_FIRST(&ifnethead); 121251881Speter ifnetaddr != 0; 122251881Speter ifnetaddr = ifnetaddr_next) { 123251881Speter if (kread(kd, ifnetaddr, (char *) &ifnet, sizeof(ifnet)) != 0) 124251881Speter goto out; 125251881Speter ifnetaddr_next = (u_long) TAILQ_NEXT(&ifnet, if_link); 126251881Speter 127251881Speter printf("%s\n", ifnet.if_xname); 128251881Speter 129251881Speter for (ifaddraddr = (u_long) TAILQ_FIRST(&ifnet.if_addrhead); 130251881Speter ifaddraddr != 0; 131251881Speter ifaddraddr = ifaddraddr_next) { 132251881Speter if (kread(kd, ifaddraddr, 133251881Speter (char *) &ifaddr, sizeof(ifaddr)) != 0) 134251881Speter goto out; 135251881Speter 136251881Speter ifaddraddr_next = (u_long) 137251881Speter TAILQ_NEXT(&ifaddr.ifa, ifa_link); 138251881Speter 139251881Speter sa.sa = (struct sockaddr *)( 140251881Speter (unsigned char *) ifaddr.ifa.ifa_addr - 141251881Speter (unsigned char *) ifaddraddr + 142251881Speter (unsigned char *) &ifaddr); 143251881Speter 144251881Speter switch (sa.sa->sa_family) { 145251881Speter case AF_LINK: 146251881Speter switch (sa.sal->sdl_type) { 147251881Speter case IFT_ETHER: 148251881Speter case IFT_FDDI: 149251881Speter ether_ntoa_r((struct ether_addr * ) 150251881Speter LLADDR(sa.sal), addr); 151251881Speter break; 152251881Speter 153251881Speter case IFT_LOOP: 154251881Speter strcpy(addr, "loopback"); 155251881Speter break; 156251881Speter 157251881Speter default: 158251881Speter snprintf(addr, sizeof(addr), 159251881Speter "<Link type %#x>", 160251881Speter sa.sal->sdl_type); 161251881Speter break; 162251881Speter } 163251881Speter break; 164251881Speter 165251881Speter case AF_INET: 166251881Speter inet_ntop(AF_INET, &sa.sa4->sin_addr, 167251881Speter addr, sizeof(addr)); 168251881Speter break; 169251881Speter 170251881Speter case AF_INET6: 171251881Speter inet_ntop(AF_INET6, &sa.sa6->sin6_addr, 172251881Speter addr, sizeof(addr)); 173251881Speter break; 174251881Speter 175251881Speter default: 176251881Speter snprintf(addr, sizeof(addr), "family=%d", 177251881Speter sa.sa->sa_family); 178251881Speter break; 179251881Speter } 180251881Speter 181251881Speter printf("\t%s ifa_refcnt=%u\n", 182251881Speter addr, ifaddr.ifa.ifa_refcnt); 183251881Speter } 184251881Speter } 185251881Speterout: 186251881Speter kvm_close(kd); 187251881Speter 188251881Speter return (0); 189251881Speter} 190251881Speter 191251881Speter