af_link.c revision 256281
1240116Smarcel/* 2240116Smarcel * Copyright (c) 1983, 1993 3240116Smarcel * The Regents of the University of California. All rights reserved. 4240116Smarcel * 5240116Smarcel * Redistribution and use in source and binary forms, with or without 6240116Smarcel * modification, are permitted provided that the following conditions 7240116Smarcel * are met: 8240116Smarcel * 1. Redistributions of source code must retain the above copyright 9240116Smarcel * notice, this list of conditions and the following disclaimer. 10240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11240116Smarcel * notice, this list of conditions and the following disclaimer in the 12240116Smarcel * documentation and/or other materials provided with the distribution. 13240116Smarcel * 4. Neither the name of the University nor the names of its contributors 14240116Smarcel * may be used to endorse or promote products derived from this software 15240116Smarcel * without specific prior written permission. 16240116Smarcel * 17240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18240116Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19240116Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20240116Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21240116Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23240116Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25240116Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26240116Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27240116Smarcel * SUCH DAMAGE. 28240116Smarcel */ 29240116Smarcel 30240116Smarcel#ifndef lint 31240116Smarcelstatic const char rcsid[] = 32240116Smarcel "$FreeBSD: stable/10/sbin/ifconfig/af_link.c 210936 2010-08-06 15:09:21Z jhb $"; 33240116Smarcel#endif /* not lint */ 34240116Smarcel 35240116Smarcel#include <sys/types.h> 36240116Smarcel#include <sys/ioctl.h> 37240116Smarcel#include <sys/socket.h> 38240116Smarcel#include <net/if.h> 39240116Smarcel 40240116Smarcel#include <err.h> 41240116Smarcel#include <stdio.h> 42240116Smarcel#include <stdlib.h> 43240116Smarcel#include <string.h> 44240116Smarcel#include <ifaddrs.h> 45240116Smarcel 46240116Smarcel#include <net/if_dl.h> 47240116Smarcel#include <net/if_types.h> 48240116Smarcel#include <net/ethernet.h> 49240116Smarcel 50240116Smarcel#include "ifconfig.h" 51240116Smarcel 52240116Smarcelstatic struct ifreq link_ridreq; 53240116Smarcel 54240116Smarcelstatic void 55240116Smarcellink_status(int s __unused, const struct ifaddrs *ifa) 56240116Smarcel{ 57240116Smarcel /* XXX no const 'cuz LLADDR is defined wrong */ 58240116Smarcel struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr; 59240116Smarcel 60240116Smarcel if (sdl != NULL && sdl->sdl_alen > 0) { 61240116Smarcel if ((sdl->sdl_type == IFT_ETHER || 62240116Smarcel sdl->sdl_type == IFT_L2VLAN || 63240116Smarcel sdl->sdl_type == IFT_BRIDGE) && 64240116Smarcel sdl->sdl_alen == ETHER_ADDR_LEN) 65240116Smarcel printf("\tether %s\n", 66240116Smarcel ether_ntoa((struct ether_addr *)LLADDR(sdl))); 67240116Smarcel else { 68240116Smarcel int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; 69240116Smarcel 70240116Smarcel printf("\tlladdr %s\n", link_ntoa(sdl) + n); 71240116Smarcel } 72240116Smarcel } 73240116Smarcel} 74240116Smarcel 75240116Smarcelstatic void 76240116Smarcellink_getaddr(const char *addr, int which) 77240116Smarcel{ 78240116Smarcel char *temp; 79240116Smarcel struct sockaddr_dl sdl; 80240116Smarcel struct sockaddr *sa = &link_ridreq.ifr_addr; 81240116Smarcel 82240116Smarcel if (which != ADDR) 83240116Smarcel errx(1, "can't set link-level netmask or broadcast"); 84240116Smarcel if ((temp = malloc(strlen(addr) + 2)) == NULL) 85240116Smarcel errx(1, "malloc failed"); 86240116Smarcel temp[0] = ':'; 87240116Smarcel strcpy(temp + 1, addr); 88240116Smarcel sdl.sdl_len = sizeof(sdl); 89240116Smarcel link_addr(temp, &sdl); 90240116Smarcel free(temp); 91240116Smarcel if (sdl.sdl_alen > sizeof(sa->sa_data)) 92240116Smarcel errx(1, "malformed link-level address"); 93240116Smarcel sa->sa_family = AF_LINK; 94240116Smarcel sa->sa_len = sdl.sdl_alen; 95240116Smarcel bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen); 96240116Smarcel} 97240116Smarcel 98240116Smarcelstatic struct afswtch af_link = { 99240116Smarcel .af_name = "link", 100240116Smarcel .af_af = AF_LINK, 101240116Smarcel .af_status = link_status, 102240116Smarcel .af_getaddr = link_getaddr, 103240116Smarcel .af_aifaddr = SIOCSIFLLADDR, 104240116Smarcel .af_addreq = &link_ridreq, 105240116Smarcel}; 106240116Smarcelstatic struct afswtch af_ether = { 107240116Smarcel .af_name = "ether", 108240116Smarcel .af_af = AF_LINK, 109240116Smarcel .af_status = link_status, 110240116Smarcel .af_getaddr = link_getaddr, 111240116Smarcel .af_aifaddr = SIOCSIFLLADDR, 112240116Smarcel .af_addreq = &link_ridreq, 113240116Smarcel}; 114240116Smarcelstatic struct afswtch af_lladdr = { 115240116Smarcel .af_name = "lladdr", 116240116Smarcel .af_af = AF_LINK, 117240116Smarcel .af_status = link_status, 118240116Smarcel .af_getaddr = link_getaddr, 119240116Smarcel .af_aifaddr = SIOCSIFLLADDR, 120240116Smarcel .af_addreq = &link_ridreq, 121240116Smarcel}; 122240116Smarcel 123240116Smarcelstatic __constructor void 124240116Smarcellink_ctor(void) 125240116Smarcel{ 126240116Smarcel af_register(&af_link); 127240116Smarcel af_register(&af_ether); 128240116Smarcel af_register(&af_lladdr); 129240116Smarcel} 130240116Smarcel