Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* drivers/net/pppopns.c |
2 | * | |
3 | * Driver for PPP on PPTP Network Server / PPPoPNS Socket (RFC 2637) | |
4 | * | |
5 | * Copyright (C) 2009 Google, Inc. | |
6 | * | |
7 | * This software is licensed under the terms of the GNU General Public | |
8 | * License version 2, as published by the Free Software Foundation, and | |
9 | * may be copied, distributed, and modified under those terms. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | */ | |
16 | ||
17 | /* This driver handles PPTP data packets between a RAW socket and a PPP channel. | |
18 | * The socket is created in the kernel space and connected to the same address | |
19 | * of the control socket. Outgoing packets are always sent with sequences but | |
20 | * without acknowledgements. Incoming packets with sequences are reordered | |
21 | * within a sliding window of one second. Currently reordering only happens when | |
22 | * a packet is received. It is done for simplicity since no additional locks or | |
23 | * threads are required. This driver should work on both IPv4 and IPv6. */ | |
24 | ||
25 | #include <linux/module.h> | |
26 | #include <linux/jiffies.h> | |
27 | #include <linux/workqueue.h> | |
28 | #include <linux/skbuff.h> | |
29 | #include <linux/file.h> | |
30 | #include <linux/netdevice.h> | |
31 | #include <linux/net.h> | |
32 | #include <linux/ppp_defs.h> | |
33 | #include <linux/if.h> | |
34 | #include <linux/if_ppp.h> | |
35 | #include <linux/if_pppox.h> | |
36 | #include <linux/ppp_channel.h> | |
37 | #include <asm/uaccess.h> | |
38 | ||
39 | #define GRE_HEADER_SIZE 8 | |
40 | ||
41 | #define PPTP_GRE_BITS htons(0x2001) | |
42 | #define PPTP_GRE_BITS_MASK htons(0xEF7F) | |
43 | #define PPTP_GRE_SEQ_BIT htons(0x1000) | |
44 | #define PPTP_GRE_ACK_BIT htons(0x0080) | |
45 | #define PPTP_GRE_TYPE htons(0x880B) | |
46 | ||
47 | #define PPP_ADDR 0xFF | |
48 | #define PPP_CTRL 0x03 | |
49 | ||
50 | struct header { | |
51 | __u16 bits; | |
52 | __u16 type; | |
53 | __u16 length; | |
54 | __u16 call; | |
55 | __u32 sequence; | |
56 | } __attribute__((packed)); | |
57 | ||
58 | struct meta { | |
59 | __u32 sequence; | |
60 | __u32 timestamp; | |
61 | }; | |
62 | ||
63 | static inline struct meta *skb_meta(struct sk_buff *skb) | |
64 | { | |
65 | return (struct meta *)skb->cb; | |
66 | } | |
67 | ||
68 | /******************************************************************************/ | |
69 | ||
70 | static int pppopns_recv_core(struct sock *sk_raw, struct sk_buff *skb) | |
71 | { | |
72 | struct sock *sk = (struct sock *)sk_raw->sk_user_data; | |
73 | struct pppopns_opt *opt = &pppox_sk(sk)->proto.pns; | |
74 | struct meta *meta = skb_meta(skb); | |
75 | __u32 now = jiffies; | |
76 | struct header *hdr; | |
77 | ||
78 | /* Skip transport header */ | |
79 | skb_pull(skb, skb_transport_header(skb) - skb->data); | |
80 | ||
81 | /* Drop the packet if GRE header is missing. */ | |
82 | if (skb->len < GRE_HEADER_SIZE) | |
83 | goto drop; | |
84 | hdr = (struct header *)skb->data; | |
85 | ||
86 | /* Check the header. */ | |
87 | if (hdr->type != PPTP_GRE_TYPE || hdr->call != opt->local || | |
88 | (hdr->bits & PPTP_GRE_BITS_MASK) != PPTP_GRE_BITS) | |
89 | goto drop; | |
90 | ||
91 | /* Skip all fields including optional ones. */ | |
92 | if (!skb_pull(skb, GRE_HEADER_SIZE + | |
93 | (hdr->bits & PPTP_GRE_SEQ_BIT ? 4 : 0) + | |
94 | (hdr->bits & PPTP_GRE_ACK_BIT ? 4 : 0))) | |
95 | goto drop; | |
96 | ||
97 | /* Check the length. */ | |
98 | if (skb->len != ntohs(hdr->length)) | |
99 | goto drop; | |
100 | ||
101 | /* Check the sequence if it is present. */ | |
102 | if (hdr->bits & PPTP_GRE_SEQ_BIT) { | |
103 | meta->sequence = ntohl(hdr->sequence); | |
104 | if ((__s32)(meta->sequence - opt->recv_sequence) < 0) | |
105 | goto drop; | |
106 | } | |
107 | ||
108 | /* Skip PPP address and control if they are present. */ | |
109 | if (skb->len >= 2 && skb->data[0] == PPP_ADDR && | |
110 | skb->data[1] == PPP_CTRL) | |
111 | skb_pull(skb, 2); | |
112 | ||
113 | /* Fix PPP protocol if it is compressed. */ | |
114 | if (skb->len >= 1 && skb->data[0] & 1) | |
115 | skb_push(skb, 1)[0] = 0; | |
116 | ||
117 | /* Drop the packet if PPP protocol is missing. */ | |
118 | if (skb->len < 2) | |
119 | goto drop; | |
120 | ||
121 | /* Perform reordering if sequencing is enabled. */ | |
122 | if (hdr->bits & PPTP_GRE_SEQ_BIT) { | |
123 | struct sk_buff *skb1; | |
124 | ||
125 | /* Insert the packet into receive queue in order. */ | |
126 | skb_set_owner_r(skb, sk); | |
127 | skb_queue_walk(&sk->sk_receive_queue, skb1) { | |
128 | struct meta *meta1 = skb_meta(skb1); | |
129 | __s32 order = meta->sequence - meta1->sequence; | |
130 | if (order == 0) | |
131 | goto drop; | |
132 | if (order < 0) { | |
133 | meta->timestamp = meta1->timestamp; | |
134 | skb_insert(skb1, skb, &sk->sk_receive_queue); | |
135 | skb = NULL; | |
136 | break; | |
137 | } | |
138 | } | |
139 | if (skb) { | |
140 | meta->timestamp = now; | |
141 | skb_queue_tail(&sk->sk_receive_queue, skb); | |
142 | } | |
143 | ||
144 | /* Remove packets from receive queue as long as | |
145 | * 1. the receive buffer is full, | |
146 | * 2. they are queued longer than one second, or | |
147 | * 3. there are no missing packets before them. */ | |
148 | skb_queue_walk_safe(&sk->sk_receive_queue, skb, skb1) { | |
149 | meta = skb_meta(skb); | |
150 | if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf && | |
151 | now - meta->timestamp < HZ && | |
152 | meta->sequence != opt->recv_sequence) | |
153 | break; | |
154 | skb_unlink(skb, &sk->sk_receive_queue); | |
155 | opt->recv_sequence = meta->sequence + 1; | |
156 | skb_orphan(skb); | |
157 | ppp_input(&pppox_sk(sk)->chan, skb); | |
158 | } | |
159 | return NET_RX_SUCCESS; | |
160 | } | |
161 | ||
162 | /* Flush receive queue if sequencing is disabled. */ | |
163 | skb_queue_purge(&sk->sk_receive_queue); | |
164 | skb_orphan(skb); | |
165 | ppp_input(&pppox_sk(sk)->chan, skb); | |
166 | return NET_RX_SUCCESS; | |
167 | drop: | |
168 | kfree_skb(skb); | |
169 | return NET_RX_DROP; | |
170 | } | |
171 | ||
172 | static void pppopns_recv(struct sock *sk_raw, int length) | |
173 | { | |
174 | struct sk_buff *skb; | |
175 | while ((skb = skb_dequeue(&sk_raw->sk_receive_queue))) { | |
176 | sock_hold(sk_raw); | |
177 | sk_receive_skb(sk_raw, skb, 0); | |
178 | } | |
179 | } | |
180 | ||
181 | static struct sk_buff_head delivery_queue; | |
182 | ||
183 | static void pppopns_xmit_core(struct work_struct *delivery_work) | |
184 | { | |
185 | mm_segment_t old_fs = get_fs(); | |
186 | struct sk_buff *skb; | |
187 | ||
188 | set_fs(KERNEL_DS); | |
189 | while ((skb = skb_dequeue(&delivery_queue))) { | |
190 | struct sock *sk_raw = skb->sk; | |
191 | struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len}; | |
192 | struct msghdr msg = { | |
193 | .msg_iov = (struct iovec *)&iov, | |
194 | .msg_iovlen = 1, | |
195 | .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT, | |
196 | }; | |
197 | sk_raw->sk_prot->sendmsg(NULL, sk_raw, &msg, skb->len); | |
198 | kfree_skb(skb); | |
199 | } | |
200 | set_fs(old_fs); | |
201 | } | |
202 | ||
203 | static DECLARE_WORK(delivery_work, pppopns_xmit_core); | |
204 | ||
205 | static int pppopns_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |
206 | { | |
207 | struct sock *sk_raw = (struct sock *)chan->private; | |
208 | struct pppopns_opt *opt = &pppox_sk(sk_raw->sk_user_data)->proto.pns; | |
209 | struct header *hdr; | |
210 | __u16 length; | |
211 | ||
212 | /* Install PPP address and control. */ | |
213 | skb_push(skb, 2); | |
214 | skb->data[0] = PPP_ADDR; | |
215 | skb->data[1] = PPP_CTRL; | |
216 | length = skb->len; | |
217 | ||
218 | /* Install PPTP GRE header. */ | |
219 | hdr = (struct header *)skb_push(skb, 12); | |
220 | hdr->bits = PPTP_GRE_BITS | PPTP_GRE_SEQ_BIT; | |
221 | hdr->type = PPTP_GRE_TYPE; | |
222 | hdr->length = htons(length); | |
223 | hdr->call = opt->remote; | |
224 | hdr->sequence = htonl(opt->xmit_sequence); | |
225 | opt->xmit_sequence++; | |
226 | ||
227 | /* Now send the packet via the delivery queue. */ | |
228 | skb_set_owner_w(skb, sk_raw); | |
229 | skb_queue_tail(&delivery_queue, skb); | |
230 | schedule_work(&delivery_work); | |
231 | return 1; | |
232 | } | |
233 | ||
234 | /******************************************************************************/ | |
235 | ||
236 | static struct ppp_channel_ops pppopns_channel_ops = { | |
237 | .start_xmit = pppopns_xmit, | |
238 | }; | |
239 | ||
240 | static int pppopns_connect(struct socket *sock, struct sockaddr *useraddr, | |
241 | int addrlen, int flags) | |
242 | { | |
243 | struct sock *sk = sock->sk; | |
244 | struct pppox_sock *po = pppox_sk(sk); | |
245 | struct sockaddr_pppopns *addr = (struct sockaddr_pppopns *)useraddr; | |
246 | struct sockaddr_storage ss; | |
247 | struct socket *sock_tcp = NULL; | |
248 | struct socket *sock_raw = NULL; | |
249 | struct sock *sk_tcp; | |
250 | struct sock *sk_raw; | |
251 | int error; | |
252 | ||
253 | if (addrlen != sizeof(struct sockaddr_pppopns)) | |
254 | return -EINVAL; | |
255 | ||
256 | lock_sock(sk); | |
257 | error = -EALREADY; | |
258 | if (sk->sk_state != PPPOX_NONE) | |
259 | goto out; | |
260 | ||
261 | sock_tcp = sockfd_lookup(addr->tcp_socket, &error); | |
262 | if (!sock_tcp) | |
263 | goto out; | |
264 | sk_tcp = sock_tcp->sk; | |
265 | error = -EPROTONOSUPPORT; | |
266 | if (sk_tcp->sk_protocol != IPPROTO_TCP) | |
267 | goto out; | |
268 | addrlen = sizeof(struct sockaddr_storage); | |
269 | error = kernel_getpeername(sock_tcp, (struct sockaddr *)&ss, &addrlen); | |
270 | if (error) | |
271 | goto out; | |
272 | if (!sk_tcp->sk_bound_dev_if) { | |
273 | struct dst_entry *dst = sk_dst_get(sk_tcp); | |
274 | error = -ENODEV; | |
275 | if (!dst) | |
276 | goto out; | |
277 | sk_tcp->sk_bound_dev_if = dst->dev->ifindex; | |
278 | dst_release(dst); | |
279 | } | |
280 | ||
281 | error = sock_create(ss.ss_family, SOCK_RAW, IPPROTO_GRE, &sock_raw); | |
282 | if (error) | |
283 | goto out; | |
284 | sk_raw = sock_raw->sk; | |
285 | sk_raw->sk_bound_dev_if = sk_tcp->sk_bound_dev_if; | |
286 | error = kernel_connect(sock_raw, (struct sockaddr *)&ss, addrlen, 0); | |
287 | if (error) | |
288 | goto out; | |
289 | ||
290 | po->chan.hdrlen = 14; | |
291 | po->chan.private = sk_raw; | |
292 | po->chan.ops = &pppopns_channel_ops; | |
293 | po->chan.mtu = PPP_MRU - 80; | |
294 | po->proto.pns.local = addr->local; | |
295 | po->proto.pns.remote = addr->remote; | |
296 | po->proto.pns.data_ready = sk_raw->sk_data_ready; | |
297 | po->proto.pns.backlog_rcv = sk_raw->sk_backlog_rcv; | |
298 | ||
299 | error = ppp_register_channel(&po->chan); | |
300 | if (error) | |
301 | goto out; | |
302 | ||
303 | sk->sk_state = PPPOX_CONNECTED; | |
304 | lock_sock(sk_raw); | |
305 | sk_raw->sk_data_ready = pppopns_recv; | |
306 | sk_raw->sk_backlog_rcv = pppopns_recv_core; | |
307 | sk_raw->sk_user_data = sk; | |
308 | release_sock(sk_raw); | |
309 | out: | |
310 | if (sock_tcp) | |
311 | sockfd_put(sock_tcp); | |
312 | if (error && sock_raw) | |
313 | sock_release(sock_raw); | |
314 | release_sock(sk); | |
315 | return error; | |
316 | } | |
317 | ||
318 | static int pppopns_release(struct socket *sock) | |
319 | { | |
320 | struct sock *sk = sock->sk; | |
321 | ||
322 | if (!sk) | |
323 | return 0; | |
324 | ||
325 | lock_sock(sk); | |
326 | if (sock_flag(sk, SOCK_DEAD)) { | |
327 | release_sock(sk); | |
328 | return -EBADF; | |
329 | } | |
330 | ||
331 | if (sk->sk_state != PPPOX_NONE) { | |
332 | struct sock *sk_raw = (struct sock *)pppox_sk(sk)->chan.private; | |
333 | lock_sock(sk_raw); | |
334 | skb_queue_purge(&sk->sk_receive_queue); | |
335 | pppox_unbind_sock(sk); | |
336 | sk_raw->sk_data_ready = pppox_sk(sk)->proto.pns.data_ready; | |
337 | sk_raw->sk_backlog_rcv = pppox_sk(sk)->proto.pns.backlog_rcv; | |
338 | sk_raw->sk_user_data = NULL; | |
339 | release_sock(sk_raw); | |
340 | sock_release(sk_raw->sk_socket); | |
341 | } | |
342 | ||
343 | sock_orphan(sk); | |
344 | sock->sk = NULL; | |
345 | release_sock(sk); | |
346 | sock_put(sk); | |
347 | return 0; | |
348 | } | |
349 | ||
350 | /******************************************************************************/ | |
351 | ||
352 | static struct proto pppopns_proto = { | |
353 | .name = "PPPOPNS", | |
354 | .owner = THIS_MODULE, | |
355 | .obj_size = sizeof(struct pppox_sock), | |
356 | }; | |
357 | ||
358 | static struct proto_ops pppopns_proto_ops = { | |
359 | .family = PF_PPPOX, | |
360 | .owner = THIS_MODULE, | |
361 | .release = pppopns_release, | |
362 | .bind = sock_no_bind, | |
363 | .connect = pppopns_connect, | |
364 | .socketpair = sock_no_socketpair, | |
365 | .accept = sock_no_accept, | |
366 | .getname = sock_no_getname, | |
367 | .poll = sock_no_poll, | |
368 | .ioctl = pppox_ioctl, | |
369 | .listen = sock_no_listen, | |
370 | .shutdown = sock_no_shutdown, | |
371 | .setsockopt = sock_no_setsockopt, | |
372 | .getsockopt = sock_no_getsockopt, | |
373 | .sendmsg = sock_no_sendmsg, | |
374 | .recvmsg = sock_no_recvmsg, | |
375 | .mmap = sock_no_mmap, | |
376 | }; | |
377 | ||
378 | static int pppopns_create(struct net *net, struct socket *sock) | |
379 | { | |
380 | struct sock *sk; | |
381 | ||
382 | sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppopns_proto); | |
383 | if (!sk) | |
384 | return -ENOMEM; | |
385 | ||
386 | sock_init_data(sock, sk); | |
387 | sock->state = SS_UNCONNECTED; | |
388 | sock->ops = &pppopns_proto_ops; | |
389 | sk->sk_protocol = PX_PROTO_OPNS; | |
390 | sk->sk_state = PPPOX_NONE; | |
391 | return 0; | |
392 | } | |
393 | ||
394 | /******************************************************************************/ | |
395 | ||
396 | static struct pppox_proto pppopns_pppox_proto = { | |
397 | .create = pppopns_create, | |
398 | .owner = THIS_MODULE, | |
399 | }; | |
400 | ||
401 | static int __init pppopns_init(void) | |
402 | { | |
403 | int error; | |
404 | ||
405 | error = proto_register(&pppopns_proto, 0); | |
406 | if (error) | |
407 | return error; | |
408 | ||
409 | error = register_pppox_proto(PX_PROTO_OPNS, &pppopns_pppox_proto); | |
410 | if (error) | |
411 | proto_unregister(&pppopns_proto); | |
412 | else | |
413 | skb_queue_head_init(&delivery_queue); | |
414 | return error; | |
415 | } | |
416 | ||
417 | static void __exit pppopns_exit(void) | |
418 | { | |
419 | unregister_pppox_proto(PX_PROTO_OPNS); | |
420 | proto_unregister(&pppopns_proto); | |
421 | } | |
422 | ||
423 | module_init(pppopns_init); | |
424 | module_exit(pppopns_exit); | |
425 | ||
426 | MODULE_DESCRIPTION("PPP on PPTP Network Server (PPPoPNS)"); | |
427 | MODULE_AUTHOR("Chia-chi Yeh <chiachi@android.com>"); | |
428 | MODULE_LICENSE("GPL"); |