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