ifvlan.c revision 138593
144764Swpaul/*
244764Swpaul * Copyright (c) 1999
344764Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
444764Swpaul *
544764Swpaul * Redistribution and use in source and binary forms, with or without
644764Swpaul * modification, are permitted provided that the following conditions
744764Swpaul * are met:
844764Swpaul * 1. Redistributions of source code must retain the above copyright
944764Swpaul *    notice, this list of conditions and the following disclaimer.
1044764Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1144764Swpaul *    notice, this list of conditions and the following disclaimer in the
1244764Swpaul *    documentation and/or other materials provided with the distribution.
1344764Swpaul * 3. All advertising materials mentioning features or use of this software
1444764Swpaul *    must display the following acknowledgement:
1544764Swpaul *	This product includes software developed by Bill Paul.
1644764Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1744764Swpaul *    may be used to endorse or promote products derived from this software
1844764Swpaul *    without specific prior written permission.
1944764Swpaul *
2044764Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2144764Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2244764Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2344764Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
2444764Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2544764Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2644764Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2744764Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2844764Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2944764Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3044764Swpaul * THE POSSIBILITY OF SUCH DAMAGE.
3144764Swpaul */
3244764Swpaul
3344764Swpaul#include <sys/param.h>
3444764Swpaul#include <sys/ioctl.h>
3544764Swpaul#include <sys/socket.h>
3644764Swpaul#include <sys/sockio.h>
3744764Swpaul
3844764Swpaul#include <stdlib.h>
3944764Swpaul#include <unistd.h>
4044764Swpaul
4144764Swpaul#include <net/ethernet.h>
4244764Swpaul#include <net/if.h>
4344764Swpaul#include <net/if_var.h>
4444764Swpaul#include <net/if_vlan_var.h>
4544764Swpaul#include <net/route.h>
4644764Swpaul
4744764Swpaul#include <ctype.h>
4844764Swpaul#include <stdio.h>
4944764Swpaul#include <string.h>
5044764Swpaul#include <stdlib.h>
5144764Swpaul#include <unistd.h>
5244764Swpaul#include <err.h>
5344764Swpaul#include <errno.h>
5444764Swpaul
5544764Swpaul#include "ifconfig.h"
5644764Swpaul
5744764Swpaul#ifndef lint
5844764Swpaulstatic const char rcsid[] =
5950476Speter  "$FreeBSD: head/sbin/ifconfig/ifvlan.c 138593 2004-12-08 19:18:07Z sam $";
6044764Swpaul#endif
6144764Swpaulstatic int			__tag = 0;
6244764Swpaulstatic int			__have_tag = 0;
6344764Swpaul
64138593Ssamstatic void
65138593Ssamvlan_status(int s, const struct rt_addrinfo *info __unused)
6644764Swpaul{
6744764Swpaul	struct vlanreq		vreq;
6844764Swpaul
6944764Swpaul	bzero((char *)&vreq, sizeof(struct vlanreq));
7044764Swpaul	ifr.ifr_data = (caddr_t)&vreq;
7144764Swpaul
7244764Swpaul	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
7344764Swpaul		return;
7444764Swpaul
7544764Swpaul	printf("\tvlan: %d parent interface: %s\n",
7644764Swpaul	    vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ?
7744764Swpaul	    "<none>" : vreq.vlr_parent);
7844764Swpaul
7944764Swpaul	return;
8044764Swpaul}
8144764Swpaul
82138593Ssamstatic void
8395005Simpsetvlantag(const char *val, int d, int s, const struct afswtch	*afp)
8444764Swpaul{
8544764Swpaul	u_int16_t		tag;
8644764Swpaul	struct vlanreq		vreq;
8744764Swpaul
8844764Swpaul	__tag = tag = atoi(val);
8944764Swpaul	__have_tag = 1;
9044764Swpaul
9144764Swpaul	bzero((char *)&vreq, sizeof(struct vlanreq));
9244764Swpaul	ifr.ifr_data = (caddr_t)&vreq;
9344764Swpaul
9444764Swpaul	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
9544764Swpaul		err(1, "SIOCGETVLAN");
9644764Swpaul
9744764Swpaul	vreq.vlr_tag = tag;
9844764Swpaul
9944764Swpaul	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
10044764Swpaul		err(1, "SIOCSETVLAN");
10144764Swpaul
10244764Swpaul	return;
10344764Swpaul}
10444764Swpaul
105138593Ssamstatic void
10695005Simpsetvlandev(const char *val, int d, int s, const struct afswtch	*afp)
10744764Swpaul{
10844764Swpaul	struct vlanreq		vreq;
10944764Swpaul
11044764Swpaul	if (!__have_tag)
11144764Swpaul		errx(1, "must specify both vlan tag and device");
11244764Swpaul
11344764Swpaul	bzero((char *)&vreq, sizeof(struct vlanreq));
11444764Swpaul	ifr.ifr_data = (caddr_t)&vreq;
11544764Swpaul
11644764Swpaul	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
11744764Swpaul		err(1, "SIOCGETVLAN");
11844764Swpaul
11944764Swpaul	strncpy(vreq.vlr_parent, val, sizeof(vreq.vlr_parent));
12044764Swpaul	vreq.vlr_tag = __tag;
12144764Swpaul
12244764Swpaul	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
12344764Swpaul		err(1, "SIOCSETVLAN");
12444764Swpaul
12544764Swpaul	return;
12644764Swpaul}
12744764Swpaul
128138593Ssamstatic void
12995005Simpunsetvlandev(const char *val, int d, int s, const struct afswtch *afp)
13044764Swpaul{
13144764Swpaul	struct vlanreq		vreq;
13244764Swpaul
13344764Swpaul	bzero((char *)&vreq, sizeof(struct vlanreq));
13444764Swpaul	ifr.ifr_data = (caddr_t)&vreq;
13544764Swpaul
13644764Swpaul	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
13744764Swpaul		err(1, "SIOCGETVLAN");
13844764Swpaul
13944764Swpaul	bzero((char *)&vreq.vlr_parent, sizeof(vreq.vlr_parent));
14044764Swpaul	vreq.vlr_tag = 0;
14144764Swpaul
14244764Swpaul	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
14344764Swpaul		err(1, "SIOCSETVLAN");
14444764Swpaul
14544764Swpaul	return;
14644764Swpaul}
147138593Ssam
148138593Ssamstatic struct cmd vlan_cmds[] = {
149138593Ssam	DEF_CMD_ARG("vlan",				setvlantag),
150138593Ssam	DEF_CMD_ARG("vlandev",				setvlandev),
151138593Ssam	DEF_CMD_ARG("-vlandev",				unsetvlandev),
152138593Ssam	DEF_CMD("vlanmtu",	IFCAP_VLAN_MTU,		setifcap),
153138593Ssam	DEF_CMD("-vlanmtu",	-IFCAP_VLAN_MTU,	setifcap),
154138593Ssam	DEF_CMD("vlanhwtag",	IFCAP_VLAN_HWTAGGING,	setifcap),
155138593Ssam	DEF_CMD("-vlanhwtag",	-IFCAP_VLAN_HWTAGGING,	setifcap),
156138593Ssam};
157138593Ssamstatic struct afswtch af_vlan = {
158138593Ssam	.af_name	= "af_vlan",
159138593Ssam	.af_af		= AF_UNSPEC,
160138593Ssam	.af_status	= vlan_status,
161138593Ssam};
162138593Ssam
163138593Ssamstatic __constructor void
164138593Ssamvlan_ctor(void)
165138593Ssam{
166138593Ssam#define	N(a)	(sizeof(a) / sizeof(a[0]))
167138593Ssam	int i;
168138593Ssam
169138593Ssam	for (i = 0; i < N(vlan_cmds);  i++)
170138593Ssam		cmd_register(&vlan_cmds[i]);
171138593Ssam	af_register(&af_vlan);
172138593Ssam#undef N
173138593Ssam}
174