[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

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