1 /* $NetBSD: if_tokensubr.c,v 1.54.10.1 2009/11/21 19:43:41 snj Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1989, 1993
5 * The Regents of the University of California. 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 * 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.
18 *
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.
30 *
31 * from: NetBSD: if_fddisubr.c,v 1.2 1995/08/19 04:35:29 cgd Exp
32 */
33
34 /*
35 * Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
36 * All rights reserved.
37 *
38 * This code is derived from software contributed to The NetBSD Foundation
39 * by Onno van der Linden.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
51 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
54 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
61 */
62
63 /*
64 * Copyright (c) 1995
65 * Matt Thomas. All rights reserved.
66 *
67 * Redistribution and use in source and binary forms, with or without
68 * modification, are permitted provided that the following conditions
69 * are met:
70 * 1. Redistributions of source code must retain the above copyright
71 * notice, this list of conditions and the following disclaimer.
72 * 2. Redistributions in binary form must reproduce the above copyright
73 * notice, this list of conditions and the following disclaimer in the
74 * documentation and/or other materials provided with the distribution.
75 * 3. The names of its contributors may not be used to endorse or promote
76 * products derived from this software without specific prior written
77 * permission.
78 *
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89 * SUCH DAMAGE.
90 *
91 * from: NetBSD: if_fddisubr.c,v 1.2 1995/08/19 04:35:29 cgd Exp
92 */
93
94 #include <sys/cdefs.h>
95 __KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.54.10.1 2009/11/21 19:43:41 snj Exp $");
96
97 #include "opt_inet.h"
98 #include "opt_atalk.h"
99 #include "opt_iso.h"
100 #include "opt_gateway.h"
101
102 #include "bpfilter.h"
103
104 #include <sys/param.h>
105 #include <sys/systm.h>
106 #include <sys/kernel.h>
107 #include <sys/malloc.h>
108 #include <sys/mbuf.h>
109 #include <sys/protosw.h>
110 #include <sys/socket.h>
111 #include <sys/ioctl.h>
112 #include <sys/errno.h>
113 #include <sys/syslog.h>
114
115 #include <sys/cpu.h>
116
117 #include <net/if.h>
118 #include <net/netisr.h>
119 #include <net/route.h>
120 #include <net/if_llc.h>
121 #include <net/if_dl.h>
122 #include <net/if_types.h>
123
124 #if NBPFILTER > 0
125 #include <net/bpf.h>
126 #endif
127
128 #include <net/if_ether.h>
129 #include <net/if_token.h>
130
131 #include "carp.h"
132 #if NCARP > 0
133 #include <netinet/ip_carp.h>
134 #endif
135
136 #ifdef INET
137 #include <netinet/in.h>
138 #include <netinet/in_var.h>
139 #include <netinet/if_inarp.h>
140 #endif
141
142
143 #ifdef DECNET
144 #include <netdnet/dn.h>
145 #endif
146
147 #ifdef ISO
148 #include <netiso/argo_debug.h>
149 #include <netiso/iso.h>
150 #include <netiso/iso_var.h>
151 #include <netiso/iso_snpac.h>
152 #endif
153
154 #include "bpfilter.h"
155
156 #define senderr(e) { error = (e); goto bad;}
157
158 #if defined(__bsdi__) || defined(__NetBSD__)
159 #define RTALLOC1(a, b) rtalloc1(a, b)
160 #define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e)
161 #define TYPEHTONS(t) (t)
162 #elif defined(__FreeBSD__)
163 #define RTALLOC1(a, b) rtalloc1(a, b, 0UL)
164 #define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e, f)
165 #define TYPEHTONS(t) (htons(t))
166 #endif
167
168 #define RCF_ALLROUTES (2 << 8) | TOKEN_RCF_FRAME2 | TOKEN_RCF_BROADCAST_ALL
169 #define RCF_SINGLEROUTE (2 << 8) | TOKEN_RCF_FRAME2 | TOKEN_RCF_BROADCAST_SINGLE
170
171 static int token_output(struct ifnet *, struct mbuf *,
172 const struct sockaddr *, struct rtentry *);
173 static void token_input(struct ifnet *, struct mbuf *);
174
175 /*
176 * Token Ring output routine.
177 * Encapsulate a packet of type family for the local net.
178 * Assumes that ifp is actually pointer to arphdr structure.
179 * XXX route info has to go into the same mbuf as the header
180 */
181 static int
182 token_output(struct ifnet *ifp0, struct mbuf *m0, const struct sockaddr *dst,
183 struct rtentry *rt0)
184 {
185 uint16_t etype;
186 int error = 0;
187 u_char edst[ISO88025_ADDR_LEN];
188 struct mbuf *m = m0;
189 struct rtentry *rt;
190 struct mbuf *mcopy = NULL;
191 struct token_header *trh;
192 #ifdef INET
193 struct arphdr *ah = (struct arphdr *)ifp0;
194 #endif /* INET */
195 struct token_rif *rif = NULL;
196 struct token_rif bcastrif;
197 struct ifnet *ifp = ifp0;
198 size_t riflen = 0;
199 ALTQ_DECL(struct altq_pktattr pktattr;)
200
201 #if NCARP > 0
202 if (ifp->if_type == IFT_CARP) {
203 struct ifaddr *ifa;
204
205 /* loop back if this is going to the carp interface */
206 if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
207 (ifa = ifa_ifwithaddr(dst)) != NULL &&
208 ifa->ifa_ifp == ifp0)
209 return (looutput(ifp0, m, dst, rt0));
210
211 ifp = ifp->if_carpdev;
212 ah = (struct arphdr *)ifp;
213
214 if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
215 (IFF_UP|IFF_RUNNING))
216 senderr(ENETDOWN);
217 }
218 #endif /* NCARP > 0 */
219
220 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
221 senderr(ENETDOWN);
222 if ((rt = rt0)) {
223 if ((rt->rt_flags & RTF_UP) == 0) {
224 if ((rt0 = rt = RTALLOC1(dst, 1)))
225 rt->rt_refcnt--;
226 else
227 senderr(EHOSTUNREACH);
228 }
229 if (rt->rt_flags & RTF_GATEWAY) {
230 if (rt->rt_gwroute == 0)
231 goto lookup;
232 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
233 rtfree(rt); rt = rt0;
234 lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 1);
235 if ((rt = rt->rt_gwroute) == 0)
236 senderr(EHOSTUNREACH);
237 }
238 }
239 if (rt->rt_flags & RTF_REJECT)
240 if (rt->rt_rmx.rmx_expire == 0 ||
241 time_second < rt->rt_rmx.rmx_expire)
242 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
243 }
244
245 /*
246 * If the queueing discipline needs packet classification,
247 * do it before prepending link headers.
248 */
249 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
250
251 switch (dst->sa_family) {
252
253 #ifdef INET
254 case AF_INET:
255 if (m->m_flags & M_BCAST) {
256 if (ifp->if_flags & IFF_LINK0) {
257 if (ifp->if_flags & IFF_LINK1)
258 bcastrif.tr_rcf = htons(RCF_ALLROUTES);
259 else
260 bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
261 rif = &bcastrif;
262 riflen = sizeof(rif->tr_rcf);
263 }
264 memcpy(edst, tokenbroadcastaddr, sizeof(edst));
265 }
266 /*
267 * XXX m->m_flags & M_MCAST IEEE802_MAP_IP_MULTICAST ??
268 */
269 else {
270 if (!ARPRESOLVE(ifp, rt, m, dst, edst, rt0))
271 return (0); /* if not yet resolved */
272 rif = TOKEN_RIF((struct llinfo_arp *) rt->rt_llinfo);
273 riflen = (ntohs(rif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
274 }
275 /* If broadcasting on a simplex interface, loopback a copy. */
276 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
277 mcopy = m_copy(m, 0, (int)M_COPYALL);
278 etype = htons(ETHERTYPE_IP);
279 break;
280 case AF_ARP:
281 /*
282 * XXX source routing, assume m->m_data contains the useful stuff
283 */
284 ah = mtod(m, struct arphdr *);
285 ah->ar_hrd = htons(ARPHRD_IEEE802);
286
287 switch (ntohs(ah->ar_op)) {
288 case ARPOP_REVREQUEST:
289 case ARPOP_REVREPLY:
290 etype = htons(ETHERTYPE_REVARP);
291 break;
292
293 case ARPOP_REQUEST:
294 case ARPOP_REPLY:
295 default:
296 etype = htons(ETHERTYPE_ARP);
297 }
298
299 if (m->m_flags & M_BCAST) {
300 if (ifp->if_flags & IFF_LINK0) {
301 if (ifp->if_flags & IFF_LINK1)
302 bcastrif.tr_rcf = htons(RCF_ALLROUTES);
303 else
304 bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
305 rif = &bcastrif;
306 riflen = sizeof(rif->tr_rcf);
307 }
308 memcpy(edst, tokenbroadcastaddr, sizeof(edst));
309 }
310 else {
311 void *tha = ar_tha(ah);
312 if (tha == NULL)
313 return 0;
314 bcopy(tha, (void *)edst, sizeof(edst));
315 trh = (struct token_header *)M_TRHSTART(m);
316 trh->token_ac = TOKEN_AC;
317 trh->token_fc = TOKEN_FC;
318 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
319 struct token_rif *trrif;
320
321 trrif = TOKEN_RIF(trh);
322 riflen = (ntohs(trrif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
323 }
324 bcopy((void *)edst, (void *)trh->token_dhost,
325 sizeof (edst));
326 bcopy(CLLADDR(ifp->if_sadl), (void *)trh->token_shost,
327 sizeof(trh->token_shost));
328 if (riflen != 0)
329 trh->token_shost[0] |= TOKEN_RI_PRESENT;
330 /*
331 * compare (m->m_data - m->m_pktdat) with (sizeof(struct token_header) + riflen + ...
332 */
333 m->m_len += (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
334 m->m_data -= (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
335 m->m_pkthdr.len += (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
336 goto send;
337 }
338 break;
339 #endif
340 #ifdef ISO
341 case AF_ISO: {
342 int snpalen;
343 struct llc *l;
344 const struct sockaddr_dl *sdl;
345
346 if (rt && (sdl = satocsdl(rt->rt_gateway)) &&
347 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
348 memcpy(edst, CLLADDR(sdl), sizeof(edst));
349 }
350 else if ((error = iso_snparesolve(ifp,
351 (const struct sockaddr_iso *)dst, (char *)edst, &snpalen)))
352 goto bad; /* Not resolved */
353 /* If broadcasting on a simplex interface, loopback a copy. */
354 if (*edst & 1)
355 m->m_flags |= (M_BCAST|M_MCAST);
356 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
357 (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
358 M_PREPEND(mcopy, sizeof (*trh), M_DONTWAIT);
359 if (mcopy) {
360 trh = mtod(mcopy, struct token_header *);
361 bcopy((void *)edst,
362 (void *)trh->token_dhost, sizeof (edst));
363 bcopy(CLLADDR(ifp->if_sadl),
364 (void *)trh->token_shost, sizeof (edst));
365 }
366 }
367 M_PREPEND(m, 3, M_DONTWAIT);
368 if (m == NULL)
369 return (0);
370 etype = 0;
371 l = mtod(m, struct llc *);
372 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
373 l->llc_control = LLC_UI;
374 #if defined(__FreeBSD__)
375 IFDEBUG(D_ETHER)
376 int i;
377 printf("token_output: sending pkt to: ");
378 for (i=0; i < ISO88025_ADDR_LEN; i++)
379 printf("%x ", edst[i] & 0xff);
380 printf("\n");
381 ENDDEBUG
382 #endif
383 } break;
384 #endif /* ISO */
385
386 case AF_UNSPEC:
387 {
388 const struct ether_header *eh;
389 eh = (const struct ether_header *)dst->sa_data;
390 memcpy(edst, eh->ether_dhost, sizeof(edst));
391 if (*edst & 1)
392 m->m_flags |= (M_BCAST|M_MCAST);
393 etype = TYPEHTONS(eh->ether_type);
394 if (m->m_flags & M_BCAST) {
395 if (ifp->if_flags & IFF_LINK0) {
396 if (ifp->if_flags & IFF_LINK1)
397 bcastrif.tr_rcf = htons(RCF_ALLROUTES);
398 else
399 bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
400 rif = &bcastrif;
401 riflen = sizeof(bcastrif.tr_rcf);
402 }
403 }
404 break;
405 }
406
407 default:
408 printf("%s: can't handle af%d\n", ifp->if_xname,
409 dst->sa_family);
410 senderr(EAFNOSUPPORT);
411 }
412
413
414 if (mcopy)
415 (void) looutput(ifp, mcopy, dst, rt);
416 if (etype != 0) {
417 struct llc *l;
418 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
419 if (m == 0)
420 senderr(ENOBUFS);
421 l = mtod(m, struct llc *);
422 l->llc_control = LLC_UI;
423 l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
424 l->llc_snap.org_code[0] = l->llc_snap.org_code[1] =
425 l->llc_snap.org_code[2] = 0;
426 bcopy((void *) &etype, (void *) &l->llc_snap.ether_type,
427 sizeof(uint16_t));
428 }
429
430 /*
431 * Add local net header. If no space in first mbuf,
432 * allocate another.
433 */
434
435 M_PREPEND(m, (riflen + sizeof (*trh)), M_DONTWAIT);
436 if (m == 0)
437 senderr(ENOBUFS);
438 trh = mtod(m, struct token_header *);
439 trh->token_ac = TOKEN_AC;
440 trh->token_fc = TOKEN_FC;
441 bcopy((void *)edst, (void *)trh->token_dhost, sizeof (edst));
442 bcopy(CLLADDR(ifp->if_sadl), (void *)trh->token_shost,
443 sizeof(trh->token_shost));
444
445 if (riflen != 0) {
446 struct token_rif *trrif;
447
448 trh->token_shost[0] |= TOKEN_RI_PRESENT;
449 trrif = TOKEN_RIF(trh);
450 bcopy(rif, trrif, riflen);
451 }
452 #ifdef INET
453 send:
454 #endif
455
456 #if NCARP > 0
457 if (ifp0 != ifp && ifp0->if_type == IFT_CARP) {
458 bcopy(CLLADDR(ifp0->if_sadl), (void *)trh->token_shost,
459 sizeof(trh->token_shost));
460 }
461 #endif /* NCARP > 0 */
462
463 return ifq_enqueue(ifp, m ALTQ_COMMA ALTQ_DECL(&pktattr));
464 bad:
465 if (m)
466 m_freem(m);
467 return (error);
468 }
469
470 /*
471 * Process a received token ring packet;
472 * the packet is in the mbuf chain m with
473 * the token ring header.
474 */
475 static void
476 token_input(struct ifnet *ifp, struct mbuf *m)
477 {
478 struct ifqueue *inq;
479 struct llc *l;
480 struct token_header *trh;
481 int s, lan_hdr_len;
482
483 if ((ifp->if_flags & IFF_UP) == 0) {
484 m_freem(m);
485 return;
486 }
487
488 trh = mtod(m, struct token_header *);
489
490 ifp->if_ibytes += m->m_pkthdr.len;
491 if (memcmp(tokenbroadcastaddr, trh->token_dhost,
492 sizeof(tokenbroadcastaddr)) == 0)
493 m->m_flags |= M_BCAST;
494 else if (trh->token_dhost[0] & 1)
495 m->m_flags |= M_MCAST;
496 if (m->m_flags & (M_BCAST|M_MCAST))
497 ifp->if_imcasts++;
498
499 /* Skip past the Token Ring header and RIF. */
500 lan_hdr_len = sizeof(struct token_header);
501 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
502 struct token_rif *trrif;
503
504 trrif = TOKEN_RIF(trh);
505 lan_hdr_len += (ntohs(trrif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
506 }
507
508 l = (struct llc *)(mtod(m, uint8_t *) + lan_hdr_len);
509
510 switch (l->llc_dsap) {
511 #if defined(INET) || defined(NS) || defined(DECNET)
512 case LLC_SNAP_LSAP:
513 {
514 uint16_t etype;
515 if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
516 goto dropanyway;
517 if (l->llc_snap.org_code[0] != 0 ||
518 l->llc_snap.org_code[1] != 0 ||
519 l->llc_snap.org_code[2] != 0)
520 goto dropanyway;
521 etype = ntohs(l->llc_snap.ether_type);
522 m_adj(m, lan_hdr_len + LLC_SNAPFRAMELEN);
523 #if NCARP > 0
524 if (ifp->if_carp && ifp->if_type != IFT_CARP &&
525 (carp_input(m, (uint8_t *)&trh->token_shost,
526 (uint8_t *)&trh->token_dhost, l->llc_snap.ether_type) == 0))
527 return;
528 #endif /* NCARP > 0 */
529
530 switch (etype) {
531 #ifdef INET
532 case ETHERTYPE_IP:
533 schednetisr(NETISR_IP);
534 inq = &ipintrq;
535 break;
536
537 case ETHERTYPE_ARP:
538 schednetisr(NETISR_ARP);
539 inq = &arpintrq;
540 break;
541 #endif
542 #ifdef DECNET
543 case ETHERTYPE_DECNET:
544 schednetisr(NETISR_DECNET);
545 inq = &decnetintrq;
546 break;
547 #endif
548 default:
549 /*
550 printf("token_input: unknown protocol 0x%x\n", etype);
551 */
552 ifp->if_noproto++;
553 goto dropanyway;
554 }
555 break;
556 }
557 #endif /* INET || NS || DECNET */
558 #ifdef ISO
559 case LLC_ISO_LSAP:
560 switch (l->llc_control) {
561 case LLC_UI:
562 /* LLC_UI_P forbidden in class 1 service */
563 if ((l->llc_dsap == LLC_ISO_LSAP) &&
564 (l->llc_ssap == LLC_ISO_LSAP)) {
565
566 #if defined(__FreeBSD__)
567 IFDEBUG(D_ETHER)
568 printf("clnp packet");
569 ENDDEBUG
570 #endif
571 schednetisr(NETISR_ISO);
572 inq = &clnlintrq;
573 break;
574 }
575 goto dropanyway;
576
577 case LLC_XID:
578 case LLC_XID_P:
579 if(m->m_len < LLC_XID_BASIC_MINLEN + lan_hdr_len)
580 goto dropanyway;
581 l->llc_window = 0;
582 l->llc_fid = LLC_XID_FORMAT_BASIC;
583 l->llc_class = LLC_XID_CLASS_I;
584 l->llc_dsap = l->llc_ssap = 0;
585 /* Fall through to */
586 case LLC_TEST:
587 case LLC_TEST_P:
588 {
589 struct sockaddr sa;
590 struct ether_header *eh;
591 int i;
592 u_char c = l->llc_dsap;
593
594 l->llc_dsap = l->llc_ssap;
595 l->llc_ssap = c;
596 if (m->m_flags & (M_BCAST | M_MCAST))
597 bcopy(CLLADDR(ifp->if_sadl),
598 (void *)trh->token_dhost,
599 ISO88025_ADDR_LEN);
600 sa.sa_family = AF_UNSPEC;
601 sa.sa_len = sizeof(sa);
602 eh = (struct ether_header *)sa.sa_data;
603 for (i = 0; i < ISO88025_ADDR_LEN; i++) {
604 eh->ether_shost[i] = c = trh->token_dhost[i];
605 eh->ether_dhost[i] =
606 eh->ether_dhost[i] = trh->token_shost[i];
607 eh->ether_shost[i] = c;
608 }
609 eh->ether_type = 0;
610 m_adj(m, lan_hdr_len);
611 ifp->if_output(ifp, m, &sa, NULL);
612 return;
613 }
614 default:
615 m_freem(m);
616 return;
617 }
618 break;
619 #endif /* ISO */
620
621 default:
622 /* printf("token_input: unknown dsap 0x%x\n", l->llc_dsap); */
623 ifp->if_noproto++;
624 #if defined(INET) || defined(NS) || defined(DECNET) || defined(ISO)
625 dropanyway:
626 #endif
627 m_freem(m);
628 return;
629 }
630
631 s = splnet();
632 if (IF_QFULL(inq)) {
633 IF_DROP(inq);
634 m_freem(m);
635 }
636 else
637 IF_ENQUEUE(inq, m);
638 splx(s);
639 }
640
641 /*
642 * Perform common duties while attaching to interface list
643 */
644 void
645 token_ifattach(struct ifnet *ifp, void *lla)
646 {
647
648 ifp->if_type = IFT_ISO88025;
649 ifp->if_hdrlen = 14;
650 ifp->if_dlt = DLT_IEEE802;
651 ifp->if_mtu = ISO88025_MTU;
652 ifp->if_output = token_output;
653 ifp->if_input = token_input;
654 ifp->if_broadcastaddr = tokenbroadcastaddr;
655 #ifdef IFF_NOTRAILERS
656 ifp->if_flags |= IFF_NOTRAILERS;
657 #endif
658
659 if_set_sadl(ifp, lla, ISO88025_ADDR_LEN);
660
661 #if NBPFILTER > 0
662 bpfattach(ifp, DLT_IEEE802, sizeof(struct token_header));
663 #endif
664 }
665
666 void
667 token_ifdetach(struct ifnet *ifp)
668 {
669
670 #if NBPFILTER > 0
671 bpfdetach(ifp);
672 #endif
673 #if 0 /* done in if_detach() */
674 if_free_sadl(ifp);
675 #endif
676 }
Cache object: bb3065faeb86c23747a2df4ac0a60285
|