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 (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
201 return -EACCES;
202
203 sk->inuse = 1;
204 skb = NULL;
205 while (skb == NULL)
206 {
207 if(sk->err!=0)
208 {
209 err= -sk->err;
210 sk->err=0;
211 release_sock(sk);
212 return(err);
213 }
214
215 skb = sk->prot->wmalloc(sk,
216 len + sk->prot->max_header,
217 0, GFP_KERNEL);
218 if (skb == NULL)
219 {
220 int tmp;
221
222 DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
223 if (noblock)
224 return(-EAGAIN);
225 tmp = sk->wmem_alloc;
226 release_sock(sk);
227 cli();
228 if (tmp <= sk->wmem_alloc) {
229 interruptible_sleep_on(sk->sleep);
230 if (current->signal & ~current->blocked) {
231 sti();
232 return(-ERESTARTSYS);
233 }
234 }
235 sk->inuse = 1;
236 sti();
237 }
238 }
239 skb->sk = sk;
240 skb->free = 1;
241 skb->localroute = sk->localroute | (flags&MSG_DONTROUTE);
242
243 tmp = sk->prot->build_header(skb, sk->saddr,
244 sin.sin_addr.s_addr, &dev,
245 sk->protocol, sk->opt, skb->mem_len, sk->ip_tos,sk->ip_ttl);
246 if (tmp < 0)
247 {
248 DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
249 kfree_skb(skb,FREE_WRITE);
250 release_sock(sk);
251 return(tmp);
252 }
253
254 memcpy_fromfs(skb->data + tmp, from, len);
255
256
257
258
259
260
261 if(sk->protocol==IPPROTO_RAW)
262 {
263 unsigned char *buff;
264 struct iphdr *iph;
265
266 buff = skb->data;
267 buff += tmp;
268
269 iph = (struct iphdr *)buff;
270 iph->saddr = sk->saddr;
271 }
272
273 skb->len = tmp + len;
274
275 sk->prot->queue_xmit(sk, dev, skb, 1);
276 release_sock(sk);
277 return(len);
278 }
279
280
281 static int raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
282 unsigned flags)
283 {
284 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
285 }
286
287
288 static void raw_close(struct sock *sk, int timeout)
289 {
290 sk->inuse = 1;
291 sk->state = TCP_CLOSE;
292
293 DPRINTF((DBG_RAW, "raw_close: deleting protocol %d\n",
294 ((struct inet_protocol *)sk->pair)->protocol));
295
296 if (inet_del_protocol((struct inet_protocol *)sk->pair) < 0)
297 DPRINTF((DBG_RAW, "raw_close: del_protocol failed.\n"));
298 kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
299 sk->pair = NULL;
300 release_sock(sk);
301 }
302
303
304 static int
305 raw_init(struct sock *sk)
306 {
307 struct inet_protocol *p;
308
309 p = (struct inet_protocol *) kmalloc(sizeof (*p), GFP_KERNEL);
310 if (p == NULL) return(-ENOMEM);
311
312 p->handler = raw_rcv;
313 p->protocol = sk->protocol;
314 p->data = (void *)sk;
315 p->err_handler = raw_err;
316 p->name="USER";
317 p->frag_handler = NULL;
318 inet_add_protocol(p);
319
320
321 sk->pair = (struct sock *)p;
322
323 DPRINTF((DBG_RAW, "raw init added protocol %d\n", sk->protocol));
324
325 return(0);
326 }
327
328
329
330
331
332
333 int
334 raw_recvfrom(struct sock *sk, unsigned char *to, int len,
335 int noblock, unsigned flags, struct sockaddr_in *sin,
336 int *addr_len)
337 {
338 int copied=0;
339 struct sk_buff *skb;
340 int err;
341
342 DPRINTF((DBG_RAW, "raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
343 " sin=%X, addr_len=%X)\n",
344 sk, to, len, noblock, flags, sin, addr_len));
345
346 if (len == 0) return(0);
347 if (len < 0) return(-EINVAL);
348
349 if (sk->shutdown & RCV_SHUTDOWN) return(0);
350 if (addr_len) {
351 err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
352 if(err)
353 return err;
354 put_fs_long(sizeof(*sin), addr_len);
355 }
356 if(sin)
357 {
358 err=verify_area(VERIFY_WRITE, sin, sizeof(*sin));
359 if(err)
360 return err;
361 }
362
363 err=verify_area(VERIFY_WRITE,to,len);
364 if(err)
365 return err;
366
367 skb=skb_recv_datagram(sk,flags,noblock,&err);
368 if(skb==NULL)
369 return err;
370
371 copied = min(len, skb->len);
372
373 skb_copy_datagram(skb, 0, to, copied);
374 sk->stamp=skb->stamp;
375
376
377 if (sin) {
378 struct sockaddr_in addr;
379
380 addr.sin_family = AF_INET;
381 addr.sin_addr.s_addr = skb->daddr;
382 memcpy_tofs(sin, &addr, sizeof(*sin));
383 }
384
385 skb_free_datagram(skb);
386 release_sock(sk);
387 return (copied);
388 }
389
390
391 int
392 raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
393 unsigned flags)
394 {
395 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
396 }
397
398
399 struct proto raw_prot = {
400 sock_wmalloc,
401 sock_rmalloc,
402 sock_wfree,
403 sock_rfree,
404 sock_rspace,
405 sock_wspace,
406 raw_close,
407 raw_read,
408 raw_write,
409 raw_sendto,
410 raw_recvfrom,
411 ip_build_header,
412 udp_connect,
413 NULL,
414 ip_queue_xmit,
415 ip_retransmit,
416 NULL,
417 NULL,
418 raw_rcv,
419 datagram_select,
420 NULL,
421 raw_init,
422 NULL,
423 ip_setsockopt,
424 ip_getsockopt,
425 128,
426 0,
427 {NULL,},
428 "RAW"
429 };