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