This source file includes following definitions.
- ax25_output
- ax25_send_iframe
- ax25_kick
- ax25_transmit_buffer
- ax25_nr_error_recovery
- ax25_establish_data_link
- ax25_transmit_enquiry
- ax25_enquiry_response
- ax25_timeout_response
- ax25_check_iframes_acked
- ax25_check_need_response
- dama_enquiry_response
- dama_check_need_response
- dama_establish_data_link
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
29
30
31
32
33
34
35 #include <linux/config.h>
36 #ifdef CONFIG_AX25
37 #include <linux/errno.h>
38 #include <linux/types.h>
39 #include <linux/socket.h>
40 #include <linux/in.h>
41 #include <linux/kernel.h>
42 #include <linux/sched.h>
43 #include <linux/timer.h>
44 #include <linux/string.h>
45 #include <linux/sockios.h>
46 #include <linux/net.h>
47 #include <net/ax25.h>
48 #include <linux/inet.h>
49 #include <linux/netdevice.h>
50 #include <linux/skbuff.h>
51 #include <net/sock.h>
52 #include <asm/segment.h>
53 #include <asm/system.h>
54 #include <linux/fcntl.h>
55 #include <linux/mm.h>
56 #include <linux/interrupt.h>
57
58
59
60
61
62 void ax25_output(ax25_cb *ax25, struct sk_buff *skb)
63 {
64 struct sk_buff *skbn;
65 unsigned char *p;
66 int frontlen, mtu, len, fragno, ka9qfrag, first = 1;
67 long flags;
68
69
70
71
72
73
74
75
76
77 mtu = ax25->paclen;
78
79 if ((skb->len - 1) > mtu) {
80 switch (*skb->data) {
81 case AX25_P_SEGMENT:
82
83 printk("ax25_output(): woops, fragmentation of fragment?!\n");
84
85 case AX25_P_NETROM:
86 case AX25_P_IP:
87 mtu -= 2;
88 ka9qfrag = 1;
89 break;
90 default:
91 ka9qfrag = 0;
92 skb_pull(skb, 1);
93 break;
94
95 }
96
97 fragno = skb->len / mtu;
98 if (skb->len % mtu == 0) fragno--;
99
100 frontlen = skb_headroom(skb);
101
102 while (skb->len > 0) {
103 save_flags(flags);
104 cli();
105
106
107
108
109
110 if ((skbn = alloc_skb(mtu + 2 + frontlen, GFP_ATOMIC)) == NULL) {
111 restore_flags(flags);
112 printk("ax25_output(): alloc_skb returned NULL\n");
113 if (skb_device_locked(skb))
114 skb_device_unlock(skb);
115 return;
116 }
117
118 skbn->sk = skb->sk;
119
120 if (skbn->sk)
121 atomic_add(skbn->truesize, &skbn->sk->wmem_alloc);
122
123 restore_flags(flags);
124
125 skbn->free = 1;
126 skbn->arp = 1;
127
128 len = (mtu > skb->len) ? skb->len : mtu;
129
130 if (ka9qfrag == 1) {
131 skb_reserve(skbn, frontlen + 2);
132
133 memcpy(skb_put(skbn, len), skb->data, len);
134 p = skb_push(skbn, 2);
135
136 *p++ = AX25_P_SEGMENT;
137
138 *p = fragno--;
139 if (first) {
140 *p |= SEG_FIRST;
141 first = 0;
142 }
143 } else {
144 skb_reserve(skbn, frontlen + 1);
145 memcpy(skb_put(skbn, len), skb->data, len);
146 p = skb_push(skbn, 1);
147 *p = AX25_P_TEXT;
148 }
149
150 skb_pull(skb, len);
151 skb_queue_tail(&ax25->write_queue, skbn);
152 }
153
154 skb->free = 1;
155 kfree_skb(skb, FREE_WRITE);
156 } else {
157 skb_queue_tail(&ax25->write_queue, skb);
158 }
159
160 if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
161 if (!ax25->dama_slave)
162 ax25_kick(ax25);
163 }
164 }
165
166
167
168
169
170 static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
171 {
172 unsigned char *frame;
173
174 if (skb == NULL)
175 return;
176
177 if (ax25->modulus == MODULUS) {
178 frame = skb_push(skb, 1);
179
180 *frame = I;
181 *frame |= (poll_bit) ? PF : 0;
182 *frame |= (ax25->vr << 5);
183 *frame |= (ax25->vs << 1);
184 } else {
185 frame = skb_push(skb, 2);
186
187 frame[0] = I;
188 frame[0] |= (ax25->vs << 1);
189 frame[1] = (poll_bit) ? EPF : 0;
190 frame[1] |= (ax25->vr << 1);
191 }
192
193 ax25_transmit_buffer(ax25, skb, C_COMMAND);
194 }
195
196 void ax25_kick(ax25_cb *ax25)
197 {
198 struct sk_buff *skb, *skbn;
199 int last = 1;
200 unsigned short start, end, next;
201
202 del_timer(&ax25->timer);
203
204 start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
205 end = (ax25->va + ax25->window) % ax25->modulus;
206
207 if (!(ax25->condition & PEER_RX_BUSY_CONDITION) &&
208 start != end &&
209 skb_peek(&ax25->write_queue) != NULL) {
210
211 ax25->vs = start;
212
213
214
215
216
217
218
219
220
221
222 skb = skb_dequeue(&ax25->write_queue);
223
224 do {
225 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
226 skb_queue_head(&ax25->write_queue, skb);
227 return;
228 }
229
230 next = (ax25->vs + 1) % ax25->modulus;
231 #ifdef notdef
232 last = (next == end) || skb_peek(&ax25->write_queue) == NULL;
233 #else
234 last = (next == end);
235 #endif
236
237
238
239
240
241 ax25_send_iframe(ax25, skbn, (last && !ax25->dama_slave) ? POLLON : POLLOFF);
242
243 ax25->vs = next;
244
245
246
247
248 skb_queue_tail(&ax25->ack_queue, skb);
249 #ifdef notdef
250 } while (!last);
251 #else
252 } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
253 #endif
254 ax25->condition &= ~ACK_PENDING_CONDITION;
255
256 if (ax25->t1timer == 0) {
257 ax25->t3timer = 0;
258 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
259 }
260 }
261
262 ax25_set_timer(ax25);
263 }
264
265 void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
266 {
267 unsigned char *ptr;
268
269 if (ax25->device == NULL) {
270 if (ax25->sk != NULL) {
271 ax25->sk->state = TCP_CLOSE;
272 ax25->sk->err = ENETUNREACH;
273 if (!ax25->sk->dead)
274 ax25->sk->state_change(ax25->sk);
275 ax25->sk->dead = 1;
276 }
277 return;
278 }
279
280 if (skb_headroom(skb) < size_ax25_addr(ax25->digipeat)) {
281 printk("ax25_transmit_buffer: not enough room for digi-peaters\n");
282 skb->free = 1;
283 kfree_skb(skb, FREE_WRITE);
284 return;
285 }
286
287 ptr = skb_push(skb, size_ax25_addr(ax25->digipeat));
288 build_ax25_addr(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
289
290 skb->arp = 1;
291
292 ax25_queue_xmit(skb, ax25->device, SOPRI_NORMAL);
293 }
294
295
296
297
298
299
300 void ax25_nr_error_recovery(ax25_cb *ax25)
301 {
302 ax25_establish_data_link(ax25);
303 }
304
305 void ax25_establish_data_link(ax25_cb *ax25)
306 {
307 ax25->condition = 0x00;
308 ax25->n2count = 0;
309
310 if (ax25->modulus == MODULUS) {
311 ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
312 } else {
313 ax25_send_control(ax25, SABME, POLLON, C_COMMAND);
314 }
315
316 ax25->t3timer = 0;
317 ax25->t2timer = 0;
318 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
319 }
320
321 void ax25_transmit_enquiry(ax25_cb *ax25)
322 {
323 if (ax25->condition & OWN_RX_BUSY_CONDITION)
324 ax25_send_control(ax25, RNR, POLLON, C_COMMAND);
325 else
326 ax25_send_control(ax25, RR, POLLON, C_COMMAND);
327
328 ax25->condition &= ~ACK_PENDING_CONDITION;
329
330 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
331 }
332
333 void ax25_enquiry_response(ax25_cb *ax25)
334 {
335 if (ax25->condition & OWN_RX_BUSY_CONDITION)
336 ax25_send_control(ax25, RNR, POLLON, C_RESPONSE);
337 else
338 ax25_send_control(ax25, RR, POLLON, C_RESPONSE);
339
340 ax25->condition &= ~ACK_PENDING_CONDITION;
341 }
342
343 void ax25_timeout_response(ax25_cb *ax25)
344 {
345 if (ax25->condition & OWN_RX_BUSY_CONDITION)
346 ax25_send_control(ax25, RNR, POLLOFF, C_RESPONSE);
347 else
348 ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
349
350 ax25->condition &= ~ACK_PENDING_CONDITION;
351 }
352
353 void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
354 {
355 if (ax25->vs == nr) {
356 ax25_frames_acked(ax25, nr);
357 ax25_calculate_rtt(ax25);
358 ax25->t1timer = 0;
359 ax25->t3timer = ax25->t3;
360 } else {
361 if (ax25->va != nr) {
362 ax25_frames_acked(ax25, nr);
363 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
364 }
365 }
366 }
367
368
369
370
371
372 void ax25_check_need_response(ax25_cb *ax25, int type, int pf)
373 {
374 if (!ax25->dama_slave && type == C_COMMAND && pf)
375 ax25_enquiry_response(ax25);
376 }
377
378
379
380
381 void dama_enquiry_response(ax25_cb *ax25)
382 {
383 ax25_cb *ax25o;
384
385 if (!(ax25->condition & PEER_RX_BUSY_CONDITION)) {
386 ax25_requeue_frames(ax25);
387 ax25_kick(ax25);
388 }
389
390 if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 ||
391 skb_peek(&ax25->ack_queue) != NULL) {
392 ax25_t1_timeout(ax25);
393 } else {
394 ax25->n2count = 0;
395 }
396
397 ax25->t3timer = ax25->t3;
398
399
400
401
402
403
404
405
406 #if 0
407 if (ax25->condition & REJECT_CONDITION)
408 ax25_send_control(ax25, REJ, POLLOFF, C_RESPONSE);
409 else
410 #endif
411 ax25_enquiry_response(ax25);
412
413
414
415
416
417 for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
418 if (ax25o->device != ax25->device)
419 continue;
420
421 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
422 ax25_t1_timeout(ax25o);
423 continue;
424 }
425
426 if (!ax25o->dama_slave)
427 continue;
428
429 if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) &&
430 (ax25o->state == AX25_STATE_3 ||
431 (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) {
432 ax25_requeue_frames(ax25o);
433 ax25_kick(ax25o);
434 }
435
436 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 ||
437 skb_peek(&ax25o->ack_queue) != NULL) {
438 ax25_t1_timeout(ax25o);
439 }
440
441 ax25o->t3timer = ax25o->t3;
442 }
443 }
444
445 void dama_check_need_response(ax25_cb *ax25, int type, int pf)
446 {
447 if (ax25->dama_slave && type == C_COMMAND && pf)
448 dama_enquiry_response(ax25);
449 }
450
451 void dama_establish_data_link(ax25_cb *ax25)
452 {
453 ax25->condition = 0x00;
454 ax25->n2count = 0;
455
456 ax25->t3timer = ax25->t3;
457 ax25->t2timer = 0;
458 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
459 }
460
461 #endif