1 /* $NetBSD: af_iso.c,v 1.12 2008/07/02 07:44:14 dyoung Exp $ */
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
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
32 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: af_iso.c,v 1.12 2008/07/02 07:44:14 dyoung Exp $");
45 #include <sys/param.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
52 #include <netiso/iso.h>
53 #include <netiso/iso_var.h>
58 #include "af_inetany.h"
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
;
90 fixnsel(struct sockaddr_iso
*siso
, uint8_t nsellength
)
92 siso
->siso_tlen
= nsellength
;
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
);
108 iso_commit_address(prop_dictionary_t env
, prop_dictionary_t oenv
)
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
)
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
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
);
150 setnsellength(prop_dictionary_t env
, prop_dictionary_t oenv
)
154 if ((af
= getaf(env
)) == -1 || af
!= AF_ISO
)
155 errx(EXIT_FAILURE
, "Setting NSEL length valid only for ISO");
162 iso_status(prop_dictionary_t env
, prop_dictionary_t oenv
, bool force
)
164 struct sockaddr_iso
*siso
;
165 struct iso_ifreq isoifr
;
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
)
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
) {
184 memset(&isoifr
.ifr_Addr
, 0, sizeof(isoifr
.ifr_Addr
));
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
));
195 warn("SIOCGIFNETMASK_ISO");
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
));
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
));
219 iso_constructor(void)
221 register_family(&isoaf
);
222 cmdloop_branch_init(&branch
, &iso
.pk_parser
);
223 register_cmdloop_branch(&branch
);