4 # are packages seperately (eg kernel-headers on Fedora)
5 # Note: 2.6.23+ support still needs some changes in the xl2tpd source
7 -#OSFLAGS+= -DUSE_KERNEL
9 +# Kernel mode fixed by sigwall <fionov@gmail.com>
10 +OSFLAGS+= -DUSE_KERNEL
12 # Uncomment the next line for FreeBSD
17 st->peer.sin_port = port;
22 bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
23 st->next = tunnels.head;
28 if (gconfig.debug_state)
29 l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__);
32 + connect_pppol2tp(t);
34 /* Schedule a HELLO */
35 tv.tv_sec = HELLO_DELAY;
38 "Connection established to %s, %d. Local: %d, Remote: %d (ref=%u/%u).\n",
39 IPADDY (t->peer.sin_addr),
40 ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim);
44 /* This is part of a LAC, so we want to go ahead
46 IPADDY (t->peer.sin_addr),
47 ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim,
50 + connect_pppol2tp(t);
52 /* Schedule a HELLO */
53 tv.tv_sec = HELLO_DELAY;
58 int ourrws; /* Receive Window Size */
59 int rxspeed; /* Receive bps */
60 int txspeed; /* Transmit bps */
61 + int udp_fd; /* UDP fd */
62 + int pppox_fd; /* PPPOX tunnel fd */
64 struct lns *lns; /* LNS that owns us */
65 struct lac *lac; /* LAC that owns us */
68 extern int switch_io; /* jz */
69 extern int control_fd;
70 +extern int connect_pppol2tp(struct tunnel *t);
71 extern int start_pppd (struct call *c, struct ppp_opts *);
72 extern void magic_lac_dial (void *);
73 extern int get_entropy (unsigned char *, int);
74 --- a/linux/include/linux/if_pppol2tp.h
75 +++ b/linux/include/linux/if_pppol2tp.h
77 * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661)
79 * This file supplies definitions required by the PPP over L2TP driver
80 - * (pppol2tp.c). All version information wrt this file is located in pppol2tp.c
81 + * (l2tp_ppp.c). All version information wrt this file is located in l2tp_ppp.c
84 * This program is free software; you can redistribute it and/or
86 #ifndef __LINUX_IF_PPPOL2TP_H
87 #define __LINUX_IF_PPPOL2TP_H
89 -#include <asm/types.h>
92 -#include <linux/in.h>
94 +#include <linux/types.h>
96 /* Structure used to connect() the socket to a particular tunnel UDP
100 -struct pppol2tp_addr
102 - pid_t pid; /* pid that owns the fd.
103 +struct pppol2tp_addr {
104 + __kernel_pid_t pid; /* pid that owns the fd.
106 int fd; /* FD of UDP socket to use */
109 __u16 d_tunnel, d_session; /* For sending outgoing packets */
112 +/* Structure used to connect() the socket to a particular tunnel UDP
113 + * socket over IPv6.
115 +struct pppol2tpin6_addr {
116 + __kernel_pid_t pid; /* pid that owns the fd.
118 + int fd; /* FD of UDP socket to use */
120 + __u16 s_tunnel, s_session; /* For matching incoming packets */
121 + __u16 d_tunnel, d_session; /* For sending outgoing packets */
123 + struct sockaddr_in6 addr; /* IP address and port to send to */
126 +/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
127 + * bits. So we need a different sockaddr structure.
129 +struct pppol2tpv3_addr {
130 + __kernel_pid_t pid; /* pid that owns the fd.
132 + int fd; /* FD of UDP or IP socket to use */
134 + struct sockaddr_in addr; /* IP address and port to send to */
136 + __u32 s_tunnel, s_session; /* For matching incoming packets */
137 + __u32 d_tunnel, d_session; /* For sending outgoing packets */
140 +struct pppol2tpv3in6_addr {
141 + __kernel_pid_t pid; /* pid that owns the fd.
143 + int fd; /* FD of UDP or IP socket to use */
145 + __u32 s_tunnel, s_session; /* For matching incoming packets */
146 + __u32 d_tunnel, d_session; /* For sending outgoing packets */
148 + struct sockaddr_in6 addr; /* IP address and port to send to */
152 * DEBUG - bitmask of debug message categories
153 * SENDSEQ - 0 => don't send packets with sequence numbers
159 +#endif /* __LINUX_IF_PPPOL2TP_H */
163 server.sin_family = AF_INET;
164 server.sin_addr.s_addr = gconfig.listenaddr;
165 server.sin_port = htons (gconfig.port);
167 if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
169 l2tp_log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n",
175 + setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
176 + setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
178 if (bind (server_socket, (struct sockaddr *) &server, sizeof (server)))
180 close (server_socket);
185 + if (tun->udp_fd > -1) {
186 + if (tun->udp_fd > max)
188 + FD_SET (tun->udp_fd, readfds);
190 call = tun->call_head;
196 unsigned int refme, refhim;
198 + int server_socket_processed;
200 /* This one buffer can be recycled for everything except control packets */
201 buf = new_buf (MAX_RECV_SIZE);
206 - if (FD_ISSET (server_socket, &readfds))
207 + server_socket_processed = 0;
210 + while (st || !server_socket_processed) {
211 + if (st && (st->udp_fd == -1)) {
216 + currentfd = &st->udp_fd;
218 + currentfd = &server_socket;
219 + server_socket_processed = 1;
221 + if (FD_ISSET (*currentfd, &readfds))
224 * Okay, now we're ready for reading and processing new data.
225 @@ -457,12 +483,19 @@
228 /* Receive one packet. */
229 - recvsize = recvmsg(server_socket, &msgh, 0);
230 + recvsize = recvmsg(*currentfd, &msgh, 0);
232 if (recvsize < MIN_PAYLOAD_HDR_LEN)
236 + if (errno == ECONNREFUSED) {
239 + if ((errno == ECONNREFUSED) ||
240 + (errno == EBADF)) {
244 l2tp_log (LOG_WARNING,
245 "%s: recvfrom returned error %d (%s)\n",
250 + if (st) st=st->next;
254 * finished obvious sources, look for data from PPP connections.
260 +int connect_pppol2tp(struct tunnel *t) {
262 + if (kernel_support) {
263 + int ufd = -1, fd2 = -1;
265 + struct sockaddr_pppol2tp sax;
267 + struct sockaddr_in server;
268 + server.sin_family = AF_INET;
269 + server.sin_addr.s_addr = gconfig.listenaddr;
270 + server.sin_port = htons (gconfig.port);
271 + if ((ufd = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
273 + l2tp_log (LOG_CRIT, "%s: Unable to allocate UDP socket. Terminating.\n",
279 + setsockopt(ufd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
280 + setsockopt(ufd, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
282 + if (bind (ufd, (struct sockaddr *) &server, sizeof (server)))
285 + l2tp_log (LOG_CRIT, "%s: Unable to bind UDP socket: %s. Terminating.\n",
286 + __FUNCTION__, strerror(errno), errno);
290 + flags = fcntl(ufd, F_GETFL);
291 + if (flags == -1 || fcntl(ufd, F_SETFL, flags | O_NONBLOCK) == -1) {
292 + l2tp_log (LOG_WARNING, "%s: Unable to set UDP socket nonblock.\n",
296 + if (connect (ufd, (struct sockaddr *) &server, sizeof(server)) < 0) {
297 + l2tp_log (LOG_CRIT, "%s: Unable to connect UDP peer. Terminating.\n",
304 + fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
306 + l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n",
310 + flags = fcntl(fd2, F_GETFL);
311 + if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) {
312 + l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n",
316 + sax.sa_family = AF_PPPOX;
317 + sax.sa_protocol = PX_PROTO_OL2TP;
318 + sax.pppol2tp.pid = 0;
319 + sax.pppol2tp.fd = t->udp_fd;
320 + sax.pppol2tp.addr.sin_addr.s_addr = t->peer.sin_addr.s_addr;
321 + sax.pppol2tp.addr.sin_port = t->peer.sin_port;
322 + sax.pppol2tp.addr.sin_family = AF_INET;
323 + sax.pppol2tp.s_tunnel = t->ourtid;
324 + sax.pppol2tp.s_session = 0;
325 + sax.pppol2tp.d_tunnel = t->tid;
326 + sax.pppol2tp.d_session = 0;
327 + if ((connect(fd2, (struct sockaddr *)&sax, sizeof(sax))) < 0) {
328 + l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket. %d %s\n",
329 + __FUNCTION__, errno, strerror(errno));
341 struct tunnel *st, *st2;
343 l2tp_log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
345 + if (kernel_support || signal != SIGTERM) {
347 if (signal != SIGTERM) {
362 sax.sa_family = AF_PPPOX;
363 sax.sa_protocol = PX_PROTO_OL2TP;
364 sax.pppol2tp.pid = 0;
365 - sax.pppol2tp.fd = server_socket;
366 + sax.pppol2tp.fd = c->container->udp_fd;
367 sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr;
368 sax.pppol2tp.addr.sin_port = c->container->peer.sin_port;
369 sax.pppol2tp.addr.sin_family = AF_INET;
371 if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
372 l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
377 stropt[pos++] = strdup ("plugin");
384 /* close all the calls pty fds */
387 @@ -492,12 +497,17 @@
393 + if (kernel_support) {
394 + close(st->udp_fd); /* tunnel UDP fd */
395 + close(st->pppox_fd); /* tunnel PPPoX fd */
398 + close (sc->fd); /* call pty fd */
405 /* close the UDP socket fd */
406 close (server_socket);
408 the memory pointed to by t->chal_us.vector at some other place */
409 if (t->chal_them.vector)
410 free (t->chal_them.vector);
411 + if (t->pppox_fd > -1 )
412 + close (t->pppox_fd);
413 + if (t->udp_fd > -1 )