This source file includes following definitions.
- sock_setsockopt
- sock_getsockopt
- sock_wmalloc
- sock_rmalloc
- sock_rspace
- sock_wspace
- sock_wfree
- sock_rfree
- 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 #include <linux/config.h>
75 #include <linux/errno.h>
76 #include <linux/types.h>
77 #include <linux/socket.h>
78 #include <linux/in.h>
79 #include <linux/kernel.h>
80 #include <linux/major.h>
81 #include <linux/sched.h>
82 #include <linux/timer.h>
83 #include <linux/string.h>
84 #include <linux/sockios.h>
85 #include <linux/net.h>
86 #include <linux/fcntl.h>
87 #include <linux/mm.h>
88 #include <linux/interrupt.h>
89
90 #include <asm/segment.h>
91 #include <asm/system.h>
92
93 #include <linux/inet.h>
94 #include <linux/netdevice.h>
95 #include "ip.h"
96 #include "protocol.h"
97 #include "arp.h"
98 #include "rarp.h"
99 #include "route.h"
100 #include "tcp.h"
101 #include "udp.h"
102 #include <linux/skbuff.h>
103 #include "sock.h"
104 #include "raw.h"
105 #include "icmp.h"
106
107 #define min(a,b) ((a)<(b)?(a):(b))
108
109
110
111
112
113
114 int sock_setsockopt(struct sock *sk, int level, int optname,
115 char *optval, int optlen)
116 {
117 int val;
118 int err;
119 struct linger ling;
120
121 if (optval == NULL)
122 return(-EINVAL);
123
124 err=verify_area(VERIFY_READ, optval, sizeof(int));
125 if(err)
126 return err;
127
128 val = get_fs_long((unsigned long *)optval);
129 switch(optname)
130 {
131 case SO_TYPE:
132 case SO_ERROR:
133 return(-ENOPROTOOPT);
134
135 case SO_DEBUG:
136 sk->debug=val?1:0;
137 return 0;
138 case SO_DONTROUTE:
139 sk->localroute=val?1:0;
140 return 0;
141 case SO_BROADCAST:
142 sk->broadcast=val?1:0;
143 return 0;
144 case SO_SNDBUF:
145 if(val>32767)
146 val=32767;
147 if(val<256)
148 val=256;
149 sk->sndbuf=val;
150 return 0;
151 case SO_LINGER:
152 err=verify_area(VERIFY_READ,optval,sizeof(ling));
153 if(err)
154 return err;
155 memcpy_fromfs(&ling,optval,sizeof(ling));
156 if(ling.l_onoff==0)
157 sk->linger=0;
158 else
159 {
160 sk->lingertime=ling.l_linger;
161 sk->linger=1;
162 }
163 return 0;
164 case SO_RCVBUF:
165 if(val>32767)
166 val=32767;
167 if(val<256)
168 val=256;
169 sk->rcvbuf=val;
170 return(0);
171
172 case SO_REUSEADDR:
173 if (val)
174 sk->reuse = 1;
175 else
176 sk->reuse = 0;
177 return(0);
178
179 case SO_KEEPALIVE:
180 if (val)
181 sk->keepopen = 1;
182 else
183 sk->keepopen = 0;
184 return(0);
185
186 case SO_OOBINLINE:
187 if (val)
188 sk->urginline = 1;
189 else
190 sk->urginline = 0;
191 return(0);
192
193 case SO_NO_CHECK:
194 if (val)
195 sk->no_check = 1;
196 else
197 sk->no_check = 0;
198 return(0);
199
200 case SO_PRIORITY:
201 if (val >= 0 && val < DEV_NUMBUFFS)
202 {
203 sk->priority = val;
204 }
205 else
206 {
207 return(-EINVAL);
208 }
209 return(0);
210
211 default:
212 return(-ENOPROTOOPT);
213 }
214 }
215
216
217 int sock_getsockopt(struct sock *sk, int level, int optname,
218 char *optval, int *optlen)
219 {
220 int val;
221 int err;
222 struct linger ling;
223
224 switch(optname)
225 {
226 case SO_DEBUG:
227 val = sk->debug;
228 break;
229
230 case SO_DONTROUTE:
231 val = sk->localroute;
232 break;
233
234 case SO_BROADCAST:
235 val= sk->broadcast;
236 break;
237
238 case SO_LINGER:
239 err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
240 if(err)
241 return err;
242 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
243 if(err)
244 return err;
245 put_fs_long(sizeof(ling),(unsigned long *)optlen);
246 ling.l_onoff=sk->linger;
247 ling.l_linger=sk->lingertime;
248 memcpy_tofs(optval,&ling,sizeof(ling));
249 return 0;
250
251 case SO_SNDBUF:
252 val=sk->sndbuf;
253 break;
254
255 case SO_RCVBUF:
256 val =sk->rcvbuf;
257 break;
258
259 case SO_REUSEADDR:
260 val = sk->reuse;
261 break;
262
263 case SO_KEEPALIVE:
264 val = sk->keepopen;
265 break;
266
267 case SO_TYPE:
268 #if 0
269 if (sk->prot == &tcp_prot)
270 val = SOCK_STREAM;
271 else
272 val = SOCK_DGRAM;
273 #endif
274 val = sk->type;
275 break;
276
277 case SO_ERROR:
278 val = sk->err;
279 sk->err = 0;
280 break;
281
282 case SO_OOBINLINE:
283 val = sk->urginline;
284 break;
285
286 case SO_NO_CHECK:
287 val = sk->no_check;
288 break;
289
290 case SO_PRIORITY:
291 val = sk->priority;
292 break;
293
294 default:
295 return(-ENOPROTOOPT);
296 }
297 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
298 if(err)
299 return err;
300 put_fs_long(sizeof(int),(unsigned long *) optlen);
301
302 err=verify_area(VERIFY_WRITE, optval, sizeof(int));
303 if(err)
304 return err;
305 put_fs_long(val,(unsigned long *)optval);
306
307 return(0);
308 }
309
310
311 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority)
312 {
313 if (sk)
314 {
315 if (sk->wmem_alloc + size < sk->sndbuf || force)
316 {
317 struct sk_buff * c = alloc_skb(size, priority);
318 if (c)
319 {
320 cli();
321 sk->wmem_alloc+= c->mem_len;
322 sti();
323 }
324 return c;
325 }
326 return(NULL);
327 }
328 return(alloc_skb(size, priority));
329 }
330
331
332 struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
333 {
334 if (sk)
335 {
336 if (sk->rmem_alloc + size < sk->rcvbuf || force)
337 {
338 struct sk_buff *c = alloc_skb(size, priority);
339 if (c)
340 {
341 cli();
342 sk->rmem_alloc += c->mem_len;
343 sti();
344 }
345 return(c);
346 }
347 return(NULL);
348 }
349 return(alloc_skb(size, priority));
350 }
351
352
353 unsigned long sock_rspace(struct sock *sk)
354 {
355 int amt;
356
357 if (sk != NULL)
358 {
359 if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW)
360 return(0);
361 amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);
362 if (amt < 0)
363 return(0);
364 return(amt);
365 }
366 return(0);
367 }
368
369
370 unsigned long sock_wspace(struct sock *sk)
371 {
372 if (sk != NULL)
373 {
374 if (sk->shutdown & SEND_SHUTDOWN)
375 return(0);
376 if (sk->wmem_alloc >= sk->sndbuf)
377 return(0);
378 return(sk->sndbuf-sk->wmem_alloc );
379 }
380 return(0);
381 }
382
383
384 void sock_wfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
385 {
386 IS_SKB(skb);
387 kfree_skbmem(skb, size);
388 if (sk)
389 {
390 sk->wmem_alloc -= size;
391
392 if (!sk->dead)
393 sk->write_space(sk);
394 return;
395 }
396 }
397
398
399 void sock_rfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
400 {
401 IS_SKB(skb);
402 kfree_skbmem(skb, size);
403 if (sk)
404 {
405 sk->rmem_alloc -= size;
406 }
407 }
408
409
410 void release_sock(struct sock *sk)
411 {
412 struct sk_buff *skb;
413
414 if (!sk->prot)
415 return;
416 if (sk->blog)
417 return;
418 #ifdef CONFIG_INET
419
420 sk->inuse = 1;
421 while((skb = skb_dequeue(&sk->back_log)) != NULL)
422 {
423 sk->blog = 1;
424 if (sk->prot->rcv)
425 sk->prot->rcv(skb, skb->dev, sk->opt,
426 skb->saddr, skb->len, skb->daddr, 1,
427
428 (struct inet_protocol *)sk->pair);
429 }
430 #endif
431 sk->blog = 0;
432 sk->inuse = 0;
433 #ifdef CONFIG_INET
434 if (sk->dead && sk->state == TCP_CLOSE)
435 {
436
437 reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
438 }
439 #endif
440 }
441
442