This source file includes following definitions.
- min
- packet_rcv
- packet_sendto
- packet_write
- packet_close
- packet_init
- packet_recvfrom
- packet_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
36
37
38
39
40
41
42
43
44
45
46
47
48
49 #include <linux/types.h>
50 #include <linux/sched.h>
51 #include <linux/fcntl.h>
52 #include <linux/socket.h>
53 #include <netinet/in.h>
54 #include "timer.h"
55 #include "ip.h"
56 #include "tcp.h"
57 #include "sock.h"
58 #include <linux/errno.h>
59 #include <linux/timer.h>
60 #include <asm/system.h>
61 #include <asm/segment.h>
62 #include "../kern_sock.h"
63
64 extern struct proto raw_prot;
65
66 static unsigned long
67 min(unsigned long a, unsigned long b)
68 {
69 if (a < b) return (a);
70 return (b);
71 }
72
73
74
75 int
76 packet_rcv (struct sk_buff *skb, struct device *dev, struct packet_type *pt)
77 {
78 volatile struct sock *sk;
79
80 sk = pt->data;
81 skb->dev = dev;
82 skb->len += dev->hard_header_len;
83
84
85 cli();
86 if (sk->inuse)
87 {
88 sti();
89
90
91
92 skb->sk = NULL;
93 kfree_skb (skb, FREE_READ);
94 return (0);
95
96 }
97 sk->inuse = 1;
98 sti ();
99
100 skb->sk = sk;
101
102
103 if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
104 {
105 skb->sk = NULL;
106 kfree_skb (skb, FREE_READ);
107 return (0);
108 }
109
110 sk->rmem_alloc += skb->mem_len;
111
112
113 if (sk->rqueue == NULL)
114 {
115 sk->rqueue = skb;
116 skb->next = skb;
117 skb->prev = skb;
118 }
119 else
120 {
121 skb->next = sk->rqueue;
122 skb->prev = sk->rqueue->prev;
123 skb->prev->next = skb;
124 skb->next->prev = skb;
125 }
126 wake_up (sk->sleep);
127 release_sock (sk);
128 return (0);
129 }
130
131
132 static int
133 packet_sendto (volatile struct sock *sk, unsigned char *from, int len,
134 int noblock,
135 unsigned flags, struct sockaddr_in *usin, int addr_len)
136 {
137 struct sk_buff *skb;
138 struct device *dev;
139 struct sockaddr saddr;
140
141
142 if (flags) return (-EINVAL);
143 if (len < 0) return (-EINVAL);
144
145
146 if (usin)
147 {
148 if (addr_len < sizeof (saddr))
149 return (-EINVAL);
150
151 memcpy_fromfs (&saddr, usin, sizeof(saddr));
152 }
153 else
154 return (-EINVAL);
155
156 skb = sk->prot->wmalloc (sk, len+sizeof (*skb), 0, GFP_KERNEL);
157
158
159 if (skb == NULL)
160 {
161 PRINTK ("packet_sendto: write buffer full?\n");
162 return (-EAGAIN);
163 }
164 skb->lock = 0;
165 skb->mem_addr = skb;
166 skb->mem_len = len + sizeof (*skb);
167 skb->sk = sk;
168 skb->free = 1;
169 saddr.sa_data[13] = 0;
170 dev = get_dev (saddr.sa_data);
171 if (dev == NULL)
172 {
173 sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
174 return (-ENXIO);
175 }
176
177 memcpy_fromfs (skb+1, from, len);
178 skb->len = len;
179 skb->next = NULL;
180 if (dev->up)
181 dev->queue_xmit (skb, dev, sk->priority);
182 else
183 kfree_skb (skb, FREE_WRITE);
184 return (len);
185 }
186
187 static int
188 packet_write (volatile struct sock *sk, unsigned char *buff,
189 int len, int noblock, unsigned flags)
190 {
191 return (packet_sendto (sk, buff, len, noblock, flags, NULL, 0));
192 }
193
194 static void
195 packet_close (volatile struct sock *sk, int timeout)
196 {
197 sk->inuse = 1;
198 sk->state = TCP_CLOSE;
199 dev_remove_pack ((struct packet_type *)sk->pair);
200 kfree_s ((void *)sk->pair, sizeof (struct packet_type));
201 sk->pair = NULL;
202 release_sock (sk);
203 }
204
205 static int
206 packet_init (volatile struct sock *sk)
207 {
208 struct packet_type *p;
209 p = kmalloc (sizeof (*p), GFP_KERNEL);
210 if (p == NULL) return (-ENOMEM);
211
212 p->func = packet_rcv;
213 p->type = sk->num;
214 p->data = (void *)sk;
215 dev_add_pack (p);
216
217
218 sk->pair = (volatile struct sock *)p;
219
220 return (0);
221 }
222
223
224 int
225 packet_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
226 int noblock,
227 unsigned flags, struct sockaddr_in *sin, int *addr_len)
228 {
229
230
231 int copied=0;
232 struct sk_buff *skb;
233 struct sockaddr *saddr;
234 saddr = (struct sockaddr *)sin;
235
236 if (len == 0) return (0);
237 if (len < 0) return (-EINVAL);
238
239 if (sk->shutdown & RCV_SHUTDOWN) return (0);
240
241 if (addr_len)
242 {
243 verify_area (addr_len, sizeof(*addr_len));
244 put_fs_long (sizeof (*saddr), addr_len);
245 }
246
247 sk->inuse = 1;
248 while (sk->rqueue == NULL)
249 {
250 if (noblock)
251 {
252 release_sock (sk);
253 return (-EAGAIN);
254 }
255 release_sock (sk);
256 cli();
257 if (sk->rqueue == NULL)
258 {
259 interruptible_sleep_on (sk->sleep);
260 if (current->signal & ~current->blocked)
261 {
262 return (-ERESTARTSYS);
263 }
264 }
265 sk->inuse = 1;
266 sti();
267 }
268 skb = sk->rqueue;
269
270 if (!(flags & MSG_PEEK))
271 {
272 if (skb->next == skb )
273 {
274 sk->rqueue = NULL;
275 }
276 else
277 {
278 sk->rqueue = (struct sk_buff *)sk->rqueue ->next;
279 skb->prev->next = skb->next;
280 skb->next->prev = skb->prev;
281 }
282 }
283 copied = min (len, skb->len);
284 verify_area (to, copied);
285 memcpy_tofs (to, skb+1, copied);
286
287 if (saddr)
288 {
289 struct sockaddr addr;
290 addr.sa_family = skb->dev->type;
291 memcpy (addr.sa_data,skb->dev->name, 14);
292 verify_area (saddr, sizeof (*saddr));
293 memcpy_tofs(saddr, &addr, sizeof (*saddr));
294 }
295
296 if (!(flags & MSG_PEEK))
297 {
298 kfree_skb (skb, FREE_READ);
299 }
300
301 release_sock (sk);
302 return (copied);
303
304 }
305
306 int
307 packet_read (volatile struct sock *sk, unsigned char *buff,
308 int len, int noblock, unsigned flags)
309 {
310 return (packet_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
311 }
312
313
314 int udp_connect (volatile struct sock *sk, struct sockaddr_in *usin,
315 int addr_len);
316
317 int udp_select (volatile struct sock *sk, int sel_type, select_table *wait);
318
319
320 struct proto packet_prot =
321 {
322 sock_wmalloc,
323 sock_rmalloc,
324 sock_wfree,
325 sock_rfree,
326 sock_rspace,
327 sock_wspace,
328 packet_close,
329 packet_read,
330 packet_write,
331 packet_sendto,
332 packet_recvfrom,
333 ip_build_header,
334 udp_connect,
335 NULL,
336 ip_queue_xmit,
337 ip_retransmit,
338 NULL,
339 NULL,
340 NULL,
341 udp_select,
342 NULL,
343 packet_init,
344 NULL,
345 128,
346 0,
347 {NULL,},
348 "PACKET"
349 };