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