2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * The contents of this file constitute Original Code as defined in and 
   7  * are subject to the Apple Public Source License Version 1.1 (the 
   8  * "License").  You may not use this file except in compliance with the 
   9  * License.  Please obtain a copy of the License at 
  10  * http://www.apple.com/publicsource and read it before using this file. 
  12  * This Original Code and all software distributed under the License are 
  13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the 
  17  * License for the specific language governing rights and limitations 
  20  * @APPLE_LICENSE_HEADER_END@ 
  23  * Copyright 1994 Apple Computer, Inc. 
  24  * All Rights Reserved. 
  26  * Tuyen A. Nguyen. (December 5, 1994) 
  27  *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. 
  30 #include <sys/errno.h> 
  31 #include <sys/types.h> 
  32 #include <sys/param.h> 
  33 #include <machine/spl.h> 
  34 #include <sys/systm.h> 
  35 #include <sys/kernel.h> 
  37 #include <sys/filedesc.h> 
  38 #include <sys/fcntl.h> 
  40 #include <sys/ioctl.h> 
  41 #include <sys/malloc.h> 
  42 #include <sys/socket.h> 
  43 #include <sys/socketvar.h> 
  44 #include <sys/sockio.h> 
  47 #include <net/if_types.h> 
  48 #include <net/if_dl.h> 
  49 #include <net/ethernet.h> 
  51 #include <netat/sysglue.h> 
  52 #include <netat/appletalk.h> 
  53 #include <netat/at_pcb.h> 
  54 #include <netat/at_var.h> 
  55 #include <netat/ddp.h> 
  56 #include <netat/at_aarp.h> 
  57 #include <netat/at_pat.h> 
  58 #include <netat/debug.h> 
  60 #define DSAP_SNAP 0xaa 
  62 extern void gref_init(), atp_init(), atp_link(), atp_unlink(); 
  64 extern int adspInited
; 
  66 static llc_header_t     snap_hdr_at 
= SNAP_HDR_AT
; 
  67 static llc_header_t     snap_hdr_aarp 
= SNAP_HDR_AARP
; 
  68 static unsigned char snap_proto_ddp
[5] = SNAP_PROTO_AT
; 
  69 static unsigned char snap_proto_aarp
[5] = SNAP_PROTO_AARP
; 
  73 struct ifqueue atalkintrq
;      /* appletalk and aarp packet input queue */ 
  75 short appletalk_inited 
= 0; 
  78         ddpall_lock
, ddpinp_lock
, arpinp_lock
, refall_lock
, nve_lock
, 
  79         aspall_lock
, asptmo_lock
, atpall_lock
, atptmo_lock
, atpgen_lock
; 
  81 extern int (*sys_ATsocket 
)(), (*sys_ATgetmsg
)(), (*sys_ATputmsg
)(); 
  82 extern int (*sys_ATPsndreq
)(), (*sys_ATPsndrsp
)(); 
  83 extern int (*sys_ATPgetreq
)(), (*sys_ATPgetrsp
)(); 
  87         extern int _ATsocket(), _ATgetmsg(), _ATputmsg(); 
  88         extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp(); 
  90         sys_ATsocket  
= _ATsocket
; 
  91         sys_ATgetmsg  
= _ATgetmsg
; 
  92         sys_ATputmsg  
= _ATputmsg
; 
  93         sys_ATPsndreq 
= _ATPsndreq
; 
  94         sys_ATPsndrsp 
= _ATPsndrsp
; 
  95         sys_ATPgetreq 
= _ATPgetreq
; 
  96         sys_ATPgetrsp 
= _ATPgetrsp
; 
  98         ATLOCKINIT(ddpall_lock
); 
  99         ATLOCKINIT(ddpinp_lock
); 
 100         ATLOCKINIT(arpinp_lock
); 
 101         ATLOCKINIT(refall_lock
); 
 102         ATLOCKINIT(aspall_lock
); 
 103         ATLOCKINIT(asptmo_lock
); 
 104         ATLOCKINIT(atpall_lock
); 
 105         ATLOCKINIT(atptmo_lock
); 
 106         ATLOCKINIT(atpgen_lock
); 
 107         ATLOCKINIT(nve_lock
); 
 115                 this happens in adsp_open and is undone on ADSP_UNLINK  
 119 /* Undo everything atalk_load() did. */ 
 120 void atalk_unload()  /* not currently used */ 
 122         extern gbuf_t 
*scb_resource_m
; 
 123         extern gbuf_t 
