~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to sys/ultrix/at_ultrix.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1990,1991 Regents of The University of Michigan.
 
3
 * All Rights Reserved.
 
4
 *
 
5
 * Permission to use, copy, modify, and distribute this software and
 
6
 * its documentation for any purpose and without fee is hereby granted,
 
7
 * provided that the above copyright notice appears in all copies and
 
8
 * that both that copyright notice and this permission notice appear
 
9
 * in supporting documentation, and that the name of The University
 
10
 * of Michigan not be used in advertising or publicity pertaining to
 
11
 * distribution of the software without specific, written prior
 
12
 * permission. This software is supplied as is without expressed or
 
13
 * implied warranties of any kind.
 
14
 *
 
15
 *      Research Systems Unix Group
 
16
 *      The University of Michigan
 
17
 *      c/o Mike Clark
 
18
 *      535 W. William Street
 
19
 *      Ann Arbor, Michigan
 
20
 *      +1-313-763-0525
 
21
 *      netatalk@itd.umich.edu
 
22
 */
 
23
 
 
24
#include <sys/types.h>
 
25
#include <sys/mbuf.h>
 
26
#include <sys/socket.h>
 
27
#include <sys/protosw.h>
 
28
#include <sys/ioctl.h>
 
29
#include <sys/errno.h>
 
30
#include <net/if.h>
 
31
#include <net/if_llc.h>
 
32
#include <net/if_to_proto.h>
 
33
#include <net/netisr.h>
 
34
#include <netinet/in.h>
 
35
#undef s_net
 
36
#include <netinet/if_ether.h>
 
37
 
 
38
#include "at.h"
 
39
#include "at_var.h"
 
40
 
 
41
extern u_char   at_org_code[ 3 ];
 
42
extern u_char   aarp_org_code[ 3 ];
 
43
 
 
44
/*
 
45
 * This is the magic input routine, for all AppleTalk related packets.
 
46
 * It will pick up *all* packets received, on all interfaces, apparently.
 
47
 * If it turns out that receiving all packets in this fashion causes
 
48
 * DLI to not receive packets what it should, we may need to call DLI
 
49
 * directly from within the AppleTalk input routines.  Ick.
 
50
 */
 
51
struct mbuf *
 
52
ddp_ifinput( m, ifp, inq, eh )
 
53
    struct mbuf         *m;
 
54
    struct ifnet        *ifp;
 
55
    struct ifqueue      **inq;
 
56
    struct ether_header *eh;
 
57
{
 
58
    struct llc          llc;
 
59
    struct if_family    *ifam;
 
60
 
 
61
    switch ( eh->ether_type ) {
 
62
    case ETHERTYPE_AT :
 
63
        *inq = &atintrq1;
 
64
        smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
 
65
        schednetisr( NETISR_AT );
 
66
        return( m );
 
67
 
 
68
    case ETHERTYPE_AARP :
 
69
        aarpinput( ifp, m );
 
70
        return( 0 );
 
71
 
 
72
    default :
 
73
        if ( eh->ether_type <= ETHERMTU ) {             /* ieee802 */
 
74
            if ( m->m_len < sizeof( struct llc )) {
 
75
                break;
 
76
            }
 
77
 
 
78
            bcopy( mtod( m, caddr_t ), &llc, sizeof( struct llc ));
 
79
            if ( llc.llc_dsap != LLC_SNAP_LSAP ||
 
80
                    llc.llc_ssap != LLC_SNAP_LSAP ||
 
81
                    llc.llc_control != LLC_UI ) {
 
82
                break;
 
83
            }
 
84
 
 
85
            if ( bcmp( llc.llc_org_code, at_org_code,
 
86
                    sizeof( at_org_code )) == 0 &&
 
87
                    ntohs( llc.llc_ether_type ) == ETHERTYPE_AT ) {
 
88
                m_adj( m, sizeof( struct llc ));
 
89
                *inq = &atintrq2;
 
90
                smp_lock( &(*inq)->lk_ifqueue, LK_RETRY );
 
91
                schednetisr( NETISR_AT );
 
92
                return( m );
 
93
            }
 
94
 
 
95
            if ( bcmp( llc.llc_org_code, aarp_org_code,
 
96
                    sizeof( aarp_org_code )) == 0 &&
 
97
                    ntohs( llc.llc_ether_type ) == ETHERTYPE_AARP ) {
 
98
                m_adj( m, sizeof( struct llc ));
 
99
                aarpinput( ifp, m );
 
100
                return( 0 );
 
101
            }
 
102
        }
 
103
    }
 
104
 
 
105
    /*
 
106
     * Check is anyone else wants this packet.
 
107
     */
 
108
    for ( ifam = if_family; ifam->domain != -1; ifam++ ) {
 
109
        if (( eh->ether_type == ifam->if_type || ifam->if_type == -1 ) &&
 
110
                ifam->prswitch &&
 
111
                ifam->prswitch->pr_ifinput != (int (*)())ddp_ifinput ) {
 
112
            break;
 
113
        }
 
114
    }
 
115
    if ( ifam->domain != -1 && ifam->prswitch->pr_ifinput ) {
 
116
        return( (struct mbuf *)(*ifam->prswitch->pr_ifinput)( m, ifp,
 
117
                inq, eh ));
 
118
    }
 
119
 
 
120
    m_freem( m );
 
121
    return( 0 );
 
122
}
 
