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