l2tp.c revision 79e6232ffa3765d3352e01e2b7887b6425c7c655
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* A simple implementation of L2TP Access Concentrator (RFC 2661) which only
18 * creates a single session. The following code only handles control packets.
19 * Data packets are handled by PPPoLAC driver which can be found in Android
20 * kernel tree. */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <errno.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <arpa/inet.h>
29#include <linux/if_pppolac.h>
30
31#include "mtpd.h"
32
33/* TODO: Support secrets. */
34
35/* To avoid unnecessary endianness conversions, tunnels, sessions, attributes,
36 * and values are all accessed in network order. */
37
38/* 0 is reserved. We put ACK here just for convenience. */
39enum l2tp_message {
40    ACK = 0,
41    SCCRQ = 1,
42    SCCRP = 2,
43    SCCCN = 3,
44    STOPCCN = 4,
45    HELLO = 6,
46    OCRQ = 7,
47    OCRP = 8,
48    OCCN = 9,
49    ICRQ = 10,
50    ICRP = 11,
51    ICCN = 12,
52    CDN = 14,
53    WEN = 15,
54    SLI = 16,
55    MESSAGE_MAX = 16,
56};
57
58static char *messages[] = {
59    "ACK", "SCCRQ", "SCCRP", "SCCCN", "STOPCCN", NULL, "HELLO", "OCRQ",
60    "OCRP", "OCCN", "ICRQ", "ICRP", "ICCN", NULL, "CDN", "WEN", "SLI",
61};
62
63/* This is incomplete. Only those we used are listed here. */
64#define RESULT_CODE             htons(1)
65#define PROTOCOL_VERSION        htons(2)
66#define FRAMING_CAPABILITIES    htons(3)
67#define HOST_NAME               htons(7)
68#define ASSIGNED_TUNNEL         htons(9)
69#define WINDOW_SIZE             htons(10)
70#define ASSIGNED_SESSION        htons(14)
71#define CALL_SERIAL_NUMBER      htons(15)
72#define FRAMING_TYPE            htons(19)
73#define CONNECT_SPEED           htons(24)
74
75#define MESSAGE_FLAG            0xC802
76#define MESSAGE_MASK            0xCB0F
77#define ATTRIBUTE_FLAG(length)  (0x8006 + (length))
78#define ATTRIBUTE_LENGTH(flag)  (0x03FF & (flag))
79#define ATTRIBUTE_HIDDEN(flag)  (0x4000 & (flag))
80
81#define ACK_SIZE                12
82#define MESSAGE_HEADER_SIZE     20
83#define ATTRIBUTE_HEADER_SIZE   6
84
85static uint16_t local_tunnel;
86static uint16_t local_session;
87static uint16_t local_sequence;
88static uint16_t remote_tunnel;
89static uint16_t remote_session;
90static uint16_t remote_sequence;
91
92static uint16_t state;
93static int acknowledged;
94
95/* According to RFC 2661 page 46, an exponential backoff strategy is required
96 * for retransmission. However, it might waste too much time waiting for IPsec
97 * negotiation. Here we use the same interval to keep things simple. */
98#define TIMEOUT_INTERVAL 2000
99
100#define MAX_PACKET_LENGTH 2048
101
102static struct packet {
103    int message;
104    int length;
105    uint8_t buffer[MAX_PACKET_LENGTH] __attribute__((aligned));
106} incoming, outgoing;
107
108struct attribute {
109    uint16_t flag;
110    uint16_t vendor;
111    uint16_t type;
112    uint8_t value[1];
113} __attribute__((packed));
114
115static void set_message(uint16_t session, uint16_t message)
116{
117    uint16_t *p = (uint16_t *)outgoing.buffer;
118    p[0] = htons(MESSAGE_FLAG);
119    /* p[1] will be filled in send_packet(). */
120    p[2] = remote_tunnel;
121    p[3] = session;
122    p[4] = htons(local_sequence);
123    p[5] = htons(remote_sequence);
124    p[6] = htons(ATTRIBUTE_FLAG(2));
125    p[7] = 0;
126    p[8] = 0;
127    p[9] = htons(message);
128    outgoing.message = message;
129    outgoing.length = MESSAGE_HEADER_SIZE;
130    ++local_sequence;
131}
132
133static void add_attribute_raw(uint16_t type, void *value, int size)
134{
135    struct attribute *p = (struct attribute *)&outgoing.buffer[outgoing.length];
136    p->flag = htons(ATTRIBUTE_FLAG(size));
137    p->vendor = 0;
138    p->type = type;
139    memcpy(&p->value, value, size);
140    outgoing.length += ATTRIBUTE_HEADER_SIZE + size;
141}
142
143static void add_attribute_u16(uint16_t attribute, uint16_t value)
144{
145    add_attribute_raw(attribute, &value, sizeof(uint16_t));
146}
147
148static void add_attribute_u32(uint16_t attribute, uint32_t value)
149{
150    add_attribute_raw(attribute, &value, sizeof(uint32_t));
151}
152
153static void send_packet()
154{
155    uint16_t *p = (uint16_t *)outgoing.buffer;
156    p[1] = htons(outgoing.length);
157    send(the_socket, outgoing.buffer, outgoing.length, 0);
158    acknowledged = 0;
159}
160
161static void send_ack()
162{
163    uint16_t buffer[6] = {
164        htons(MESSAGE_FLAG), htons(ACK_SIZE), remote_tunnel, 0,
165        htons(local_sequence), htons(remote_sequence),
166    };
167    send(the_socket, buffer, ACK_SIZE, 0);
168}
169
170static int recv_packet(uint16_t *session)
171{
172    uint16_t *p = (uint16_t *)incoming.buffer;
173
174    incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0);
175    if (incoming.length == -1 && errno != EINTR) {
176        log_print(FATAL, "Recv() %s", strerror(errno));
177        exit(NETWORK_ERROR);
178    }
179
180    /* We only handle packets in our tunnel. */
181    if ((incoming.length != ACK_SIZE && incoming.length < MESSAGE_HEADER_SIZE)
182        || (p[0] & htons(MESSAGE_MASK)) != htons(MESSAGE_FLAG)
183        || p[1] > htons(incoming.length) || p[2] != local_tunnel) {
184        return 0;
185    }
186
187    if (incoming.length == ACK_SIZE) {
188        incoming.message = ACK;
189    } else if (p[6] == htons(ATTRIBUTE_FLAG(2)) && !p[7] && !p[8]) {
190        incoming.message = ntohs(p[9]);
191    } else {
192        return 0;
193    }
194
195    /* Check if the packet is duplicated and send ACK if necessary. */
196    if ((uint16_t)(ntohs(p[4]) - remote_sequence) > 32767) {
197        if (incoming.message != ACK) {
198            send_ack();
199        }
200        return 0;
201    }
202
203    if (ntohs(p[5]) == local_sequence) {
204        acknowledged = 1;
205    }
206
207    /* Our sending and receiving window sizes are both 1. Thus we only handle
208     * this packet if it is their next one and they received our last one. */
209    if (ntohs(p[4]) != remote_sequence || !acknowledged) {
210        return 0;
211    }
212    *session = p[3];
213    if (incoming.message != ACK) {
214        ++remote_sequence;
215    }
216    return 1;
217}
218
219static int get_attribute_raw(uint16_t type, void *value, int size)
220{
221    int offset = MESSAGE_HEADER_SIZE;
222    while (incoming.length >= offset + ATTRIBUTE_HEADER_SIZE) {
223        struct attribute *p = (struct attribute *)&incoming.buffer[offset];
224        uint16_t flag = ntohs(p->flag);
225        int length = ATTRIBUTE_LENGTH(flag);
226
227        offset += length;
228        length -= ATTRIBUTE_HEADER_SIZE;
229        if (length < 0 || offset > incoming.length) {
230            break;
231        }
232
233        /* Currently we do not support hidden attributes. */
234        if (!ATTRIBUTE_HIDDEN(flag) && !p->vendor && p->type == type) {
235            if (size > length) {
236                size = length;
237            }
238            memcpy(value, p->value, size);
239            return size;
240        }
241    }
242    return 0;
243}
244
245static int get_attribute_u16(uint16_t type, uint16_t *value)
246{
247    return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t);
248}
249
250static int l2tp_connect(int argc, char **argv)
251{
252    if (argc < 2) {
253        return -USAGE_ERROR;
254    }
255    create_socket(AF_INET, SOCK_DGRAM, argv[0], argv[1]);
256
257    while (!local_tunnel) {
258        local_tunnel = random();
259    }
260
261    log_print(DEBUG, "Sending SCCRQ (local_tunnel = %d)", local_tunnel);
262    state = SCCRQ;
263    set_message(0, SCCRQ);
264    add_attribute_u16(PROTOCOL_VERSION, htons(0x0100));
265    add_attribute_raw(HOST_NAME, "anonymous", 9);
266    add_attribute_u32(FRAMING_CAPABILITIES, htonl(3));
267    add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
268    add_attribute_u16(WINDOW_SIZE, htons(1));
269    send_packet();
270    return TIMEOUT_INTERVAL;
271}
272
273static int create_pppox()
274{
275    int pppox;
276    log_print(INFO, "Creating PPPoX socket");
277    pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OLAC);
278
279    if (pppox == -1) {
280        log_print(FATAL, "Socket() %s", strerror(errno));
281        exit(SYSTEM_ERROR);
282    } else {
283        struct sockaddr_pppolac address = {
284            .sa_family = AF_PPPOX,
285            .sa_protocol = PX_PROTO_OLAC,
286            .udp_socket = the_socket,
287            .local = {.tunnel = local_tunnel, .session = local_session},
288            .remote = {.tunnel = remote_tunnel, .session = remote_session},
289        };
290        if (connect(pppox, (struct sockaddr *)&address, sizeof(address)) != 0) {
291            log_print(FATAL, "Connect() %s", strerror(errno));
292            exit(SYSTEM_ERROR);
293        }
294    }
295    return pppox;
296}
297
298static int l2tp_process()
299{
300    uint16_t sequence = local_sequence;
301    uint16_t tunnel;
302    uint16_t session;
303
304    if (!recv_packet(&session)) {
305        return acknowledged ? 0 : TIMEOUT_INTERVAL;
306    }
307
308    /* Here is the fun part. We always try to protect our tunnel and session
309     * from being closed even if we received unexpected messages. */
310    switch(incoming.message) {
311        case SCCRP:
312            if (state == SCCRQ) {
313                if (get_attribute_u16(ASSIGNED_TUNNEL, &tunnel) && tunnel) {
314                    remote_tunnel = tunnel;
315                    log_print(DEBUG, "Received SCCRP (remote_tunnel = %d) -> "
316                              "Sending SCCCN", remote_tunnel);
317                    state = SCCCN;
318                    set_message(0, SCCCN);
319                    break;
320                }
321                log_print(DEBUG, "Received SCCRP without assigned tunnel");
322                log_print(ERROR, "Protocol error");
323                return -PROTOCOL_ERROR;
324            }
325            break;
326
327        case ICRP:
328            if (state == ICRQ && session == local_session) {
329                if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
330                    remote_session = session;
331                    log_print(DEBUG, "Received ICRP (remote_session = %d) -> "
332                              "Sending ICCN", remote_session);
333                    state = ICCN;
334                    set_message(remote_session, ICCN);
335                    add_attribute_u32(CONNECT_SPEED, htonl(100000000));
336                    add_attribute_u32(FRAMING_TYPE, htonl(3));
337                    break;
338                }
339                log_print(DEBUG, "Received ICRP without assigned session");
340                log_print(ERROR, "Protocol error");
341                return -PROTOCOL_ERROR;
342            }
343            break;
344
345        case STOPCCN:
346            log_print(DEBUG, "Received STOPCCN");
347            log_print(INFO, "Remote server hung up");
348            state = STOPCCN;
349            return -REMOTE_REQUESTED;
350
351        case CDN:
352            if (session && session == local_session) {
353                log_print(DEBUG, "Received CDN (local_session = %d)",
354                          local_session);
355                log_print(INFO, "Remote server hung up");
356                return -REMOTE_REQUESTED;
357            }
358            break;
359
360        case ACK:
361        case HELLO:
362        case WEN:
363        case SLI:
364            /* These are harmless, so we just treat them the same way. */
365            if (state == SCCCN) {
366                while (!local_session) {
367                    local_session = random();
368                }
369                log_print(DEBUG, "Received %s -> Sending ICRQ (local_session = "
370                          "%d)", messages[incoming.message], local_session);
371                log_print(INFO, "Tunnel established");
372                state = ICRQ;
373                set_message(0, ICRQ);
374                add_attribute_u16(ASSIGNED_SESSION, local_session);
375                add_attribute_u32(CALL_SERIAL_NUMBER, random());
376                break;
377            }
378
379            if (incoming.message == ACK) {
380                log_print(DEBUG, "Received ACK");
381            } else {
382                log_print(DEBUG, "Received %s -> Sending ACK",
383                          messages[incoming.message]);
384                send_ack();
385            }
386
387            if (state == ICCN) {
388                log_print(INFO, "Session established");
389                state = ACK;
390                start_pppd(create_pppox());
391            }
392            return 0;
393
394        case ICRQ:
395        case OCRQ:
396            /* Since we run pppd as a client, it does not makes sense to
397             * accept ICRQ or OCRQ. Always send CDN with a proper error. */
398            if (get_attribute_u16(ASSIGNED_SESSION, &session) && session) {
399                log_print(DEBUG, "Received %s (remote_session = %d) -> "
400                          "Sending CDN", messages[incoming.message], session);
401                set_message(session, CDN);
402                add_attribute_u32(RESULT_CODE, htonl(0x00020006));
403                add_attribute_u16(ASSIGNED_SESSION, 0);
404            }
405            break;
406    }
407
408    if (sequence != local_sequence) {
409        send_packet();
410        return TIMEOUT_INTERVAL;
411    }
412
413    /* We reach here if we got an unexpected message. Log it and send ACK. */
414    if (incoming.message > MESSAGE_MAX || !messages[incoming.message]) {
415        log_print(DEBUG, "Received UNKNOWN %d -> Sending ACK anyway",
416                incoming.message);
417    } else {
418        log_print(DEBUG, "Received UNEXPECTED %s -> Sending ACK anyway",
419                messages[incoming.message]);
420    }
421    send_ack();
422    return 0;
423}
424
425static int l2tp_timeout()
426{
427    if (acknowledged) {
428        return 0;
429    }
430    log_print(DEBUG, "Timeout -> Sending %s", messages[outgoing.message]);
431    send(the_socket, outgoing.buffer, outgoing.length, 0);
432    return TIMEOUT_INTERVAL;
433}
434
435static void l2tp_shutdown()
436{
437    if (state != STOPCCN) {
438        log_print(DEBUG, "Sending STOPCCN");
439        set_message(0, STOPCCN);
440        add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
441        add_attribute_u16(RESULT_CODE, htons(6));
442        send_packet();
443    }
444}
445
446struct protocol l2tp = {
447    .name = "l2tp",
448    .usage = "<server> <port>",
449    .connect = l2tp_connect,
450    .process = l2tp_process,
451    .timeout = l2tp_timeout,
452    .shutdown = l2tp_shutdown,
453};
454