|
|
1.1 root 1: /* raw.c - implements raw ip sockets. */
2: /*
3: Copyright (C) 1992 Ross Biro
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 2, or (at your option)
8: any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: The Author may be reached as [email protected] or
20: C/O Department of Mathematics; Stanford University; Stanford, CA 94305
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" /* for PRINTK */
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: /* this should be the easiest of all, all we do is copy it into
48: a buffer. */
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: /* now we need to copy this into memory. */
60: if (!redo )
61: {
62: skb->dev = dev;
63: skb->saddr = daddr;
64: skb->daddr = saddr;
65: /* now see if we are in use. */
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: /* charge it too the socket. */
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: /* now just put it onto the queue. */
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: /* just pretend it just came in. */
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: /* this will do terrible things if len + ipheader + devheader > dev->mtu */
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: /* check the flags. */
154: if (flags) return (-EINVAL);
155: if (len < 0) return (-EINVAL);
156:
157: /* get and verify the address. */
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: /* this shouldn't happen, but it could. */
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; /* these two should be unecessary. */
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: /* we need to remember this somewhere. */
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: /* this should be easy, if there is something there we
259: return it, otherwise we block. */
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: /* copy the address. */
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.