This source file includes following definitions.
- min
- raw_err
- raw_rcv
- raw_sendto
- raw_write
- raw_close
- raw_init
- raw_recvfrom
- raw_read
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <asm/system.h>
19 #include <asm/segment.h>
20 #include <linux/types.h>
21 #include <linux/sched.h>
22 #include <linux/errno.h>
23 #include <linux/timer.h>
24 #include <linux/mm.h>
25 #include <linux/kernel.h>
26 #include <linux/fcntl.h>
27 #include <linux/socket.h>
28 #include <linux/in.h>
29 #include "inet.h"
30 #include "dev.h"
31 #include "ip.h"
32 #include "protocol.h"
33 #include "tcp.h"
34 #include "skbuff.h"
35 #include "sock.h"
36 #include "icmp.h"
37 #include "udp.h"
38
39
40 static unsigned long
41 min(unsigned long a, unsigned long b)
42 {
43 if (a < b) return(a);
44 return(b);
45 }
46
47
48
49 void
50 raw_err (int err, unsigned char *header, unsigned long daddr,
51 unsigned long saddr, struct inet_protocol *protocol)
52 {
53 struct sock *sk;
54
55 DPRINTF((DBG_RAW, "raw_err(err=%d, hdr=%X, daddr=%X, saddr=%X, protocl=%X)\n",
56 err, header, daddr, saddr, protocol));
57
58 if (protocol == NULL) return;
59 sk = (struct sock *) protocol->data;
60 if (sk == NULL) return;
61
62
63 if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8)) {
64 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
65 return;
66 }
67
68 sk->err = icmp_err_convert[err & 0xff].errno;
69
70
71 #if 0
72 if (icmp_err_convert[err & 0xff].fatal) {
73 sk->prot->close(sk, 0);
74 }
75 #endif
76 return;
77 }
78
79
80
81
82
83
84 int
85 raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
86 unsigned long daddr, unsigned short len, unsigned long saddr,
87 int redo, struct inet_protocol *protocol)
88 {
89 struct sock *sk;
90
91 DPRINTF((DBG_RAW, "raw_rcv(skb=%X, dev=%X, opt=%X, daddr=%X,\n"
92 " len=%d, saddr=%X, redo=%d, protocol=%X)\n",
93 skb, dev, opt, daddr, len, saddr, redo, protocol));
94
95 if (skb == NULL) return(0);
96 if (protocol == NULL) {
97 kfree_skb(skb, FREE_READ);
98 return(0);
99 }
100 sk = (struct sock *) protocol->data;
101 if (sk == NULL) {
102 kfree_skb(skb, FREE_READ);
103 return(0);
104 }
105
106
107 skb->sk = sk;
108 skb->len = len;
109 skb->dev = dev;
110 skb->saddr = daddr;
111 skb->daddr = saddr;
112
113 if (!redo) {
114
115 cli();
116 if (sk->inuse) {
117 DPRINTF((DBG_RAW, "raw_rcv adding to backlog.\n"));
118 if (sk->back_log == NULL) {
119 sk->back_log = skb;
120 skb->next = skb;
121 skb->prev = skb;
122 } else {
123 skb->next = sk->back_log;
124 skb->prev = sk->back_log->prev;
125 skb->prev->next = skb;
126 skb->next->prev = skb;
127 }
128 sti();
129 return(0);
130 }
131 sk->inuse = 1;
132 sti();
133 }
134
135
136 if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX) {
137 skb->sk = NULL;
138 kfree_skb(skb, FREE_READ);
139 return(0);
140 }
141 sk->rmem_alloc += skb->mem_len;
142
143
144 if (sk->rqueue == NULL) {
145 sk->rqueue = skb;
146 skb->next = skb;
147 skb->prev = skb;
148 } else {
149 skb->next = sk->rqueue;
150 skb->prev = sk->rqueue->prev;
151 skb->prev->next = skb;
152 skb->next->prev = skb;
153 }
154 wake_up(sk->sleep);
155 release_sock(sk);
156 return(0);
157 }
158
159
160
161 static int
162 raw_sendto(struct sock *sk, unsigned char *from, int len,
163 int noblock,
164 unsigned flags, struct sockaddr_in *usin, int addr_len)
165 {
166 struct sk_buff *skb;
167 struct device *dev=NULL;
168 struct sockaddr_in sin;
169 int tmp;
170
171 DPRINTF((DBG_RAW, "raw_sendto(sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
172 " usin=%X, addr_len = %d)\n", sk, from, len, noblock,
173 flags, usin, addr_len));
174
175
176 if (flags) return(-EINVAL);
177 if (len < 0) return(-EINVAL);
178
179
180 if (usin) {
181 if (addr_len < sizeof(sin)) return(-EINVAL);
182
183 memcpy_fromfs(&sin, usin, sizeof(sin));
184 if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL);
185 } else {
186 if (sk->state != TCP_ESTABLISHED) return(-EINVAL);
187 sin.sin_family = AF_INET;
188 sin.sin_port = sk->protocol;
189 sin.sin_addr.s_addr = sk->daddr;
190 }
191 if (sin.sin_port == 0) sin.sin_port = sk->protocol;
192
193 sk->inuse = 1;
194 skb = NULL;
195 while (skb == NULL) {
196 skb = (struct sk_buff *) sk->prot->wmalloc(sk,
197 len+sizeof(*skb) + sk->prot->max_header,
198 0, GFP_KERNEL);
199
200
201 if (skb == NULL) {
202 int tmp;
203
204 DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
205 if (noblock) return(-EAGAIN);
206 tmp = sk->wmem_alloc;
207 release_sock(sk);
208 cli();
209 if (tmp <= sk->wmem_alloc) {
210 interruptible_sleep_on(sk->sleep);
211 if (current->signal & ~current->blocked) {
212 sti();
213 return(-ERESTARTSYS);
214 }
215 }
216 sk->inuse = 1;
217 sti();
218 }
219 }
220 skb->lock = 0;
221 skb->mem_addr = skb;
222 skb->mem_len = len + sizeof(*skb) +sk->prot->max_header;
223 skb->sk = sk;
224
225 skb->free = 1;
226 skb->arp = 0;
227
228 tmp = sk->prot->build_header(skb, sk->saddr,
229 sin.sin_addr.s_addr, &dev,
230 sk->protocol, sk->opt, skb->mem_len);
231 if (tmp < 0) {
232 DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
233 sk->prot->wfree(sk, skb->mem_addr, skb->mem_len);
234 release_sock(sk);
235 return(tmp);
236 }
237
238
239 memcpy_fromfs ((unsigned char *)(skb+1)+tmp, from, len);
240
241
242
243
244 if(sk->protocol==IPPROTO_RAW) {
245 unsigned char *buff;
246 struct iphdr *iph;
247
248 buff = (unsigned char *)(skb + 1);
249 buff += tmp;
250 iph = (struct iphdr *)buff;
251 iph->saddr = sk->saddr;
252 }
253
254 skb->len = tmp + len;
255 sk->prot->queue_xmit(sk, dev, skb, 1);
256 release_sock(sk);
257 return(len);
258 }
259
260
261 static int
262 raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
263 unsigned flags)
264 {
265 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
266 }
267
268
269 static void
270 raw_close(struct sock *sk, int timeout)
271 {
272 sk->inuse = 1;
273 sk->state = TCP_CLOSE;
274
275 DPRINTF((DBG_RAW, "raw_close: deleting protocol %d\n",
276 ((struct inet_protocol *)sk->pair)->protocol));
277
278 if (inet_del_protocol((struct inet_protocol *)sk->pair) < 0)
279 DPRINTF((DBG_RAW, "raw_close: del_protocol failed.\n"));
280 kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
281 sk->pair = NULL;
282 release_sock(sk);
283 }
284
285
286 static int
287 raw_init(struct sock *sk)
288 {
289 struct inet_protocol *p;
290
291 p = (struct inet_protocol *) kmalloc(sizeof (*p), GFP_KERNEL);
292 if (p == NULL) return(-ENOMEM);
293
294 p->handler = raw_rcv;
295 p->protocol = sk->protocol;
296 p->data = (void *)sk;
297 p->err_handler = raw_err;
298 inet_add_protocol(p);
299
300
301 sk->pair = (struct sock *)p;
302
303 DPRINTF((DBG_RAW, "raw init added protocol %d\n", sk->protocol));
304
305 return(0);
306 }
307
308
309
310
311
312
313 int
314 raw_recvfrom(struct sock *sk, unsigned char *to, int len,
315 int noblock, unsigned flags, struct sockaddr_in *sin,
316 int *addr_len)
317 {
318 int copied=0;
319 struct sk_buff *skb;
320
321 DPRINTF((DBG_RAW, "raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
322 " sin=%X, addr_len=%X)\n",
323 sk, to, len, noblock, flags, sin, addr_len));
324
325 if (len == 0) return(0);
326 if (len < 0) return(-EINVAL);
327
328 if (sk->shutdown & RCV_SHUTDOWN) return(0);
329 if (addr_len) {
330 verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
331 put_fs_long(sizeof(*sin), addr_len);
332 }
333 sk->inuse = 1;
334 while (sk->rqueue == NULL) {
335 if (noblock) {
336 release_sock(sk);
337 if (copied) return(copied);
338 return(-EAGAIN);
339 }
340 release_sock(sk);
341 cli();
342 if (sk->rqueue == NULL) {
343 interruptible_sleep_on(sk->sleep);
344 if (current->signal & ~current->blocked) {
345 sti();
346 return(-ERESTARTSYS);
347 }
348 }
349 sk->inuse = 1;
350 sti();
351 }
352 skb = sk->rqueue;
353
354 if (!(flags & MSG_PEEK)) {
355 if (skb->next == skb) {
356 sk->rqueue = NULL;
357 } else {
358 sk->rqueue = (struct sk_buff *)sk->rqueue ->next;
359 skb->prev->next = skb->next;
360 skb->next->prev = skb->prev;
361 }
362 }
363 copied = min(len, skb->len);
364 verify_area(VERIFY_WRITE, to, copied);
365 memcpy_tofs(to, skb->h.raw, copied);
366
367
368 if (sin) {
369 struct sockaddr_in addr;
370
371 addr.sin_family = AF_INET;
372 addr.sin_addr.s_addr = skb->daddr;
373 verify_area(VERIFY_WRITE, sin, sizeof(*sin));
374 memcpy_tofs(sin, &addr, sizeof(*sin));
375 }
376
377 if (!(flags & MSG_PEEK)) {
378 kfree_skb(skb, FREE_READ);
379 }
380 release_sock(sk);
381 return (copied);
382 }
383
384
385 int
386 raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
387 unsigned flags)
388 {
389 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
390 }
391
392
393 struct proto raw_prot = {
394 sock_wmalloc,
395 sock_rmalloc,
396 sock_wfree,
397 sock_rfree,
398 sock_rspace,
399 sock_wspace,
400 raw_close,
401 raw_read,
402 raw_write,
403 raw_sendto,
404 raw_recvfrom,
405 ip_build_header,
406 udp_connect,
407 NULL,
408 ip_queue_xmit,
409 ip_retransmit,
410 NULL,
411 NULL,
412 raw_rcv,
413 udp_select,
414 NULL,
415 raw_init,
416 NULL,
417 128,
418 0,
419 {NULL,},
420 "RAW"
421 };