Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / sbin / ifconfig / af_iso.c
blob5b2926c2330d39ec43094a254adfaf46d3307f28
1 /* $NetBSD: af_iso.c,v 1.12 2008/07/02 07:44:14 dyoung Exp $ */
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
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 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __RCSID("$NetBSD: af_iso.c,v 1.12 2008/07/02 07:44:14 dyoung Exp $");
35 #endif /* not lint */
37 #include <err.h>
38 #include <errno.h>
39 #include <string.h>
40 #include <stddef.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <util.h>
45 #include <sys/param.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
49 #include <net/if.h>
51 #define EON
52 #include <netiso/iso.h>
53 #include <netiso/iso_var.h>
55 #include "env.h"
56 #include "parse.h"
57 #include "extern.h"
58 #include "af_inetany.h"
60 #define DEFNSELLEN 1
62 static void iso_constructor(void) __attribute__((constructor));
63 static int setnsellength(prop_dictionary_t, prop_dictionary_t);
64 static void iso_status(prop_dictionary_t, prop_dictionary_t, bool);
65 static void iso_commit_address(prop_dictionary_t, prop_dictionary_t);
67 static struct afswtch isoaf = {
68 .af_name = "iso", .af_af = AF_ISO, .af_status = iso_status,
69 .af_addr_commit = iso_commit_address
72 struct pinteger parse_snpaoffset = PINTEGER_INITIALIZER1(&snpaoffset,
73 "snpaoffset", INT_MIN, INT_MAX, 10, NULL, "snpaoffset",
74 &command_root.pb_parser);
75 struct pinteger parse_nsellength = PINTEGER_INITIALIZER1(&nsellength,
76 "nsellength", 0, UINT8_MAX, 10, setnsellength, "nsellength",
77 &command_root.pb_parser);
79 static const struct kwinst isokw[] = {
80 {.k_word = "nsellength", .k_nextparser = &parse_nsellength.pi_parser}
81 , {.k_word = "snpaoffset", .k_nextparser = &parse_snpaoffset.pi_parser}
84 struct pkw iso = PKW_INITIALIZER(&iso, "ISO", NULL, NULL,
85 isokw, __arraycount(isokw), NULL);
87 static cmdloop_branch_t branch;
89 static void
90 fixnsel(struct sockaddr_iso *siso, uint8_t nsellength)
92 siso->siso_tlen = nsellength;
95 /* fixup mask */
96 static int
97 iso_pre_aifaddr(prop_dictionary_t env, const struct afparam *param)
99 struct sockaddr_iso *siso;
101 siso = param->mask.buf;
102 siso->siso_len = TSEL(siso) - (char *)(siso);
103 siso->siso_nlen = 0;
104 return 0;
107 static void
108 iso_commit_address(prop_dictionary_t env, prop_dictionary_t oenv)
110 uint8_t nsellength;
111 struct iso_ifreq ifr = {.ifr_Addr = {.siso_tlen = DEFNSELLEN}};
112 struct iso_aliasreq ifra = {
113 .ifra_dstaddr = {.siso_tlen = DEFNSELLEN},
114 .ifra_addr = {.siso_tlen = DEFNSELLEN}
116 struct afparam isoparam = {
117 .req = BUFPARAM(ifra)
118 , .dgreq = BUFPARAM(ifr)
119 , .name = {
120 {.buf = ifr.ifr_name,
121 .buflen = sizeof(ifr.ifr_name)}
122 , {.buf = ifra.ifra_name,
123 .buflen = sizeof(ifra.ifra_name)}
125 , .dgaddr = BUFPARAM(ifr.ifr_Addr)
126 , .addr = BUFPARAM(ifra.ifra_addr)
127 , .dst = BUFPARAM(ifra.ifra_dstaddr)
128 , .brd = BUFPARAM(ifra.ifra_broadaddr)
129 , .mask = BUFPARAM(ifra.ifra_mask)
130 , .aifaddr = IFADDR_PARAM(SIOCAIFADDR_ISO)
131 , .difaddr = IFADDR_PARAM(SIOCDIFADDR_ISO)
132 , .gifaddr = IFADDR_PARAM(SIOCGIFADDR_ISO)
133 , .defmask = {.buf = NULL, .buflen = 0}
134 , .pre_aifaddr = iso_pre_aifaddr
136 int64_t snpaoffset;
138 if (prop_dictionary_get_int64(env, "snpaoffset", &snpaoffset))
139 ifra.ifra_snpaoffset = snpaoffset;
141 if (prop_dictionary_get_uint8(env, "nsellength", &nsellength)) {
142 fixnsel(&ifr.ifr_Addr, nsellength);
143 fixnsel(&ifra.ifra_addr, nsellength);
144 fixnsel(&ifra.ifra_dstaddr, nsellength);
146 commit_address(env, oenv, &isoparam);
149 static int
150 setnsellength(prop_dictionary_t env, prop_dictionary_t oenv)
152 int af;
154 if ((af = getaf(env)) == -1 || af != AF_ISO)
155 errx(EXIT_FAILURE, "Setting NSEL length valid only for ISO");
157 return 0;
161 static void
162 iso_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
164 struct sockaddr_iso *siso;
165 struct iso_ifreq isoifr;
166 int s;
167 const char *ifname;
168 unsigned short flags;
170 if ((ifname = getifinfo(env, oenv, &flags)) == NULL)
171 err(EXIT_FAILURE, "%s: getifinfo", __func__);
173 if ((s = getsock(AF_ISO)) == -1) {
174 if (errno == EAFNOSUPPORT)
175 return;
176 err(EXIT_FAILURE, "socket");
178 memset(&isoifr, 0, sizeof(isoifr));
179 estrlcpy(isoifr.ifr_name, ifname, sizeof(isoifr.ifr_name));
180 if (ioctl(s, SIOCGIFADDR_ISO, &isoifr) == -1) {
181 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
182 if (!force)
183 return;
184 memset(&isoifr.ifr_Addr, 0, sizeof(isoifr.ifr_Addr));
185 } else
186 warn("SIOCGIFADDR_ISO");
188 strlcpy(isoifr.ifr_name, ifname, sizeof(isoifr.ifr_name));
189 siso = &isoifr.ifr_Addr;
190 printf("\tiso %s", iso_ntoa(&siso->siso_addr));
191 if (ioctl(s, SIOCGIFNETMASK_ISO, &isoifr) == -1) {
192 if (errno == EADDRNOTAVAIL)
193 memset(&isoifr.ifr_Addr, 0, sizeof(isoifr.ifr_Addr));
194 else
195 warn("SIOCGIFNETMASK_ISO");
196 } else {
197 if (siso->siso_len > offsetof(struct sockaddr_iso, siso_addr))
198 siso->siso_addr.isoa_len = siso->siso_len
199 - offsetof(struct sockaddr_iso, siso_addr);
200 printf(" netmask %s", iso_ntoa(&siso->siso_addr));
203 if (flags & IFF_POINTOPOINT) {
204 if (ioctl(s, SIOCGIFDSTADDR_ISO, &isoifr) == -1) {
205 if (errno == EADDRNOTAVAIL)
206 memset(&isoifr.ifr_Addr, 0,
207 sizeof(isoifr.ifr_Addr));
208 else
209 warn("SIOCGIFDSTADDR_ISO");
211 strlcpy(isoifr.ifr_name, ifname, sizeof(isoifr.ifr_name));
212 siso = &isoifr.ifr_Addr;
213 printf(" --> %s", iso_ntoa(&siso->siso_addr));
215 printf("\n");
218 static void
219 iso_constructor(void)
221 register_family(&isoaf);
222 cmdloop_branch_init(&branch, &iso.pk_parser);
223 register_cmdloop_branch(&branch);