darwin-xnu/bsd/netat/drv_dep.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   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.
  11 * 
  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
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/*
  23 * Copyright 1994 Apple Computer, Inc.
  24 * All Rights Reserved.
  25 *
  26 * Tuyen A. Nguyen. (December 5, 1994)
  27 *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
  28 */
  29
  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>
  36#include <sys/proc.h>
  37#include <sys/filedesc.h>
  38#include <sys/fcntl.h>
  39#include <sys/mbuf.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>
  45
  46#include <net/if.h>
  47#include <net/if_types.h>
  48#include <net/if_dl.h>
  49#include <net/ethernet.h>
  50
  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>
  59
  60#define DSAP_SNAP 0xaa
  61
  62extern void gref_init(), atp_init(), atp_link(), atp_unlink();
  63
  64extern int adspInited;
  65
  66static llc_header_t     snap_hdr_at = SNAP_HDR_AT;
  67static llc_header_t     snap_hdr_aarp = SNAP_HDR_AARP;
  68static unsigned char snap_proto_ddp[5] = SNAP_PROTO_AT;
  69static unsigned char snap_proto_aarp[5] = SNAP_PROTO_AARP;
  70
  71static void at_input_packet(protocol_family_t protocol, mbuf_t m);
  72
  73int pktsIn, pktsOut;
  74
  75struct ifqueue atalkintrq;      /* appletalk and aarp packet input queue */
  76
  77short appletalk_inited = 0;
  78
  79extern atlock_t 
  80        ddpall_lock, ddpinp_lock, arpinp_lock, refall_lock, nve_lock,
  81        aspall_lock, asptmo_lock, atpall_lock, atptmo_lock, atpgen_lock;
  82
  83extern int (*sys_ATsocket )(), (*sys_ATgetmsg)(), (*sys_ATputmsg)();
  84extern int (*sys_ATPsndreq)(), (*sys_ATPsndrsp)();
  85extern int (*sys_ATPgetreq)(), (*sys_ATPgetrsp)();
  86
  87void atalk_load()
  88{
  89        extern int _ATsocket(), _ATgetmsg(), _ATputmsg();
  90        extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp();
  91        extern lck_mtx_t *domain_proto_mtx;
  92
  93        sys_ATsocket  = _ATsocket;
  94        sys_ATgetmsg  = _ATgetmsg;
  95        sys_ATputmsg  = _ATputmsg;
  96        sys_ATPsndreq = _ATPsndreq;
  97        sys_ATPsndrsp = _ATPsndrsp;
  98        sys_ATPgetreq = _ATPgetreq;
  99        sys_ATPgetrsp = _ATPgetrsp;
 100
 101        ATLOCKINIT(ddpall_lock);
 102        ATLOCKINIT(ddpinp_lock);
 103        ATLOCKINIT(arpinp_lock);
 104        ATLOCKINIT(refall_lock);
 105        ATLOCKINIT(aspall_lock);
 106        ATLOCKINIT(asptmo_lock);
 107        ATLOCKINIT(atpall_lock);
 108        ATLOCKINIT(atptmo_lock);
 109        ATLOCKINIT(atpgen_lock);
 110        ATLOCKINIT(nve_lock);
 111
 112        atp_init();
 113        atp_link();
 114        adspInited = 0;
 115
 116/*      adsp_init(); 
 117                for 2225395
 118                this happens in adsp_open and is undone on ADSP_UNLINK 
 119*/
 120        lck_mtx_unlock(domain_proto_mtx);
 121        proto_register_input(PF_APPLETALK, at_input_packet, NULL);
 122        lck_mtx_lock(domain_proto_mtx);
 123} /* atalk_load */
 124
 125/* Undo everything atalk_load() did. */
 126void atalk_unload()  /* not currently used */
 127{
 128        extern gbuf_t *scb_resource_m;
 129        extern gbuf_t *atp_resource_m;
 130
 131        sys_ATsocket  = 0;
 132        sys_ATgetmsg  = 0;
 133        sys_ATputmsg  = 0;
 134        sys_ATPsndreq = 0;
 135        sys_ATPsndrsp = 0;
 136        sys_ATPgetreq = 0;
 137        sys_ATPgetrsp = 0;
 138
 139        atp_unlink();
 140
 141#ifdef NOT_YET
 142        if (scb_resource_m) { 
 143                gbuf_freem(scb_resource_m);
 144                scb_resource_m = 0;
 145                scb_free_list = 0;
 146        }
 147        /* allocated in atp_trans_alloc() */
 148        if (atp_resource_m) {
 149                gbuf_freem(atp_resource_m);
 150                atp_resource_m = 0;
 151                atp_trans_free_list = 0;
 152        }
 153#endif
 154
 155        appletalk_inited = 0;
 156} /* atalk_unload */
 157
 158void appletalk_hack_start()
 159{
 160        if (!appletalk_inited) {
 161                atalk_load();
 162                atalkintrq.ifq_maxlen = IFQ_MAXLEN; 
 163                appletalk_inited = 1;
 164        }
 165} /* appletalk_hack_start */
 166
 167int pat_output(patp, mlist, dst_addr, type)
 168        at_ifaddr_t *patp;
 169        struct mbuf *mlist;                     /* packet chain */
 170        unsigned char *dst_addr;
 171        int     type;
 172{
 173        struct mbuf *m, *m1;
 174        llc_header_t *llc_header;
 175        struct sockaddr dst;
 176
 177        if (! patp->aa_ifp) {
 178                for (m = mlist; m; m = mlist) {
 179                        mlist = m->m_nextpkt;
 180                        m->m_nextpkt = 0;
 181                        m_freem(m);
 182                }
 183                return ENOTREADY;
 184        }
 185
 186        /* this is for ether_output */
 187        dst.sa_family = AF_APPLETALK;
 188        dst.sa_len = 2 + sizeof(struct etalk_addr);
 189        bcopy (dst_addr, &dst.sa_data[0], sizeof(struct etalk_addr)); 
 190
 191        /* packet chains are used on output and can be tested using aufs */
 192        for (m = mlist; m; m = mlist) {
 193                mlist = m->m_nextpkt;
 194                m->m_nextpkt = 0;
 195
 196                M_PREPEND(m, sizeof(llc_header_t), M_DONTWAIT);
 197                if (m == 0) {
 198                        continue;
 199                }
 200
 201                llc_header = mtod(m, llc_header_t *);
 202                *llc_header = 
 203                  (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at;
 204
 205                for (m->m_pkthdr.len = 0, m1 = m; m1; m1 = m1->m_next)
 206                        m->m_pkthdr.len += m1->m_len;
 207                m->m_pkthdr.rcvif = 0;
 208
 209                /* *** Note: AT is sending out mbufs of type MSG_DATA,
 210                   not MT_DATA.  *** */
 211#ifdef APPLETALK_DEBUG
 212                if (m->m_next && 
 213                    !((m->m_next)->m_flags & M_EXT))
 214                        kprintf("po: mlen= %d, m2len= %d\n", m->m_len, 
 215                                (m->m_next)->m_len);
 216#endif
 217                atalk_unlock();
 218                dlil_output(patp->aa_ifp, PF_APPLETALK, m, NULL, &dst, 0);
 219                atalk_lock();
 220
 221                pktsOut++;
 222        }
 223
 224        return 0;
 225} /* pat_output */
 226
 227static void
 228at_input_packet(
 229        __unused protocol_family_t      protocol,
 230        mbuf_t                                          m)
 231{
 232        struct mbuf *m1;
 233        struct ifnet *ifp;
 234        llc_header_t *llc_header;
 235        at_ifaddr_t *ifID;
 236        char src[6];
 237        enet_header_t *enet_header;
 238
 239        if (!appletalk_inited) {
 240                m_freem(m);
 241                return;
 242        }
 243
 244        if ((m->m_flags & M_PKTHDR) == 0) {
 245#ifdef APPLETALK_DEBUG
 246                kprintf("atalkintr: no HDR on packet received");
 247#endif
 248                m_freem(m);
 249                return;
 250        }
 251
 252          /* make sure the interface this packet was received on is configured
 253             for AppleTalk */
 254          ifp = m->m_pkthdr.rcvif;
 255          TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
 256                if (ifID->aa_ifp && (ifID->aa_ifp == ifp)) 
 257                        break;
 258          }
 259          /* if we didn't find a matching interface */
 260          if (!ifID) {
 261                m_freem(m);
 262                return; /* was EAFNOSUPPORT */
 263          }
 264
 265          /* make sure the entire packet header is in the current mbuf */
 266          if (m->m_len < ENET_LLC_SIZE &&
 267              (m = m_pullup(m, ENET_LLC_SIZE)) == 0) {
 268#ifdef APPLETALK_DEBUG
 269                kprintf("atalkintr: packet too small\n");
 270#endif
 271                m_freem(m);
 272                return;
 273          }
 274          enet_header = mtod(m, enet_header_t *);
 275
 276          /* Ignore multicast packets from local station */
 277          /* *** Note: code for IFTYPE_TOKENTALK may be needed here. *** */
 278          if (ifID->aa_ifp->if_type == IFT_ETHER ||
 279                ifID->aa_ifp->if_type == IFT_L2VLAN ||
 280                ifID->aa_ifp->if_type == IFT_IEEE8023ADLAG) {
 281                bcopy((char *)enet_header->src, src, sizeof(src));
 282
 283#ifdef COMMENT  /* In order to receive packets from the Blue Box, we cannot 
 284                   reject packets whose source address matches our local address.
 285                */
 286                if ((enet_header->dst[0] & 1) && 
 287                    (bcmp(src, ifID->xaddr, sizeof(src)) == 0)) {
 288                  /* Packet rejected: think it's a local mcast. */
 289                  m_freem(m);
 290                  return; /* was EAFNOSUPPORT */
 291                }
 292#endif /* COMMENT */
 293
 294                llc_header = (llc_header_t *)(enet_header+1);
 295
 296                /* advance the mbuf pointers past the ethernet header */
 297                m->m_data += ENET_LLC_SIZE;
 298                m->m_len -= ENET_LLC_SIZE;
 299
 300                pktsIn++;
 301
 302                if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) {
 303                        (void)aarp_rcv_pkt(mtod(m, aarp_pkt_t *), ifID);
 304                        m_freem(m);
 305                } 
 306                else if (LLC_PROTO_EQUAL(llc_header->protocol, snap_proto_ddp)) {
 307                        /* if we're a router take all pkts */
 308                        if (!ROUTING_MODE) {
 309                          if (aarp_chk_addr(mtod(m, at_ddp_t  *), ifID)
 310                              == AARP_ERR_NOT_OURS) {
 311#ifdef APPLETALK_DEBUG
 312                            kprintf("pat_input: Packet Rejected: not for us? dest=%x.%x.%x.%x.%x.%x LLC_PROTO= %02x%02x\n",
 313                                    enet_header->dst[0], enet_header->dst[1], 
 314                                    enet_header->dst[2], enet_header->dst[3], 
 315                                    enet_header->dst[4], enet_header->dst[5], 
 316                                    llc_header->protocol[3],
 317                                    llc_header->protocol[4]);
 318#endif
 319                            m_freem(m);
 320                            return; /* was EAFNOSUPPORT */
 321                          }
 322                        }
 323                        MCHTYPE(m, MSG_DATA); /* set the mbuf type */
 324
 325                        ifID->stats.rcv_packets++;
 326                        for (m1 = m; m1; m1 = m1->m_next)
 327                                ifID->stats.rcv_bytes += m1->m_len;
 328
 329                        if (!MULTIPORT_MODE)
 330                                ddp_glean(m, ifID, src);
 331
 332                        ddp_input(m, ifID);
 333                } else {
 334#ifdef APPLETALK_DEBUG
 335                        kprintf("pat_input: Packet Rejected: wrong LLC_PROTO = %02x%02x\n",
 336                                llc_header->protocol[3],
 337                                llc_header->protocol[4]);
 338#endif
 339                        m_freem(m);
 340                }
 341        }
 342}
 343
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.