This source file includes following definitions.
- nr_queue_rx_frame
- nr_state1_machine
- nr_state2_machine
- nr_state3_machine
- nr_process_rx_frame
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/config.h>
29 #ifdef CONFIG_NETROM
30 #include <linux/errno.h>
31 #include <linux/types.h>
32 #include <linux/socket.h>
33 #include <linux/in.h>
34 #include <linux/kernel.h>
35 #include <linux/sched.h>
36 #include <linux/timer.h>
37 #include <linux/string.h>
38 #include <linux/sockios.h>
39 #include <linux/net.h>
40 #include <net/ax25.h>
41 #include <linux/inet.h>
42 #include <linux/netdevice.h>
43 #include <linux/skbuff.h>
44 #include <net/sock.h>
45 #include <net/ip.h>
46 #include <asm/segment.h>
47 #include <asm/system.h>
48 #include <linux/fcntl.h>
49 #include <linux/mm.h>
50 #include <linux/interrupt.h>
51 #include <net/netrom.h>
52
53 static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
54 {
55 struct sk_buff *skbo, *skbn = skb;
56
57 if (more) {
58 sk->nr->fraglen += skb->len;
59 skb_queue_tail(&sk->nr->frag_queue, skb);
60 return 0;
61 }
62
63 if (!more && sk->nr->fraglen > 0) {
64 sk->nr->fraglen += skb->len;
65 skb_queue_tail(&sk->nr->frag_queue, skb);
66
67 if ((skbn = alloc_skb(sk->nr->fraglen, GFP_ATOMIC)) == NULL)
68 return 1;
69
70 skbn->free = 1;
71 skbn->arp = 1;
72 skbn->sk = sk;
73 sk->rmem_alloc += skbn->truesize;
74 skbn->h.raw = skbn->data;
75
76 skbo = skb_dequeue(&sk->nr->frag_queue);
77 memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
78 kfree_skb(skbo, FREE_READ);
79
80 while ((skbo = skb_dequeue(&sk->nr->frag_queue)) != NULL) {
81 skb_pull(skbo, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
82 memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
83 kfree_skb(skbo, FREE_READ);
84 }
85
86 sk->nr->fraglen = 0;
87 }
88
89 return sock_queue_rcv_skb(sk, skbn);
90 }
91
92
93
94
95
96
97 static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
98 {
99 switch (frametype) {
100
101 case NR_CONNACK:
102 nr_calculate_rtt(sk);
103 sk->window = skb->data[20];
104 sk->nr->your_index = skb->data[17];
105 sk->nr->your_id = skb->data[18];
106 sk->nr->t1timer = 0;
107 sk->nr->t2timer = 0;
108 sk->nr->t4timer = 0;
109 sk->nr->vs = 0;
110 sk->nr->va = 0;
111 sk->nr->vr = 0;
112 sk->nr->vl = 0;
113 sk->nr->state = NR_STATE_3;
114 sk->state = TCP_ESTABLISHED;
115 sk->nr->n2count = 0;
116
117 if (!sk->dead)
118 sk->state_change(sk);
119 break;
120
121 case NR_CONNACK | NR_CHOKE_FLAG:
122 nr_clear_queues(sk);
123 sk->nr->state = NR_STATE_0;
124 sk->state = TCP_CLOSE;
125 sk->err = ECONNREFUSED;
126 if (!sk->dead)
127 sk->state_change(sk);
128 sk->dead = 1;
129 break;
130
131 default:
132 break;
133 }
134
135 return 0;
136 }
137
138
139
140
141
142
143 static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
144 {
145 switch (frametype) {
146
147 case NR_DISCREQ:
148 nr_write_internal(sk, NR_DISCACK);
149
150 case NR_DISCACK:
151 sk->nr->state = NR_STATE_0;
152 sk->state = TCP_CLOSE;
153 sk->err = 0;
154 if (!sk->dead)
155 sk->state_change(sk);
156 sk->dead = 1;
157 break;
158
159 default:
160 break;
161 }
162
163 return 0;
164 }
165
166
167
168
169
170
171 static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype)
172 {
173 struct sk_buff_head temp_queue;
174 struct sk_buff *skbn;
175 unsigned short save_vr;
176 unsigned short nr, ns;
177 int queued = 0;
178
179 nr = skb->data[18];
180 ns = skb->data[17];
181
182 switch (frametype) {
183
184 case NR_CONNREQ:
185 nr_write_internal(sk, NR_CONNACK);
186 break;
187
188 case NR_DISCREQ:
189 nr_clear_queues(sk);
190 nr_write_internal(sk, NR_DISCACK);
191 sk->nr->state = NR_STATE_0;
192 sk->state = TCP_CLOSE;
193 sk->err = 0;
194 if (!sk->dead)
195 sk->state_change(sk);
196 sk->dead = 1;
197 break;
198
199 case NR_DISCACK:
200 nr_clear_queues(sk);
201 sk->nr->state = NR_STATE_0;
202 sk->state = TCP_CLOSE;
203 sk->err = ECONNRESET;
204 if (!sk->dead)
205 sk->state_change(sk);
206 sk->dead = 1;
207 break;
208
209 case NR_INFOACK:
210 case NR_INFOACK | NR_CHOKE_FLAG:
211 case NR_INFOACK | NR_NAK_FLAG:
212 case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
213 if (frametype & NR_CHOKE_FLAG) {
214 sk->nr->condition |= PEER_RX_BUSY_CONDITION;
215 sk->nr->t4timer = nr_default.busy_delay;
216 } else {
217 sk->nr->condition &= ~PEER_RX_BUSY_CONDITION;
218 sk->nr->t4timer = 0;
219 }
220 if (!nr_validate_nr(sk, nr)) {
221 break;
222 }
223 if (frametype & NR_NAK_FLAG) {
224 nr_frames_acked(sk, nr);
225 nr_send_nak_frame(sk);
226 } else {
227 if (sk->nr->condition & PEER_RX_BUSY_CONDITION) {
228 nr_frames_acked(sk, nr);
229 } else {
230 nr_check_iframes_acked(sk, nr);
231 }
232 }
233 break;
234
235 case NR_INFO:
236 case NR_INFO | NR_NAK_FLAG:
237 case NR_INFO | NR_CHOKE_FLAG:
238 case NR_INFO | NR_MORE_FLAG:
239 case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
240 case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
241 case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
242 case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
243 if (frametype & NR_CHOKE_FLAG) {
244 sk->nr->condition |= PEER_RX_BUSY_CONDITION;
245 sk->nr->t4timer = nr_default.busy_delay;
246 } else {
247 sk->nr->condition &= ~PEER_RX_BUSY_CONDITION;
248 sk->nr->t4timer = 0;
249 }
250 if (nr_validate_nr(sk, nr)) {
251 if (frametype & NR_NAK_FLAG) {
252 nr_frames_acked(sk, nr);
253 nr_send_nak_frame(sk);
254 } else {
255 if (sk->nr->condition & PEER_RX_BUSY_CONDITION) {
256 nr_frames_acked(sk, nr);
257 } else {
258 nr_check_iframes_acked(sk, nr);
259 }
260 }
261 }
262 queued = 1;
263 skb_queue_head(&sk->nr->reseq_queue, skb);
264 if (sk->nr->condition & OWN_RX_BUSY_CONDITION)
265 break;
266 skb_queue_head_init(&temp_queue);
267 do {
268 save_vr = sk->nr->vr;
269 while ((skbn = skb_dequeue(&sk->nr->reseq_queue)) != NULL) {
270 ns = skbn->data[17];
271 if (ns == sk->nr->vr) {
272 if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
273 sk->nr->vr = (sk->nr->vr + 1) % NR_MODULUS;
274 } else {
275 sk->nr->condition |= OWN_RX_BUSY_CONDITION;
276 skb_queue_tail(&temp_queue, skbn);
277 }
278 } else if (nr_in_rx_window(sk, ns)) {
279 skb_queue_tail(&temp_queue, skbn);
280 } else {
281 skbn->free = 1;
282 kfree_skb(skbn, FREE_READ);
283 }
284 }
285 while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
286 skb_queue_tail(&sk->nr->reseq_queue, skbn);
287 }
288 } while (save_vr != sk->nr->vr);
289
290
291
292 if (((sk->nr->vl + sk->window) % NR_MODULUS) == sk->nr->vr) {
293 nr_enquiry_response(sk);
294 } else {
295 if (!(sk->nr->condition & ACK_PENDING_CONDITION)) {
296 sk->nr->t2timer = sk->nr->t2;
297 sk->nr->condition |= ACK_PENDING_CONDITION;
298 }
299 }
300 break;
301
302 default:
303 break;
304 }
305
306 return queued;
307 }
308
309
310 int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
311 {
312 int queued = 0, frametype;
313
314 if (sk->nr->state == NR_STATE_0 && sk->dead)
315 return queued;
316
317 if (sk->nr->state != NR_STATE_1 && sk->nr->state != NR_STATE_2 &&
318 sk->nr->state != NR_STATE_3) {
319 printk("nr_process_rx_frame: frame received - state: %d\n", sk->nr->state);
320 return queued;
321 }
322
323 del_timer(&sk->timer);
324
325 frametype = skb->data[19];
326
327 switch (sk->nr->state)
328 {
329 case NR_STATE_1:
330 queued = nr_state1_machine(sk, skb, frametype);
331 break;
332 case NR_STATE_2:
333 queued = nr_state2_machine(sk, skb, frametype);
334 break;
335 case NR_STATE_3:
336 queued = nr_state3_machine(sk, skb, frametype);
337 break;
338 }
339
340 nr_set_timer(sk);
341
342 return queued;
343 }
344
345 #endif