agr.c revision 1.10
1/* $NetBSD: agr.c,v 1.10 2008/05/07 23:55:06 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.10 2008/05/07 23:55:06 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 const struct kwinst agrkw[] = { 58 {.k_word = "agrport", .k_type = KW_T_NUM, .k_neg = true, 59 .k_num = AGRCMD_ADDPORT, .k_negnum = AGRCMD_REMPORT, 60 .k_exec = agrsetport} 61}; 62 63struct pkw agr = PKW_INITIALIZER(&agr, "agr", NULL, NULL, 64 agrkw, __arraycount(agrkw), NULL); 65 66static int 67checkifname(prop_dictionary_t env) 68{ 69 const char *ifname; 70 71 if ((ifname = getifname(env)) == NULL) 72 return 1; 73 74 return strncmp(ifname, "agr", 3) != 0 || 75 !isdigit((unsigned char)ifname[3]); 76} 77 78static void 79assertifname(prop_dictionary_t env) 80{ 81 if (checkifname(env)) 82 errx(EXIT_FAILURE, "valid only with agr(4) interfaces"); 83} 84 85int 86agrsetport(prop_dictionary_t env, prop_dictionary_t xenv) 87{ 88 char buf[IFNAMSIZ]; 89 struct agrreq ar; 90 const char *port; 91 int64_t cmd; 92 93 if (!prop_dictionary_get_int64(env, "agrcmd", &cmd)) { 94 warnx("%s.%d", __func__, __LINE__); 95 errno = ENOENT; 96 return -1; 97 } 98 99 if (!prop_dictionary_get_cstring_nocopy(env, "agrport", &port)) { 100 warnx("%s.%d", __func__, __LINE__); 101 errno = ENOENT; 102 return -1; 103 } 104 strlcpy(buf, port, sizeof(buf)); 105 106 assertifname(env); 107 memset(&ar, 0, sizeof(ar)); 108 ar.ar_version = AGRREQ_VERSION; 109 ar.ar_cmd = cmd; 110 ar.ar_buf = buf; 111 ar.ar_buflen = strlen(buf); 112 113 if (indirect_ioctl(env, SIOCSETAGR, &ar) == -1) 114 err(EXIT_FAILURE, "SIOCSETAGR"); 115 return 0; 116} 117 118void 119agr_status(prop_dictionary_t env, prop_dictionary_t oenv) 120{ 121 struct agrreq ar; 122 void *buf = NULL; 123 size_t buflen = 0; 124 struct agrportlist *apl; 125 struct agrportinfo *api; 126 int i; 127 128 if (checkifname(env)) 129 return; 130 131again: 132 memset(&ar, 0, sizeof(ar)); 133 ar.ar_version = AGRREQ_VERSION; 134 ar.ar_cmd = AGRCMD_PORTLIST; 135 ar.ar_buf = buf; 136 ar.ar_buflen = buflen; 137 138 if (indirect_ioctl(env, SIOCGETAGR, &ar) == -1) { 139 if (errno != E2BIG) { 140 warn("SIOCGETAGR"); 141 return; 142 } 143 144 free(buf); 145 buf = NULL; 146 buflen = 0; 147 goto again; 148 } 149 150 if (buf == NULL) { 151 buflen = ar.ar_buflen; 152 buf = malloc(buflen); 153 if (buf == NULL) { 154 err(EXIT_FAILURE, "agr_status"); 155 } 156 goto again; 157 } 158 159 apl = buf; 160 api = (void *)(apl + 1); 161 162 for (i = 0; i < apl->apl_nports; i++) { 163 char tmp[256]; 164 165 snprintb(tmp, sizeof(tmp), AGRPORTINFO_BITS, api->api_flags); 166 printf("\tagrport: %s, flags=%s\n", api->api_ifname, tmp); 167 api++; 168 } 169} 170