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