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