This source file includes following definitions.
- nr_output
- nr_send_iframe
- nr_send_nak_frame
- nr_kick
- nr_transmit_buffer
- nr_nr_error_recovery
- nr_establish_data_link
- nr_enquiry_response
- nr_check_iframes_acked
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
48 void nr_output(struct sock *sk, struct sk_buff *skb)
49 {
50 struct sk_buff *skbn;
51 unsigned char transport[NR_TRANSPORT_LEN];
52 int err, frontlen, len, mtu;
53
54 mtu = sk->nr->device->mtu;
55
56 if (skb->len - NR_TRANSPORT_LEN > mtu) {
57
58 memcpy(transport, skb->data, NR_TRANSPORT_LEN);
59 skb_pull(skb, NR_TRANSPORT_LEN);
60
61 frontlen = skb_headroom(skb);
62
63 while (skb->len > 0) {
64 if ((skbn = sock_alloc_send_skb(sk, frontlen + mtu, 0, &err)) == NULL)
65 return;
66
67 skbn->sk = sk;
68 skbn->free = 1;
69 skbn->arp = 1;
70
71 skb_reserve(skbn, frontlen);
72
73 len = (mtu > skb->len) ? skb->len : mtu;
74
75
76 memcpy(skb_put(skbn, len), skb->data, len);
77 skb_pull(skb, len);
78
79
80 skb_push(skbn, NR_TRANSPORT_LEN);
81 memcpy(skbn->data, transport, NR_TRANSPORT_LEN);
82
83 if (skb->len > 0)
84 skbn->data[4] |= NR_MORE_FLAG;
85
86 skb_queue_tail(&sk->write_queue, skbn);
87 }
88
89 skb->free = 1;
90 kfree_skb(skb, FREE_WRITE);
91 } else {
92 skb_queue_tail(&sk->write_queue, skb);
93 }
94
95 if (sk->nr->state == NR_STATE_3)
96 nr_kick(sk);
97 }
98
99
100
101
102
103 static void nr_send_iframe(struct sock *sk, struct sk_buff *skb)
104 {
105 if (skb == NULL)
106 return;
107
108 skb->data[2] = sk->nr->vs;
109 skb->data[3] = sk->nr->vr;
110
111 if (sk->nr->condition & OWN_RX_BUSY_CONDITION)
112 skb->data[4] |= NR_CHOKE_FLAG;
113
114 nr_transmit_buffer(sk, skb);
115 }
116
117 void nr_send_nak_frame(struct sock *sk)
118 {
119 struct sk_buff *skb, *skbn;
120
121 if ((skb = skb_peek(&sk->nr->ack_queue)) == NULL)
122 return;
123
124 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL)
125 return;
126
127 nr_send_iframe(sk, skbn);
128
129 sk->nr->condition &= ~ACK_PENDING_CONDITION;
130 sk->nr->vl = sk->nr->vr;
131 sk->nr->t1timer = 0;
132 }
133
134 void nr_kick(struct sock *sk)
135 {
136 struct sk_buff *skb, *skbn;
137 int last = 1;
138 unsigned short start, end, next;
139
140 del_timer(&sk->timer);
141
142 start = (skb_peek(&sk->nr->ack_queue) == NULL) ? sk->nr->va : sk->nr->vs;
143 end = (sk->nr->va + sk->window) % NR_MODULUS;
144
145 if (!(sk->nr->condition & PEER_RX_BUSY_CONDITION) &&
146 start != end &&
147 skb_peek(&sk->write_queue) != NULL) {
148
149 sk->nr->vs = start;
150
151
152
153
154
155 do {
156
157
158
159 skb = skb_dequeue(&sk->write_queue);
160
161 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
162 skb_queue_head(&sk->write_queue, skb);
163 return;
164 }
165
166 next = (sk->nr->vs + 1) % NR_MODULUS;
167 last = (next == end);
168
169
170
171
172 nr_send_iframe(sk, skbn);
173
174 sk->nr->vs = next;
175
176
177
178
179 skb_queue_tail(&sk->nr->ack_queue, skb);
180
181 } while (!last && skb_peek(&sk->write_queue) != NULL);
182
183 sk->nr->vl = sk->nr->vr;
184 sk->nr->condition &= ~ACK_PENDING_CONDITION;
185
186 if (sk->nr->t1timer == 0) {
187 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
188 }
189 }
190
191 nr_set_timer(sk);
192 }
193
194 void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
195 {
196 unsigned char *dptr;
197
198
199
200
201 dptr = skb_push(skb, NR_NETWORK_LEN);
202
203 memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
204 dptr[6] &= ~LAPB_C;
205 dptr[6] &= ~LAPB_E;
206 dptr[6] |= SSSID_SPARE;
207 dptr += AX25_ADDR_LEN;
208
209 memcpy(dptr, &sk->nr->dest_addr, sizeof(ax25_address));
210 dptr[6] &= ~LAPB_C;
211 dptr[6] |= LAPB_E;
212 dptr[6] |= SSSID_SPARE;
213 dptr += AX25_ADDR_LEN;
214
215 *dptr++ = nr_default.ttl;
216
217 skb->arp = 1;
218
219 if (!nr_route_frame(skb, NULL)) {
220 kfree_skb(skb, FREE_WRITE);
221
222 sk->state = TCP_CLOSE;
223 sk->err = ENETUNREACH;
224 if (!sk->dead)
225 sk->state_change(sk);
226 sk->dead = 1;
227 }
228 }
229
230
231
232
233
234
235 void nr_nr_error_recovery(struct sock *sk)
236 {
237 nr_establish_data_link(sk);
238 }
239
240 void nr_establish_data_link(struct sock *sk)
241 {
242 sk->nr->condition = 0x00;
243 sk->nr->n2count = 0;
244
245 nr_write_internal(sk, NR_CONNREQ);
246
247 sk->nr->t2timer = 0;
248 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
249 }
250
251
252
253
254 void nr_enquiry_response(struct sock *sk)
255 {
256 int frametype = NR_INFOACK;
257
258 if (sk->nr->condition & OWN_RX_BUSY_CONDITION) {
259 frametype |= NR_CHOKE_FLAG;
260 } else {
261 if (skb_peek(&sk->nr->reseq_queue) != NULL) {
262 frametype |= NR_NAK_FLAG;
263 }
264 }
265
266 nr_write_internal(sk, frametype);
267
268 sk->nr->vl = sk->nr->vr;
269 sk->nr->condition &= ~ACK_PENDING_CONDITION;
270 }
271
272 void nr_check_iframes_acked(struct sock *sk, unsigned short nr)
273 {
274 if (sk->nr->vs == nr) {
275 nr_frames_acked(sk, nr);
276 nr_requeue_frames(sk);
277 nr_calculate_rtt(sk);
278 sk->nr->t1timer = 0;
279 sk->nr->n2count = 0;
280 } else {
281 if (sk->nr->va != nr) {
282 nr_frames_acked(sk, nr);
283 nr_requeue_frames(sk);
284 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
285 }
286 }
287 }
288
289 #endif