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