OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [x25/] [x25_dev.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      X.25 Packet Layer release 002
3
 *
4
 *      This is ALPHA test software. This code may break your machine, randomly fail to work with new
5
 *      releases, misbehave and/or generally screw up. It might even work.
6
 *
7
 *      This code REQUIRES 2.1.15 or higher
8
 *
9
 *      This module:
10
 *              This module is free software; you can redistribute it and/or
11
 *              modify it under the terms of the GNU General Public License
12
 *              as published by the Free Software Foundation; either version
13
 *              2 of the License, or (at your option) any later version.
14
 *
15
 *      History
16
 *      X.25 001        Jonathan Naylor Started coding.
17
 *      2000-09-04      Henner Eisen    Prevent freeing a dangling skb.
18
 */
19
 
20
#include <linux/config.h>
21
#include <linux/errno.h>
22
#include <linux/types.h>
23
#include <linux/socket.h>
24
#include <linux/in.h>
25
#include <linux/kernel.h>
26
#include <linux/sched.h>
27
#include <linux/timer.h>
28
#include <linux/string.h>
29
#include <linux/sockios.h>
30
#include <linux/net.h>
31
#include <linux/stat.h>
32
#include <linux/inet.h>
33
#include <linux/netdevice.h>
34
#include <linux/skbuff.h>
35
#include <net/sock.h>
36
#include <asm/segment.h>
37
#include <asm/system.h>
38
#include <asm/uaccess.h>
39
#include <linux/fcntl.h>
40
#include <linux/termios.h>      /* For TIOCINQ/OUTQ */
41
#include <linux/mm.h>
42
#include <linux/interrupt.h>
43
#include <linux/notifier.h>
44
#include <linux/proc_fs.h>
45
#include <linux/if_arp.h>
46
#include <net/x25.h>
47
 
48
static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh)
49
{
50
        struct sock *sk;
51
        unsigned short frametype;
52
        unsigned int lci;
53
 
54
        frametype = skb->data[2];
55
        lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
56
 
57
        /*
58
         *      LCI of zero is always for us, and its always a link control
59
         *      frame.
60
         */
61
        if (lci == 0) {
62
                x25_link_control(skb, neigh, frametype);
63
                return 0;
64
        }
65
 
66
        /*
67
         *      Find an existing socket.
68
         */
69
        if ((sk = x25_find_socket(lci, neigh)) != NULL) {
70
                int queued = 1;
71
 
72
                skb->h.raw = skb->data;
73
                bh_lock_sock(sk);
74
                if (!sk->lock.users) {
75
                        queued = x25_process_rx_frame(sk, skb);
76
                } else {
77
                        sk_add_backlog(sk, skb);
78
                }
79
                bh_unlock_sock(sk);
80
                return queued;
81
        }
82
 
83
        /*
84
         *      Is is a Call Request ? if so process it.
85
         */
86
        if (frametype == X25_CALL_REQUEST)
87
                return x25_rx_call_request(skb, neigh, lci);
88
 
89
        /*
90
         *      Its not a Call Request, nor is it a control frame.
91
         *      Let caller throw it away.
92
         */
93
/*
94
        x25_transmit_clear_request(neigh, lci, 0x0D);
95
*/
96
        printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype);
97
 
98
        return 0;
99
}
100
 
101
int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
102
{
103
        struct x25_neigh *neigh;
104
        int queued;
105
 
106
        skb->sk = NULL;
107
 
108
        /*
109
         *      Packet received from unrecognised device, throw it away.
110
         */
111
        if ((neigh = x25_get_neigh(dev)) == NULL) {
112
                printk(KERN_DEBUG "X.25: unknown neighbour - %s\n", dev->name);
113
                kfree_skb(skb);
114
                return 0;
115
        }
116
 
117
        switch (skb->data[0]) {
118
                case 0x00:
119
                        skb_pull(skb, 1);
120
                        queued = x25_receive_data(skb, neigh);
121
                        if( ! queued )
122
                                /* We need to free the skb ourselves because
123
                                 * net_bh() won't care about our return code.
124
                                 */
125
                                kfree_skb(skb);
126
                        return 0;
127
 
128
                case 0x01:
129
                        x25_link_established(neigh);
130
                        kfree_skb(skb);
131
                        return 0;
132
 
133
                case 0x02:
134
                        x25_link_terminated(neigh);
135
                        kfree_skb(skb);
136
                        return 0;
137
 
138
                case 0x03:
139
                        kfree_skb(skb);
140
                        return 0;
141
 
142
                default:
143
                        kfree_skb(skb);
144
                        return 0;
145
        }
146
}
147
 
148
int x25_llc_receive_frame(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
149
{
150
        struct x25_neigh *neigh;
151
 
152
        skb->sk = NULL;
153
 
154
        /*
155
         *      Packet received from unrecognised device, throw it away.
156
         */
157
        if ((neigh = x25_get_neigh(dev)) == NULL) {
158
                printk(KERN_DEBUG "X.25: unknown_neighbour - %s\n", dev->name);
159
                kfree_skb(skb);
160
                return 0;
161
        }
162
 
163
        return x25_receive_data(skb, neigh);
164
}
165
 
166
void x25_establish_link(struct x25_neigh *neigh)
167
{
168
        struct sk_buff *skb;
169
        unsigned char *ptr;
170
 
171
        switch (neigh->dev->type) {
172
                case ARPHRD_X25:
173
                        if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) {
174
                                printk(KERN_ERR "x25_dev: out of memory\n");
175
                                return;
176
                        }
177
                        ptr  = skb_put(skb, 1);
178
                        *ptr = 0x01;
179
                        break;
180
 
181
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
182
                case ARPHRD_ETHER:
183
                        return;
184
#endif
185
                default:
186
                        return;
187
        }
188
 
189
        skb->protocol = htons(ETH_P_X25);
190
        skb->dev      = neigh->dev;
191
 
192
        dev_queue_xmit(skb);
193
}
194
 
195
void x25_terminate_link(struct x25_neigh *neigh)
196
{
197
        struct sk_buff *skb;
198
        unsigned char *ptr;
199
 
200
        switch (neigh->dev->type) {
201
                case ARPHRD_X25:
202
                        if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) {
203
                                printk(KERN_ERR "x25_dev: out of memory\n");
204
                                return;
205
                        }
206
                        ptr  = skb_put(skb, 1);
207
                        *ptr = 0x02;
208
                        break;
209
 
210
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
211
                case ARPHRD_ETHER:
212
                        return;
213
#endif
214
                default:
215
                        return;
216
        }
217
 
218
        skb->protocol = htons(ETH_P_X25);
219
        skb->dev      = neigh->dev;
220
 
221
        dev_queue_xmit(skb);
222
}
223
 
224
void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh)
225
{
226
        unsigned char *dptr;
227
 
228
        skb->nh.raw = skb->data;
229
 
230
        switch (neigh->dev->type) {
231
                case ARPHRD_X25:
232
                        dptr  = skb_push(skb, 1);
233
                        *dptr = 0x00;
234
                        break;
235
 
236
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
237
                case ARPHRD_ETHER:
238
                        kfree_skb(skb);
239
                        return;
240
#endif
241
                default:
242
                        kfree_skb(skb);
243
                        return;
244
        }
245
 
246
        skb->protocol = htons(ETH_P_X25);
247
        skb->dev      = neigh->dev;
248
 
249
        dev_queue_xmit(skb);
250
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.