Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 441828
Collapse All | Expand All

(-)a/Makefile (-2 / +2 lines)
Lines 62-69 Link Here
62
# are packages seperately (eg kernel-headers on Fedora)
62
# are packages seperately (eg kernel-headers on Fedora)
63
# Note: 2.6.23+ support still needs some changes in the xl2tpd source
63
# Note: 2.6.23+ support still needs some changes in the xl2tpd source
64
#
64
#
65
#OSFLAGS+= -DUSE_KERNEL
65
# Kernel mode fixed by sigwall <fionov@gmail.com>
66
#
66
OSFLAGS+= -DUSE_KERNEL
67
#
67
#
68
# Uncomment the next line for FreeBSD
68
# Uncomment the next line for FreeBSD
69
#
69
#
(-)a/call.c (+2 lines)
Lines 680-685 struct call *get_call (int tunnel, int call, struct in_addr addr, int port, Link Here
680
        st->peer.sin_port = port;
680
        st->peer.sin_port = port;
681
	st->refme  = refme;
681
	st->refme  = refme;
682
	st->refhim = refhim;
682
	st->refhim = refhim;
683
        st->udp_fd = -1;
684
        st->pppox_fd = -1;
683
        bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
685
        bcopy (&addr, &st->peer.sin_addr, sizeof (addr));
684
        st->next = tunnels.head;
686
        st->next = tunnels.head;
685
        tunnels.head = st;
687
        tunnels.head = st;
(-)a/control.c (+7 lines)
Lines 596-601 int control_finish (struct tunnel *t, struct call *c) Link Here
596
        if (gconfig.debug_state)
596
        if (gconfig.debug_state)
597
            l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__);
597
            l2tp_log (LOG_DEBUG, "%s: sending SCCCN\n", __FUNCTION__);
598
        control_xmit (buf);
598
        control_xmit (buf);
599
600
        connect_pppol2tp(t);
601
599
        /* Schedule a HELLO */
602
        /* Schedule a HELLO */
600
        tv.tv_sec = HELLO_DELAY;
603
        tv.tv_sec = HELLO_DELAY;
601
        tv.tv_usec = 0;
604
        tv.tv_usec = 0;
Lines 608-613 int control_finish (struct tunnel *t, struct call *c) Link Here
608
		  "Connection established to %s, %d.  Local: %d, Remote: %d (ref=%u/%u).\n",
611
		  "Connection established to %s, %d.  Local: %d, Remote: %d (ref=%u/%u).\n",
609
		  IPADDY (t->peer.sin_addr),
612
		  IPADDY (t->peer.sin_addr),
610
		  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim);
613
		  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim);
614
611
        if (t->lac)
615
        if (t->lac)
612
        {
616
        {
613
            /* This is part of a LAC, so we want to go ahead
617
            /* This is part of a LAC, so we want to go ahead
Lines 635-640 int control_finish (struct tunnel *t, struct call *c) Link Here
635
		  IPADDY (t->peer.sin_addr),
639
		  IPADDY (t->peer.sin_addr),
636
		  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim,
640
		  ntohs (t->peer.sin_port), t->ourtid, t->tid, t->refme, t->refhim,
637
		  t->lns->entname);
641
		  t->lns->entname);
642
643
        connect_pppol2tp(t);
644
638
        /* Schedule a HELLO */
645
        /* Schedule a HELLO */
639
        tv.tv_sec = HELLO_DELAY;
646
        tv.tv_sec = HELLO_DELAY;
640
        tv.tv_usec = 0;
647
        tv.tv_usec = 0;
(-)a/l2tp.h (+3 lines)
Lines 167-172 struct tunnel Link Here
167
    int ourrws;                 /* Receive Window Size */
167
    int ourrws;                 /* Receive Window Size */
168
    int rxspeed;		/* Receive bps */
168
    int rxspeed;		/* Receive bps */
169
    int txspeed;		/* Transmit bps */
169
    int txspeed;		/* Transmit bps */
170
    int udp_fd;			/* UDP fd */
171
    int pppox_fd;			/* PPPOX tunnel fd */
170
    struct call *self;
172
    struct call *self;
171
    struct lns *lns;            /* LNS that owns us */
173
    struct lns *lns;            /* LNS that owns us */
172
    struct lac *lac;            /* LAC that owns us */
174
    struct lac *lac;            /* LAC that owns us */
Lines 220-225 extern void control_xmit (void *); Link Here
220
extern int ppd;
222
extern int ppd;
221
extern int switch_io;           /* jz */
223
extern int switch_io;           /* jz */
222
extern int control_fd;
224
extern int control_fd;
225
extern int connect_pppol2tp(struct tunnel *t);
223
extern int start_pppd (struct call *c, struct ppp_opts *);
226
extern int start_pppd (struct call *c, struct ppp_opts *);
224
extern void magic_lac_dial (void *);
227
extern void magic_lac_dial (void *);
225
extern int get_entropy (unsigned char *, int);
228
extern int get_entropy (unsigned char *, int);
(-)a/linux/include/linux/if_pppol2tp.h (+14 lines)
Lines 36-41 struct pppol2tp_addr Link Here
36
	__u16 d_tunnel, d_session;	/* For sending outgoing packets */
36
	__u16 d_tunnel, d_session;	/* For sending outgoing packets */
37
};
37
};
38
38
39
/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
40
 * bits. So we need a different sockaddr structure.
