This source file includes following definitions.
- sock_setsockopt
- sock_getsockopt
- sock_wmalloc
- sock_rmalloc
- sock_rspace
- sock_wspace
- sock_wfree
- sock_rfree
- sock_alloc_send_skb
- sock_queue_rcv_skb
- release_sock
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 #include <linux/config.h>
76 #include <linux/errno.h>
77 #include <linux/types.h>
78 #include <linux/socket.h>
79 #include <linux/in.h>
80 #include <linux/kernel.h>
81 #include <linux/major.h>
82 #include <linux/sched.h>
83 #include <linux/timer.h>
84 #include <linux/string.h>
85 #include <linux/sockios.h>
86 #include <linux/net.h>
87 #include <linux/fcntl.h>
88 #include <linux/mm.h>
89 #include <linux/interrupt.h>
90
91 #include <asm/segment.h>
92 #include <asm/system.h>
93
94 #include <linux/inet.h>
95 #include <linux/netdevice.h>
96 #include "ip.h"
97 #include "protocol.h"
98 #include "arp.h"
99 #include "rarp.h"
100 #include "route.h"
101 #include "tcp.h"
102 #include "udp.h"
103 #include <linux/skbuff.h>
104 #include "sock.h"
105 #include "raw.h"
106 #include "icmp.h"
107
108 #define min(a,b) ((a)<(b)?(a):(b))
109
110
111
112
113
114
115 int sock_setsockopt(struct sock *sk, int level, int optname,
116 char *optval, int optlen)
117 {
118 int val;
119 int err;
120 struct linger ling;
121
122 if (optval == NULL)
123 return(-EINVAL);
124
125 err=verify_area(VERIFY_READ, optval, sizeof(int));
126 if(err)
127 return err;
128
129 val = get_fs_long((unsigned long *)optval);
130 switch(optname)
131 {
132 case SO_TYPE:
133 case SO_ERROR:
134 return(-ENOPROTOOPT);
135
136 case SO_DEBUG:
137 if(!suser())
138 return(-EPERM);
139 sk->debug=val?1:0;
140 return 0;
141 case SO_DONTROUTE:
142 sk->localroute=val?1:0;
143 return 0;
144 case SO_BROADCAST:
145 sk->broadcast=val?1:0;
146 return 0;
147 case SO_SNDBUF:
148 if(val>32767)
149 val=32767;
150 if(val<256)
151 val=256;
152 sk->sndbuf=val;
153 return 0;
154 case SO_LINGER:
155 err=verify_area(VERIFY_READ,optval,sizeof(ling));
156 if(err)
157 return err;
158 memcpy_fromfs(&ling,optval,sizeof(ling));
159 if(ling.l_onoff==0)
160 sk->linger=0;
161 else
162 {
163 sk->lingertime=ling.l_linger;
164 sk->linger=1;
165 }
166 return 0;
167 case SO_RCVBUF:
168 if(val>32767)
169 val=32767;
170 if(val<256)
171 val=256;
172 sk->rcvbuf=val;
173 return(0);
174
175 case SO_REUSEADDR:
176 if (val)
177 sk->reuse = 1;
178 else
179 sk->reuse = 0;
180 return(0);
181
182 case SO_KEEPALIVE:
183 if (val)
184 sk->keepopen = 1;
185 else
186 sk->keepopen = 0;
187 return(0);
188
189 case SO_OOBINLINE:
190 if (val)
191 sk->urginline = 1;
192 else
193 sk->urginline = 0;
194 return(0);
195
196 case SO_NO_CHECK:
197 if (val)
198 sk->no_check = 1;
199 else
200 sk->no_check = 0;
201 return(0);
202
203 case SO_PRIORITY:
204 if (val >= 0 && val < DEV_NUMBUFFS)
205 {
206 sk->priority = val;
207 }
208 else
209 {
210 return(-EINVAL);
211 }
212 return(0);
213
214 default:
215 return(-ENOPROTOOPT);
216 }
217 }
218
219
220 int sock_getsockopt(struct sock *sk, int level, int optname,
221 char *optval, int *optlen)
222 {
223 int val;
224 int err;
225 struct linger ling;
226
227 switch(optname)
228 {
229 case SO_DEBUG:
230 val = sk->debug;
231 break;
232
233 case SO_DONTROUTE:
234 val = sk->localroute;
235 break;
236
237 case SO_BROADCAST:
238 val= sk->broadcast;
239 break;
240
241 case SO_LINGER:
242 err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
243 if(err)
244 return err;
245 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
246 if(err)
247 return err;
248 put_fs_long(sizeof(ling),(unsigned long *)optlen);
249 ling.l_onoff=sk->linger;
250 ling.l_linger=sk->lingertime;
251 memcpy_tofs(optval,&ling,sizeof(ling));
252 return 0;
253
254 case SO_SNDBUF:
255 val=sk->sndbuf;
256 break;
257
258 case SO_RCVBUF:
259 val =sk->rcvbuf;
260 break;
261
262 case SO_REUSEADDR:
263 val = sk->reuse;
264 break;
265
266 case SO_KEEPALIVE:
267 val = sk->keepopen;
268 break;
269
270 case SO_TYPE:
271 #if 0
272 if (sk->prot == &tcp_prot)
273 val = SOCK_STREAM;
274 else
275 val = SOCK_DGRAM;
276 #endif
277 val = sk->type;
278 break;
279
280 case SO_ERROR:
281 val = sk->err;
282 sk->err = 0;
283 break;
284
285 case SO_OOBINLINE:
286 val = sk->urginline;
287 break;
288
289 case SO_NO_CHECK:
290 val = sk->no_check;
291 break;
292
293 case SO_PRIORITY:
294 val = sk->priority;
295 break;
296
297 default:
298 return(-ENOPROTOOPT);
299 }
300 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
301 if(err)
302 return err;
303 put_fs_long(sizeof(int),(unsigned long *) optlen);
304
305 err=verify_area(VERIFY_WRITE, optval, sizeof(int));
306 if(err)
307 return err;
308 put_fs_long(val,(unsigned long *)optval);
309
310 return(0);
311 }
312
313
314 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority)
315 {
316 if (sk)
317 {
318 if (sk->wmem_alloc + size < sk->sndbuf || force)
319 {
320 struct sk_buff * c = alloc_skb(size, priority);
321 if (c)
322 {
323 unsigned long flags;
324 save_flags(flags);
325 cli();
326 sk->wmem_alloc+= c->mem_len;
327 restore_flags(flags);
328 }
329 return c;
330 }
331 return(NULL);
332 }
333 return(alloc_skb(size, priority));
334 }
335
336
337 struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
338 {
339 if (sk)
340 {
341 if (sk->rmem_alloc + size < sk->rcvbuf || force)
342 {
343 struct sk_buff *c = alloc_skb(size, priority);
344 if (c)
345 {
346 unsigned long flags;
347 save_flags(flags);
348 cli();
349 sk->rmem_alloc += c->mem_len;
350 restore_flags(flags);
351 }
352 return(c);
353 }
354 return(NULL);
355 }
356 return(alloc_skb(size, priority));
357 }
358
359
360 unsigned long sock_rspace(struct sock *sk)
361 {
362 int amt;
363
364 if (sk != NULL)
365 {
366 if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW)
367 return(0);
368 amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
369 if (amt < 0)
370 return(0);
371 return(amt);
372 }
373 return(0);
374 }
375
376
377 unsigned long sock_wspace(struct sock *sk)
378 {
379 if (sk != NULL)
380 {
381 if (sk->shutdown & SEND_SHUTDOWN)
382 return(0);
383 if (sk->wmem_alloc >= sk->sndbuf)
384 return(0);
385 return(sk->sndbuf-sk->wmem_alloc );
386 }
387 return(0);
388 }
389
390
391 void sock_wfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
392 {
393 #ifdef CONFIG_SKB_CHECK
394 IS_SKB(skb);
395 #endif
396 kfree_skbmem(skb, size);
397 if (sk)
398 {
399 unsigned long flags;
400 save_flags(flags);
401 cli();
402 sk->wmem_alloc -= size;
403 restore_flags(flags);
404
405 if (!sk->dead)
406 sk->write_space(sk);
407 return;
408 }
409 }
410
411
412 void sock_rfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
413 {
414 #ifdef CONFIG_SKB_CHECK
415 IS_SKB(skb);
416 #endif
417 kfree_skbmem(skb, size);
418 if (sk)
419 {
420 unsigned long flags;
421 save_flags(flags);
422 cli();
423 sk->rmem_alloc -= size;
424 restore_flags(flags);
425 }
426 }
427
428
429
430
431
432 struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, int noblock, int *errcode)
433 {
434 struct sk_buff *skb;
435 int err;
436
437 sk->inuse=1;
438
439 do
440 {
441 if(sk->err!=0)
442 {
443 cli();
444 err= -sk->err;
445 sk->err=0;
446 sti();
447 *errcode=err;
448 return NULL;
449 }
450
451 if(sk->shutdown&SEND_SHUTDOWN)
452 {
453 *errcode=-EPIPE;
454 return NULL;
455 }
456
457 skb = sock_wmalloc(sk, size, 0, GFP_KERNEL);
458
459 if(skb==NULL)
460 {
461 unsigned long tmp;
462
463 sk->socket->flags |= SO_NOSPACE;
464 if(noblock)
465 {
466 *errcode=-EAGAIN;
467 return NULL;
468 }
469 if(sk->shutdown&SEND_SHUTDOWN)
470 {
471 *errcode=-EPIPE;
472 return NULL;
473 }
474 tmp = sk->wmem_alloc;
475 cli();
476 if(sk->shutdown&SEND_SHUTDOWN)
477 {
478 sti();
479 *errcode=-EPIPE;
480 return NULL;
481 }
482
483 if( tmp <= sk->wmem_alloc)
484 {
485 sk->socket->flags &= ~SO_NOSPACE;
486 interruptible_sleep_on(sk->sleep);
487 if (current->signal & ~current->blocked)
488 {
489 sti();
490 *errcode = -ERESTARTSYS;
491 return NULL;
492 }
493 }
494 sti();
495 }
496 }
497 while(skb==NULL);
498
499 return skb;
500 }
501
502
503
504
505
506
507 int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
508 {
509 unsigned long flags;
510 if(sk->rmem_alloc + skb->mem_len >= sk->rcvbuf)
511 return -ENOMEM;
512 save_flags(flags);
513 cli();
514 sk->rmem_alloc+=skb->mem_len;
515 skb->sk=sk;
516 restore_flags(flags);
517 skb_queue_tail(&sk->receive_queue,skb);
518 if(!sk->dead)
519 sk->data_ready(sk,skb->len);
520 return 0;
521 }
522
523 void release_sock(struct sock *sk)
524 {
525 struct sk_buff *skb;
526 unsigned long flags;
527
528 if (!sk->prot)
529 return;
530
531
532
533
534
535
536
537 save_flags(flags);
538 cli();
539 if (sk->blog)
540 {
541 restore_flags(flags);
542 return;
543 }
544 sk->blog=1;
545 sk->inuse = 1;
546 restore_flags(flags);
547 #ifdef CONFIG_INET
548
549 while((skb = skb_dequeue(&sk->back_log)) != NULL)
550 {
551 sk->blog = 1;
552 if (sk->prot->rcv)
553 sk->prot->rcv(skb, skb->dev, sk->opt,
554 skb->saddr, skb->len, skb->daddr, 1,
555
556 (struct inet_protocol *)sk->pair);
557 }
558 #endif
559 sk->blog = 0;
560 sk->inuse = 0;
561 #ifdef CONFIG_INET
562 if (sk->dead && sk->state == TCP_CLOSE)
563 {
564
565 reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
566 }
567 #endif
568 }
569
570