]> arthur.barton.de Git - netatalk.git/blob - sys/ultrix/at_ultrix.c
Big configure.in cleanup
[netatalk.git] / sys / ultrix / at_ultrix.c
1 /*
2  * Copyright (c) 1990,1991 Regents of The University of Michigan.
3  * All Rights Reserved.
4  *
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.
14  *
15  *      Research Systems Unix Group
16  *      The University of Michigan
17  *      c/o Mike Clark
18  *      535 W. William Street
19  *      Ann Arbor, Michigan
20  *      +1-313-763-0525
21  *      netatalk@itd.umich.edu
22  */
23
24 #include <sys/types.h>
25 #include <sys/mbuf.h>
26 #include <sys/socket.h>
27 #include <sys/protosw.h>
28 #include <sys/ioctl.h>
29 #include <sys/errno.h>
30 #include <net/if.h>
31 #include <net/if_llc.h>
32 #include <net/if_to_proto.h>
33 #include <net/netisr.h>
34 #include <netinet/in.h>
35 #undef s_net
36 #include <netinet/if_ether.h>
37
38 #include "at.h"
39 #include "at_var.h"
40
41 extern u_char   at_org_code[ 3 ];
42 extern u_char   aarp_org_code[ 3 ];
43
44 /*
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.
50  */
51 struct mbuf *
52 ddp_ifinput( m, ifp, inq, eh )
53     struct mbuf         *m;
54     struct ifnet        *ifp;
55     struct ifqueue      **inq;
56     struct ether_header *eh;
57 {
58     struct llc          llc;
59     struct if_family    *ifam;
60
61     switch ( eh->ether_type ) {
62     case ETHERTYPE_AT :
63         *inq = &atintrq1;
64         smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
65         schednetisr( NETISR_AT );
66         return( m );
67
68     case ETHERTYPE_AARP :
69         aarpinput( ifp, m );
70         return( 0 );
71
72     default :
73         if ( eh->ether_type <= ETHERMTU ) {             /* ieee802 */
74             if ( m->m_len < sizeof( struct llc )) {
75                 break;
76             }
77
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 ) {
82                 break;
83             }
84
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 ));
89                 *inq = &atintrq2;
90                 smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
91                 schednetisr( NETISR_AT );
92                 return( m );
93             }
94
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 ));
99                 aarpinput( ifp, m );
100                 return( 0 );
101             }
102         }
103     }
104
105     /*
106      * Check is anyone else wants this packet.
107      */
108     for ( ifam = if_family; ifam->domain != -1; ifam++ ) {
109         if (( eh->ether_type == ifam->if_type || ifam->if_type == -1 ) &&
110                 ifam->prswitch &&
111                 ifam->prswitch->pr_ifinput != (int (*)())ddp_ifinput ) {
112             break;
113         }
114     }
115     if ( ifam->domain != -1 && ifam->prswitch->pr_ifinput ) {
116         return( (struct mbuf *)(*ifam->prswitch->pr_ifinput)( m, ifp,
117                 inq, eh ));
118     }
119
120     m_freem( m );
121     return( 0 );
122 }
123
124 /*
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.
128  *
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
133  * mfree-ed twice.
134  */
135 ddp_ifoutput( ifp, m, dst, type, odst )
136     struct ifnet        *ifp;
137     struct mbuf         *m;
138     struct sockaddr_at  *dst;
139     short               *type;
140     char                *odst;
141 {
142     struct at_ifaddr    *aa;
143     struct llc          *llc;
144     struct mbuf         *m0;
145
146     if ( !aarpresolve( ifp, 0, dst, odst )) {
147         *type = 0xffff;
148         return( 0 );
149     }
150
151     if (( aa = (struct at_ifaddr *)at_ifawithnet( dst, ifp->if_addrlist ))
152             == 0 ) {
153         *type = 0xffff;
154         return( 0 );
155     }
156
157     if ( aa->aa_flags & AFA_PHASE2 ) {
158         /*
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.
162          */
163         MGET( m0, M_WAIT, MT_HEADER );
164         if ( m0 == 0 ) {
165             *type = 0xffff;
166             return( 0 );
167         }
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 );
172         m->m_next = m0;
173         m->m_off = MMINOFF;
174         m->m_len = sizeof( struct llc );
175
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 );
181
182         /*
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.
186          */
187         for ( *type = 0; m; m = m->m_next ) {
188             *type += m->m_len;
189         }
190     } else {
191         *type = ETHERTYPE_AT;
192     }
193
194     return( 1 );
195 }
196
197 ddp_ifioctl( ifp, cmd, data )
198     struct ifnet        *ifp;
199     int                 cmd;
200     caddr_t             data;
201 {
202     switch( cmd ) {
203     case SIOCSIFADDR :
204         aarpwhohas((struct arpcom *)ifp,
205                 &AA_SAT((struct ifaddr *)data)->sat_addr );
206         break;
207     default :
208         return( EINVAL );
209     }
210     return( 0 );
211 }