41
 */
42
struct pppol2tpv3_addr {
43
	pid_t	pid;			/* pid that owns the fd.
44
					 * 0 => current */
45
	int	fd;			/* FD of UDP or IP socket to use */
46
47
	struct sockaddr_in addr;	/* IP address and port to send to */
48
49
	__u32 s_tunnel, s_session;	/* For matching incoming packets */
50
	__u32 d_tunnel, d_session;	/* For sending outgoing packets */
51
};
52
39
/* Socket options:
53
/* Socket options:
40
 * DEBUG	- bitmask of debug message categories
54
 * DEBUG	- bitmask of debug message categories
41
 * SENDSEQ	- 0 => don't send packets with sequence numbers
55
 * SENDSEQ	- 0 => don't send packets with sequence numbers
(-)a/network.c (-2 / +163 lines)
Lines 22-27 Link Here
22
#include <unistd.h>
22
#include <unistd.h>
23
#include <stdlib.h>
23
#include <stdlib.h>
24
#include <sys/ioctl.h>
24
#include <sys/ioctl.h>
25
#include <sys/wait.h>
25
#ifndef LINUX
26
#ifndef LINUX
26
# include <sys/uio.h>
27
# include <sys/uio.h>
27
#endif
28
#endif
Lines 36-41 int server_socket; /* Server socket */ Link Here
36
int kernel_support;             /* Kernel Support there or not? */
37
int kernel_support;             /* Kernel Support there or not? */
37
#endif
38
#endif
38
39
40
#ifdef USE_KERNEL
41
void modprobe() {
42
    char * modules[] = { "l2tp_ppp", "pppol2tp", NULL };
43
    char ** module;
44
    char buf[256], *tok;
45
    int pid, exit_status, fd;
46
47
    FILE * fmod = fopen("/proc/modules", "r");
48
49
    if (fmod == NULL)
50
        return;
51
52
    while (fgets(buf, 255, fmod) != NULL) {
53
        if ((tok = strtok(buf, " ")) != NULL) {
54
            for (module = modules; *module != NULL; ++module) {
55
                if (!strcmp(*module, tok)) {
56
                    fclose(fmod);
57
                    return;
58
                }
59
            }
60
        }
61
    }
62
63
    fclose(fmod);
64
65
    for (module = modules; *module != NULL; ++module) {
66
        if ((pid = fork()) >= 0) {
67
            if (pid == 0) {
68
                setenv("PATH", "/sbin:/usr/sbin:/bin:/usr/bin", 1);
69
                if ((fd = open("/dev/null", O_RDWR)) > -1) {
70
                    dup2(fd, 1);
71
                    dup2(fd, 2);
72
                }
73
                execlp("modprobe", "modprobe", "-q", *module, (char *)NULL);
74
                exit(1);
75
            } else {
76
                if ((pid = waitpid(pid, &exit_status, 0)) != -1 && WIFEXITED(exit_status)) {
77
                    if (WEXITSTATUS(exit_status) == 0)
78
                        return;
79
                }
80
            }
81
        }
82
    }
83
}
84
#endif
39
85
40
int init_network (void)
86
int init_network (void)
41
{
87
{
Lines 45-50 int init_network (void) Link Here
45
    server.sin_family = AF_INET;
91
    server.sin_family = AF_INET;
46
    server.sin_addr.s_addr = gconfig.listenaddr; 
92
    server.sin_addr.s_addr = gconfig.listenaddr; 
47
    server.sin_port = htons (gconfig.port);
93
    server.sin_port = htons (gconfig.port);
94
    int flags;
48
    if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
95
    if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
49
    {
96
    {
50
        l2tp_log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n",
97
        l2tp_log (LOG_CRIT, "%s: Unable to allocate socket. Terminating.\n",
Lines 52-57 int init_network (void) Link Here
52
        return -EINVAL;
99
        return -EINVAL;
53
    };
100
    };
54
101
102
    flags = 1;
103
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
104
    setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
105
55
    if (bind (server_socket, (struct sockaddr *) &server, sizeof (server)))
106
    if (bind (server_socket, (struct sockaddr *) &server, sizeof (server)))
56
    {
107
    {
57
        close (server_socket);
108
        close (server_socket);
Lines 91-96 int init_network (void) Link Here
91
    }
142
    }
92
    else
143
    else
93
    {
144
    {
145
        modprobe();
94
        int kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
146
        int kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
95
        if (kernel_fd < 0)
147
        if (kernel_fd < 0)
96
        {
148
        {
Lines 321-326 int build_fdset (fd_set *readfds) Link Here
321
373
322
	while (tun)
374
	while (tun)
323
	{
375
	{
376
		if (tun->udp_fd > -1) {
377
			if (tun->udp_fd > max)
378
				max = tun->udp_fd;
379
			FD_SET (tun->udp_fd, readfds);
380
		}
324
		call = tun->call_head;
381
		call = tun->call_head;
325
		while (call)
382
		while (call)
326
		{
383
		{
Lines 390-395 void network_thread () Link Here
390
    struct iovec iov;
447
    struct iovec iov;
391
    char cbuf[256];
448
    char cbuf[256];
392
    unsigned int refme, refhim;
449
    unsigned int refme, refhim;
450
    int * currentfd;
451
    int server_socket_processed;
393
452
394
    /* This one buffer can be recycled for everything except control packets */
453
    /* This one buffer can be recycled for everything except control packets */
395
    buf = new_buf (MAX_RECV_SIZE);
454
    buf = new_buf (MAX_RECV_SIZE);
Lines 428-434 void network_thread () Link Here
428
        {
487
        {
429
            do_control ();
488
            do_control ();
430
        }
489
        }
431
        if (FD_ISSET (server_socket, &readfds))
490
        server_socket_processed = 0;
491
        currentfd = NULL;
492
        st = tunnels.head;
493
        while (st || !server_socket_processed) {
494
            if (st && (st->udp_fd == -1)) {
495
                st=st->next;
496
                continue;
497
            }
498
            if (st) {
499
                currentfd = &st->udp_fd;
500
            } else {
501
                currentfd = &server_socket;
502
                server_socket_processed = 1;
503
            }
504
            if (FD_ISSET (*currentfd, &readfds))
432
        {
505
        {
433
            /*
506
            /*
434
             * Okay, now we're ready for reading and processing new data.
507
             * Okay, now we're ready for reading and processing new data.
Lines 457-468 void network_thread () Link Here
457
	    msgh.msg_flags = 0;
530
	    msgh.msg_flags = 0;
458
	    
531
	    
459
	    /* Receive one packet. */
532
	    /* Receive one packet. */
460
	    recvsize = recvmsg(server_socket, &msgh, 0);
533
	    recvsize = recvmsg(*currentfd, &msgh, 0);
461
534
462
            if (recvsize < MIN_PAYLOAD_HDR_LEN)
535
            if (recvsize < MIN_PAYLOAD_HDR_LEN)
463
            {
536
            {
464
                if (recvsize < 0)
537
                if (recvsize < 0)
465
                {
538
                {
539
                    if (errno == ECONNREFUSED) {
540
                        close(*currentfd);
541
                    }
542
                    if ((errno == ECONNREFUSED) ||
543
                        (errno == EBADF)) {
544
                        *currentfd = -1;
545
                    }
466
                    if (errno != EAGAIN)
546
                    if (errno != EAGAIN)
467
                        l2tp_log (LOG_WARNING,
547
                        l2tp_log (LOG_WARNING,
468
                             "%s: recvfrom returned error %d (%s)\n",
548
                             "%s: recvfrom returned error %d (%s)\n",
Lines 567-572 void network_thread () Link Here
567
		}
647
		}
568
	    };
648
	    };
569
	}
649
	}
650
	if (st) st=st->next;
651
	}
570
652
571
	/*
653
	/*
572
	 * finished obvious sources, look for data from PPP connections.
654
	 * finished obvious sources, look for data from PPP connections.
Lines 639-641 void network_thread () Link Here
639
    }
721
    }
640
722
641
}
723
}
724
725
int connect_pppol2tp(struct tunnel *t) {
726
#ifdef USE_KERNEL
727
        if (kernel_support) {
728
            int ufd = -1, fd2 = -1;
729
            int flags;
730
            struct sockaddr_pppol2tp sax;
731
732
            struct sockaddr_in server;
733
            server.sin_family = AF_INET;
734
            server.sin_addr.s_addr = gconfig.listenaddr;
735
            server.sin_port = htons (gconfig.port);
736
            if ((ufd = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
737
            {
738
                l2tp_log (LOG_CRIT, "%s: Unable to allocate UDP socket. Terminating.\n",
739
                    __FUNCTION__);
740
                return -EINVAL;
741
            };
742
743
            flags=1;
744
            setsockopt(ufd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
745
            setsockopt(ufd, SOL_SOCKET, SO_NO_CHECK, &flags, sizeof(flags));
746
747
            if (bind (ufd, (struct sockaddr *) &server, sizeof (server)))
748
            {
749
                close (ufd);
750
                l2tp_log (LOG_CRIT, "%s: Unable to bind UDP socket: %s. Terminating.\n",
751
                     __FUNCTION__, strerror(errno), errno);
752
                return -EINVAL;
753
            };
754
            server = t->peer;
755
            flags = fcntl(ufd, F_GETFL);
756
            if (flags == -1 || fcntl(ufd, F_SETFL, flags | O_NONBLOCK) == -1) {
757
                l2tp_log (LOG_WARNING, "%s: Unable to set UDP socket nonblock.\n",
758
                     __FUNCTION__);
759
                return -EINVAL;
760
            }
761
            if (connect (ufd, (struct sockaddr *) &server, sizeof(server)) < 0) {
762
                l2tp_log (LOG_CRIT, "%s: Unable to connect UDP peer. Terminating.\n",
763
                 __FUNCTION__);
764
                return -EINVAL;
765
            }
766
767
            t->udp_fd=ufd;
768
769
            fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
770
            if (fd2 < 0) {
771
                l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n",
772
                     __FUNCTION__);
773
                return -EINVAL;
774
            }
775
            flags = fcntl(fd2, F_GETFL);
776
            if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) {
777
                l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n",
778
                     __FUNCTION__);
779
                return -EINVAL;
780
            }
781
            sax.sa_family = AF_PPPOX;
782
            sax.sa_protocol = PX_PROTO_OL2TP;
783
            sax.pppol2tp.pid = 0;
784
            sax.pppol2tp.fd = t->udp_fd;
785
            sax.pppol2tp.addr.sin_addr.s_addr = t->peer.sin_addr.s_addr;
786
            sax.pppol2tp.addr.sin_port = t->peer.sin_port;
787
            sax.pppol2tp.addr.sin_family = AF_INET;
788
            sax.pppol2tp.s_tunnel  = t->ourtid;
789
            sax.pppol2tp.s_session = 0;
790
            sax.pppol2tp.d_tunnel  = t->tid;
791
            sax.pppol2tp.d_session = 0;
792
            if ((connect(fd2, (struct sockaddr *)&sax, sizeof(sax))) < 0) {
793
                l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket. %d %s\n",
794
                     __FUNCTION__, errno, strerror(errno));
795
                close(fd2);
796
                return -EINVAL;
797
            }
798
            t->pppox_fd = fd2;
799
        }
800
#endif
801
    return 0;
802
}
(-)a/xl2tpd.c (-5 / +19 lines)
Lines 278-284 void death_handler (int signal) Link Here
278
    struct tunnel *st, *st2;
278
    struct tunnel *st, *st2;
279
    int sec;
279
    int sec;
280
    l2tp_log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
280
    l2tp_log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
281
#ifdef USE_KERNEL
282
        if (kernel_support || signal != SIGTERM) {
283
#else
281
        if (signal != SIGTERM) {
284
        if (signal != SIGTERM) {
285
#endif
282
                st = tunnels.head;
286
                st = tunnels.head;
283
                while (st)
287
                while (st)
284
                {
288
                {
Lines 349-355 int start_pppd (struct call *c, struct ppp_opts *opts) Link Here
349
    int flags;
353
    int flags;
350
#endif
354
#endif
351
    int pos = 1;
355
    int pos = 1;
352
    int fd2;
356
    int fd2 = -1;
353
#ifdef DEBUG_PPPD
357
#ifdef DEBUG_PPPD
354
    int x;
358
    int x;
355
#endif
359
#endif
Lines 397-403 int start_pppd (struct call *c, struct ppp_opts *opts) Link Here
397
       sax.sa_family = AF_PPPOX;
401
       sax.sa_family = AF_PPPOX;
398
       sax.sa_protocol = PX_PROTO_OL2TP;
402
       sax.sa_protocol = PX_PROTO_OL2TP;
399
       sax.pppol2tp.pid = 0;
403
       sax.pppol2tp.pid = 0;
400
       sax.pppol2tp.fd = server_socket;
404
       sax.pppol2tp.fd = c->container->udp_fd;
401
       sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr;
405
       sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr;
402
       sax.pppol2tp.addr.sin_port = c->container->peer.sin_port;
406
       sax.pppol2tp.addr.sin_port = c->container->peer.sin_port;
403
       sax.pppol2tp.addr.sin_family = AF_INET;
407
       sax.pppol2tp.addr.sin_family = AF_INET;
Lines 408-413 int start_pppd (struct call *c, struct ppp_opts *opts) Link Here
408
       if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
412
       if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
409
           l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
413
           l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
410
                __FUNCTION__);
414
                __FUNCTION__);
415
           close(fd2);
411
           return -EINVAL;
416
           return -EINVAL;
412
       }
417
       }
413
       stropt[pos++] = strdup ("plugin");
418
       stropt[pos++] = strdup ("plugin");
Lines 484-490 int start_pppd (struct call *c, struct ppp_opts *opts) Link Here
484
        dup2 (fd2, 0);
489
        dup2 (fd2, 0);
485
        dup2 (fd2, 1);
490
        dup2 (fd2, 1);
486
	close(fd2);
491
	close(fd2);
487
492
       }
488
        /* close all the calls pty fds */
493
        /* close all the calls pty fds */
489
        st = tunnels.head;
494
        st = tunnels.head;
490
        while (st)
495
        while (st)
Lines 492-503 int start_pppd (struct call *c, struct ppp_opts *opts) Link Here
492
            sc = st->call_head;
497
            sc = st->call_head;
493
            while (sc)
498
            while (sc)
494
            {
499
            {
495
                close (sc->fd);
500
#ifdef USE_KERNEL
501
                if (kernel_support) {
502
                    close(st->udp_fd); /* tunnel UDP fd */
503
                    close(st->pppox_fd); /* tunnel PPPoX fd */
504
                } else
505
#endif
506
                    close (sc->fd); /* call pty fd */
496
                sc = sc->next;
507
                sc = sc->next;
497
            }
508
            }
498
            st = st->next;
509
            st = st->next;
499
        }
510
        }
500
       }
501
511
502
        /* close the UDP socket fd */
512
        /* close the UDP socket fd */
503
        close (server_socket);
513
        close (server_socket);
Lines 615-620 void destroy_tunnel (struct tunnel *t) Link Here
615
       the memory pointed to by t->chal_us.vector at some other place */
625
       the memory pointed to by t->chal_us.vector at some other place */
616
    if (t->chal_them.vector)
626
    if (t->chal_them.vector)
617
        free (t->chal_them.vector);
627
        free (t->chal_them.vector);
628
    if (t->pppox_fd > -1 )
629
        close (t->pppox_fd);
630
    if (t->udp_fd > -1 )
631
        close (t->udp_fd);
618
    free (t);
632
    free (t);
619
    free (me);
633
    free (me);
620
}
634
}

Return to bug 441828