if_ieee1394subr.c revision 1.1 1 1.1 onoe /* $NetBSD: if_ieee1394subr.c,v 1.1 2000/11/05 17:17:15 onoe Exp $ */
2 1.1 onoe
3 1.1 onoe /*
4 1.1 onoe * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.1 onoe * All rights reserved.
6 1.1 onoe *
7 1.1 onoe * This code is derived from software contributed to The NetBSD Foundation
8 1.1 onoe * by Atsushi Onoe.
9 1.1 onoe *
10 1.1 onoe * Redistribution and use in source and binary forms, with or without
11 1.1 onoe * modification, are permitted provided that the following conditions
12 1.1 onoe * are met:
13 1.1 onoe * 1. Redistributions of source code must retain the above copyright
14 1.1 onoe * notice, this list of conditions and the following disclaimer.
15 1.1 onoe * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 onoe * notice, this list of conditions and the following disclaimer in the
17 1.1 onoe * documentation and/or other materials provided with the distribution.
18 1.1 onoe * 3. All advertising materials mentioning features or use of this software
19 1.1 onoe * must display the following acknowledgement:
20 1.1 onoe * This product includes software developed by the NetBSD
21 1.1 onoe * Foundation, Inc. and its contributors.
22 1.1 onoe * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 onoe * contributors may be used to endorse or promote products derived
24 1.1 onoe * from this software without specific prior written permission.
25 1.1 onoe *
26 1.1 onoe * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 onoe * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 onoe * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 onoe * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 onoe * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 onoe * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 onoe * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 onoe * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 onoe * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 onoe * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 onoe * POSSIBILITY OF SUCH DAMAGE.
37 1.1 onoe */
38 1.1 onoe
39 1.1 onoe #include "opt_inet.h"
40 1.1 onoe #include "bpfilter.h"
41 1.1 onoe
42 1.1 onoe #include <sys/param.h>
43 1.1 onoe #include <sys/systm.h>
44 1.1 onoe #include <sys/types.h>
45 1.1 onoe #include <sys/socket.h>
46 1.1 onoe #include <sys/sockio.h>
47 1.1 onoe #include <sys/kernel.h>
48 1.1 onoe #include <sys/mbuf.h>
49 1.1 onoe #include <sys/device.h>
50 1.1 onoe
51 1.1 onoe #include <net/if.h>
52 1.1 onoe #include <net/if_dl.h>
53 1.1 onoe #include <net/if_ieee1394.h>
54 1.1 onoe #include <net/if_types.h>
55 1.1 onoe #include <net/if_media.h>
56 1.1 onoe #include <net/ethertypes.h>
57 1.1 onoe #include <net/netisr.h>
58 1.1 onoe #include <net/route.h>
59 1.1 onoe
60 1.1 onoe #if NBPFILTER > 0
61 1.1 onoe #include <net/bpf.h>
62 1.1 onoe #endif
63 1.1 onoe
64 1.1 onoe #ifdef INET
65 1.1 onoe #include <netinet/in.h>
66 1.1 onoe #include <netinet/in_var.h>
67 1.1 onoe #include <netinet/if_ieee1394arp.h>
68 1.1 onoe #endif /* INET */
69 1.1 onoe #ifdef INET6
70 1.1 onoe #include <netinet/in.h>
71 1.1 onoe #include <netinet6/in6_var.h>
72 1.1 onoe #include <netinet6/nd6.h>
73 1.1 onoe #endif /* INET6 */
74 1.1 onoe
75 1.1 onoe #define senderr(e) do { error = (e); goto bad; } while(0/*CONSTCOND*/)
76 1.1 onoe
77 1.1 onoe static int ieee1394_output(struct ifnet *, struct mbuf *, struct sockaddr *,
78 1.1 onoe struct rtentry *);
79 1.1 onoe static void ieee1394_input(struct ifnet *, struct mbuf *);
80 1.1 onoe
81 1.1 onoe static int
82 1.1 onoe ieee1394_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
83 1.1 onoe struct rtentry *rt0)
84 1.1 onoe {
85 1.1 onoe u_int16_t etype = 0;
86 1.1 onoe int s, hdrlen, maxrec, len, off, tlen, error = 0;
87 1.1 onoe struct mbuf *m = m0, **mp;
88 1.1 onoe struct rtentry *rt;
89 1.1 onoe struct mbuf *mcopy = NULL;
90 1.1 onoe struct ieee1394com *ic = (struct ieee1394com *)ifp;
91 1.1 onoe #ifdef INET
92 1.1 onoe struct ieee1394_arphdr *ah;
93 1.1 onoe #endif /* INET */
94 1.1 onoe struct ieee1394_unfraghdr *iuh;
95 1.1 onoe struct ieee1394_fraghdr *ifh;
96 1.1 onoe struct ieee1394_hwaddr hwdst;
97 1.1 onoe
98 1.1 onoe if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
99 1.1 onoe senderr(ENETDOWN);
100 1.1 onoe ifp->if_lastchange = time;
101 1.1 onoe if ((rt = rt0) != NULL) {
102 1.1 onoe if ((rt->rt_flags & RTF_UP) == 0) {
103 1.1 onoe if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
104 1.1 onoe rt->rt_refcnt--;
105 1.1 onoe if (rt->rt_ifp != ifp)
106 1.1 onoe return (*rt->rt_ifp->if_output)
107 1.1 onoe (ifp, m0, dst, rt);
108 1.1 onoe } else
109 1.1 onoe senderr(EHOSTUNREACH);
110 1.1 onoe }
111 1.1 onoe if (rt->rt_flags & RTF_GATEWAY) {
112 1.1 onoe if (rt->rt_gwroute == 0)
113 1.1 onoe goto lookup;
114 1.1 onoe if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
115 1.1 onoe rtfree(rt);
116 1.1 onoe rt = rt0;
117 1.1 onoe lookup:
118 1.1 onoe rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
119 1.1 onoe if ((rt = rt->rt_gwroute) == 0)
120 1.1 onoe senderr(EHOSTUNREACH);
121 1.1 onoe /* the "G" test below also prevents rt == rt0 */
122 1.1 onoe if ((rt->rt_flags & RTF_GATEWAY) ||
123 1.1 onoe (rt->rt_ifp != ifp)) {
124 1.1 onoe rt->rt_refcnt--;
125 1.1 onoe rt0->rt_gwroute = 0;
126 1.1 onoe senderr(EHOSTUNREACH);
127 1.1 onoe }
128 1.1 onoe }
129 1.1 onoe }
130 1.1 onoe if (rt->rt_flags & RTF_REJECT)
131 1.1 onoe if (rt->rt_rmx.rmx_expire == 0 ||
132 1.1 onoe time.tv_sec < rt->rt_rmx.rmx_expire)
133 1.1 onoe senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
134 1.1 onoe }
135 1.1 onoe switch (dst->sa_family) {
136 1.1 onoe #ifdef INET
137 1.1 onoe case AF_INET:
138 1.1 onoe if (m->m_flags & (M_BCAST|M_MCAST))
139 1.1 onoe memcpy(&hwdst, ifp->if_broadcastaddr, sizeof(hwdst));
140 1.1 onoe else if (!ieee1394arpresolve(ifp, rt, m, dst, &hwdst))
141 1.1 onoe return 0; /* if not yet resolved */
142 1.1 onoe /* if broadcasting on a simplex interface, loopback a copy */
143 1.1 onoe if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
144 1.1 onoe mcopy = m_copy(m, 0, (int)M_COPYALL);
145 1.1 onoe etype = htons(ETHERTYPE_IP);
146 1.1 onoe break;
147 1.1 onoe
148 1.1 onoe case AF_ARP:
149 1.1 onoe ah = mtod(m, struct ieee1394_arphdr *);
150 1.1 onoe memcpy(&hwdst, ifp->if_broadcastaddr, sizeof(hwdst));
151 1.1 onoe etype = htons(ETHERTYPE_ARP);
152 1.1 onoe break;
153 1.1 onoe #endif /* INET */
154 1.1 onoe #ifdef INET6
155 1.1 onoe case AF_INET6:
156 1.1 onoe if (m->m_flags & M_MCAST)
157 1.1 onoe memcpy(&hwdst, ifp->if_broadcastaddr, sizeof(hwdst));
158 1.1 onoe else if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)&hwdst)) {
159 1.1 onoe /* this must be impossible, so we bark */
160 1.1 onoe printf("ieee1394_output: nd6_storelladdr failed\n");
161 1.1 onoe return 0;
162 1.1 onoe }
163 1.1 onoe etype = htons(ETHERTYPE_IPV6);
164 1.1 onoe break;
165 1.1 onoe #endif /* INET6 */
166 1.1 onoe
167 1.1 onoe case pseudo_AF_HDRCMPLT:
168 1.1 onoe case AF_UNSPEC:
169 1.1 onoe /* TODO? */
170 1.1 onoe default:
171 1.1 onoe printf("%s: can't handle af%d\n", ifp->if_xname,
172 1.1 onoe dst->sa_family);
173 1.1 onoe senderr(EAFNOSUPPORT);
174 1.1 onoe break;
175 1.1 onoe }
176 1.1 onoe
177 1.1 onoe if (mcopy)
178 1.1 onoe looutput(ifp, mcopy, dst, rt);
179 1.1 onoe #if NBPFILTER > 0
180 1.1 onoe if (ifp->if_bpf) {
181 1.1 onoe struct mbuf mb;
182 1.1 onoe
183 1.1 onoe mb.m_next = m;
184 1.1 onoe mb.m_len = 14;
185 1.1 onoe mb.m_data = mb.m_dat;
186 1.1 onoe ((u_int32_t *)mb.m_data)[0] = 0;
187 1.1 onoe ((u_int32_t *)mb.m_data)[1] = 0;
188 1.1 onoe ((u_int32_t *)mb.m_data)[2] = 0;
189 1.1 onoe ((u_int16_t *)mb.m_data)[6] = etype;
190 1.1 onoe bpf_mtap(ifp->if_bpf, &mb);
191 1.1 onoe }
192 1.1 onoe #endif
193 1.1 onoe
194 1.1 onoe /* determine fragmented or not */
195 1.1 onoe maxrec = 1 << (hwdst.iha_maxrec + 1);
196 1.1 onoe if (m->m_flags & (M_BCAST|M_MCAST))
197 1.1 onoe hdrlen = IEEE1394_STRHDRLEN + sizeof(*iuh);
198 1.1 onoe else
199 1.1 onoe hdrlen = IEEE1394_AWBHDRLEN + sizeof(*iuh);
200 1.1 onoe if (m->m_pkthdr.len < maxrec - hdrlen) {
201 1.1 onoe M_PREPEND(m, sizeof(hwdst) + sizeof(*iuh), M_DONTWAIT);
202 1.1 onoe if (m == 0)
203 1.1 onoe senderr(ENOBUFS);
204 1.1 onoe memcpy(mtod(m, caddr_t), &hwdst, sizeof(hwdst));
205 1.1 onoe iuh = (struct ieee1394_unfraghdr *)
206 1.1 onoe (mtod(m, caddr_t) + sizeof(hwdst));
207 1.1 onoe iuh->iuh_ft = 0;
208 1.1 onoe iuh->iuh_etype = etype;
209 1.1 onoe
210 1.1 onoe s = splimp();
211 1.1 onoe if (IF_QFULL(&ifp->if_snd)) {
212 1.1 onoe IF_DROP(&ifp->if_snd);
213 1.1 onoe splx(s);
214 1.1 onoe senderr(ENOBUFS);
215 1.1 onoe }
216 1.1 onoe IF_ENQUEUE(&ifp->if_snd, m);
217 1.1 onoe ifp->if_obytes += m0->m_pkthdr.len;
218 1.1 onoe goto done;
219 1.1 onoe }
220 1.1 onoe printf("ieee1304_output: fragment packet\n");
221 1.1 onoe hdrlen += sizeof(*ifh) - sizeof(*iuh);
222 1.1 onoe len = maxrec - hdrlen;
223 1.1 onoe off = len;
224 1.1 onoe mp = &m0->m_nextpkt;
225 1.1 onoe while (off < m0->m_pkthdr.len) {
226 1.1 onoe MGETHDR(m, M_DONTWAIT, MT_HEADER);
227 1.1 onoe if (m == NULL)
228 1.1 onoe senderr(ENOBUFS);
229 1.1 onoe m->m_flags |= m0->m_flags & (M_BCAST|M_MCAST);
230 1.1 onoe tlen = len;
231 1.1 onoe if (tlen > m0->m_pkthdr.len - off)
232 1.1 onoe tlen = m0->m_pkthdr.len - off;
233 1.1 onoe m->m_data += hdrlen - sizeof(hwdst);
234 1.1 onoe m->m_len = sizeof(hwdst) + sizeof(*ifh);
235 1.1 onoe memcpy(mtod(m, caddr_t), &hwdst, sizeof(hwdst));
236 1.1 onoe ifh = (struct ieee1394_fraghdr *)
237 1.1 onoe (mtod(m, caddr_t) + sizeof(hwdst));
238 1.1 onoe ifh->ifh_ft_size = htons(0xc000 | tlen);
239 1.1 onoe ifh->ifh_etype_off = htons(off);
240 1.1 onoe ifh->ifh_dgl = htons(ic->ic_dgl);
241 1.1 onoe ifh->ifh_reserved = 0;
242 1.1 onoe m->m_next = m_copy(m0, off, tlen);
243 1.1 onoe if (m->m_next == NULL)
244 1.1 onoe senderr(ENOBUFS);
245 1.1 onoe off += tlen;
246 1.1 onoe *mp = m;
247 1.1 onoe mp = &m->m_nextpkt;
248 1.1 onoe }
249 1.1 onoe ifh->ifh_ft_size &= ~htons(0x4000); /* note last fragment */
250 1.1 onoe
251 1.1 onoe /* first fragment */
252 1.1 onoe m = m0;
253 1.1 onoe M_PREPEND(m, sizeof(hwdst) + sizeof(*ifh), M_DONTWAIT);
254 1.1 onoe memcpy(mtod(m, caddr_t), &hwdst, sizeof(hwdst));
255 1.1 onoe ifh = (struct ieee1394_fraghdr *)(mtod(m, caddr_t) + sizeof(hwdst));
256 1.1 onoe ifh->ifh_ft_size = htons(0x4000 | (maxrec - hdrlen));
257 1.1 onoe ifh->ifh_etype_off = etype;
258 1.1 onoe ifh->ifh_dgl = htons(ic->ic_dgl++);
259 1.1 onoe ifh->ifh_reserved = 0;
260 1.1 onoe
261 1.1 onoe /* send off */
262 1.1 onoe
263 1.1 onoe s = splimp();
264 1.1 onoe if (IF_QFULL(&ifp->if_snd)) {
265 1.1 onoe IF_DROP(&ifp->if_snd);
266 1.1 onoe splx(s);
267 1.1 onoe senderr(ENOBUFS);
268 1.1 onoe }
269 1.1 onoe while (m0 != NULL) {
270 1.1 onoe m = m0->m_nextpkt;
271 1.1 onoe m0->m_nextpkt = NULL;
272 1.1 onoe IF_ENQUEUE(&ifp->if_snd, m0);
273 1.1 onoe ifp->if_obytes += m0->m_pkthdr.len;
274 1.1 onoe m0 = m;
275 1.1 onoe }
276 1.1 onoe
277 1.1 onoe done:
278 1.1 onoe if (m0->m_flags & M_MCAST)
279 1.1 onoe ifp->if_omcasts++;
280 1.1 onoe if ((ifp->if_flags & IFF_OACTIVE) == 0)
281 1.1 onoe (*ifp->if_start)(ifp);
282 1.1 onoe splx(s);
283 1.1 onoe return error;
284 1.1 onoe
285 1.1 onoe bad:
286 1.1 onoe while (m0 != NULL) {
287 1.1 onoe m = m0->m_nextpkt;
288 1.1 onoe m_freem(m0);
289 1.1 onoe m0 = m;
290 1.1 onoe }
291 1.1 onoe
292 1.1 onoe return error;
293 1.1 onoe }
294 1.1 onoe
295 1.1 onoe static void
296 1.1 onoe ieee1394_input(struct ifnet *ifp, struct mbuf *m)
297 1.1 onoe {
298 1.1 onoe struct ifqueue *inq;
299 1.1 onoe u_int16_t etype;
300 1.1 onoe int s;
301 1.1 onoe struct ieee1394_unfraghdr *iuh;
302 1.1 onoe
303 1.1 onoe if ((ifp->if_flags & IFF_UP) == 0) {
304 1.1 onoe m_freem(m);
305 1.1 onoe return;
306 1.1 onoe }
307 1.1 onoe
308 1.1 onoe iuh = mtod(m, struct ieee1394_unfraghdr *);
309 1.1 onoe if (iuh->iuh_ft != 0) {
310 1.1 onoe printf("%s: ieee1394_input: fragment not implemented yet\n",
311 1.1 onoe ifp->if_xname);
312 1.1 onoe m_freem(m);
313 1.1 onoe return;
314 1.1 onoe }
315 1.1 onoe etype = ntohs(iuh->iuh_etype);
316 1.1 onoe
317 1.1 onoe /* strip off the ieee1394 header */
318 1.1 onoe m_adj(m, sizeof(struct ieee1394_unfraghdr));
319 1.1 onoe #if NBPFILTER > 0
320 1.1 onoe if (ifp->if_bpf) {
321 1.1 onoe struct mbuf mb;
322 1.1 onoe
323 1.1 onoe mb.m_next = m;
324 1.1 onoe mb.m_len = 14;
325 1.1 onoe mb.m_data = mb.m_dat;
326 1.1 onoe ((u_int32_t *)mb.m_data)[0] = 0;
327 1.1 onoe ((u_int32_t *)mb.m_data)[1] = 0;
328 1.1 onoe ((u_int32_t *)mb.m_data)[2] = 0;
329 1.1 onoe ((u_int16_t *)mb.m_data)[6] = iuh->iuh_etype;
330 1.1 onoe bpf_mtap(ifp->if_bpf, &mb);
331 1.1 onoe }
332 1.1 onoe #endif
333 1.1 onoe
334 1.1 onoe switch (etype) {
335 1.1 onoe #ifdef INET
336 1.1 onoe case ETHERTYPE_IP:
337 1.1 onoe schednetisr(NETISR_IP);
338 1.1 onoe inq = &ipintrq;
339 1.1 onoe break;
340 1.1 onoe
341 1.1 onoe case ETHERTYPE_ARP:
342 1.1 onoe in_ieee1394arpinput(m);
343 1.1 onoe return;
344 1.1 onoe #endif /* INET */
345 1.1 onoe
346 1.1 onoe #ifdef INET6
347 1.1 onoe case ETHERTYPE_IPV6:
348 1.1 onoe schednetisr(NETISR_IPV6);
349 1.1 onoe inq = &ip6intrq;
350 1.1 onoe break;
351 1.1 onoe #endif /* INET6 */
352 1.1 onoe
353 1.1 onoe default:
354 1.1 onoe m_freem(m);
355 1.1 onoe return;
356 1.1 onoe }
357 1.1 onoe
358 1.1 onoe s = splimp();
359 1.1 onoe if (IF_QFULL(inq)) {
360 1.1 onoe IF_DROP(inq);
361 1.1 onoe m_freem(m);
362 1.1 onoe } else
363 1.1 onoe IF_ENQUEUE(inq, m);
364 1.1 onoe splx(s);
365 1.1 onoe }
366 1.1 onoe
367 1.1 onoe const char *
368 1.1 onoe ieee1394_sprintf(const u_int8_t *laddr)
369 1.1 onoe {
370 1.1 onoe static char buf[3*8];
371 1.1 onoe
372 1.1 onoe snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
373 1.1 onoe laddr[0], laddr[1], laddr[2], laddr[3],
374 1.1 onoe laddr[4], laddr[5], laddr[6], laddr[7]);
375 1.1 onoe return buf;
376 1.1 onoe }
377 1.1 onoe
378 1.1 onoe void
379 1.1 onoe ieee1394_ifattach(struct ifnet *ifp, const struct ieee1394_hwaddr *hwaddr)
380 1.1 onoe {
381 1.1 onoe struct sockaddr_dl *sdl;
382 1.1 onoe
383 1.1 onoe ifp->if_type = IFT_IEEE1394;
384 1.1 onoe ifp->if_addrlen = sizeof(struct ieee1394_hwaddr);
385 1.1 onoe ifp->if_hdrlen = sizeof(struct ieee1394_header);
386 1.1 onoe ifp->if_mtu = IEEE1394MTU;
387 1.1 onoe ifp->if_output = ieee1394_output;
388 1.1 onoe ifp->if_input = ieee1394_input;
389 1.1 onoe if (ifp->if_baudrate == 0)
390 1.1 onoe ifp->if_baudrate = IF_Mbps(100);
391 1.1 onoe if ((sdl = ifp->if_sadl) && sdl->sdl_family == AF_LINK) {
392 1.1 onoe sdl->sdl_type = ifp->if_type;
393 1.1 onoe sdl->sdl_alen = ifp->if_addrlen;
394 1.1 onoe memcpy(LLADDR(sdl), hwaddr, ifp->if_addrlen);
395 1.1 onoe }
396 1.1 onoe ifp->if_broadcastaddr = malloc(ifp->if_addrlen, M_DEVBUF, M_WAITOK);
397 1.1 onoe memcpy(ifp->if_broadcastaddr, hwaddr, ifp->if_addrlen);
398 1.1 onoe memset(ifp->if_broadcastaddr, 0xff, IEEE1394_ADDR_LEN);
399 1.1 onoe }
400 1.1 onoe
401 1.1 onoe void
402 1.1 onoe ieee1394_ifdetach(struct ifnet *ifp)
403 1.1 onoe {
404 1.1 onoe struct sockaddr_dl *sdl = ifp->if_sadl;
405 1.1 onoe
406 1.1 onoe free(ifp->if_broadcastaddr, M_DEVBUF);
407 1.1 onoe ifp->if_broadcastaddr = NULL;
408 1.1 onoe memset(LLADDR(sdl), 0, sizeof(struct ieee1394_hwaddr));
409 1.1 onoe sdl->sdl_alen = 0;
410 1.1 onoe sdl->sdl_type = 0;
411 1.1 onoe }
412 1.1 onoe
413 1.1 onoe int
414 1.1 onoe ieee1394_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
415 1.1 onoe {
416 1.1 onoe struct ifreq *ifr = (struct ifreq *)data;
417 1.1 onoe struct ifaddr *ifa = (struct ifaddr *)data;
418 1.1 onoe int error = 0;
419 1.1 onoe #if __NetBSD_Version < 105080000
420 1.1 onoe int fw_init(struct ifnet *);
421 1.1 onoe void fw_stop(struct ifnet *, int);
422 1.1 onoe #endif
423 1.1 onoe
424 1.1 onoe switch (cmd) {
425 1.1 onoe case SIOCSIFADDR:
426 1.1 onoe ifp->if_flags |= IFF_UP;
427 1.1 onoe switch (ifa->ifa_addr->sa_family) {
428 1.1 onoe #ifdef INET
429 1.1 onoe case AF_INET:
430 1.1 onoe #if __NetBSD_Version >= 105080000
431 1.1 onoe if ((error = (*ifp->if_init)(ifp)) != 0)
432 1.1 onoe #else
433 1.1 onoe if ((error = fw_init(ifp)) != 0)
434 1.1 onoe #endif
435 1.1 onoe break;
436 1.1 onoe ieee1394arp_ifinit(ifp, ifa);
437 1.1 onoe break;
438 1.1 onoe #endif /* INET */
439 1.1 onoe default:
440 1.1 onoe #if __NetBSD_Version >= 105080000
441 1.1 onoe error = (*ifp->if_init)(ifp);
442 1.1 onoe #else
443 1.1 onoe error = fw_init(ifp);
444 1.1 onoe #endif
445 1.1 onoe break;
446 1.1 onoe }
447 1.1 onoe break;
448 1.1 onoe
449 1.1 onoe case SIOCGIFADDR:
450 1.1 onoe memcpy(((struct sockaddr *)&ifr->ifr_data)->sa_data,
451 1.1 onoe LLADDR(ifp->if_sadl), IEEE1394_ADDR_LEN);
452 1.1 onoe break;
453 1.1 onoe
454 1.1 onoe case SIOCSIFMTU:
455 1.1 onoe if (ifr->ifr_mtu > IEEE1394MTU)
456 1.1 onoe error = EINVAL;
457 1.1 onoe else
458 1.1 onoe ifp->if_mtu = ifr->ifr_mtu;
459 1.1 onoe break;
460 1.1 onoe
461 1.1 onoe case SIOCSIFFLAGS:
462 1.1 onoe #if __NetBSD_Version >= 105080000
463 1.1 onoe if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING)
464 1.1 onoe (*ifp->if_stop)(ifp, 1);
465 1.1 onoe else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP)
466 1.1 onoe error = (*ifp->if_init)(ifp);
467 1.1 onoe else if ((ifp->if_flags & IFF_UP) != 0)
468 1.1 onoe error = (*ifp->if_init)(ifp);
469 1.1 onoe #else
470 1.1 onoe if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING)
471 1.1 onoe fw_stop(ifp, 1);
472 1.1 onoe else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP)
473 1.1 onoe error = fw_init(ifp);
474 1.1 onoe else if ((ifp->if_flags & IFF_UP) != 0)
475 1.1 onoe error = fw_init(ifp);
476 1.1 onoe #endif
477 1.1 onoe break;
478 1.1 onoe
479 1.1 onoe case SIOCADDMULTI:
480 1.1 onoe case SIOCDELMULTI:
481 1.1 onoe /* nothing to do */
482 1.1 onoe break;
483 1.1 onoe
484 1.1 onoe default:
485 1.1 onoe error = ENOTTY;
486 1.1 onoe break;
487 1.1 onoe }
488 1.1 onoe
489 1.1 onoe return error;
490 1.1 onoe }
491