2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation, and that the name of The University
10 * of Michigan not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior
12 * permission. This software is supplied as is without expressed or
13 * implied warranties of any kind.
15 * Research Systems Unix Group
16 * The University of Michigan
18 * 535 W. William Street
21 * netatalk@itd.umich.edu
24 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/protosw.h>
28 #include <sys/ioctl.h>
29 #include <sys/errno.h>
31 #include <net/if_llc.h>
32 #include <net/if_to_proto.h>
33 #include <net/netisr.h>
34 #include <netinet/in.h>
36 #include <netinet/if_ether.h>
41 extern u_char at_org_code[ 3 ];
42 extern u_char aarp_org_code[ 3 ];
45 * This is the magic input routine, for all AppleTalk related packets.
46 * It will pick up *all* packets received, on all interfaces, apparently.
47 * If it turns out that receiving all packets in this fashion causes
48 * DLI to not receive packets what it should, we may need to call DLI
49 * directly from within the AppleTalk input routines. Ick.
52 ddp_ifinput( m, ifp, inq, eh )
56 struct ether_header *eh;
59 struct if_family *ifam;
61 switch ( eh->ether_type ) {
64 smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
65 schednetisr( NETISR_AT );
73 if ( eh->ether_type <= ETHERMTU ) { /* ieee802 */
74 if ( m->m_len < sizeof( struct llc )) {
78 bcopy( mtod( m, caddr_t ), &llc, sizeof( struct llc ));
79 if ( llc.llc_dsap != LLC_SNAP_LSAP ||
80 llc.llc_ssap != LLC_SNAP_LSAP ||
81 llc.llc_control != LLC_UI ) {
85 if ( bcmp( llc.llc_org_code, at_org_code,
86 sizeof( at_org_code )) == 0 &&
87 ntohs( llc.llc_ether_type ) == ETHERTYPE_AT ) {
88 m_adj( m, sizeof( struct llc ));
90 smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
91 schednetisr( NETISR_AT );
95 if ( bcmp( llc.llc_org_code, aarp_org_code,
96 sizeof( aarp_org_code )) == 0 &&
97 ntohs( llc.llc_ether_type ) == ETHERTYPE_AARP ) {
98 m_adj( m, sizeof( struct llc ));
106 * Check is anyone else wants this packet.
108 for ( ifam = if_family; ifam->domain != -1; ifam++ ) {
109 if (( eh->ether_type == ifam->if_type || ifam->if_type == -1 ) &&
111 ifam->prswitch->pr_ifinput != (int (*)())ddp_ifinput ) {
115 if ( ifam->domain != -1 && ifam->prswitch->pr_ifinput ) {
116 return( (struct mbuf *)(*ifam->prswitch->pr_ifinput)( m, ifp,
125 * Fill in type and odst. odst is the media output address, i.e.
126 * the MAC layer address. Type is the MAC type. Should be 0 to
127 * indicate IEEE addressing.
129 * Stupidly enough, there's no way to say "can't send this now."
130 * So, we just let the first packet go into the air. Not much
131 * else to be done, except maybe bitch at DEC. Note: we're not
132 * passing the mbuf to aarpresolve() -- that way it doesn't get
135 ddp_ifoutput( ifp, m, dst, type, odst )
138 struct sockaddr_at *dst;
142 struct at_ifaddr *aa;
146 if ( !aarpresolve( ifp, 0, dst, odst )) {
151 if (( aa = (struct at_ifaddr *)at_ifawithnet( dst, ifp->if_addrlist ))
157 if ( aa->aa_flags & AFA_PHASE2 ) {
159 * This code needs to be modeled after the similar code in
160 * at_sun.c -- you can't just MGET() and bcopy(), since we might be
161 * dealing with mbufs which are really pages.
163 MGET( m0, M_WAIT, MT_HEADER );
168 m0->m_next = m->m_next;
169 m0->m_off = m->m_off;
170 m0->m_len = m->m_len;
171 bcopy( mtod( m, caddr_t ), mtod( m0, caddr_t ), m->m_len );
174 m->m_len = sizeof( struct llc );
176 llc = mtod( m, struct llc *);
177 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
178 llc->llc_control = LLC_UI;
179 bcopy( at_org_code, llc->llc_org_code, sizeof( at_org_code ));
180 llc->llc_ether_type = htons( ETHERTYPE_AT );
183 * Set the type to be the length of the packet, instead of 0.
184 * Ultrix used to put the length in the packet when we set type
185 * to 0, however, now we do it ourselves.
187 for ( *type = 0; m; m = m->m_next ) {
191 *type = ETHERTYPE_AT;
197 ddp_ifioctl( ifp, cmd, data )
204 aarpwhohas((struct arpcom *)ifp,
205 &AA_SAT((struct ifaddr *)data)->sat_addr );