2
* $Id: at_sun.c,v 1.2 2001/08/06 13:39:30 rufustfirefly Exp $
7
#include <sys/socket.h>
9
#include <sys/protosw.h>
10
#include <sys/domain.h>
11
#include <sys/errno.h>
13
#include <net/if_arp.h>
15
#include <net/route.h>
17
#include <net/netisr.h>
19
#include <sun/vddrv.h>
21
#include <netinet/in.h>
23
#include <netinet/if_ether.h>
25
#include <netatalk/at.h>
26
#include <netatalk/at_var.h>
27
#include <netatalk/ddp_var.h>
28
#include <netatalk/phase2.h>
34
VDMAGIC_USER, "netatalk"
37
struct ifqueue *atef_input();
41
extern u_char aarp_org_code[ 3 ];
42
extern u_char at_org_code[ 3 ];
45
* Entries in this table are inserted into the ether_families linked
46
* list at the beginnning. As such, they will be searched by the input
47
* and output routines opposite to the order here.
49
* In order to do both phase 1 and phase 2 during output, we have a
50
* special entry (the AF_APPLETALK entry) whose ethertype field is
51
* changed by the output function, to reflect the actual link layer
52
* to be used. This ether_family entry is never seen during Ethernet
53
* input, since the earlier entry captures all packets (it is seen
54
* during loopback input, in that the input function is called directly
55
* on loopback output).
57
struct ether_family ether_atalk[] = {
59
AF_APPLETALK, 0, /* Changed by atef_output() */
60
atef_input, atef_output, atintr,
68
atef_input, 0, atintr,
72
atef_input, 0, atintr,
75
int ether_atalkN = sizeof( ether_atalk ) / sizeof( ether_atalk[ 0 ] );
77
extern struct ether_family *ether_families;
79
extern int atalk_hash(), atalk_netmatch();
80
extern int null_hash(), null_netmatch();
82
xxxinit( cmd, vdd, vdi, vds )
88
struct ether_family *ef;
95
vdd->vdd_vdtab = (struct vdlinkage *)&atvdl;
98
* Register with the network-interface layer (ethernet).
100
for ( i = 0; i < ether_atalkN; i++ ) {
101
ether_register( ðer_atalk[ i ] );
105
* Register with the socket layer.
107
atalkdomain.dom_next = domains;
108
domains = &atalkdomain;
109
if ( atalkdomain.dom_init ) {
110
(*atalkdomain.dom_init)();
112
for ( pr = atalkdomain.dom_protosw;
113
pr < atalkdomain.dom_protoswNPROTOSW; pr++ ) {
120
* Cobble ourselves into the routing table.
122
afswitch[ AF_APPLETALK ].af_hash = atalk_hash;
123
afswitch[ AF_APPLETALK ].af_netmatch = atalk_netmatch;
128
* Make sure that there are no open appletalk sockets.
130
if ( ddpcb != NULL ) {
135
* There is no ether_unregister(), so we'll have to do it
138
for ( i = 0; i < ether_atalkN; i++ ) {
139
if ( ether_families == ðer_atalk[ i ] ) {
140
ether_families = ether_families->ef_next;
143
for ( ef = ether_families; ef->ef_next; ef = ef->ef_next ) {
144
if ( ef->ef_next == ðer_atalk[ i ] ) {
145
ef->ef_next = ef->ef_next->ef_next;
153
* Remove aarp timers and held packets.
158
* Remove AppleTalk interface addresses.
163
* Remove our routines from the routing table.
165
afswitch[ AF_APPLETALK ].af_hash = null_hash;
166
afswitch[ AF_APPLETALK ].af_netmatch = null_netmatch;
169
* Remove atalkdomain from the domains list.
170
* Unlikely, but someone may have registered after us.
172
if ( domains == &atalkdomain ) {
173
domains = domains->dom_next;
175
for ( dom = domains; dom->dom_next; dom = dom->dom_next ) {
176
if ( dom->dom_next == &atalkdomain ) {
177
dom->dom_next = dom->dom_next->dom_next;
192
* Input routine for netatalk on suns. There are five possible
193
* packets. First, packets received on the loopback interface
194
* are immediately sent to the phase 1 interrupt queue (this will
195
* have to change if we ever do a phase 2 only version). Second,
196
* IEEE802 packet are sent to either the aarpinput() routine or
197
* the phase 2 interrupt queue. Finally, DIX packets are sent
198
* to either aarpinput() or the phase 1 interrupt queue.
201
atef_input( ifp, m, header )
204
struct ether_header *header;
210
* Check first for LOOPBACK flag, since loopback code passes NULL for
213
if ( ifp->if_flags & IFF_LOOPBACK ) {
218
* Before SunOS 4.1, the ether_type was passed as is from the
219
* packet. After SunOS 4.1, the ether_type is swapped in
220
* do_protocol(), before the ether_family routines are called.
222
#if defined( sun ) && defined( i386 )
223
header->ether_type = ntohs( header->ether_type );
224
#endif /* sun i386 */
226
if ( header->ether_type <= ETHERMTU ) { /* IEEE802 */
228
* We need to remove the interface pointer from the beginning of this
229
* packet. We can't always use IF_ADJ(), since it can (and will,
230
* very often) MFREE() the first mbuf in our chain. If IF_ADJ()
231
* would free the first mbuf, we just advance our pointer to the
232
* next mbuf. Since our calling routine passes m by value, we're
233
* not actually losing m. Later, we don't need to put the interface
234
* pointer back on, since the caller still has it in its copy of m.
236
if ( m->m_len == sizeof( struct ifnet * )) {
244
* We can't call m_pullup(), since we need to preserve
247
if ( m->m_len < sizeof( struct llc )) {
248
printf( "atef_input size llc\n" );
249
( n ) ? m_freem( n ) : m_freem( m );
252
bcopy( mtod( m, caddr_t ), &llc, sizeof( struct llc ));
253
if ( llc.llc_dsap != LLC_SNAP_LSAP || llc.llc_ssap != LLC_SNAP_LSAP ||
254
llc.llc_control != LLC_UI ) {
255
( n ) ? m_freem( n ) : m_freem( m );
260
* See IF_ADJ() above. Here we prepend ifp to the mbuf chain. If we
261
* didn't remove it earlier, we don't replace it here.
264
m_adj( m, sizeof( struct llc ));
266
m_adj( m, sizeof( struct llc ) - sizeof( struct ifnet *));
267
if ( m->m_len < sizeof( struct ifnet * )) {
268
printf( "atef_input too small!\n" );
272
*mtod( m, struct ifnet ** ) = ifp;
275
if ( ntohs( llc.llc_ether_type ) == ETHERTYPE_AT &&
276
bcmp( llc.llc_org_code, at_org_code,
277
sizeof( at_org_code )) == 0 ) {
281
/* do we really want to pass m, here? what happened to n? XXX */
282
if ( ntohs( llc.llc_ether_type ) == ETHERTYPE_AARP &&
283
bcmp( llc.llc_org_code, aarp_org_code,
284
sizeof( aarp_org_code )) == 0 ) {
285
aarpinput( ifp, n ? n : m );
290
switch ( header->ether_type ) {
294
case ETHERTYPE_AARP :
300
( n ) ? m_freem( n ) : m_freem( m );
305
* If the destination is on a 802.3 wire, do phase 2 encapsulation,
306
* adding the 802.2 and SNAP headers. Always fill in the edst with the
307
* ethernet address of the destination.
309
atef_output( dst, m, ifp, edst )
310
struct sockaddr_at *dst;
313
struct ether_addr *edst;
315
struct at_ifaddr *aa;
321
if ( !aarpresolve( ifp, m, dst, edst )) {
328
* ifaddr is the first thing in at_ifaddr
330
if (( aa = (struct at_ifaddr *)at_ifawithnet( dst, ifp->if_addrlist ))
337
* In the phase 2 case, we need to prepend an mbuf for the llc header.
338
* Since we must preserve the value of m, which is passed to us by
339
* value, we m_copy() the first mbuf, and use it for our llc header.
341
* We could worry about leaving space for the ether header, but
342
* since we'll have to go through all sorts of hoops, including a
343
* possibly large copy, there's really no sense.
345
if ( aa->aa_flags & AFA_PHASE2 ) {
346
if ( M_HASCL( m ) || m->m_off - MMINOFF < sizeof( struct llc )) {
347
if (( m0 = m_copy( m, 0, m->m_len )) == 0 ) {
351
if ( M_HASCL( m )) { /* m is a cluster */
358
m0->m_next = m->m_next;
360
m->m_off = MMAXOFF - sizeof( struct llc );
361
m->m_len = sizeof( struct llc );
363
m->m_off -= sizeof( struct llc );
364
m->m_len += sizeof( struct llc );
367
llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
368
llc.llc_control = LLC_UI;
369
bcopy( at_org_code, llc.llc_org_code, sizeof( at_org_code ));
370
llc.llc_ether_type = htons( ETHERTYPE_AT );
371
bcopy( &llc, mtod( m, caddr_t ), sizeof( struct llc ));
372
ether_atalk[ 0 ].ef_ethertype = EF_8023_TYPE;
375
ether_atalk[ 0 ].ef_ethertype = ETHERTYPE_AT;