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