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