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