Annotation of XNU/bsd/net/dlil_ethersubr.c, revision 1.1.1.1

1.1       root        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 (c) 1982, 1989, 1993
                     24:  *     The Regents of the University of California.  All rights reserved.
                     25:  *
                     26:  * Redistribution and use in source and binary forms, with or without
                     27:  * modification, are permitted provided that the following conditions
                     28:  * are met:
                     29:  * 1. Redistributions of source code must retain the above copyright
                     30:  *    notice, this list of conditions and the following disclaimer.
                     31:  * 2. Redistributions in binary form must reproduce the above copyright
                     32:  *    notice, this list of conditions and the following disclaimer in the
                     33:  *    documentation and/or other materials provided with the distribution.
                     34:  * 3. All advertising materials mentioning features or use of this software
                     35:  *    must display the following acknowledgement:
                     36:  *     This product includes software developed by the University of
                     37:  *     California, Berkeley and its contributors.
                     38:  * 4. Neither the name of the University nor the names of its contributors
                     39:  *    may be used to endorse or promote products derived from this software
                     40:  *    without specific prior written permission.
                     41:  *
                     42:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     43:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     44:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     45:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     46:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     47:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     48:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     49:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     50:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     51:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     52:  * SUCH DAMAGE.
                     53:  *
                     54:  */
                     55: 
                     56: 
                     57: 
                     58: #include <sys/param.h>
                     59: #include <sys/systm.h>
                     60: #include <sys/kernel.h>
                     61: #include <sys/malloc.h>
                     62: #include <sys/mbuf.h>
                     63: #include <sys/socket.h>
                     64: #include <sys/sockio.h>
                     65: #include <sys/sysctl.h>
                     66: 
                     67: #include <net/if.h>
                     68: #include <net/netisr.h>
                     69: #include <net/route.h>
                     70: #include <net/if_llc.h>
                     71: #include <net/if_dl.h>
                     72: #include <net/if_types.h>
                     73: #include <net/ndrv.h>
                     74: 
                     75: #if INET
                     76: #include <netinet/in.h>
                     77: #include <netinet/in_var.h>
                     78: #include <netinet/if_ether.h>
                     79: #include <netinet/in_systm.h>
                     80: #include <netinet/ip.h>
                     81: #endif
                     82: 
                     83: 
                     84: #include <sys/socketvar.h>
                     85: #include <net/if_blue.h>
                     86: 
                     87: #include <net/dlil.h>
                     88: 
                     89: 
                     90: #if LLC && CCITT
                     91: extern struct ifqueue pkintrq;
                     92: #endif
                     93: 
                     94: /* General stuff from if_ethersubr.c - may not need some of it */
                     95: 
                     96: #include <netat/at_pat.h>
                     97: #if NETAT
                     98: extern struct ifqueue atalkintrq;
                     99: #endif
                    100: 
                    101: 
                    102: #if BRIDGE
                    103: #include <net/bridge.h>
                    104: #endif
                    105: 
                    106: /* #include "vlan.h" */
                    107: #if NVLAN > 0
                    108: #include <net/if_vlan_var.h>
                    109: #endif /* NVLAN > 0 */
                    110: 
                    111: 
                    112: extern struct ifnet_blue *blue_if;
                    113: extern struct mbuf *splitter_input(struct mbuf *, struct ifnet *);
                    114: 
                    115: static u_long lo_dlt = 0;
                    116: static ivedonethis = 0;
                    117: static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **, 
                    118:                                    struct sockaddr *));
                    119: u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
                    120: 
                    121: #define IFP2AC(IFP) ((struct arpcom *)IFP)
                    122: 
                    123: /* This stuff is new */
                    124: 
                    125: #define DB_HEADER_SIZE 20
                    126: struct en_desc {
                    127:     short           total_len;
                    128:     u_short         ethertype;
                    129:     u_long         dl_tag;
                    130:     struct ifnet    *ifp;
                    131:     struct if_proto *proto;
                    132:     u_long          proto_id_length;
                    133:     u_long           proto_id_data[8]; /* probably less - proto-id and bitmasks */
                    134: };
                    135:     
                    136: #define LITMUS_SIZE 16
                    137: #define ETHER_DESC_BLK_SIZE 50
                    138: #define MAX_INTERFACES 50
                    139: 
                    140: /*
                    141:  * Statics for demux module
                    142:  */
                    143: 
                    144: struct ether_desc_blk_str {
                    145:     u_long   n_blocks;
                    146:     u_long   *block_ptr;
                    147: };
                    148: 
                    149: static struct ether_desc_blk_str ether_desc_blk[MAX_INTERFACES];
                    150: static u_long  litmus_mask[LITMUS_SIZE];
                    151: static u_long  litmus_length = 0;
                    152: 
                    153: 
                    154: /*
                    155:  * Temp static for protocol registration XXX
                    156:  */
                    157: 
                    158: #define MAX_EN_COUNT 30
                    159: 
                    160: static struct if_proto *en_array[MAX_EN_COUNT];
                    161: 
                    162: /*
                    163:  * This could be done below in-line with heavy casting, but the pointer arithmetic is 
                    164:  * prone to error.
                    165:  */
                    166: 
                    167: static
                    168: int  desc_in_bounds(block, current_ptr, offset_length)
                    169:     u_int  block;
                    170:     char   *current_ptr;
                    171:     u_long offset_length;
                    172: {
                    173:     u_long end_of_block;
                    174:     u_long current_ptr_tmp;
                    175: 
                    176:     current_ptr_tmp = (u_long) current_ptr;
                    177:     end_of_block = (u_long) ether_desc_blk[block].block_ptr;
                    178:     end_of_block += (ETHER_DESC_BLK_SIZE * ether_desc_blk[block].n_blocks);
                    179:     if ((current_ptr_tmp + offset_length) < end_of_block)
                    180:        return 1;
                    181:     else
                    182:        return 0;
                    183: }
                    184: 
                    185: 
                    186: /*
                    187:  * Release all descriptor entries owned by this dl_tag (there may be several).
                    188:  * Setting the dl_tag to 0 releases the entry. Eventually we should compact-out
                    189:  * the unused entries.
                    190:  */
                    191: static
                    192: int  ether_del_proto(struct if_proto *proto, u_long dl_tag)
                    193: {
                    194:     char *current_ptr = (char *) ether_desc_blk[proto->ifp->family_cookie].block_ptr;
                    195:     struct en_desc        *ed;
                    196:     int i;
                    197:     int found = 0;
                    198: 
                    199:     ed = (struct en_desc *) current_ptr;
                    200: 
                    201:     while(ed->total_len) {
                    202:        if (ed->dl_tag == dl_tag) {
                    203:            found = 1;
                    204:            ed->dl_tag = 0;
                    205:        }
                    206: 
                    207:        current_ptr += ed->total_len;
                    208:        ed = (struct en_desc *) current_ptr;
                    209:     }
                    210:     
                    211:     if (found) {
                    212:        for (i=0; i < MAX_EN_COUNT; i++)
                    213:            if (en_array[i] == proto) {
                    214:                en_array[i] = 0;
                    215:                break;
                    216:            }
                    217:        
                    218:        return 0;
                    219:     }
                    220:     else
                    221:        return ENOENT;
                    222: }
                    223: 
                    224: 
                    225: 
                    226: static
                    227: int  ether_add_proto(struct ddesc_head_str *desc_head, struct if_proto *proto, u_long dl_tag)
                    228: {
                    229:    char *current_ptr;
                    230:    struct dlil_demux_desc  *desc;
                    231:    u_long                 id_length; /* IN LONGWORDS!!! */
                    232:    struct en_desc         *ed;
                    233:    u_long                 *bitmask;
                    234:    u_long                 *proto_id;
                    235:    int                    i;
                    236:    short                  total_length;
                    237:    u_long                 block_count;
                    238:    u_long                  *tmp;
                    239: 
                    240:    for (i=0; i < MAX_EN_COUNT; i++)
                    241:        if (en_array[i] == 0) {
                    242:           en_array[i] = proto;
                    243:           break;
                    244:        }
                    245:    
                    246:    if (i == MAX_EN_COUNT) {
                    247:           printf("WARNING: ether_add_proto -- Too many attachments\n");
                    248:           return ENOMEM;
                    249:    }
                    250: 
                    251:    TAILQ_FOREACH(desc, desc_head, next) {
                    252:        switch (desc->type) 
                    253:        {
                    254:        case DLIL_DESC_RAW:
                    255:           id_length   = desc->variants.bitmask.proto_id_length;
                    256:           break;
                    257:           
                    258:        case DLIL_DESC_802_2:
                    259:           id_length = 1; 
                    260:           break;
                    261:           
                    262:        case DLIL_DESC_802_2_SNAP:
                    263:           id_length = 2;
                    264:           break;
                    265:           
                    266:        default:
                    267:           return EINVAL;
                    268:        }
                    269: 
                    270: restart:
                    271:        block_count = ether_desc_blk[proto->ifp->family_cookie].n_blocks;
                    272:        current_ptr =  (char *) ether_desc_blk[proto->ifp->family_cookie].block_ptr;
                    273:        ed = (struct en_desc *) current_ptr;
                    274:        total_length = ((id_length << 2) * 2) + DB_HEADER_SIZE;
                    275: 
                    276:        while ((ed->total_len) && (desc_in_bounds(proto->ifp->family_cookie, 
                    277:                              current_ptr, total_length))) {
                    278:           if ((ed->dl_tag == 0) && (total_length <= ed->total_len)) 
                    279:               break;
                    280:           else
                    281:               current_ptr += *(short *)current_ptr;
                    282:           
                    283:           ed = (struct en_desc *) current_ptr;
                    284:        }
                    285: 
                    286:        if (!desc_in_bounds(proto->ifp->family_cookie, current_ptr, total_length)) {
                    287: 
                    288:           tmp = _MALLOC((ETHER_DESC_BLK_SIZE * (block_count + 1)), 
                    289:                         M_IFADDR, M_NOWAIT);
                    290:           if (tmp  == 0) {
                    291:               /*
                    292:                * Remove any previous descriptors set in the call.
                    293:                */
                    294:               ether_del_proto(proto, dl_tag);
                    295:               return ENOMEM;
                    296:           }
                    297: 
                    298:           bzero(tmp, ETHER_DESC_BLK_SIZE * (block_count + 1));
                    299:           bcopy(ether_desc_blk[proto->ifp->family_cookie].block_ptr, 
                    300:                 tmp, (ETHER_DESC_BLK_SIZE * block_count));
                    301:           FREE(ether_desc_blk[proto->ifp->family_cookie].block_ptr, M_IFADDR);
                    302:           ether_desc_blk[proto->ifp->family_cookie].n_blocks = block_count + 1;
                    303:           ether_desc_blk[proto->ifp->family_cookie].block_ptr = tmp;
                    304:           goto restart;
                    305:        }
                    306: 
                    307:        if (ed->total_len == 0)
                    308:           ed->total_len = total_length;
                    309:        ed->ethertype = *((u_short *) desc->native_type);
                    310: 
                    311:        ed->dl_tag    = dl_tag;
                    312:        ed->proto     = proto;
                    313:        ed->proto_id_length = id_length;
                    314:        ed->ifp       = proto->ifp;
                    315: 
                    316:        switch (desc->type)
                    317:        {
                    318:        case DLIL_DESC_RAW:
                    319:           bcopy(desc->variants.bitmask.proto_id, &ed->proto_id_data[0], (id_length << 2) );
                    320:           bcopy(desc->variants.bitmask.proto_id_mask, &ed->proto_id_data[id_length],
                    321:                 (id_length << 2));
                    322:           break;
                    323: 
                    324:        case DLIL_DESC_802_2:
                    325:           ed->proto_id_data[0] = 0;
                    326:           bcopy(&desc->variants.desc_802_2, &ed->proto_id_data[0], 3);
                    327:           ed->proto_id_data[1] = 0xffffff00;
                    328:           break;
                    329: 
                    330:        case DLIL_DESC_802_2_SNAP:
                    331:           /* XXX Add verification of fixed values here */
                    332: 
                    333:           ed->proto_id_data[0] = 0;
                    334:           ed->proto_id_data[1] = 0;
                    335:           bcopy(&desc->variants.desc_802_2_SNAP, &ed->proto_id_data[0], 8);
                    336:           ed->proto_id_data[2] = 0xffffffff;
                    337:           ed->proto_id_data[3] = 0xffffffff;;
                    338:           break;  
                    339:        }
                    340:        
                    341:        if (id_length) {
                    342:           proto_id = (u_long *) &ed->proto_id_data[0];
                    343:           bitmask  = (u_long *) &ed->proto_id_data[id_length];
                    344:           for (i=0; i < (id_length); i++) {
                    345:               litmus_mask[i] &= bitmask[i];
                    346:               litmus_mask[i] &= proto_id[i];
                    347:           }
                    348:           if (id_length > litmus_length)
                    349:               litmus_length = id_length;
                    350:        }
                    351:    }   
                    352: 
                    353:    return 0;
                    354: } 
                    355: 
                    356: 
                    357: static
                    358: int  ether_shutdown()
                    359: {
                    360:     return 0;
                    361: }
                    362: 
                    363: 
                    364: 
                    365: 
                    366: /*
                    367:  * Process a received Ethernet packet;
                    368:  * the packet is in the mbuf chain m without
                    369:  * the ether header, which is provided separately.
                    370:  */
                    371: int
                    372: new_ether_input(m, frame_header, ifp, dl_tag, sync_ok)
                    373:     struct mbuf  *m;
                    374:     char         *frame_header;
                    375:     struct ifnet *ifp;
                    376:     u_long          dl_tag;
                    377:     int          sync_ok;
                    378: 
                    379: {
                    380:     register struct ether_header *eh = (struct ether_header *) frame_header;
                    381:     register struct ifqueue *inq=0;
                    382:     u_short ether_type;
                    383:     int s;
                    384:     u_int16_t ptype = -1;
                    385:     unsigned char buf[18];
                    386: 
                    387: #if ISO || LLC || NETAT
                    388:     register struct llc *l;
                    389: #endif
                    390: 
                    391: 
                    392: #if DLIL_BLUEBOX
                    393: 
                    394:     /*
                    395:      * Y-adapter input processing:
                    396:      *  - Don't split if coming from a dummy if
                    397:      *  - If coming from a real if, if splitting enabled,
                    398:      *    then filter the incoming packet
                    399:      */
                    400:     if (ifp != (struct ifnet *)blue_if)
                    401:     {  /* Is splitter turned on? */
                    402:        if (ifp->if_flags&IFF_SPLITTER)
                    403:        {       m->m_data -= sizeof(struct ether_header);
                    404:        m->m_len += sizeof (struct ether_header);
                    405:        m->m_pkthdr.len += sizeof(struct ether_header);
                    406:        /*
                    407:         * Check to see if destined for BlueBox or Rhapsody
                    408:         * If NULL return, mbuf's been consumed by the BlueBox.
                    409:         * Otherwise, send on to Rhapsody
                    410:         */
                    411:        if ((m = splitter_input(m, ifp)) == NULL)
                    412:            return EJUSTRETURN;
                    413:        m->m_data += sizeof(struct ether_header);
                    414:        m->m_len -= sizeof (struct ether_header);
                    415:        m->m_pkthdr.len -= sizeof(struct ether_header);
                    416:        }
                    417:     } else
                    418:     {  /* Get the "real" IF */
                    419:        ifp = ((struct ndrv_cb *)(blue_if->ifb_so->so_pcb))->nd_if;
                    420:        m->m_pkthdr.rcvif = ifp;
                    421:        blue_if->pkts_looped_b2r++;
                    422:     }
                    423: 
                    424: #endif
                    425:     if ((ifp->if_flags & IFF_UP) == 0) {
                    426:        m_freem(m);
                    427:        return EJUSTRETURN;
                    428:     }
                    429: 
                    430:     ifp->if_lastchange = time;
                    431: 
                    432:     if (eh->ether_dhost[0] & 1) {
                    433:        if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
                    434:                 sizeof(etherbroadcastaddr)) == 0)
                    435:            m->m_flags |= M_BCAST;
                    436:        else
                    437:            m->m_flags |= M_MCAST;
                    438:     }
                    439:     if (m->m_flags & (M_BCAST|M_MCAST))
                    440:        ifp->if_imcasts++;
                    441: 
                    442:     ether_type = ntohs(eh->ether_type);
                    443: 
                    444: #if NVLAN > 0
                    445:        if (ether_type == vlan_proto) {
                    446:                if (vlan_input(eh, m) < 0)
                    447:                        ifp->if_data.ifi_noproto++;
                    448:                return EJUSTRETURN;
                    449:        }
                    450: #endif /* NVLAN > 0 */
                    451: 
                    452:     switch (ether_type) {
                    453: #if INET
                    454:     case ETHERTYPE_IP:
                    455:        if (ipflow_fastforward(m))
                    456:            return EJUSTRETURN;
                    457:        ptype = mtod(m, struct ip *)->ip_p;
                    458:        if ((sync_ok == 0) || 
                    459:            (ptype != IPPROTO_TCP && ptype != IPPROTO_UDP)) {
                    460:            schednetisr(NETISR_IP); 
                    461:        }
                    462: 
                    463:        inq = &ipintrq;
                    464:        break;
                    465: 
                    466:     case ETHERTYPE_ARP:
                    467:        schednetisr(NETISR_ARP);
                    468:        inq = &arpintrq;
                    469:        break;
                    470: #endif
                    471: 
                    472:     default: {
                    473: #if NETAT
                    474:        if (ether_type > ETHERMTU)
                    475:            return ENOENT;
                    476:        l = mtod(m, struct llc *);
                    477:        switch (l->llc_dsap) {
                    478:        case LLC_SNAP_LSAP:
                    479: 
                    480:            /* Temporary hack: check for AppleTalk and AARP packets */
                    481:            /* WARNING we're checking only on the "ether_type" (the 2 bytes
                    482:             * of the SNAP header. This shouldn't be a big deal, 
                    483:             * AppleTalk pat_input is making sure we have the right packets
                    484:             * because it needs to discrimante AARP from EtherTalk packets.
                    485:             */
                    486: 
                    487:            if (l->llc_ssap == LLC_SNAP_LSAP &&
                    488:                l->llc_un.type_snap.control == 0x03) {
                    489: 
                    490: #ifdef APPLETALK_DEBUG
                    491:                printf("new_ether_input: SNAP Cntrol type=0x%x Src=%s\n",
                    492:                       l->llc_un.type_snap.ether_type,
                    493:                       ether_sprintf(buf, &eh->ether_shost));
                    494:                printf("                                     Dst=%s\n",
                    495:                       ether_sprintf(buf, &eh->ether_dhost));
                    496: #endif /* APPLETALK_DEBUG */
                    497: 
                    498:                if ((l->llc_un.type_snap.ether_type == 0x809B) ||
                    499:                    (l->llc_un.type_snap.ether_type == 0x80F3)) {
                    500: 
                    501: 
                    502:                                /*
                    503:                                 * note: for AppleTalk we need to pass the enet header of the
                    504:                                 * packet up stack. To do so, we made sure in that the FULL packet
                    505:                                 * is copied in the mbuf by the mace driver, and only the m_data and
                    506:                                 * length have been shifted to make IP and the other guys happy.
                    507:                                 */
                    508: 
                    509:                    m->m_data -= sizeof(*eh);
                    510:                    m->m_len += sizeof(*eh);
                    511:                    m->m_pkthdr.len += sizeof(*eh);     
                    512: #ifdef APPLETALK_DEBUG
                    513:                    l == (struct llc *)(eh+1);
                    514:                    if (l->llc_un.type_snap.ether_type == 0x80F3) {
                    515:                        kprintf("new_ether_input: RCV AppleTalk type=0x%x Src=%s\n",
                    516:                                l->llc_un.type_snap.ether_type,
                    517:                                ether_sprintf(buf, &eh->ether_shost));
                    518:                        kprintf("                                     Dst=%s\n",
                    519:                                ether_sprintf(buf, &eh->ether_dhost));
                    520:                    }
                    521: #endif /* APPLETALK_DEBUG */
                    522:                    schednetisr(NETISR_APPLETALK);
                    523:                    inq = &atalkintrq ;
                    524:                    
                    525:                    break;
                    526:                }
                    527:            }
                    528:            
                    529:            break;
                    530:            
                    531:            
                    532:        default:
                    533:            return ENOENT;
                    534:        }
                    535: 
                    536: #else /*NETAT*/
                    537:        return ENOENT;
                    538: #endif /* NETAT */
                    539: 
                    540:        }
                    541:     }
                    542: 
                    543:     if (inq == 0)
                    544:        return ENOENT;
                    545: 
                    546:        s = splimp();
                    547:        if (IF_QFULL(inq)) {
                    548:                IF_DROP(inq);
                    549:                m_freem(m);
                    550:                splx(s);
                    551:                return EJUSTRETURN;
                    552:        } else
                    553:                IF_ENQUEUE(inq, m);
                    554:        splx(s);
                    555: 
                    556:     if ((sync_ok) && 
                    557:        (ptype == IPPROTO_TCP || ptype == IPPROTO_UDP)) {
                    558:        extern void ipintr(void);
                    559: 
                    560:        s = splnet();
                    561:        ipintr();
                    562:        splx(s);
                    563:     }
                    564: 
                    565:     return 0;
                    566: }
                    567: 
                    568: 
                    569: 
                    570: 
                    571: int ether_demux(ifp, m, frame_header, proto)
                    572:     struct ifnet *ifp;
                    573:     struct mbuf  *m;
                    574:     char         *frame_header;
                    575:     struct if_proto **proto;
                    576: 
                    577: {
                    578:     register struct ether_header *eh = (struct ether_header *)frame_header;
                    579:     u_short ether_type;
                    580:     char *current_ptr = (char *) ether_desc_blk[ifp->family_cookie].block_ptr;
                    581:     struct dlil_demux_desc  *desc;
                    582:     register u_long          temp;
                    583:     u_long                 *data;
                    584:     register struct if_proto *ifproto;
                    585:     u_long                  i;
                    586:     struct en_desc          *ed;
                    587: 
                    588: 
                    589:     if (eh->ether_dhost[0] & 1) {
                    590:        if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
                    591:                 sizeof(etherbroadcastaddr)) == 0)
                    592:            m->m_flags |= M_BCAST;
                    593:        else
                    594:            m->m_flags |= M_MCAST;
                    595:     }
                    596: 
                    597:     ether_type = ntohs(eh->ether_type);
                    598: 
                    599:     /* 
                    600:      * Search through the connected protocols for a match. 
                    601:      */
                    602: 
                    603: 
                    604:     data = mtod(m, u_long *);
                    605:     ed = (struct en_desc *) current_ptr;
                    606:     while (desc_in_bounds(ifp->family_cookie, current_ptr, DB_HEADER_SIZE)) {
                    607:        if (ed->total_len == 0)
                    608:            break;
                    609: 
                    610:        if ((ed->dl_tag !=  0) && (ed->ifp == ifp) && 
                    611:            ((ed->ethertype == ntohs(eh->ether_type)) || (ed->ethertype == 0))) {
                    612:            if (ed->proto_id_length) {
                    613:                for (i=0; i < (ed->proto_id_length); i++) {
                    614:                    temp = ntohs(data[i]) & ed->proto_id_data[ed->proto_id_length + i];
                    615:                    if ((temp ^ ed->proto_id_data[i]))
                    616:                        break;
                    617:                }
                    618: 
                    619:                if (i >= (ed->proto_id_length)) {
                    620:                    *proto = ed->proto;
                    621:                    return 0;
                    622:                }
                    623:            }
                    624:            else {
                    625:                *proto = ed->proto;
                    626:                return 0;
                    627:            }
                    628:        }
                    629:        current_ptr += ed->total_len;
                    630:        ed = (struct en_desc *) current_ptr;
                    631:     }
                    632: 
                    633: /*
                    634:     kprintf("ether_demux - No match for <%x><%x><%x><%x><%x><%x><%x<%x>\n",
                    635:            eh->ether_type,data[0], data[1], data[2], data[3], data[4],data[5],data[6]);
                    636: */
                    637: 
                    638:     return ENOENT;
                    639: }                      
                    640: 
                    641: 
                    642: 
                    643: /*
                    644:  * Ethernet output routine.
                    645:  * Encapsulate a packet of type family for the local net.
                    646:  * Use trailer local net encapsulation if enough data in first
                    647:  * packet leaves a multiple of 512 bytes of data in remainder.
                    648:  * Assumes that ifp is actually pointer to arpcom structure.
                    649:  */
                    650: int
                    651: ether_frameout(ifp, m, ndest, edst, ether_type)
                    652:        register struct ifnet   *ifp;
                    653:        struct mbuf             **m;
                    654:        struct sockaddr         *ndest;
                    655:        char                    *edst;
                    656:        char                    *ether_type;
                    657: {
                    658:        register struct ether_header *eh;
                    659:        int hlen;       /* link layer header lenght */
                    660:        struct arpcom *ac = IFP2AC(ifp);
                    661: 
                    662: 
                    663:        hlen = ETHER_HDR_LEN;
                    664: 
                    665:        /*
                    666:         * If a simplex interface, and the packet is being sent to our
                    667:         * Ethernet address or a broadcast address, loopback a copy.
                    668:         * XXX To make a simplex device behave exactly like a duplex
                    669:         * device, we should copy in the case of sending to our own
                    670:         * ethernet address (thus letting the original actually appear
                    671:         * on the wire). However, we don't do that here for security
                    672:         * reasons and compatibility with the original behavior.
                    673:         */
                    674:        if ((ifp->if_flags & IFF_SIMPLEX) &&
                    675:            ((*m)->m_flags & M_LOOP)) {
                    676:            if (lo_dlt == 0) 
                    677:                dlil_find_dltag(APPLE_IF_FAM_LOOPBACK, 0, PF_INET, &lo_dlt);
                    678: 
                    679:            if (lo_dlt) {
                    680:                if ((*m)->m_flags & M_BCAST) {
                    681:                    struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL);
                    682:                    dlil_output(lo_dlt, n, 0, ndest, 0);
                    683:                } 
                    684:                else 
                    685:                {
                    686:                    if (bcmp(edst,  ac->ac_enaddr, ETHER_ADDR_LEN) == 0) {
                    687:                        dlil_output(lo_dlt, *m, 0, ndest, 0);
                    688:                        return EJUSTRETURN;
                    689:                    }
                    690:                }
                    691:            }
                    692:        }
                    693: 
                    694: 
                    695:        /*
                    696:         * Add local net header.  If no space in first mbuf,
                    697:         * allocate another.
                    698:         */
                    699:        M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT);
                    700:        if (*m == 0) {
                    701:            return (EJUSTRETURN);
                    702:        }
                    703: 
                    704: 
                    705:        eh = mtod(*m, struct ether_header *);
                    706:        (void)memcpy(&eh->ether_type, ether_type,
                    707:                sizeof(eh->ether_type));
                    708:        (void)memcpy(eh->ether_dhost, edst, 6);
                    709:        (void)memcpy(eh->ether_shost, ac->ac_enaddr,
                    710:            sizeof(eh->ether_shost));
                    711: 
                    712: #if DLIL_BLUEBOX
                    713:        /*
                    714:         * We're already to send.  Let's check for the blue box...
                    715:         */
                    716:        if (ifp->if_flags&IFF_SPLITTER)
                    717:        {       
                    718:            (*m)->m_flags |= 0x10;
                    719:            if ((*m = splitter_input(*m, ifp)) == NULL) 
                    720:                return EJUSTRETURN;
                    721:            else
                    722:                return (0);
                    723:        }
                    724:        else
                    725: #endif
                    726:            return 0;
                    727: }
                    728: 
                    729: 
                    730: static
                    731: int  ether_add_if(struct ifnet *ifp)
                    732: {
                    733:     u_long  i;
                    734: 
                    735:     ifp->if_framer = ether_frameout;
                    736:     ifp->if_demux  = ether_demux;
                    737: 
                    738:     for (i=0; i < MAX_INTERFACES; i++)
                    739:        if (ether_desc_blk[i].n_blocks == 0)
                    740:            break;
                    741: 
                    742:     if (i == MAX_INTERFACES)
                    743:        return EOVERFLOW;
                    744: 
                    745:     ether_desc_blk[i].block_ptr = _MALLOC(ETHER_DESC_BLK_SIZE, M_IFADDR, M_NOWAIT);
                    746:     if (ether_desc_blk[i].block_ptr == 0)
                    747:        return ENOMEM;
                    748: 
                    749:     ether_desc_blk[i].n_blocks = 1;
                    750:     bzero(ether_desc_blk[i].block_ptr, ETHER_DESC_BLK_SIZE);
                    751: 
                    752:     ifp->family_cookie = i;
                    753:     
                    754:     return 0;
                    755: }
                    756: 
                    757: static
                    758: int  ether_del_if(struct ifnet *ifp)
                    759: {
                    760:     if ((ifp->family_cookie < MAX_INTERFACES) &&
                    761:        (ether_desc_blk[ifp->family_cookie].n_blocks)) {
                    762:        FREE(ether_desc_blk[ifp->family_cookie].block_ptr, M_IFADDR);
                    763:        ether_desc_blk[ifp->family_cookie].n_blocks = 0;
                    764:        return 0;
                    765:     }
                    766:     else
                    767:        return ENOENT;
                    768: }
                    769: 
                    770: 
                    771: 
                    772: 
                    773: int
                    774: ether_pre_output(ifp, m0, dst_netaddr, route, type, edst, dl_tag )
                    775:     struct ifnet    *ifp;
                    776:     struct mbuf     **m0;
                    777:     struct sockaddr *dst_netaddr;
                    778:     caddr_t        route;
                    779:     char           *type;
                    780:     char            *edst;
                    781:     u_long         dl_tag;
                    782: {
                    783:     struct rtentry  *rt0 = (struct rtentry *) route;
                    784:     int s;
                    785:     register struct mbuf *m = *m0;
                    786:     register struct rtentry *rt;
                    787:     register struct ether_header *eh;
                    788:     int off, len = m->m_pkthdr.len;
                    789:     int hlen;  /* link layer header lenght */
                    790:     struct arpcom *ac = IFP2AC(ifp);
                    791: 
                    792: 
                    793: 
                    794:     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 
                    795:        return ENETDOWN;
                    796: 
                    797:     rt = rt0;
                    798:     if (rt) {
                    799:        if ((rt->rt_flags & RTF_UP) == 0) {
                    800:            rt0 = rt = rtalloc1(dst_netaddr, 1, 0UL);
                    801:            if (rt0)
                    802:                rt->rt_refcnt--;
                    803:            else
                    804:                return EHOSTUNREACH;
                    805:        }
                    806: 
                    807:        if (rt->rt_flags & RTF_GATEWAY) {
                    808:            if (rt->rt_gwroute == 0)
                    809:                goto lookup;
                    810:            if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
                    811:                rtfree(rt); rt = rt0;
                    812:            lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
                    813:                                              0UL);
                    814:                if ((rt = rt->rt_gwroute) == 0)
                    815:                    return (EHOSTUNREACH);
                    816:            }
                    817:        }
                    818: 
                    819:        
                    820:        if (rt->rt_flags & RTF_REJECT)
                    821:            if (rt->rt_rmx.rmx_expire == 0 ||
                    822:                time_second < rt->rt_rmx.rmx_expire)
                    823:                return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
                    824:     }
                    825: 
                    826:     hlen = ETHER_HDR_LEN;
                    827: 
                    828:     /*
                    829:      * Tell ether_frameout it's ok to loop packet unless negated below.
                    830:      */
                    831:     m->m_flags |= M_LOOP;
                    832: 
                    833:     switch (dst_netaddr->sa_family) {
                    834: 
                    835: #if INET
                    836:     case AF_INET:
                    837:        if (!arpresolve(ac, rt, m, dst_netaddr, edst, rt0))
                    838:            return (EJUSTRETURN);       /* if not yet resolved */
                    839:        off = m->m_pkthdr.len - m->m_len;
                    840:        *(u_short *)type = htons(ETHERTYPE_IP);
                    841:        break;
                    842: #endif
                    843: 
                    844:     case AF_UNSPEC:
                    845:        m->m_flags &= ~M_LOOP;
                    846:        eh = (struct ether_header *)dst_netaddr->sa_data;
                    847:        (void)memcpy(edst, eh->ether_dhost, 6);
                    848:        *(u_short *)type = eh->ether_type;
                    849:        break;
                    850:        
                    851: #if NETAT
                    852:     case AF_APPLETALK:
                    853:     {
                    854:        eh = (struct ether_header *)dst_netaddr->sa_data;
                    855:        bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, 6);
                    856:                
                    857:        *(u_short *)type = m->m_pkthdr.len;
                    858:     }
                    859:     break;
                    860: 
                    861: #endif /* NETAT */
                    862: 
                    863:     default:
                    864:        kprintf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
                    865:               dst_netaddr->sa_family);
                    866: 
                    867:         return EAFNOSUPPORT;
                    868:     }
                    869: 
                    870:     return (0);
                    871: }
                    872: 
                    873: 
                    874: 
                    875: 
                    876: 
                    877: int
                    878: ether_ioctl(dl_tag, ifp, command, data)
                    879:     u_long       dl_tag;
                    880:     struct ifnet *ifp;
                    881:     int          command;
                    882:     caddr_t      data;
                    883: {
                    884:     struct ifaddr *ifa = (struct ifaddr *) data;
                    885:     struct ifreq *ifr = (struct ifreq *) data;
                    886:     int error = 0;
                    887:     boolean_t funnel_state;
                    888: 
                    889:     funnel_state = thread_set_funneled(TRUE);
                    890: 
                    891:     switch (command) {
                    892:     case SIOCSIFADDR:
                    893:        ifp->if_flags |= IFF_UP;
                    894: 
                    895:        switch (ifa->ifa_addr->sa_family) {
                    896: 
                    897:        case AF_INET:
                    898: 
                    899:            if (ifp->if_init)
                    900:                ifp->if_init(ifp->if_softc);    /* before arpwhohas */
                    901: 
                    902: 
                    903:            arp_ifinit(IFP2AC(ifp), ifa);
                    904: 
                    905:            break;
                    906: 
                    907:        default:
                    908:            break;
                    909:        }
                    910: 
                    911:        break;
                    912: 
                    913:     case SIOCGIFADDR:
                    914:     {
                    915:        struct sockaddr *sa;
                    916: 
                    917:        sa = (struct sockaddr *) & ifr->ifr_data;
                    918:        bcopy(IFP2AC(ifp)->ac_enaddr,
                    919:              (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
                    920:     }
                    921:     break;
                    922: 
                    923:     case SIOCSIFMTU:
                    924:        /*
                    925:         * Set the interface MTU.
                    926:         */
                    927:        if (ifr->ifr_mtu > ETHERMTU) {
                    928:            error = EINVAL;
                    929:        } else {
                    930:            ifp->if_mtu = ifr->ifr_mtu;
                    931:        }
                    932:        break;
                    933:     }
                    934: 
                    935:     (void) thread_set_funneled(funnel_state);
                    936: 
                    937:     return (error);
                    938: }
                    939: 
                    940: 
                    941: 
                    942: 
                    943: /*
                    944:  * Y-adapter filter check
                    945:  * The rules here:
                    946:  *  For Rhap: return 1
                    947:  *  For Both: return 0
                    948:  *  Not for Rhap: return -1
                    949:  *  Multicast/Broadcast => For Both
                    950:  *  Atalk address registered
                    951:  *   filter matches => For Rhap else Not For Rhap
                    952:  *  IP address registered
                    953:  *   filter matches => For Rhap else Not For Rhap
                    954:  *  For Rhap
                    955:  * Note this is *not* a general filter mechanism in that we know
                    956:  *  what we *could* be looking for.
                    957:  * WARNING: this is a big-endian routine.
                    958:  * Note: ARP and AARP packets are implicitly accepted for "both"
                    959:  */
                    960: int
                    961: Filter_check(struct mbuf **m0)
                    962: {      register struct BlueFilter *bf;
                    963:        register unsigned char *p;
                    964:        register unsigned short *s;
                    965:        register unsigned long *l;
                    966:        int total, flags;
                    967:        struct mbuf *m;
                    968:        extern struct mbuf *m_pullup(struct mbuf *, int);
                    969:        extern void kprintf( const char *, ...);
                    970: #define FILTER_LEN 32
                    971: 
                    972:        m = *m0;
                    973:        flags = m->m_flags;
                    974:        if (FILTER_LEN > m->m_pkthdr.len)
                    975:                return(1);
                    976:        while ((FILTER_LEN > m->m_len) && m->m_next) {
                    977:                total = m->m_len + (m->m_next)->m_len;
                    978:                if ((m = m_pullup(m, min(FILTER_LEN, total))) == 0)
                    979:                        return(-1);
                    980:        }        
                    981:        *m0 = m;
                    982: 
                    983:        p = mtod(m, unsigned char *);   /* Point to destination media addr */
                    984:        if (p[0] & 0x01)        /* Multicast/broadcast */
                    985:                return(0);
                    986:        s = (unsigned short *)p;
                    987:        bf = &RhapFilter[BFS_ATALK];
                    988: #if 0
                    989:        kprintf("!PKT: %x, %x, %x\n", s[6], s[7],       s[8]);
                    990: #endif
                    991: 
                    992:        if (bf->BF_flags)       /* Filtering Appletalk */
                    993:        {
                    994:                l = (unsigned long *)&s[8];
                    995: #if 0
                    996:                kprintf("!AT: %x, %x, %x, %x, %x, %x\n", s[6], s[7],
                    997:                        *l, s[10], s[13], p[30]);
                    998: #endif
                    999:                if (s[6] <= ETHERMTU)
                   1000:                {       if (s[7] == 0xaaaa) /* Could be Atalk */
                   1001:                        {       /* Verify SNAP header */
                   1002:                                if (*l == 0x03080007 && s[10] == 0x809b)
                   1003:                                {       if (s[13] == bf->BF_address &&
                   1004:                                             p[30] == bf->BF_node)
                   1005:                                                return(1);
                   1006:                                } else if (*l == 0x03000000 && s[10] == 0x80f3)
                   1007:                                        /* AARP pkts aren't net-addressed */
                   1008:                                        return(0);
                   1009:                                return(0);
                   1010:                        } else /* Not for us? */
                   1011:                                return(0);
                   1012:                } /* Fall through */
                   1013:        } /* Fall through */
                   1014:        bf++;                   /* Look for IP next */
                   1015:        if (bf->BF_flags)       /* Filtering IP */
                   1016:        {
                   1017:                l = (unsigned long *)&s[15];
                   1018: #if 0
                   1019:                kprintf("!IP: %x, %x\n", s[6], *l);
                   1020: #endif
                   1021:                if (s[6] > ETHERMTU)
                   1022:                {       if (s[6] == 0x800)      /* Is IP */
                   1023:                        {       /* Verify IP address */
                   1024:                                if (*l == bf->BF_address)
                   1025:                                        return(1);
                   1026:                                else    /* Not for us */
                   1027:                                        return(0);
                   1028:                        } else if (s[6] == 0x806)
                   1029:                                /* ARP pkts aren't net-addressed */
                   1030:                                return(0);
                   1031:                }
                   1032:        }
                   1033:        return(0);              /* No filters => Accept */
                   1034: }
                   1035: 
                   1036: 
                   1037: 
                   1038: int ether_family_init()
                   1039: {
                   1040: 
                   1041:     int  i;
                   1042: 
                   1043:     if (ivedonethis)
                   1044:        return 0;
                   1045: 
                   1046:     ivedonethis = 1;
                   1047: 
                   1048: 
                   1049:     if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET, ether_add_if, ether_del_if,
                   1050:                        ether_add_proto, ether_del_proto,
                   1051:                            ether_shutdown)) {
                   1052:        printf("WARNING: ether_family_init -- Can't register if family modules\n");
                   1053:        return EIO;
                   1054:     }
                   1055: 
                   1056:     for (i=0; i < (LITMUS_SIZE/4); i++)
                   1057:        litmus_mask[i] = 0xffffffff;
                   1058: 
                   1059:     for (i=0; i < MAX_EN_COUNT; i++)
                   1060:        en_array[i] = (struct if_proto *) 0;
                   1061: 
                   1062:     for (i=0; i < MAX_INTERFACES; i++)
                   1063:        ether_desc_blk[i].n_blocks = 0;
                   1064: 
                   1065:     return 0;
                   1066: }
                   1067: 
                   1068: 
                   1069: 
                   1070: u_long  ether_attach_inet(struct ifnet *ifp)
                   1071: {
                   1072:     struct dlil_proto_reg_str   reg;
                   1073:     struct dlil_demux_desc      desc;
                   1074:     struct dlil_demux_desc      desc2;
                   1075:     u_long                     ip_dl_tag=0;
                   1076:     u_short en_native=ETHERTYPE_IP;
                   1077:     u_short arp_native=ETHERTYPE_ARP;
                   1078:     int   stat;
                   1079:     int i;
                   1080: 
                   1081: 
                   1082:     for (i=0; i < MAX_EN_COUNT; i++)
                   1083:        if ((en_array[i]) && (en_array[i]->ifp == ifp) && 
                   1084:            (en_array[i]->protocol_family == PF_INET)) {
                   1085:            return en_array[i]->dl_tag;
                   1086:        }
                   1087: 
                   1088:     TAILQ_INIT(&reg.demux_desc_head);
                   1089:     desc.type = DLIL_DESC_RAW;
                   1090:     desc.variants.bitmask.proto_id_length = 0;
                   1091:     desc.variants.bitmask.proto_id = 0;
                   1092:     desc.variants.bitmask.proto_id_mask = 0;
                   1093:     desc.native_type = (char *) &en_native;
                   1094:     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc, next);
                   1095:     reg.interface_family = ifp->if_family;
                   1096:     reg.unit_number      = ifp->if_unit;
                   1097:     reg.input            = new_ether_input;
                   1098:     reg.pre_output       = ether_pre_output;
                   1099:     reg.event            = 0;
                   1100:     reg.offer            = 0;
                   1101:     reg.ioctl            = ether_ioctl;
                   1102:     reg.default_proto    = 1;
                   1103:     reg.protocol_family  = PF_INET;
                   1104: 
                   1105:     desc2 = desc;
                   1106:     desc2.native_type = (char *) &arp_native;
                   1107:     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc2, next);
                   1108: 
                   1109:     stat = dlil_attach_protocol(&reg, &ip_dl_tag);
                   1110:     if (stat) {
                   1111:        printf("WARNING: ether_attach_inet can't attach ip to interface\n");
                   1112:        return stat;
                   1113:     }
                   1114: 
                   1115:     return ip_dl_tag;
                   1116: }
                   1117: 
                   1118: void ether_attach_at(struct ifnet *ifp, u_long *at_dl_tag, u_long *aarp_dl_tag)
                   1119: {
                   1120:     struct dlil_proto_reg_str   reg;
                   1121:     struct dlil_demux_desc      desc;
                   1122:     struct dlil_demux_desc      desc2;
                   1123:     u_short native = 0;           /* 802.2 frames use a length here */
                   1124:     int   stat;
                   1125: 
                   1126:     TAILQ_INIT(&reg.demux_desc_head);
                   1127:     desc.type = DLIL_DESC_802_2_SNAP;
                   1128:     desc.variants.desc_802_2_SNAP.dsap = LLC_SNAP_LSAP;
                   1129:     desc.variants.desc_802_2_SNAP.ssap = LLC_SNAP_LSAP;
                   1130:     desc.variants.desc_802_2_SNAP.control_code = 0x03;
                   1131:     desc.variants.desc_802_2_SNAP.org[0] = 0x08;
                   1132:     desc.variants.desc_802_2_SNAP.org[1] = 0x00;
                   1133:     desc.variants.desc_802_2_SNAP.org[2] = 0x07;
                   1134:     desc.variants.desc_802_2_SNAP.protocol_type = 0x809B;
                   1135:     desc.native_type = (char *) &native;
                   1136:     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc, next);
                   1137:     reg.interface_family = ifp->if_family;
                   1138:     reg.unit_number      = ifp->if_unit;
                   1139:     reg.input            = new_ether_input;
                   1140:     reg.pre_output       = ether_pre_output;
                   1141:     reg.event            = 0;
                   1142:     reg.offer            = 0;
                   1143:     reg.ioctl            = ether_ioctl;
                   1144:     reg.default_proto    = 0;
                   1145:     reg.protocol_family  = PF_APPLETALK;
                   1146: 
                   1147:     desc2 = desc;
                   1148:     desc2.variants.desc_802_2_SNAP.protocol_type = 0x80F3;
                   1149:     desc2.variants.desc_802_2_SNAP.org[0] = 0;
                   1150:     desc2.variants.desc_802_2_SNAP.org[1] = 0;
                   1151:     desc2.variants.desc_802_2_SNAP.org[2] = 0;
                   1152: 
                   1153:     TAILQ_INSERT_TAIL(&reg.demux_desc_head, &desc2, next); 
                   1154: 
                   1155:     stat = dlil_attach_protocol(&reg, at_dl_tag);
                   1156:     if (stat) {
                   1157:        printf("WARNING: ether_attach_at can't attach at to interface\n");
                   1158:        return;
                   1159:     }
                   1160: 
                   1161:     *aarp_dl_tag = *at_dl_tag;
                   1162: 
                   1163: } /* ether_attach_at */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.