This source file includes following definitions.
- fddi_output
- fddi_input
- fddi_ifattach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/malloc.h>
81 #include <sys/mbuf.h>
82 #include <sys/protosw.h>
83 #include <sys/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/errno.h>
86 #include <sys/syslog.h>
87
88 #include <machine/cpu.h>
89
90 #include <net/if.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
93 #include <net/if_llc.h>
94 #include <net/if_dl.h>
95 #include <net/if_types.h>
96
97 #ifdef INET
98 #include <netinet/in.h>
99 #include <netinet/in_var.h>
100 #endif
101 #include <netinet/if_ether.h>
102 #include <net/if_fddi.h>
103
104 #ifdef INET6
105 #ifndef INET
106 #include <netinet/in.h>
107 #include <netinet/in_var.h>
108 #endif
109 #include <netinet6/nd6.h>
110 #endif
111
112 #include "bpfilter.h"
113
114 #include "carp.h"
115 #if NCARP > 0
116 #include <netinet/ip_carp.h>
117 #endif
118
119 #define senderr(e) { error = (e); goto bad;}
120
121
122
123
124 #ifndef llc_snap
125 #define llc_snap llc_un.type_snap
126 #endif
127
128
129
130
131
132
133 int
134 fddi_output(ifp0, m0, dst, rt0)
135 struct ifnet *ifp0;
136 struct mbuf *m0;
137 struct sockaddr *dst;
138 struct rtentry *rt0;
139 {
140 u_int16_t type;
141 int s, len, error = 0, hdrcmplt = 0;
142 u_char edst[6], esrc[6];
143 struct mbuf *m = m0;
144 struct rtentry *rt;
145 struct mbuf *mcopy = (struct mbuf *)0;
146 struct fddi_header *fh;
147 struct arpcom *ac = (struct arpcom *)ifp0;
148 short mflags;
149 struct ifnet *ifp = ifp0;
150
151 #if NCARP > 0
152 if (ifp->if_type == IFT_CARP) {
153 struct ifaddr *ifa;
154
155
156 if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) &&
157 (ifa = ifa_ifwithaddr(dst)) != NULL &&
158 ifa->ifa_ifp == ifp0)
159 return (looutput(ifp0, m, dst, rt0));
160
161 ifp = ifp->if_carpdev;
162 ac = (struct arpcom *)ifp;
163
164 if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
165 (IFF_UP|IFF_RUNNING))
166 senderr(ENETDOWN);
167 }
168 #endif
169 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
170 senderr(ENETDOWN);
171 if ((rt = rt0) != NULL) {
172 if ((rt->rt_flags & RTF_UP) == 0) {
173 if ((rt0 = rt = rtalloc1(dst, 1, 0)) != NULL)
174 rt->rt_refcnt--;
175 else
176 senderr(EHOSTUNREACH);
177 }
178 if (rt->rt_flags & RTF_GATEWAY) {
179 if (rt->rt_gwroute == 0)
180 goto lookup;
181 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
182 rtfree(rt); rt = rt0;
183 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);
184 if ((rt = rt->rt_gwroute) == 0)
185 senderr(EHOSTUNREACH);
186 }
187 }
188 if (rt->rt_flags & RTF_REJECT)
189 if (rt->rt_rmx.rmx_expire == 0 ||
190 time_second < rt->rt_rmx.rmx_expire)
191 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
192 }
193
194 switch (dst->sa_family) {
195
196 #ifdef INET
197 case AF_INET:
198 if (!arpresolve(ac, rt, m, dst, edst))
199 return (0);
200
201 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
202 !m->m_pkthdr.pf.routed)
203 mcopy = m_copy(m, 0, (int)M_COPYALL);
204 type = htons(ETHERTYPE_IP);
205 break;
206 #endif
207 #ifdef INET6
208 case AF_INET6:
209 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
210 return (0);
211 type = htons(ETHERTYPE_IPV6);
212 break;
213 #endif
214 #if 0
215 #ifdef INET6
216 case AF_INET6:
217
218
219
220
221
222 if (m->m_flags & M_MCAST) {
223
224
225
226
227 ETHER_MAP_IN6_MULTICAST(((struct sockaddr_in6 *)dst)->sin6_addr,
228 edst);
229 } else {
230
231 if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
232 return 0;
233 }
234 type = htons(ETHERTYPE_IPV6);
235 break;
236 #endif
237 #endif
238
239 case pseudo_AF_HDRCMPLT:
240 {
241 struct fddi_header *fh = (struct fddi_header *)dst->sa_data;
242 hdrcmplt = 1;
243 bcopy((caddr_t)fh->fddi_shost, (caddr_t)esrc, sizeof (esrc));
244
245 }
246
247 case AF_UNSPEC:
248 {
249 struct ether_header *eh;
250 eh = (struct ether_header *)dst->sa_data;
251 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
252 if (*edst & 1)
253 m->m_flags |= (M_BCAST|M_MCAST);
254 type = eh->ether_type;
255 break;
256 }
257
258 #if NBPFILTER > 0
259 case AF_IMPLINK:
260 {
261 fh = mtod(m, struct fddi_header *);
262 error = EPROTONOSUPPORT;
263 switch (fh->fddi_fc & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) {
264 case FDDIFC_LLC_ASYNC: {
265
266 if ((fh->fddi_fc & FDDIFC_Z) > 7)
267 goto bad;
268 break;
269 }
270 case FDDIFC_LLC_SYNC: {
271
272 if (fh->fddi_fc & FDDIFC_Z)
273 goto bad;
274 break;
275 }
276 case FDDIFC_SMT: {
277
278 if ((fh->fddi_fc & FDDIFC_Z) == 0)
279 goto bad;
280 break;
281 }
282 default: {
283
284 goto bad;
285 }
286 }
287 error = 0;
288 if (fh->fddi_dhost[0] & 1)
289 m->m_flags |= (M_BCAST|M_MCAST);
290 goto queue_it;
291 }
292 #endif
293 default:
294 printf("%s: can't handle af%d\n", ifp->if_xname,
295 dst->sa_family);
296 senderr(EAFNOSUPPORT);
297 }
298
299 if (mcopy)
300 (void) looutput(ifp, mcopy, dst, rt);
301
302 if (type != 0) {
303 struct llc *l;
304 M_PREPEND(m, sizeof (struct llc), M_DONTWAIT);
305 if (m == 0)
306 senderr(ENOBUFS);
307 l = mtod(m, struct llc *);
308 l->llc_control = LLC_UI;
309 l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
310 l->llc_snap.org_code[0] = l->llc_snap.org_code[1] = l->llc_snap.org_code[2] = 0;
311 bcopy((caddr_t) &type, (caddr_t) &l->llc_snap.ether_type,
312 sizeof(u_short));
313 }
314
315
316
317
318 M_PREPEND(m, sizeof (struct fddi_header), M_DONTWAIT);
319 if (m == 0)
320 senderr(ENOBUFS);
321 fh = mtod(m, struct fddi_header *);
322 fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
323 bcopy((caddr_t)edst, (caddr_t)fh->fddi_dhost, sizeof (edst));
324 #if NBPFILTER > 0
325 queue_it:
326 #endif
327 if (hdrcmplt)
328 bcopy((caddr_t)esrc, (caddr_t)fh->fddi_shost,
329 sizeof(fh->fddi_shost));
330 else
331 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)fh->fddi_shost,
332 sizeof(fh->fddi_shost));
333 #if NCARP > 0
334 if (ifp0 != ifp && ifp0->if_type == IFT_CARP) {
335 bcopy((caddr_t)((struct arpcom *)ifp0)->ac_enaddr,
336 (caddr_t)fh->fddi_shost, sizeof(fh->fddi_shost));
337 }
338 #endif
339 mflags = m->m_flags;
340 len = m->m_pkthdr.len;
341 s = splnet();
342
343
344
345
346 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
347 if (error) {
348
349 splx(s);
350 return (error);
351 }
352 ifp->if_obytes += len;
353 #if NCARP > 0
354 if (ifp != ifp0)
355 ifp0->if_obytes += len;
356 #endif
357 if (mflags & M_MCAST)
358 ifp->if_omcasts++;
359 if ((ifp->if_flags & IFF_OACTIVE) == 0)
360 (*ifp->if_start)(ifp);
361 splx(s);
362 return (error);
363
364 bad:
365 if (m)
366 m_freem(m);
367 return (error);
368 }
369
370
371
372
373
374
375 void
376 fddi_input(ifp, fh, m)
377 struct ifnet *ifp;
378 struct fddi_header *fh;
379 struct mbuf *m;
380 {
381 struct ifqueue *inq;
382 struct llc *l;
383 int s;
384
385 if ((ifp->if_flags & IFF_UP) == 0) {
386 m_freem(m);
387 return;
388 }
389 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*fh);
390 if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
391 sizeof(fddibroadcastaddr)) == 0)
392 m->m_flags |= M_BCAST;
393 else if (fh->fddi_dhost[0] & 1)
394 m->m_flags |= M_MCAST;
395 if (m->m_flags & (M_BCAST|M_MCAST))
396 ifp->if_imcasts++;
397
398 l = mtod(m, struct llc *);
399 switch (l->llc_dsap) {
400 #if defined(INET) || defined(INET6)
401 case LLC_SNAP_LSAP:
402 {
403 u_int16_t etype;
404 if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
405 goto dropanyway;
406 if (l->llc_snap.org_code[0] != 0 || l->llc_snap.org_code[1] != 0|| l->llc_snap.org_code[2] != 0)
407 goto dropanyway;
408 etype = ntohs(l->llc_snap.ether_type);
409 m_adj(m, LLC_SNAPFRAMELEN);
410
411 #if NCARP > 0
412 if (ifp->if_carp && ifp->if_type != IFT_CARP &&
413 (carp_input(m, (u_int8_t *)&fh->fddi_shost,
414 (u_int8_t *)&fh->fddi_dhost, l->llc_snap.ether_type) == 0))
415 return;
416 #endif
417
418 switch (etype) {
419 #ifdef INET
420 case ETHERTYPE_IP:
421 schednetisr(NETISR_IP);
422 inq = &ipintrq;
423 break;
424
425 case ETHERTYPE_ARP:
426 if (ifp->if_flags & IFF_NOARP)
427 goto dropanyway;
428 schednetisr(NETISR_ARP);
429 inq = &arpintrq;
430 break;
431 #endif
432 #ifdef INET6
433 case ETHERTYPE_IPV6:
434 schednetisr(NETISR_IPV6);
435 inq = &ip6intrq;
436 break;
437 #endif
438 default:
439
440 ifp->if_noproto++;
441 goto dropanyway;
442 }
443 break;
444 }
445 #endif
446
447 default:
448
449 ifp->if_noproto++;
450 dropanyway:
451 m_freem(m);
452 return;
453 }
454
455 s = splnet();
456 IF_INPUT_ENQUEUE(inq, m);
457 splx(s);
458 }
459
460
461
462 void
463 fddi_ifattach(ifp)
464 struct ifnet *ifp;
465 {
466
467 ifp->if_type = IFT_FDDI;
468 ifp->if_addrlen = 6;
469 ifp->if_hdrlen = 21;
470 ifp->if_mtu = FDDIMTU;
471 ifp->if_output = fddi_output;
472 if_alloc_sadl(ifp);
473 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
474 LLADDR(ifp->if_sadl), ifp->if_addrlen);
475 }