This source file includes following definitions.
- min
- raw_err
- raw_rcv
- 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
24
25
26
27
28
29
30
31
32 #include <asm/system.h>
33 #include <asm/segment.h>
34 #include <linux/types.h>
35 #include <linux/sched.h>
36 #include <linux/errno.h>
37 #include <linux/timer.h>
38 #include <linux/mm.h>
39 #include <linux/kernel.h>
40 #include <linux/fcntl.h>
41 #include <linux/socket.h>
42 #include <linux/in.h>
43 #include "inet.h"
44 #include "dev.h"
45 #include "ip.h"
46 #include "protocol.h"
47 #include "tcp.h"
48 #include "skbuff.h"
49 #include "sock.h"
50 #include "icmp.h"
51 #include "udp.h"
52
53
54 static unsigned long
55 min(unsigned long a, unsigned long b)
56 {
57 if (a < b) return(a);
58 return(b);
59 }
60
61
62
63 void
64 raw_err (int err, unsigned char *header, unsigned long daddr,
65 unsigned long saddr, struct inet_protocol *protocol)
66 {
67 struct sock *sk;
68
69 DPRINTF((DBG_RAW, "raw_err(err=%d, hdr=%X, daddr=%X, saddr=%X, protocl=%X)\n",
70 err, header, daddr, saddr, protocol));
71
72 if (protocol == NULL) return;
73 sk = (struct sock *) protocol->data;
74 if (sk == NULL) return;
75
76
77 if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8)) {
78 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
79 return;
80 }
81
82 sk->err = icmp_err_convert[err & 0xff].errno;
83 sk->error_report(sk);
84
85 return;
86 }
87
88
89
90
91
92
93 int
94 raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
95 unsigned long daddr, unsigned short len, unsigned long saddr,
96 int redo, struct inet_protocol *protocol)
97 {
98 struct sock *sk;
99
100 DPRINTF((DBG_RAW, "raw_rcv(skb=%X, dev=%X, opt=%X, daddr=%X,\n"
101 " len=%d, saddr=%X, redo=%d, protocol=%X)\n",
102 skb, dev, opt, daddr, len, saddr, redo, protocol));
103
104 if (skb == NULL) return(0);
105 if (protocol == NULL) {
106 kfree_skb(skb, FREE_READ);
107 return(0);
108 }
109 sk = (struct sock *) protocol->data;
110 if (sk == NULL) {
111 kfree_skb(skb, FREE_READ);
112 return(0);
113 }
114
115
116 skb->sk = sk;
117 skb->len = len + skb->ip_hdr->ihl*sizeof(long);
118 skb->h.raw = skb->ip_hdr;
119 skb->dev = dev;
120 skb->saddr = daddr;
121 skb->daddr = saddr;
122
123
124 if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
125 skb->sk = NULL;
126 kfree_skb(skb, FREE_READ);
127 return(0);
128 }
129 sk->rmem_alloc += skb->mem_len;
130 skb_queue_tail(&sk->rqueue,skb);
131 sk->data_ready(sk,skb->len);
132 release_sock(sk);
133 return(0);
134 }
135
136
137
138 static int
139 raw_sendto(struct sock *sk, unsigned char *from, int len,
140 int noblock,
141 unsigned flags, struct sockaddr_in *usin, int addr_len)
142 {
143 struct sk_buff *skb;
144 struct device *dev=NULL;
145 struct sockaddr_in sin;
146 int tmp;
147 int err;
148
149 DPRINTF((DBG_RAW, "raw_sendto(sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
150 " usin=%X, addr_len = %d)\n", sk, from, len, noblock,
151 flags, usin, addr_len));
152
153
154 if (flags) return(-EINVAL);
155 if (len < 0) return(-EINVAL);
156
157 err=verify_area(VERIFY_READ,from,len);
158 if(err)
159 return err;
160
161 if (usin) {
162 if (addr_len < sizeof(sin)) return(-EINVAL);
163 err=verify_area (VERIFY_READ, usin, sizeof (sin));
164 if(err)
165 return err;
166 memcpy_fromfs(&sin, usin, sizeof(sin));
167 if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL);
168 } else {
169 if (sk->state != TCP_ESTABLISHED) return(-EINVAL);
170 sin.sin_family = AF_INET;
171 sin.sin_port = sk->protocol;
172 sin.sin_addr.s_addr = sk->daddr;
173 }
174 if (sin.sin_port == 0) sin.sin_port = sk->protocol;
175
176 if (sk->broadcast == 0 && chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
177 return -EACCES;
178
179 sk->inuse = 1;
180 skb = NULL;
181 while (skb == NULL) {
182 if(sk->err!=0)
183 {
184 err= -sk->err;
185 sk->err=0;
186 release_sock(sk);
187 return(err);
188 }
189
190 skb = sk->prot->wmalloc(sk,
191 len+sizeof(*skb) + sk->prot->max_header,
192 0, GFP_KERNEL);
193 if (skb == NULL) {
194 int tmp;
195
196 DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
197 if (noblock)
198 return(-EAGAIN);
199 tmp = sk->wmem_alloc;
200 release_sock(sk);
201 cli();
202 if (tmp <= sk->wmem_alloc) {
203 interruptible_sleep_on(sk->sleep);
204 if (current->signal & ~current->blocked) {
205 sti();
206 return(-ERESTARTSYS);
207 }
208 }
209 sk->inuse = 1;
210 sti();
211 }
212 }
213 skb->mem_addr = skb;
214 skb->mem_len = len + sizeof(*skb) +sk->prot->max_header;
215 skb->sk = sk;
216
217 skb->free = 1;
218 skb->arp = 0;
219
220 tmp = sk->prot->build_header(skb, sk->saddr,
221 sin.sin_addr.s_addr, &dev,
222 sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl);
223 if (tmp < 0) {
224 DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
225 kfree_skb(skb,FREE_WRITE);
226 release_sock(sk);
227 return(tmp);
228 }
229
230
231 memcpy_fromfs(skb->data + tmp, from, len);
232
233
234
235
236 if(sk->protocol==IPPROTO_RAW) {
237 unsigned char *buff;
238 struct iphdr *iph;
239
240 buff = skb->data;
241 buff += tmp;
242 iph = (struct iphdr *)buff;
243 iph->saddr = sk->saddr;
244 }
245
246 skb->len = tmp + len;
247
248 if(dev!=NULL && skb->len > 4095)
249 {
250 kfree_skb(skb, FREE_WRITE);
251 release_sock(sk);
252 return(-EMSGSIZE);
253 }
254
255 sk->prot->queue_xmit(sk, dev, skb, 1);
256 release_sock(sk);
257 return(len);
258 }
259
260
261 static int
262 raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
263 unsigned flags)
264 {
265 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
266 }
267
268
269 static void
270 raw_close(struct sock *sk, int timeout)
271 {
272 sk->inuse = 1;
273 sk->state = TCP_CLOSE;
274
275 DPRINTF((DBG_RAW, "raw_close: deleting protocol %d\n",
276 ((struct inet_protocol *)sk->pair)->protocol));
277
278 if (inet_del_protocol((struct inet_protocol *)sk->pair) < 0)
279 DPRINTF((DBG_RAW, "raw_close: del_protocol failed.\n"));
280 kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
281 sk->pair = NULL;
282 release_sock(sk);
283 }
284
285
286 static int
287 raw_init(struct sock *sk)
288 {
289 struct inet_protocol *p;
290
291 p = (struct inet_protocol *) kmalloc(sizeof (*p), GFP_KERNEL);
292 if (p == NULL) return(-ENOMEM);
293
294 p->handler = raw_rcv;
295 p->protocol = sk->protocol;
296 p->data = (void *)sk;
297 p->err_handler = raw_err;
298 p->name="USER";
299 p->frag_handler = NULL;
300 inet_add_protocol(p);
301
302
303 sk->pair = (struct sock *)p;
304
305 DPRINTF((DBG_RAW, "raw init added protocol %d\n", sk->protocol));
306
307 return(0);
308 }
309
310
311
312
313
314
315 int
316 raw_recvfrom(struct sock *sk, unsigned char *to, int len,
317 int noblock, unsigned flags, struct sockaddr_in *sin,
318 int *addr_len)
319 {
320 int copied=0;
321 struct sk_buff *skb;
322 int err;
323
324 DPRINTF((DBG_RAW, "raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
325 " sin=%X, addr_len=%X)\n",
326 sk, to, len, noblock, flags, sin, addr_len));
327
328 if (len == 0) return(0);
329 if (len < 0) return(-EINVAL);
330
331 if (sk->shutdown & RCV_SHUTDOWN) return(0);
332 if (addr_len) {
333 err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
334 if(err)
335 return err;
336 put_fs_long(sizeof(*sin), addr_len);
337 }
338 if(sin)
339 {
340 err=verify_area(VERIFY_WRITE, sin, sizeof(*sin));
341 if(err)
342 return err;
343 }
344
345 err=verify_area(VERIFY_WRITE,to,len);
346 if(err)
347 return err;
348
349 skb=skb_recv_datagram(sk,flags,noblock,&err);
350 if(skb==NULL)
351 return err;
352
353 copied = min(len, skb->len);
354
355 skb_copy_datagram(skb, 0, to, copied);
356
357
358 if (sin) {
359 struct sockaddr_in addr;
360
361 addr.sin_family = AF_INET;
362 addr.sin_addr.s_addr = skb->daddr;
363 memcpy_tofs(sin, &addr, sizeof(*sin));
364 }
365
366 skb_free_datagram(skb);
367 release_sock(sk);
368 return (copied);
369 }
370
371
372 int
373 raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
374 unsigned flags)
375 {
376 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
377 }
378
379
380 struct proto raw_prot = {
381 sock_wmalloc,
382 sock_rmalloc,
383 sock_wfree,
384 sock_rfree,
385 sock_rspace,
386 sock_wspace,
387 raw_close,
388 raw_read,
389 raw_write,
390 raw_sendto,
391 raw_recvfrom,
392 ip_build_header,
393 udp_connect,
394 NULL,
395 ip_queue_xmit,
396 ip_retransmit,
397 NULL,
398 NULL,
399 raw_rcv,
400 datagram_select,
401 NULL,
402 raw_init,
403 NULL,
404 ip_setsockopt,
405 ip_getsockopt,
406 128,
407 0,
408 {NULL,},
409 "RAW"
410 };