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