This source file includes following definitions.
- nr_clear_queues
- nr_frames_acked
- nr_requeue_frames
- nr_validate_nr
- nr_in_rx_window
- nr_write_internal
- nr_transmit_dm
- nr_calculate_t1
- nr_calculate_rtt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/config.h>
21 #ifdef CONFIG_NETROM
22 #include <linux/errno.h>
23 #include <linux/types.h>
24 #include <linux/socket.h>
25 #include <linux/in.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/timer.h>
29 #include <linux/string.h>
30 #include <linux/sockios.h>
31 #include <linux/net.h>
32 #include <net/ax25.h>
33 #include <linux/inet.h>
34 #include <linux/netdevice.h>
35 #include <linux/skbuff.h>
36 #include <net/sock.h>
37 #include <asm/segment.h>
38 #include <asm/system.h>
39 #include <linux/fcntl.h>
40 #include <linux/mm.h>
41 #include <linux/interrupt.h>
42 #include <net/netrom.h>
43
44
45
46
47 void nr_clear_queues(struct sock *sk)
48 {
49 struct sk_buff *skb;
50
51 while ((skb = skb_dequeue(&sk->write_queue)) != NULL) {
52 skb->sk = sk;
53 skb->free = 1;
54 kfree_skb(skb, FREE_WRITE);
55 }
56
57 while ((skb = skb_dequeue(&sk->nr->ack_queue)) != NULL) {
58 skb->sk = sk;
59 skb->free = 1;
60 kfree_skb(skb, FREE_WRITE);
61 }
62
63 while ((skb = skb_dequeue(&sk->nr->reseq_queue)) != NULL) {
64 kfree_skb(skb, FREE_READ);
65 }
66
67 while ((skb = skb_dequeue(&sk->nr->frag_queue)) != NULL) {
68 kfree_skb(skb, FREE_READ);
69 }
70 }
71
72
73
74
75
76
77 void nr_frames_acked(struct sock *sk, unsigned short nr)
78 {
79 struct sk_buff *skb;
80
81
82
83
84 if (sk->nr->va != nr) {
85 while (skb_peek(&sk->nr->ack_queue) != NULL && sk->nr->va != nr) {
86 skb = skb_dequeue(&sk->nr->ack_queue);
87 skb->sk = sk;
88 skb->free = 1;
89 kfree_skb(skb, FREE_WRITE);
90 sk->nr->va = (sk->nr->va + 1) % NR_MODULUS;
91 }
92 }
93 }
94
95
96
97
98
99
100 void nr_requeue_frames(struct sock *sk)
101 {
102 struct sk_buff *skb, *skb_prev = NULL;
103
104 while ((skb = skb_dequeue(&sk->nr->ack_queue)) != NULL) {
105 if (skb_prev == NULL)
106 skb_queue_head(&sk->write_queue, skb);
107 else
108 skb_append(skb_prev, skb);
109 skb_prev = skb;
110 }
111 }
112
113
114
115
116
117 int nr_validate_nr(struct sock *sk, unsigned short nr)
118 {
119 unsigned short vc = sk->nr->va;
120
121 while (vc != sk->nr->vs) {
122 if (nr == vc) return 1;
123 vc = (vc + 1) % NR_MODULUS;
124 }
125
126 if (nr == sk->nr->vs) return 1;
127
128 return 0;
129 }
130
131
132
133
134 int nr_in_rx_window(struct sock *sk, unsigned short ns)
135 {
136 unsigned short vc = sk->nr->vr;
137 unsigned short vt = (sk->nr->vl + sk->window) % NR_MODULUS;
138
139 while (vc != vt) {
140 if (ns == vc) return 1;
141 vc = (vc + 1) % NR_MODULUS;
142 }
143
144 return 0;
145 }
146
147
148
149
150
151 void nr_write_internal(struct sock *sk, int frametype)
152 {
153 struct sk_buff *skb;
154 unsigned char *dptr;
155 int len, timeout;
156
157 len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
158
159 switch (frametype & 0x0F) {
160 case NR_CONNREQ:
161 len += 17;
162 break;
163 case NR_CONNACK:
164 len += (sk->nr->bpqext) ? 2 : 1;
165 break;
166 case NR_DISCREQ:
167 case NR_DISCACK:
168 case NR_INFOACK:
169 break;
170 default:
171 printk("nr_write_internal: invalid frame type %d\n", frametype);
172 return;
173 }
174
175 if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
176 return;
177
178
179
180
181 skb_reserve(skb, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN);
182
183 dptr = skb_put(skb, skb_tailroom(skb));
184
185 switch (frametype & 0x0F) {
186
187 case NR_CONNREQ:
188 timeout = (sk->nr->rtt / PR_SLOWHZ) * 2;
189 *dptr++ = sk->nr->my_index;
190 *dptr++ = sk->nr->my_id;
191 *dptr++ = 0;
192 *dptr++ = 0;
193 *dptr++ = frametype;
194 *dptr++ = sk->window;
195 memcpy(dptr, &sk->nr->user_addr, sizeof(ax25_address));
196 dptr[6] &= ~LAPB_C;
197 dptr[6] &= ~LAPB_E;
198 dptr[6] |= SSSID_SPARE;
199 dptr += AX25_ADDR_LEN;
200 memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
201 dptr[6] &= ~LAPB_C;
202 dptr[6] &= ~LAPB_E;
203 dptr[6] |= SSSID_SPARE;
204 dptr += AX25_ADDR_LEN;
205 *dptr++ = timeout % 256;
206 *dptr++ = timeout / 256;
207 break;
208
209 case NR_CONNACK:
210 *dptr++ = sk->nr->your_index;
211 *dptr++ = sk->nr->your_id;
212 *dptr++ = sk->nr->my_index;
213 *dptr++ = sk->nr->my_id;
214 *dptr++ = frametype;
215 *dptr++ = sk->window;
216 if (sk->nr->bpqext) *dptr++ = nr_default.ttl;
217 break;
218
219 case NR_DISCREQ:
220 case NR_DISCACK:
221 *dptr++ = sk->nr->your_index;
222 *dptr++ = sk->nr->your_id;
223 *dptr++ = 0;
224 *dptr++ = 0;
225 *dptr++ = frametype;
226 break;
227
228 case NR_INFOACK:
229 *dptr++ = sk->nr->your_index;
230 *dptr++ = sk->nr->your_id;
231 *dptr++ = 0;
232 *dptr++ = sk->nr->vr;
233 *dptr++ = frametype;
234 break;
235 }
236
237 skb->free = 1;
238
239 nr_transmit_buffer(sk, skb);
240 }
241
242
243
244
245
246 void nr_transmit_dm(struct sk_buff *skb)
247 {
248 struct sk_buff *skbn;
249 unsigned char *dptr;
250 int len;
251
252 len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1;
253
254 if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL)
255 return;
256
257 skb_reserve(skbn, AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN);
258
259 dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
260
261 memcpy(dptr, skb->data + 7, AX25_ADDR_LEN);
262 dptr[6] &= ~LAPB_C;
263 dptr[6] &= ~LAPB_E;
264 dptr[6] |= SSSID_SPARE;
265 dptr += AX25_ADDR_LEN;
266
267 memcpy(dptr, skb->data + 0, AX25_ADDR_LEN);
268 dptr[6] &= ~LAPB_C;
269 dptr[6] |= LAPB_E;
270 dptr[6] |= SSSID_SPARE;
271 dptr += AX25_ADDR_LEN;
272
273 *dptr++ = nr_default.ttl;
274
275 *dptr++ = skb->data[15];
276 *dptr++ = skb->data[16];
277 *dptr++ = 0;
278 *dptr++ = 0;
279 *dptr++ = NR_CONNACK | NR_CHOKE_FLAG;
280 *dptr++ = 0;
281
282 skbn->free = 1;
283 skbn->sk = NULL;
284
285 if (!nr_route_frame(skbn, NULL))
286 kfree_skb(skbn, FREE_WRITE);
287 }
288
289
290
291
292 unsigned short nr_calculate_t1(struct sock *sk)
293 {
294 int n, t;
295
296 for (t = 2, n = 0; n < sk->nr->n2count; n++)
297 t *= 2;
298
299 if (t > 8) t = 8;
300
301 return t * sk->nr->rtt;
302 }
303
304
305
306
307 void nr_calculate_rtt(struct sock *sk)
308 {
309 if (sk->nr->t1timer > 0 && sk->nr->n2count == 0)
310 sk->nr->rtt = (9 * sk->nr->rtt + sk->nr->t1 - sk->nr->t1timer) / 10;
311
312 #ifdef NR_T1CLAMPLO
313
314 if (sk->nr->rtt < (NR_T1CLAMPLO))
315 sk->nr->rtt = (NR_T1CLAMPLO);
316 #else
317 if (sk->nr->rtt == 0)
318 sk->nr->rtt = PR_SLOWHZ;
319 #endif
320 #ifdef NR_T1CLAMPHI
321
322 if (sk->nr->rtt > (NR_T1CLAMPHI))
323 sk->nr->rtt = (NR_T1CLAMPHI);
324 #endif
325 }
326
327 #endif