118816Swollman/*
218816Swollman * Copyright (c) 1983, 1993
318816Swollman *	The Regents of the University of California.  All rights reserved.
418816Swollman *
518816Swollman * Redistribution and use in source and binary forms, with or without
618816Swollman * modification, are permitted provided that the following conditions
718816Swollman * are met:
818816Swollman * 1. Redistributions of source code must retain the above copyright
918816Swollman *    notice, this list of conditions and the following disclaimer.
1018816Swollman * 2. Redistributions in binary form must reproduce the above copyright
1118816Swollman *    notice, this list of conditions and the following disclaimer in the
1218816Swollman *    documentation and/or other materials provided with the distribution.
1318816Swollman * 4. Neither the name of the University nor the names of its contributors
1418816Swollman *    may be used to endorse or promote products derived from this software
1579727Sschweikh *    without specific prior written permission.
1618816Swollman *
1718816Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1818816Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1918816Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2018816Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2118816Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2218816Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2318816Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2418816Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2518816Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2618816Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2718816Swollman * SUCH DAMAGE.
2818816Swollman */
2950476Speter
30130538Sru#ifndef lint
31263478Sglebiusstatic const char rcsid[] =
32206622Suqs  "$FreeBSD: releng/11.0/sbin/ifconfig/af_link.c 301185 2016-06-02 03:16:02Z allanjude $";
3318816Swollman#endif /* not lint */
3418816Swollman
3518816Swollman#include <sys/types.h>
3618816Swollman#include <sys/ioctl.h>
3718816Swollman#include <sys/socket.h>
3884306Sru#include <net/if.h>
3984306Sru
4084306Sru#include <err.h>
4118816Swollman#include <stdio.h>
4220059Smpp#include <stdlib.h>
43121383Shmp#include <string.h>
44121383Shmp#include <ifaddrs.h>
4518816Swollman
4618816Swollman#include <net/if_dl.h>
4718816Swollman#include <net/if_types.h>
4818816Swollman#include <net/ethernet.h>
4918816Swollman
50119893Sru#include "ifconfig.h"
5118816Swollman
5218816Swollmanstatic struct ifreq link_ridreq;
5318816Swollman
5492279Sschweikhextern char *f_ether;
55130538Sru
5618816Swollmanstatic void
5718816Swollmanlink_status(int s __unused, const struct ifaddrs *ifa)
58130538Sru{
59121383Shmp	/* XXX no const 'cuz LLADDR is defined wrong */
60121383Shmp	struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr;
6118816Swollman	char *ether_format, *format_char;
62121383Shmp
63121383Shmp	if (sdl != NULL && sdl->sdl_alen > 0) {
64130538Sru		if ((sdl->sdl_type == IFT_ETHER ||
6518816Swollman		    sdl->sdl_type == IFT_L2VLAN ||
66130538Sru		    sdl->sdl_type == IFT_BRIDGE) &&
6718816Swollman		    sdl->sdl_alen == ETHER_ADDR_LEN) {
68130538Sru			ether_format = ether_ntoa((struct ether_addr *)LLADDR(sdl));
6918816Swollman			if (f_ether != NULL && strcmp(f_ether, "dash") == 0) {
70130538Sru				for (format_char = strchr(ether_format, ':');
71130538Sru				    format_char != NULL;
7218816Swollman				    format_char = strchr(ether_format, ':'))
7318816Swollman					*format_char = '-';
7418816Swollman			}
7520059Smpp			printf("\tether %s\n", ether_format);
7618816Swollman		} else {
7718816Swollman			int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0;
7818816Swollman
79186119Sqingli			printf("\tlladdr %s\n", link_ntoa(sdl) + n);
8018816Swollman		}
81263478Sglebius	}
82263478Sglebius}
83263478Sglebius
84263478Sglebiusstatic void
85263478Sglebiuslink_getaddr(const char *addr, int which)
86263478Sglebius{
87186119Sqingli	char *temp;
88186119Sqingli	struct sockaddr_dl sdl;
89186119Sqingli	struct sockaddr *sa = &link_ridreq.ifr_addr;
90130538Sru
91130538Sru	if (which != ADDR)
9218816Swollman		errx(1, "can't set link-level netmask or broadcast");
9318816Swollman	if ((temp = malloc(strlen(addr) + 2)) == NULL)
9418816Swollman		errx(1, "malloc failed");
9518816Swollman	temp[0] = ':';
9618816Swollman	strcpy(temp + 1, addr);
9718816Swollman	sdl.sdl_len = sizeof(sdl);
98263478Sglebius	link_addr(temp, &sdl);
99263478Sglebius	free(temp);
100263478Sglebius	if (sdl.sdl_alen > sizeof(sa->sa_data))
101263478Sglebius		errx(1, "malformed link-level address");
102263478Sglebius	sa->sa_family = AF_LINK;
103263478Sglebius	sa->sa_len = sdl.sdl_alen;
104263478Sglebius	bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen);
105263478Sglebius}
106130538Sru
10718816Swollmanstatic struct afswtch af_link = {
108130538Sru	.af_name	= "link",
10918816Swollman	.af_af		= AF_LINK,
11018816Swollman	.af_status	= link_status,
11118816Swollman	.af_getaddr	= link_getaddr,
112136256Sglebius	.af_aifaddr	= SIOCSIFLLADDR,
113136256Sglebius	.af_addreq	= &link_ridreq,
11418816Swollman};
11518816Swollmanstatic struct afswtch af_ether = {
11618816Swollman	.af_name	= "ether",
117136256Sglebius	.af_af		= AF_LINK,
11818816Swollman	.af_status	= link_status,
11918816Swollman	.af_getaddr	= link_getaddr,
12018816Swollman	.af_aifaddr	= SIOCSIFLLADDR,
12118816Swollman	.af_addreq	= &link_ridreq,
12218816Swollman};
123130538Srustatic struct afswtch af_lladdr = {
12418816Swollman	.af_name	= "lladdr",
125130538Sru	.af_af		= AF_LINK,
12618816Swollman	.af_status	= link_status,
12718816Swollman	.af_getaddr	= link_getaddr,
12818816Swollman	.af_aifaddr	= SIOCSIFLLADDR,
12918816Swollman	.af_addreq	= &link_ridreq,
130121383Shmp};
131121383Shmp
13218816Swollmanstatic __constructor void
13318816Swollmanlink_ctor(void)
13418816Swollman{
13518816Swollman	af_register(&af_link);
13618816Swollman	af_register(&af_ether);
13718816Swollman	af_register(&af_lladdr);
13818816Swollman}
13918816Swollman