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