This source file includes following definitions.
- ax25_clear_tx_queue
- ax25_frames_acked
- ax25_validate_nr
- ax25_decode
- ax25_send_control
- ax25_return_dm
- ax25_calculate_t1
- ax25_calculate_rtt
- ax25_parse_addr
- build_ax25_addr
- size_ax25_addr
- ax25_digi_invert
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_AX25
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 <asm/segment.h>
44 #include <asm/system.h>
45 #include <linux/fcntl.h>
46 #include <linux/mm.h>
47 #include <linux/interrupt.h>
48
49
50
51
52
53
54 void ax25_clear_tx_queue(ax25_cb *ax25)
55 {
56 struct sk_buff *skb;
57
58 while ((skb = skb_dequeue(&ax25->write_queue)) != NULL) {
59 skb->free = 1;
60 kfree_skb(skb, FREE_WRITE);
61 }
62
63 while ((skb = skb_dequeue(&ax25->ack_queue)) != NULL) {
64 skb->free = 1;
65 kfree_skb(skb, FREE_WRITE);
66 }
67 }
68
69
70
71
72
73
74 void ax25_frames_acked(ax25_cb *ax25, unsigned short nr)
75 {
76 struct sk_buff *skb, *skb_prev = NULL;
77
78
79
80
81 if (ax25->va != nr) {
82 while (skb_peek(&ax25->ack_queue) != NULL && ax25->va != nr) {
83 skb = skb_dequeue(&ax25->ack_queue);
84 skb->free = 1;
85 kfree_skb(skb, FREE_WRITE);
86 ax25->va = (ax25->va + 1) % MODULUS;
87 }
88 }
89
90
91
92
93
94
95 while ((skb = skb_dequeue(&ax25->ack_queue)) != NULL) {
96 if (skb_prev == NULL)
97 skb_queue_head(&ax25->write_queue, skb);
98 else
99 skb_append(skb_prev, skb);
100 skb_prev = skb;
101 }
102 }
103
104
105
106
107
108 int ax25_validate_nr(ax25_cb *ax25, unsigned short nr)
109 {
110 unsigned short vc = ax25->va;
111
112 while (vc != ax25->vs) {
113 if (nr == vc) return 1;
114 vc = (vc + 1) % MODULUS;
115 }
116
117 if (nr == ax25->vs) return 1;
118
119 return 0;
120 }
121
122 int ax25_decode(unsigned char *frame)
123 {
124 int frametype = ILLEGAL;
125
126 if ((frame[0] & S) == 0)
127 frametype = I;
128 else if ((frame[0] & U) == 1)
129 frametype = frame[0] & 0x0F;
130 else if ((frame[0] & U) == 3)
131 frametype = frame[0] & ~PF;
132
133 return frametype;
134 }
135
136
137
138
139
140
141 void ax25_send_control(ax25_cb *ax25, int frametype, int type)
142 {
143 struct sk_buff *skb;
144 unsigned char *dptr;
145 struct device *dev;
146
147 if ((dev = ax25->device) == NULL)
148 return;
149
150 if ((skb = alloc_skb(AX25_BPQ_HEADER_LEN + size_ax25_addr(ax25->digipeat) + 1, GFP_ATOMIC)) == NULL)
151 return;
152
153 skb_reserve(skb, AX25_BPQ_HEADER_LEN + size_ax25_addr(ax25->digipeat));
154
155 if (ax25->sk != NULL) {
156 skb->sk = ax25->sk;
157 ax25->sk->wmem_alloc += skb->truesize;
158 }
159
160
161 dptr = skb_put(skb, 1);
162
163 if ((frametype & U) == S)
164 frametype |= (ax25->vr << 5);
165
166 *dptr = frametype;
167
168 skb->free = 1;
169
170 ax25_transmit_buffer(ax25, skb, type);
171 }
172
173
174
175
176
177
178 void ax25_return_dm(struct device *dev, ax25_address *src, ax25_address *dest, ax25_digi *digi)
179 {
180 struct sk_buff *skb;
181 char *dptr;
182 ax25_digi retdigi;
183
184 if (dev == NULL)
185 return;
186
187 if ((skb = alloc_skb(AX25_BPQ_HEADER_LEN + size_ax25_addr(digi) + 1, GFP_ATOMIC)) == NULL)
188 return;
189
190 skb_reserve(skb, AX25_BPQ_HEADER_LEN + size_ax25_addr(digi));
191
192 ax25_digi_invert(digi, &retdigi);
193
194 dptr = skb_put(skb, 1);
195 skb->sk = NULL;
196
197 *dptr = DM | PF;
198
199
200
201
202
203 dptr = skb_push(skb, size_ax25_addr(digi));
204 dptr += build_ax25_addr(dptr, dest, src, &retdigi, C_RESPONSE);
205
206 skb->arp = 1;
207 skb->free = 1;
208
209 ax25_queue_xmit(skb, dev, SOPRI_NORMAL);
210 }
211
212
213
214
215 unsigned short ax25_calculate_t1(ax25_cb *ax25)
216 {
217 #ifndef NO_BACKOFF
218 int n, t = 2;
219
220 if (ax25->backoff)
221 for (n = 0; n < ax25->n2count; n++)
222 t *= 2;
223
224 return t * ax25->rtt;
225 #else
226 return 2 * ax25->rtt;
227 #endif
228 }
229
230
231
232
233 void ax25_calculate_rtt(ax25_cb *ax25)
234 {
235 if (ax25->t1timer > 0 && ax25->n2count == 0)
236 ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25->t1timer) / 10;
237
238
239 if (ax25->rtt < 1 * PR_SLOWHZ)
240 ax25->rtt = 1 * PR_SLOWHZ;
241 }
242
243
244
245
246
247
248
249
250
251
252
253 unsigned char *ax25_parse_addr(unsigned char *buf, int len, ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags)
254 {
255 int d = 0;
256
257 if (len < 14) return NULL;
258
259 if (flags != NULL) {
260 *flags = 0;
261
262 if (buf[6] & LAPB_C) {
263 *flags = C_COMMAND;
264 }
265 if (buf[13] & LAPB_C) {
266 *flags = C_RESPONSE;
267 }
268 }
269
270
271 if (dest != NULL) memcpy(dest, buf + 0, AX25_ADDR_LEN);
272 if (src != NULL) memcpy(src, buf + 7, AX25_ADDR_LEN);
273 buf += 2 * AX25_ADDR_LEN;
274 len -= 2 * AX25_ADDR_LEN;
275 digi->lastrepeat = -1;
276 digi->ndigi = 0;
277
278 while (!(buf[-1] & LAPB_E))
279 {
280 if (d >= 6) return NULL;
281 if (len < 7) return NULL;
282
283 if (digi != NULL) {
284 memcpy(&digi->calls[d], buf, AX25_ADDR_LEN);
285 digi->ndigi = d + 1;
286 if (buf[6] & AX25_REPEATED) {
287 digi->repeated[d] = 1;
288 digi->lastrepeat = d;
289 } else {
290 digi->repeated[d] = 0;
291 }
292 }
293
294 buf += AX25_ADDR_LEN;
295 len -= AX25_ADDR_LEN;
296 d++;
297 }
298
299 return buf;
300 }
301
302
303
304
305
306 int build_ax25_addr(unsigned char *buf, ax25_address *src, ax25_address *dest, ax25_digi *d, int flag)
307 {
308 int len = 0;
309 int ct = 0;
310
311 memcpy(buf, dest, AX25_ADDR_LEN);
312
313 if (flag != C_COMMAND && flag != C_RESPONSE)
314 printk("build_ax25_addr: Bogus flag %d\n!", flag);
315 buf[6] &= ~(LAPB_E | LAPB_C);
316 buf[6] |= SSID_SPARE;
317
318 if (flag == C_COMMAND) buf[6] |= LAPB_C;
319
320 buf += AX25_ADDR_LEN;
321 len += AX25_ADDR_LEN;
322 memcpy(buf, src, AX25_ADDR_LEN);
323 buf[6] &= ~(LAPB_E | LAPB_C);
324 buf[6] |= SSID_SPARE;
325
326 if (flag == C_RESPONSE) buf[6] |= LAPB_C;
327
328
329
330 if (d == NULL || d->ndigi == 0) {
331 buf[6] |= LAPB_E;
332 return 2 * AX25_ADDR_LEN;
333 }
334
335 buf += AX25_ADDR_LEN;
336 len += AX25_ADDR_LEN;
337
338 while (ct < d->ndigi) {
339 memcpy(buf, &d->calls[ct], AX25_ADDR_LEN);
340 if (d->repeated[ct])
341 buf[6] |= AX25_REPEATED;
342 else
343 buf[6] &= ~AX25_REPEATED;
344 buf[6] &= ~LAPB_E;
345 buf[6] |= SSID_SPARE;
346
347 buf += AX25_ADDR_LEN;
348 len += AX25_ADDR_LEN;
349 ct++;
350 }
351
352 buf[-1] |= LAPB_E;
353
354 return len;
355 }
356
357 int size_ax25_addr(ax25_digi *dp)
358 {
359 if (dp == NULL)
360 return 2 * AX25_ADDR_LEN;
361
362 return AX25_ADDR_LEN * (2 + dp->ndigi);
363 }
364
365
366
367
368
369 void ax25_digi_invert(ax25_digi *in, ax25_digi *out)
370 {
371 int ct = 0;
372
373
374
375 while (ct < in->ndigi) {
376 out->calls[ct] = in->calls[in->ndigi - ct - 1];
377 out->repeated[ct] = 0;
378 ct++;
379 }
380
381
382 out->ndigi = in->ndigi;
383
384
385 out->lastrepeat = 0;
386 }
387
388 #endif