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