10d688beasomers/*
20d688beasomers * Copyright (c) 2017, Marie Helene Kvello-Aune
30d688beasomers * All rights reserved.
40d688beasomers *
50d688beasomers * Redistribution and use in source and binary forms, with or without modification,
60d688beasomers * are permitted provided that the following conditions are met:
70d688beasomers *
80d688beasomers * 1. Redistributions of source code must retain the above copyright notice,
90d688beasomers * thislist of conditions and the following disclaimer.
100d688beasomers *
110d688beasomers * 2. Redistributions in binary form must reproduce the above copyright notice,
120d688beasomers * this list of conditions and the following disclaimer in the documentation and/or
130d688beasomers * other materials provided with the distribution.
140d688beasomers *
150d688beasomers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
160d688beasomers * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
170d688beasomers * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
180d688beasomers * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
190d688beasomers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
200d688beasomers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
210d688beasomers * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
220d688beasomers * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
230d688beasomers * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
240d688beasomers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250d688beasomers *
260d688beasomers * $FreeBSD$
270d688beasomers */
280d688beasomers
290d688beasomers#include <err.h>
300d688beasomers#include <errno.h>
310d688beasomers#include <net/if.h>
320d688beasomers#include <sys/ioctl.h>
330d688beasomers#include <limits.h>
340d688beasomers#include <stdio.h>
350d688beasomers#include <stdlib.h>
360d688beasomers#include <string.h>
370d688beasomers#include <libifconfig.h>
380d688beasomers
390d688beasomers#include <net/if_vlan_var.h>
400d688beasomers
410d688beasomersint
420d688beasomersmain(int argc, char *argv[])
430d688beasomers{
440d688beasomers	char *ifname, *parentif;
450d688beasomers	unsigned short vlantag;
460d688beasomers	const char *errstr;
470d688beasomers	ifconfig_handle_t *lifh;
480d688beasomers
490d688beasomers	if (argc != 4) {
500d688beasomers		errx(EINVAL, "Invalid number of arguments."
510d688beasomers		    " Should provide exactly three arguments: "
520d688beasomers		    "INTERFACE, PARENT_INTERFACE and VLAN_TAG.");
530d688beasomers	}
540d688beasomers
550d688beasomers	/* We have a static number of arguments. Therefore we can do it simple. */
560d688beasomers	ifname = strdup(argv[1]);
570d688beasomers	parentif = strdup(argv[2]);
580d688beasomers	vlantag = strtonum(argv[3], 0, USHRT_MAX, &errstr);
590d688beasomers
600d688beasomers	if (errstr != NULL) {
610d688beasomers		errx(1, "VLAN_TAG must be between 0 and %i.\n", USHRT_MAX);
620d688beasomers	}
630d688beasomers
640d688beasomers	printf("Interface: %s\nNew VLAN tag: %i\n", ifname, vlantag);
650d688beasomers
660d688beasomers	lifh = ifconfig_open();
670d688beasomers	if (lifh == NULL) {
680d688beasomers		errx(ENOMEM, "Failed to open libifconfig handle.");
690d688beasomers		return (-1);
700d688beasomers	}
710d688beasomers
720d688beasomers	if (ifconfig_set_vlantag(lifh, ifname, parentif, vlantag) == 0) {
730d688beasomers		printf("Successfully changed vlan tag.\n");
740d688beasomers		ifconfig_close(lifh);
750d688beasomers		lifh = NULL;
760d688beasomers		free(ifname);
770d688beasomers		free(parentif);
780d688beasomers		return (0);
790d688beasomers	}
800d688beasomers
810d688beasomers	switch (ifconfig_err_errtype(lifh)) {
820d688beasomers	case SOCKET:
830d688beasomers		warnx("couldn't create socket. This shouldn't happen.\n");
840d688beasomers		break;
850d688beasomers	case IOCTL:
860d688beasomers		if (ifconfig_err_ioctlreq(lifh) == SIOCGETVLAN) {
870d688beasomers			warnx("Target interface isn't a VLAN interface.\n");
880d688beasomers		}
890d688beasomers		if (ifconfig_err_ioctlreq(lifh) == SIOCSETVLAN) {
900d688beasomers			warnx(
910d688beasomers				"Couldn't change VLAN properties of interface.\n");
920d688beasomers		}
930d688beasomers		break;
940d688beasomers	default:
950d688beasomers		warnx(
960d688beasomers			"This is a thorough example accommodating for temporary"
970d688beasomers			" 'not implemented yet' errors. That's likely what happened"
980d688beasomers			" now. If not, your guess is as good as mine. ;)"
990d688beasomers			" Error code: %d\n", ifconfig_err_errno(
1000d688beasomers				lifh));
1010d688beasomers		break;
1020d688beasomers	}
1030d688beasomers
1040d688beasomers	ifconfig_close(lifh);
1050d688beasomers	lifh = NULL;
1060d688beasomers	free(ifname);
1070d688beasomers	free(parentif);
1080d688beasomers	return (-1);
1090d688beasomers}
110