xref: /minix3/sbin/ifconfig/agr.c (revision 90b801219a391518dca4b04b17c88ad3b82b6ad9)
1*90b80121SDavid van Moolenbroek /*	$NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $	*/
2*90b80121SDavid van Moolenbroek 
3*90b80121SDavid van Moolenbroek /*-
4*90b80121SDavid van Moolenbroek  * Copyright (c)2005 YAMAMOTO Takashi,
5*90b80121SDavid van Moolenbroek  * All rights reserved.
6*90b80121SDavid van Moolenbroek  *
7*90b80121SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
8*90b80121SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
9*90b80121SDavid van Moolenbroek  * are met:
10*90b80121SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
11*90b80121SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
12*90b80121SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
13*90b80121SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
14*90b80121SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
15*90b80121SDavid van Moolenbroek  *
16*90b80121SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*90b80121SDavid van Moolenbroek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*90b80121SDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*90b80121SDavid van Moolenbroek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*90b80121SDavid van Moolenbroek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*90b80121SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*90b80121SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*90b80121SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*90b80121SDavid van Moolenbroek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*90b80121SDavid van Moolenbroek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*90b80121SDavid van Moolenbroek  * SUCH DAMAGE.
27*90b80121SDavid van Moolenbroek  */
28*90b80121SDavid van Moolenbroek 
29*90b80121SDavid van Moolenbroek #include <sys/cdefs.h>
30*90b80121SDavid van Moolenbroek #if !defined(lint)
31*90b80121SDavid van Moolenbroek __RCSID("$NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $");
32*90b80121SDavid van Moolenbroek #endif /* !defined(lint) */
33*90b80121SDavid van Moolenbroek 
34*90b80121SDavid van Moolenbroek #include <sys/param.h>
35*90b80121SDavid van Moolenbroek #include <sys/ioctl.h>
36*90b80121SDavid van Moolenbroek 
37*90b80121SDavid van Moolenbroek #include <net/if.h>
38*90b80121SDavid van Moolenbroek #include <net/agr/if_agrioctl.h>
39*90b80121SDavid van Moolenbroek 
40*90b80121SDavid van Moolenbroek #include <ctype.h>
41*90b80121SDavid van Moolenbroek #include <err.h>
42*90b80121SDavid van Moolenbroek #include <errno.h>
43*90b80121SDavid van Moolenbroek #include <string.h>
44*90b80121SDavid van Moolenbroek #include <stdio.h>
45*90b80121SDavid van Moolenbroek #include <stdlib.h>
46*90b80121SDavid van Moolenbroek #include <util.h>
47*90b80121SDavid van Moolenbroek 
48*90b80121SDavid van Moolenbroek #include "env.h"
49*90b80121SDavid van Moolenbroek #include "extern.h"
50*90b80121SDavid van Moolenbroek #include "parse.h"
51*90b80121SDavid van Moolenbroek #include "util.h"
52*90b80121SDavid van Moolenbroek 
53*90b80121SDavid van Moolenbroek static int agrsetport(prop_dictionary_t, prop_dictionary_t);
54*90b80121SDavid van Moolenbroek static void agr_constructor(void) __attribute__((constructor));
55*90b80121SDavid van Moolenbroek static int checkifname(prop_dictionary_t);
56*90b80121SDavid van Moolenbroek static void assertifname(prop_dictionary_t);
57*90b80121SDavid van Moolenbroek 
58*90b80121SDavid van Moolenbroek static struct piface agrif = PIFACE_INITIALIZER(&agrif, "agr interface",
59*90b80121SDavid van Moolenbroek     agrsetport, "agrport", &command_root.pb_parser);
60*90b80121SDavid van Moolenbroek 
61*90b80121SDavid van Moolenbroek static const struct kwinst agrkw[] = {
62*90b80121SDavid van Moolenbroek 	  {.k_word = "agrport", .k_type = KW_T_INT, .k_int = AGRCMD_ADDPORT,
63*90b80121SDavid van Moolenbroek 	   .k_nextparser = &agrif.pif_parser}
64*90b80121SDavid van Moolenbroek 	, {.k_word = "-agrport", .k_type = KW_T_INT, .k_int = AGRCMD_REMPORT,
65*90b80121SDavid van Moolenbroek 	   .k_nextparser = &agrif.pif_parser}
66*90b80121SDavid van Moolenbroek };
67*90b80121SDavid van Moolenbroek 
68*90b80121SDavid van Moolenbroek struct pkw agr = PKW_INITIALIZER(&agr, "agr", NULL, "agrcmd",
69*90b80121SDavid van Moolenbroek     agrkw, __arraycount(agrkw), NULL);
70*90b80121SDavid van Moolenbroek 
71*90b80121SDavid van Moolenbroek static int
checkifname(prop_dictionary_t env)72*90b80121SDavid van Moolenbroek checkifname(prop_dictionary_t env)
73*90b80121SDavid van Moolenbroek {
74*90b80121SDavid van Moolenbroek 	const char *ifname;
75*90b80121SDavid van Moolenbroek 
76*90b80121SDavid van Moolenbroek 	if ((ifname = getifname(env)) == NULL)
77*90b80121SDavid van Moolenbroek 		return 1;
78*90b80121SDavid van Moolenbroek 
79*90b80121SDavid van Moolenbroek 	return strncmp(ifname, "agr", 3) != 0 ||
80*90b80121SDavid van Moolenbroek 	    !isdigit((unsigned char)ifname[3]);
81*90b80121SDavid van Moolenbroek }
82*90b80121SDavid van Moolenbroek 
83*90b80121SDavid van Moolenbroek static void
assertifname(prop_dictionary_t env)84*90b80121SDavid van Moolenbroek assertifname(prop_dictionary_t env)
85*90b80121SDavid van Moolenbroek {
86*90b80121SDavid van Moolenbroek 	if (checkifname(env))
87*90b80121SDavid van Moolenbroek 		errx(EXIT_FAILURE, "valid only with agr(4) interfaces");
88*90b80121SDavid van Moolenbroek }
89*90b80121SDavid van Moolenbroek 
90*90b80121SDavid van Moolenbroek int
agrsetport(prop_dictionary_t env,prop_dictionary_t oenv)91*90b80121SDavid van Moolenbroek agrsetport(prop_dictionary_t env, prop_dictionary_t oenv)
92*90b80121SDavid van Moolenbroek {
93*90b80121SDavid van Moolenbroek 	char buf[IFNAMSIZ];
94*90b80121SDavid van Moolenbroek 	struct agrreq ar;
95*90b80121SDavid van Moolenbroek 	const char *port;
96*90b80121SDavid van Moolenbroek 	int64_t cmd;
97*90b80121SDavid van Moolenbroek 
98*90b80121SDavid van Moolenbroek 	if (!prop_dictionary_get_int64(env, "agrcmd", &cmd)) {
99*90b80121SDavid van Moolenbroek 		warnx("%s.%d", __func__, __LINE__);
100*90b80121SDavid van Moolenbroek 		errno = ENOENT;
101*90b80121SDavid van Moolenbroek 		return -1;
102*90b80121SDavid van Moolenbroek 	}
103*90b80121SDavid van Moolenbroek 
104*90b80121SDavid van Moolenbroek 	if (!prop_dictionary_get_cstring_nocopy(env, "agrport", &port)) {
105*90b80121SDavid van Moolenbroek 		warnx("%s.%d", __func__, __LINE__);
106*90b80121SDavid van Moolenbroek 		errno = ENOENT;
107*90b80121SDavid van Moolenbroek 		return -1;
108*90b80121SDavid van Moolenbroek 	}
109*90b80121SDavid van Moolenbroek 	strlcpy(buf, port, sizeof(buf));
110*90b80121SDavid van Moolenbroek 
111*90b80121SDavid van Moolenbroek 	assertifname(env);
112*90b80121SDavid van Moolenbroek 	memset(&ar, 0, sizeof(ar));
113*90b80121SDavid van Moolenbroek 	ar.ar_version = AGRREQ_VERSION;
114*90b80121SDavid van Moolenbroek 	ar.ar_cmd = cmd;
115*90b80121SDavid van Moolenbroek 	ar.ar_buf = buf;
116*90b80121SDavid van Moolenbroek 	ar.ar_buflen = strlen(buf);
117*90b80121SDavid van Moolenbroek 
118*90b80121SDavid van Moolenbroek 	if (indirect_ioctl(env, SIOCSETAGR, &ar) == -1)
119*90b80121SDavid van Moolenbroek 		err(EXIT_FAILURE, "SIOCSETAGR");
120*90b80121SDavid van Moolenbroek 	return 0;
121*90b80121SDavid van Moolenbroek }
122*90b80121SDavid van Moolenbroek 
123*90b80121SDavid van Moolenbroek static void
agr_status(prop_dictionary_t env,prop_dictionary_t oenv)124*90b80121SDavid van Moolenbroek agr_status(prop_dictionary_t env, prop_dictionary_t oenv)
125*90b80121SDavid van Moolenbroek {
126*90b80121SDavid van Moolenbroek 	struct agrreq ar;
127*90b80121SDavid van Moolenbroek 	void *buf = NULL;
128*90b80121SDavid van Moolenbroek 	size_t buflen = 0;
129*90b80121SDavid van Moolenbroek 	struct agrportlist *apl;
130*90b80121SDavid van Moolenbroek 	struct agrportinfo *api;
131*90b80121SDavid van Moolenbroek 	int i;
132*90b80121SDavid van Moolenbroek 
133*90b80121SDavid van Moolenbroek 	if (checkifname(env))
134*90b80121SDavid van Moolenbroek 		return;
135*90b80121SDavid van Moolenbroek 
136*90b80121SDavid van Moolenbroek again:
137*90b80121SDavid van Moolenbroek 	memset(&ar, 0, sizeof(ar));
138*90b80121SDavid van Moolenbroek 	ar.ar_version = AGRREQ_VERSION;
139*90b80121SDavid van Moolenbroek 	ar.ar_cmd = AGRCMD_PORTLIST;
140*90b80121SDavid van Moolenbroek 	ar.ar_buf = buf;
141*90b80121SDavid van Moolenbroek 	ar.ar_buflen = buflen;
142*90b80121SDavid van Moolenbroek 
143*90b80121SDavid van Moolenbroek 	if (indirect_ioctl(env, SIOCGETAGR, &ar) == -1) {
144*90b80121SDavid van Moolenbroek 		if (errno != E2BIG) {
145*90b80121SDavid van Moolenbroek 			warn("SIOCGETAGR");
146*90b80121SDavid van Moolenbroek 			return;
147*90b80121SDavid van Moolenbroek 		}
148*90b80121SDavid van Moolenbroek 
149*90b80121SDavid van Moolenbroek 		free(buf);
150*90b80121SDavid van Moolenbroek 		buf = NULL;
151*90b80121SDavid van Moolenbroek 		buflen = 0;
152*90b80121SDavid van Moolenbroek 		goto again;
153*90b80121SDavid van Moolenbroek 	}
154*90b80121SDavid van Moolenbroek 
155*90b80121SDavid van Moolenbroek 	if (buf == NULL) {
156*90b80121SDavid van Moolenbroek 		buflen = ar.ar_buflen;
157*90b80121SDavid van Moolenbroek 		buf = malloc(buflen);
158*90b80121SDavid van Moolenbroek 		if (buf == NULL) {
159*90b80121SDavid van Moolenbroek 			err(EXIT_FAILURE, "agr_status");
160*90b80121SDavid van Moolenbroek 		}
161*90b80121SDavid van Moolenbroek 		goto again;
162*90b80121SDavid van Moolenbroek 	}
163*90b80121SDavid van Moolenbroek 
164*90b80121SDavid van Moolenbroek 	apl = buf;
165*90b80121SDavid van Moolenbroek 	api = (void *)(apl + 1);
166*90b80121SDavid van Moolenbroek 
167*90b80121SDavid van Moolenbroek 	for (i = 0; i < apl->apl_nports; i++) {
168*90b80121SDavid van Moolenbroek 		char tmp[256];
169*90b80121SDavid van Moolenbroek 
170*90b80121SDavid van Moolenbroek 		snprintb(tmp, sizeof(tmp), AGRPORTINFO_BITS, api->api_flags);
171*90b80121SDavid van Moolenbroek 		printf("\tagrport: %s, flags=%s\n", api->api_ifname, tmp);
172*90b80121SDavid van Moolenbroek 		api++;
173*90b80121SDavid van Moolenbroek 	}
174*90b80121SDavid van Moolenbroek }
175*90b80121SDavid van Moolenbroek 
176*90b80121SDavid van Moolenbroek static status_func_t status;
177*90b80121SDavid van Moolenbroek static usage_func_t usage;
178*90b80121SDavid van Moolenbroek static cmdloop_branch_t branch;
179*90b80121SDavid van Moolenbroek 
180*90b80121SDavid van Moolenbroek static void
agr_usage(prop_dictionary_t env)181*90b80121SDavid van Moolenbroek agr_usage(prop_dictionary_t env)
182*90b80121SDavid van Moolenbroek {
183*90b80121SDavid van Moolenbroek 	fprintf(stderr, "\t[ agrport i ] [ -agrport i ]\n");
184*90b80121SDavid van Moolenbroek }
185*90b80121SDavid van Moolenbroek 
186*90b80121SDavid van Moolenbroek static void
agr_constructor(void)187*90b80121SDavid van Moolenbroek agr_constructor(void)
188*90b80121SDavid van Moolenbroek {
189*90b80121SDavid van Moolenbroek 	status_func_init(&status, agr_status);
190*90b80121SDavid van Moolenbroek 	usage_func_init(&usage, agr_usage);
191*90b80121SDavid van Moolenbroek 	register_status(&status);
192*90b80121SDavid van Moolenbroek 	register_usage(&usage);
193*90b80121SDavid van Moolenbroek 	cmdloop_branch_init(&branch, &agr.pk_parser);
194*90b80121SDavid van Moolenbroek 	register_cmdloop_branch(&branch);
195*90b80121SDavid van Moolenbroek }
196