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