*atp_resource_m
; 
 136         if (scb_resource_m
) {  
 137                 gbuf_freem(scb_resource_m
); 
 141         /* allocated in atp_trans_alloc() */ 
 142         if (atp_resource_m
) { 
 143                 gbuf_freem(atp_resource_m
); 
 145                 atp_trans_free_list 
= 0; 
 149         appletalk_inited 
= 0; 
 152 void appletalk_hack_start() 
 154         if (!appletalk_inited
) { 
 156                 atalkintrq
.ifq_maxlen 
= IFQ_MAXLEN
;  
 157                 appletalk_inited 
= 1; 
 159 } /* appletalk_hack_start */ 
 161 int pat_output(patp
, mlist
, dst_addr
, type
) 
 163         struct mbuf 
*mlist
;                     /* packet chain */ 
 164         unsigned char *dst_addr
; 
 168         llc_header_t 
*llc_header
; 
 171         if (! patp
->aa_ifp
) { 
 172                 for (m 
= mlist
; m
; m 
= mlist
) { 
 173                         mlist 
= m
->m_nextpkt
; 
 180         /* this is for ether_output */ 
 181         dst
.sa_family 
= AF_APPLETALK
; 
 182         dst
.sa_len 
= 2 + sizeof(struct etalk_addr
); 
 183         bcopy (dst_addr
, &dst
.sa_data
[0], sizeof(struct etalk_addr
));  
 185         /* packet chains are used on output and can be tested using aufs */ 
 186         for (m 
= mlist
; m
; m 
= mlist
) { 
 187                 mlist 
= m
->m_nextpkt
; 
 190                 M_PREPEND(m
, sizeof(llc_header_t
), M_DONTWAIT
); 
 195                 llc_header 
= mtod(m
, llc_header_t 
*); 
 197                   (type 
== AARP_AT_TYPE
) ? snap_hdr_aarp 
: snap_hdr_at
; 
 199                 for (m
->m_pkthdr
.len 
= 0, m1 
= m
; m1
; m1 
= m1
->m_next
) 
 200                         m
->m_pkthdr
.len 
+= m1
->m_len
; 
 201                 m
->m_pkthdr
.rcvif 
= 0; 
 203                 /* *** Note: AT is sending out mbufs of type MSG_DATA, 
 205 #ifdef APPLETALK_DEBUG 
 207                     !((m
->m_next
)->m_flags 
& M_EXT
)) 
 208                         kprintf("po: mlen= %d, m2len= %d\n", m
->m_len
,  
 211                 dlil_output(patp
->at_dl_tag
, m
, NULL
, &dst
, 0); 
 221         struct mbuf 
*m
, *m1
, *mlist 
= NULL
; 
 224         llc_header_t 
*llc_header
; 
 227         enet_header_t 
*enet_header
; 
 231         IF_DEQUEUE(&atalkintrq
, m
); 
 237         for ( ; m 
; m 
= mlist
) { 
 238           mlist 
= m
->m_nextpkt
; 
 239 #ifdef APPLETALK_DEBUG 
 240           /* packet chains are not yet in use on input */ 
 241           if (mlist
) kprintf("atalkintr: packet chain\n"); 
 245           if (!appletalk_inited
) { 
 250           if ((m
->m_flags 
& M_PKTHDR
) == 0) { 
 251 #ifdef APPLETALK_DEBUG 
 252                 kprintf("atalkintr: no HDR on packet received"); 
 258           /* make sure the interface this packet was received on is configured 
 260           ifp 
= m
->m_pkthdr
.rcvif
; 
 261           TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) { 
 262                 if (ifID
->aa_ifp 
&& (ifID
->aa_ifp 
== ifp
))  
 265           /* if we didn't find a matching interface */ 
 268                 continue; /* was EAFNOSUPPORT */ 
 271           /* make sure the entire packet header is in the current mbuf */ 
 272           if (m
->m_len 
< ENET_LLC_SIZE 
&& 
 273               (m 
= m_pullup(m
, ENET_LLC_SIZE
)) == 0) { 
 274 #ifdef APPLETALK_DEBUG 
 275                 kprintf("atalkintr: packet too small\n"); 
 280           enet_header 
= mtod(m
, enet_header_t 
*); 
 282           /* Ignore multicast packets from local station */ 
 283           /* *** Note: code for IFTYPE_TOKENTALK may be needed here. *** */ 
 284           if (ifID
->aa_ifp
->if_type 
== IFT_ETHER
) { 
 285                 bcopy((char *)enet_header
->src
, src
, sizeof(src
)); 
 287 #ifdef COMMENT  /* In order to receive packets from the Blue Box, we cannot  
 288                    reject packets whose source address matches our local address. 
 290                 if ((enet_header
->dst
[0] & 1) &&  
 291                     (bcmp(src
, ifID
->xaddr
, sizeof(src
)) == 0)) { 
 292                   /* Packet rejected: think it's a local mcast. */ 
 294                   continue; /* was EAFNOSUPPORT */ 
 298                 llc_header 
= (llc_header_t 
*)(enet_header
+1); 
 300                 /* advance the mbuf pointers past the ethernet header */ 
 301                 m
->m_data 
+= ENET_LLC_SIZE
; 
 302                 m
->m_len 
-= ENET_LLC_SIZE
; 
 306                 if (LLC_PROTO_EQUAL(llc_header
->protocol
,snap_proto_aarp
)) { 
 307                         (void)aarp_rcv_pkt(mtod(m
, aarp_pkt_t 
*), ifID
); 
 310                 else if (LLC_PROTO_EQUAL(llc_header
->protocol
, snap_proto_ddp
)) { 
 311                         /* if we're a router take all pkts */ 
 313                           if (aarp_chk_addr(mtod(m
, at_ddp_t  
*), ifID
) 
 314                               == AARP_ERR_NOT_OURS
) { 
 315 #ifdef APPLETALK_DEBUG 
 316                             kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n", 
 317                                     enet_header
->dst
[0], enet_header
->dst
[1],  
 318                                     enet_header
->dst
[2], enet_header
->dst
[3],  
 319                                     enet_header
->dst
[4], enet_header
->dst
[5],  
 320                                     llc_header
->protocol
[3], 
 321                                     llc_header
->protocol
[4]); 
 324                             continue; /* was EAFNOSUPPORT */ 
 327                         MCHTYPE(m
, MSG_DATA
); /* set the mbuf type */ 
 329                         ifID
->stats
.rcv_packets
++; 
 330                         for (m1 
= m
; m1
; m1 
= m1
->m_next
) 
 331                                 ifID
->stats
.rcv_bytes 
+= m1
->m_len
; 
 334                                 ddp_glean(m
, ifID
, src
); 
 338 #ifdef APPLETALK_DEBUG 
 339                         kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n", 
 340                                 llc_header
->protocol
[3], 
 341                                 llc_header
->protocol
[4]);