123
 
 
124
/*
 
125
 * Fill in type and odst. odst is the media output address, i.e.
 
126
 * the MAC layer address. Type is the MAC type. Should be 0 to
 
127
 * indicate IEEE addressing.
 
128
 *
 
129
 * Stupidly enough, there's no way to say "can't send this now."
 
130
 * So, we just let the first packet go into the air. Not much
 
131
 * else to be done, except maybe bitch at DEC. Note: we're not
 
132
 * passing the mbuf to aarpresolve() -- that way it doesn't get
 
133
 * mfree-ed twice.
 
134
 */
 
135
ddp_ifoutput( ifp, m, dst, type, odst )
 
136
    struct ifnet        *ifp;
 
137
    struct mbuf         *m;
 
138
    struct sockaddr_at  *dst;
 
139
    short               *type;
 
140
    char                *odst;
 
141
{
 
142
    struct at_ifaddr    *aa;
 
143
    struct llc          *llc;
 
144
    struct mbuf         *m0;
 
145
 
 
146
    if ( !aarpresolve( ifp, 0, dst, odst )) {
 
147
        *type = 0xffff;
 
148
        return( 0 );
 
149
    }
 
150
 
 
151
    if (( aa = (struct at_ifaddr *)at_ifawithnet( dst, ifp->if_addrlist ))
 
152
            == 0 ) {
 
153
        *type = 0xffff;
 
154
        return( 0 );
 
155
    }
 
156
 
 
157
    if ( aa->aa_flags & AFA_PHASE2 ) {
 
158
        /*
 
159
         * This code needs to be modeled after the similar code in
 
160
         * at_sun.c -- you can't just MGET() and bcopy(), since we might be
 
161
         * dealing with mbufs which are really pages.
 
162
         */
 
163
        MGET( m0, M_WAIT, MT_HEADER );
 
164
        if ( m0 == 0 ) {
 
165
            *type = 0xffff;
 
166
            return( 0 );
 
167
        }
 
168
        m0->m_next = m->m_next;
 
169
        m0->m_off = m->m_off;
 
170
        m0->m_len = m->m_len;
 
171
        bcopy( mtod( m, caddr_t ), mtod( m0, caddr_t ), m->m_len );
 
172
        m->m_next = m0;
 
173
        m->m_off = MMINOFF;
 
174
        m->m_len = sizeof( struct llc );
 
175
 
 
176
        llc = mtod( m, struct llc *);
 
177
        llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
 
178
        llc->llc_control = LLC_UI;
 
179
        bcopy( at_org_code, llc->llc_org_code, sizeof( at_org_code ));
 
180
        llc->llc_ether_type = htons( ETHERTYPE_AT );
 
181
 
 
182
        /*
 
183
         * Set the type to be the length of the packet, instead of 0.
 
184
         * Ultrix used to put the length in the packet when we set type
 
185
         * to 0, however, now we do it ourselves.
 
186
         */
 
187
        for ( *type = 0; m; m = m->m_next ) {
 
188
            *type += m->m_len;
 
189
        }
 
190
    } else {
 
191
        *type = ETHERTYPE_AT;
 
192
    }
 
193
 
 
194
    return( 1 );
 
195
}
 
196
 
 
197
ddp_ifioctl( ifp, cmd, data )
 
198
    struct ifnet        *ifp;
 
199
    int                 cmd;
 
200
    caddr_t             data;
 
201
{
 
202
    switch( cmd ) {
 
203
    case SIOCSIFADDR :
 
204
        aarpwhohas((struct arpcom *)ifp,
 
205
                &AA_SAT((struct ifaddr *)data)->sat_addr );
 
206
        break;
 
207
    default :
 
208
        return( EINVAL );
 
209
    }
 
210
    return( 0 );
 
211
}