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