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
132 if (skb == NULL)
133 {
134 PRINTK ("packet_sendto: write buffer full?\n");
135 print_sk (sk);
136 return (-EAGAIN);
137 }
138 skb->mem_addr = skb;
139 skb->mem_len = len + sizeof (*skb) +sk->prot->max_header;
140 skb->sk = sk;
141 skb->free = 1;
142 saddr.sa_data[13] = 0;
143 dev = get_dev (saddr.sa_data);
144 if (dev == NULL)
145 {
146 sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
147 return (-ENXIO);
148 }
149 verify_area (from, len);
150 memcpy_fromfs (skb+1, from, len);
151 skb->len = len;
152 skb->next = NULL;
153 if (dev->up)
154 dev->queue_xmit (skb, dev, sk->priority);
155 else
156 free_skb (skb, FREE_WRITE);
157 return (len);
158 }
159
160 static int
161 packet_write (volatile struct sock *sk, unsigned char *buff,
162 int len, int noblock, unsigned flags)
163 {
164 return (packet_sendto (sk, buff, len, noblock, flags, NULL, 0));
165 }
166
167 static void
168 packet_close (volatile struct sock *sk, int timeout)
169 {
170 sk->inuse = 1;
171 sk->state = TCP_CLOSE;
172 dev_remove_pack ((struct packet_type *)sk->pair);
173 free_s ((void *)sk->pair, sizeof (struct packet_type));
174 release_sock (sk);
175 }
176
177 static int
178 packet_init (volatile struct sock *sk)
179 {
180 struct packet_type *p;
181 p = malloc (sizeof (*p));
182 if (p == NULL) return (-ENOMEM);
183
184 p->func = packet_rcv;
185 p->type = sk->num;
186 p->data = (void *)sk;
187 dev_add_pack (p);
188
189
190 sk->pair = (volatile struct sock *)p;
191
192 return (0);
193 }
194
195
196 int
197 packet_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
198 int noblock,
199 unsigned flags, struct sockaddr_in *sin, int *addr_len)
200 {
201
202
203 int copied=0;
204 struct sk_buff *skb;
205 struct sockaddr *saddr;
206 saddr = (struct sockaddr *)sin;
207
208 if (len == 0) return (0);
209 if (len < 0) return (-EINVAL);
210 if (addr_len)
211 {
212 verify_area (addr_len, sizeof(*addr_len));
213 put_fs_long (sizeof (*saddr), addr_len);
214 }
215
216 sk->inuse = 1;
217 while (sk->rqueue == NULL)
218 {
219 if (noblock)
220 {
221 release_sock (sk);
222 return (-EAGAIN);
223 }
224 release_sock (sk);
225 cli();
226 if (sk->rqueue == NULL)
227 {
228 interruptible_sleep_on (sk->sleep);
229 if (current->signal & ~current->blocked)
230 {
231 return (-ERESTARTSYS);
232 }
233 }
234 sti();
235 }
236 skb = sk->rqueue;
237
238 if (!(flags & MSG_PEEK))
239 {
240 if (skb->next == skb )
241 {
242 sk->rqueue = NULL;
243 }
244 else
245 {
246 sk->rqueue = sk->rqueue ->next;
247 skb->prev->next = skb->next;
248 skb->next->prev = skb->prev;
249 }
250 }
251 copied = min (len, skb->len);
252 verify_area (to, copied);
253 memcpy_tofs (to, skb+1, copied);
254
255 if (saddr)
256 {
257 struct sockaddr addr;
258 addr.sa_family = skb->dev->type;
259 memcpy (addr.sa_data,skb->dev->name, 14);
260 verify_area (saddr, sizeof (*saddr));
261 memcpy_tofs(saddr, &addr, sizeof (*saddr));
262 }
263
264 if (!(flags & MSG_PEEK))
265 {
266 free_skb (skb, FREE_READ);
267 }
268
269 release_sock (sk);
270 return (copied);
271
272 }
273
274 int
275 packet_read (volatile struct sock *sk, unsigned char *buff,
276 int len, int noblock, unsigned flags)
277 {
278 return (packet_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
279 }
280
281
282 int udp_connect (volatile struct sock *sk, struct sockaddr_in *usin,
283 int addr_len);
284
285 int udp_select (volatile struct sock *sk, int sel_type, select_table *wait);
286
287
288 struct proto packet_prot =
289 {
290 sock_wmalloc,
291 sock_rmalloc,
292 sock_wfree,
293 sock_rfree,
294 sock_rspace,
295 sock_wspace,
296 packet_close,
297 packet_read,
298 packet_write,
299 packet_sendto,
300 packet_recvfrom,
301 ip_build_header,
302 udp_connect,
303 NULL,
304 ip_queue_xmit,
305 ip_retransmit,
306 NULL,
307 NULL,
308 NULL,
309 udp_select,
310 NULL,
311 packet_init,
312 128,
313 0,
314 {NULL,}
315 };