[BACK]Return to ddp_output.c CVS log [TXT][DIR] Up to [local] / sys / netatalk

Annotation of sys/netatalk/ddp_output.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ddp_output.c,v 1.6 2003/06/06 09:45:08 itojun Exp $   */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1990,1991 Regents of The University of Michigan.
        !             5:  * All Rights Reserved.
        !             6:  *
        !             7:  * Permission to use, copy, modify, and distribute this software and
        !             8:  * its documentation for any purpose and without fee is hereby granted,
        !             9:  * provided that the above copyright notice appears in all copies and
        !            10:  * that both that copyright notice and this permission notice appear
        !            11:  * in supporting documentation, and that the name of The University
        !            12:  * of Michigan not be used in advertising or publicity pertaining to
        !            13:  * distribution of the software without specific, written prior
        !            14:  * permission. This software is supplied as is without expressed or
        !            15:  * implied warranties of any kind.
        !            16:  *
        !            17:  *     Research Systems Unix Group
        !            18:  *     The University of Michigan
        !            19:  *     c/o Mike Clark
        !            20:  *     535 W. William Street
        !            21:  *     Ann Arbor, Michigan
        !            22:  *     +1-313-763-0525
        !            23:  *     netatalk@itd.umich.edu
        !            24:  */
        !            25:
        !            26: /*
        !            27:  * The following is the contents of the COPYRIGHT file from the
        !            28:  * netatalk-1.4a2 distribution, from which this file is derived.
        !            29:  */
        !            30: /*
        !            31:  * Copyright (c) 1990,1996 Regents of The University of Michigan.
        !            32:  *
        !            33:  * All Rights Reserved.
        !            34:  *
        !            35:  *    Permission to use, copy, modify, and distribute this software and
        !            36:  *    its documentation for any purpose and without fee is hereby granted,
        !            37:  *    provided that the above copyright notice appears in all copies and
        !            38:  *    that both that copyright notice and this permission notice appear
        !            39:  *    in supporting documentation, and that the name of The University
        !            40:  *    of Michigan not be used in advertising or publicity pertaining to
        !            41:  *    distribution of the software without specific, written prior
        !            42:  *    permission. This software is supplied as is without expressed or
        !            43:  *    implied warranties of any kind.
        !            44:  *
        !            45:  * This product includes software developed by the University of
        !            46:  * California, Berkeley and its contributors.
        !            47:  *
        !            48:  * Solaris code is encumbered by the following:
        !            49:  *
        !            50:  *     Copyright (C) 1996 by Sun Microsystems Computer Co.
        !            51:  *
        !            52:  *     Permission to use, copy, modify, and distribute this software and
        !            53:  *     its documentation for any purpose and without fee is hereby
        !            54:  *     granted, provided that the above copyright notice appear in all
        !            55:  *     copies and that both that copyright notice and this permission
        !            56:  *     notice appear in supporting documentation.  This software is
        !            57:  *     provided "as is" without express or implied warranty.
        !            58:  *
        !            59:  * Research Systems Unix Group
        !            60:  * The University of Michigan
        !            61:  * c/o Wesley Craig
        !            62:  * 535 W. William Street
        !            63:  * Ann Arbor, Michigan
        !            64:  * +1-313-764-2278
        !            65:  * netatalk@umich.edu
        !            66:  */
        !            67: /*
        !            68:  * None of the Solaris code mentioned is included in OpenBSD.
        !            69:  * This code also relies heavily on previous effort in FreeBSD and NetBSD.
        !            70:  */
        !            71:
        !            72: #include <sys/types.h>
        !            73: #include <sys/param.h>
        !            74: #include <sys/systm.h>
        !            75: #include <sys/mbuf.h>
        !            76: #include <sys/socket.h>
        !            77: #include <sys/errno.h>
        !            78: #include <sys/syslog.h>
        !            79:
        !            80: #include <net/if.h>
        !            81: #include <net/route.h>
        !            82:
        !            83: #include <netinet/in.h>
        !            84: #undef s_net
        !            85: #include <netinet/if_ether.h>
        !            86:
        !            87: #include <machine/endian.h>
        !            88:
        !            89: #include <netatalk/at.h>
        !            90: #include <netatalk/at_var.h>
        !            91: #include <netatalk/ddp.h>
        !            92: #include <netatalk/ddp_var.h>
        !            93: #include <netatalk/at_extern.h>
        !            94:
        !            95: int ddp_output( struct mbuf *, ... );
        !            96: u_int16_t at_cksum( struct mbuf *, int );
        !            97: int ddp_route(struct mbuf *, struct route * );
        !            98:
        !            99: int    ddp_cksum = 1;
        !           100:
        !           101: int
        !           102: ddp_output(struct mbuf *m, ...)
        !           103: {
        !           104:     struct ddpcb       *ddp;
        !           105:     struct ddpehdr     *deh;
        !           106:     va_list            ap;
        !           107:
        !           108:     va_start(ap, m);
        !           109:     ddp = va_arg(ap, struct ddpcb *);
        !           110:     va_end(ap);
        !           111:
        !           112:     M_PREPEND( m, sizeof( struct ddpehdr ), M_DONTWAIT );
        !           113:     if (!m)
        !           114:        return (ENOBUFS);
        !           115:
        !           116:     deh = mtod( m, struct ddpehdr *);
        !           117:     deh->deh_pad = 0;
        !           118:     deh->deh_hops = 0;
        !           119:
        !           120:     deh->deh_len = m->m_pkthdr.len;
        !           121:
        !           122:     deh->deh_dnet = ddp->ddp_fsat.sat_addr.s_net;
        !           123:     deh->deh_dnode = ddp->ddp_fsat.sat_addr.s_node;
        !           124:     deh->deh_dport = ddp->ddp_fsat.sat_port;
        !           125:     deh->deh_snet = ddp->ddp_lsat.sat_addr.s_net;
        !           126:     deh->deh_snode = ddp->ddp_lsat.sat_addr.s_node;
        !           127:     deh->deh_sport = ddp->ddp_lsat.sat_port;
        !           128:
        !           129:     /*
        !           130:      * The checksum calculation is done after all of the other bytes have
        !           131:      * been filled in.
        !           132:      */
        !           133:     if ( ddp_cksum ) {
        !           134:        deh->deh_sum = at_cksum( m, sizeof( int ));
        !           135:     } else {
        !           136:        deh->deh_sum = 0;
        !           137:     }
        !           138:     deh->deh_bytes = htonl( deh->deh_bytes );
        !           139:
        !           140:     return( ddp_route( m, &ddp->ddp_route ));
        !           141: }
        !           142:
        !           143: u_int16_t
        !           144: at_cksum( m, skip )
        !           145:     struct mbuf        *m;
        !           146:     int                skip;
        !           147: {
        !           148:     u_int8_t   *data, *end;
        !           149:     u_long     cksum = 0;
        !           150:
        !           151:     for (; m; m = m->m_next ) {
        !           152:        for ( data = mtod( m, u_int8_t * ), end = data + m->m_len; data < end;
        !           153:                data++ ) {
        !           154:            if ( skip ) {
        !           155:                skip--;
        !           156:                continue;
        !           157:            }
        !           158:            cksum = ( cksum + *data ) << 1;
        !           159:            if ( cksum & 0x00010000 ) {
        !           160:                cksum++;
        !           161:            }
        !           162:            cksum &= 0x0000ffff;
        !           163:        }
        !           164:     }
        !           165:
        !           166:     if ( cksum == 0 ) {
        !           167:        cksum = 0x0000ffff;
        !           168:     }
        !           169:     return( (u_int16_t)cksum );
        !           170: }
        !           171:
        !           172: int
        !           173: ddp_route( m, ro )
        !           174:     struct mbuf                *m;
        !           175:     struct route       *ro;
        !           176: {
        !           177:     struct sockaddr_at gate;
        !           178:     struct elaphdr     *elh;
        !           179:     struct at_ifaddr   *aa = NULL;
        !           180:     struct ifnet       *ifp;
        !           181:     u_int16_t          net;
        !           182:
        !           183:     if ( ro->ro_rt && ( ifp = ro->ro_rt->rt_ifp )) {
        !           184:        net = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_net;
        !           185:        for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {
        !           186:            if ( aa->aa_ifp == ifp &&
        !           187:                    ntohs( net ) >= ntohs( aa->aa_firstnet ) &&
        !           188:                    ntohs( net ) <= ntohs( aa->aa_lastnet )) {
        !           189:                break;
        !           190:            }
        !           191:        }
        !           192:     }
        !           193:     if ( aa == NULL ) {
        !           194:        m_freem( m );
        !           195:        return( EINVAL );
        !           196:     }
        !           197:
        !           198:     /*
        !           199:      * There are several places in the kernel where data is added to
        !           200:      * an mbuf without ensuring that the mbuf pointer is aligned.
        !           201:      * This is bad for transition routing, since phase 1 and phase 2
        !           202:      * packets end up poorly aligned due to the three byte elap header.
        !           203:      */
        !           204:     if ( aa->aa_flags & AFA_PHASE2 ) {
        !           205:        if (( m = m_pullup( m, MIN( MHLEN, m->m_pkthdr.len ))) == 0 ) {
        !           206:            return( ENOBUFS );
        !           207:        }
        !           208:     } else {
        !           209:        M_PREPEND(m, SZ_ELAPHDR, M_DONTWAIT);
        !           210:        if (!m)
        !           211:            return (ENOBUFS);
        !           212:
        !           213:        elh = mtod( m, struct elaphdr *);
        !           214:        elh->el_snode = satosat( &aa->aa_addr )->sat_addr.s_node;
        !           215:        elh->el_type = ELAP_DDPEXTEND;
        !           216:        if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
        !           217:                ntohs( aa->aa_firstnet ) &&
        !           218:                ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
        !           219:                ntohs( aa->aa_lastnet )) {
        !           220:            elh->el_dnode = satosat( &ro->ro_dst )->sat_addr.s_node;
        !           221:        } else {
        !           222:            elh->el_dnode = satosat( ro->ro_rt->rt_gateway )->sat_addr.s_node;
        !           223:        }
        !           224:     }
        !           225:
        !           226:     if ( ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) >=
        !           227:            ntohs( aa->aa_firstnet ) &&
        !           228:            ntohs( satosat( &ro->ro_dst )->sat_addr.s_net ) <=
        !           229:            ntohs( aa->aa_lastnet )) {
        !           230:        gate = *satosat( &ro->ro_dst );
        !           231:     } else {
        !           232:        gate = *satosat( ro->ro_rt->rt_gateway );
        !           233:     }
        !           234:     ro->ro_rt->rt_use++;
        !           235:
        !           236:     /* XXX The NULL should be a struct rtentry */
        !           237:     return((*ifp->if_output)( ifp, m, (struct sockaddr *) &gate, NULL ));
        !           238: }

CVSweb