source: freewrt/package/l2tpd/patches/03-jacco-pty.patch@ 428f140

freewrt_1_0 freewrt_2_0
Last change on this file since 428f140 was 475ad56, checked in by Waldemar Brodkorb <wbx@…>, 20 years ago

add OpenWrt trunk revision 3830.

git-svn-id: svn://www.freewrt.org/trunk/freewrt@1 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100644
File size: 32.7 KB
  • l2tpd.c

    diff -ruN l2tpd-0.70pre-old/l2tpd.c l2tpd-0.70pre-new/l2tpd.c
    old new  
    1616 */
    1717
    1818#include <stdlib.h>
     19#include <sys/types.h>
    1920#include <sys/utsname.h>
    2021#include <sys/stat.h>
    2122#include <sys/wait.h>
     
    274275
    275276int start_pppd (struct call *c, struct ppp_opts *opts)
    276277{
    277     char a, b;
    278     char tty[80];
     278    /* char a, b; */
     279    char *tty;
    279280    char *stropt[80];
    280281    struct ppp_opts *p;
    281282#ifdef USE_KERNEL
     
    324325    else
    325326    {
    326327#endif
    327         if ((c->fd = getPtyMaster (&a, &b)) < 0)
     328        c->fd = open("/dev/ptmx", O_RDWR);
     329        if (c->fd == -1)
     330        {
     331                log (LOG_WARN, "%s: unable to open /dev/ptmx to allocate pty\n",
     332                                __FUNCTION__);
     333                return -EINVAL;
     334        } else
     335        {
     336            if (grantpt(c->fd))
     337            {
     338                log (LOG_WARN, "%s: unable to grantpt() on pty\n",
     339                                __FUNCTION__);
     340                close(c->fd);
     341                return -EINVAL;
     342            }
     343            if (unlockpt(c->fd))
     344            {
     345                log (LOG_WARN, "%s: unable to unlockpt() on pty\n",
     346                        __FUNCTION__);
     347                close(c->fd);
     348                return -EINVAL;
     349            }
     350            tty = ptsname(c->fd);
     351            if (tty == NULL)
     352            {
     353                log (LOG_WARN, "%s: unable to obtain name of slave tty\n",
     354                        __FUNCTION__);
     355                close(c->fd);
     356                return -EINVAL;
     357            }
     358        }
     359       
     360       
     361 /*     if ((c->fd = getPtyMaster (&a, &b)) < 0)
    328362        {
    329363            log (LOG_WARN, "%s: unable to allocate pty, abandoning!\n",
    330364                 __FUNCTION__);
    331365            return -EINVAL;
    332         }
     366        } */
    333367
    334368        /* set fd opened above to not echo so we don't see read our own packets
    335369           back of the file descriptor that we just wrote them to */
     
    338372        ptyconf.c_cflag &= ~(ICANON | ECHO);
    339373        tcsetattr (c->fd, TCSANOW, &ptyconf);
    340374
    341         snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b);
     375/*        snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b); */
    342376        fd2 = open (tty, O_RDWR);
     377        if (fd2 == -1)
     378        {
     379                log (LOG_WARN, "%s: unable to open slave tty %s\n", __FUNCTION__, tty);
     380                close(c->fd);
     381                return -EINVAL;
     382        }
    343383
    344384#ifdef USE_KERNEL
    345385    }
  • l2tpd.c.orig

    diff -ruN l2tpd-0.70pre-old/l2tpd.c.orig l2tpd-0.70pre-new/l2tpd.c.orig
    old new  
     1/*
     2 * $Id$
     3 *
     4 * Layer Two Tunnelling Protocol Daemon
     5 * Copyright (C) 1998 Adtran, Inc.
     6 * Copyright (C) 2002 Jeff McAdams
     7 *
     8 * Mark Spencer
     9 *
     10 * This software is distributed under the terms
     11 * of the GPL, which you should have received
     12 * along with this source.
     13 *
     14 * Main Daemon source.
     15 *
     16 */
     17
     18#include <stdlib.h>
     19#include <sys/utsname.h>
     20#include <sys/stat.h>
     21#include <sys/wait.h>
     22#include <stdio.h>
     23#include <errno.h>
     24#include <unistd.h>
     25#include <time.h>
     26#if (__GLIBC__ < 2)
     27# if defined(FREEBSD)
     28#  include <sys/signal.h>
     29# elif defined(LINUX)
     30#  include <bsd/signal.h>
     31# elif defined(SOLARIS)
     32#  include <signal.h>
     33# endif
     34#else
     35# include <signal.h>
     36#endif
     37#include <netdb.h>
     38#include <string.h>
     39#include <fcntl.h>
     40#include <netinet/in.h>
     41#include <arpa/inet.h>
     42#ifdef USE_KERNEL
     43#include <sys/ioctl.h>
     44#endif
     45#include "l2tp.h"
     46
     47struct tunnel_list tunnels;
     48int max_tunnels = DEF_MAX_TUNNELS;
     49struct utsname uts;
     50int ppd = 1;                    /* Packet processing delay */
     51int control_fd;                 /* descriptor of control area */
     52char *args;
     53
     54char *dial_no_tmp;              /* jz: Dialnumber for Outgoing Call */
     55int switch_io = 0;              /* jz: Switch for Incoming or Outgoing Call */
     56
     57void init_tunnel_list (struct tunnel_list *t)
     58{
     59    t->head = NULL;
     60    t->count = 0;
     61    t->calls = 0;
     62}
     63
     64/* Now sends to syslog instead - MvO */
     65void show_status (void)
     66{
     67    struct schedule_entry *se;
     68    struct tunnel *t;
     69    struct call *c;
     70    struct lns *tlns;
     71    struct lac *tlac;
     72    struct host *h;
     73    int s = 0;
     74    log (LOG_WARN, "====== l2tpd statistics ========\n");
     75    log (LOG_WARN, " Scheduler entries:\n");
     76    se = events;
     77    while (se)
     78    {
     79        s++;
     80        t = (struct tunnel *) se->data;
     81        tlac = (struct lac *) se->data;
     82        c = (struct call *) se->data;
     83        if (se->func == &hello)
     84        {
     85            log (LOG_WARN, "%d: HELLO to %d\n", s, t->tid);
     86        }
     87        else if (se->func == &magic_lac_dial)
     88        {
     89            log (LOG_WARN, "%d: Magic dial on %s\n", s, tlac->entname);
     90        }
     91        else if (se->func == &send_zlb)
     92        {
     93            log (LOG_WARN, "%d: Send payload ZLB on call %d:%d\n", s,
     94                     c->container->tid, c->cid);
     95        }
     96        else if (se->func == &dethrottle)
     97        {
     98            log (LOG_WARN, "%d: Dethrottle call %d:%d\n", s, c->container->tid,
     99                     c->cid);
     100        }
     101        else
     102            log (LOG_WARN, "%d: Unknown event\n", s);
     103        se = se->next;
     104    };
     105    log (LOG_WARN, "Total Events scheduled: %d\n", s);
     106    log (LOG_WARN, "Number of tunnels open: %d\n", tunnels.count);
     107    t = tunnels.head;
     108    while (t)
     109    {
     110        log (LOG_WARN, "Tunnel %s, ID = %d (local), %d (remote) to %s:%d\n"
     111                 "   control_seq_num = %d, control_rec_seq_num = %d,\n"
     112                 "   cLr = %d\n",
     113                 (t->lac ? t->lac->entname : (t->lns ? t->lns->entname : "")),
     114                 t->ourtid, t->tid, IPADDY (t->peer.sin_addr),
     115                 ntohs (t->peer.sin_port), t->control_seq_num,
     116                 t->control_rec_seq_num, t->cLr);
     117        c = t->call_head;
     118        while (c)
     119        {
     120            log (LOG_WARN,
     121                     "Call %s, ID = %d (local), %d (remote), serno = %u,\n"
     122                     "      data_seq_num = %d, data_rec_seq_num = %d,\n"
     123                     "      pLr = %d, tx = %u bytes (%u), rx= %u bytes (%u)\n",
     124                     (c->lac ? c->lac->
     125                      entname : (c->lns ? c->lns->entname : "")), c->ourcid,
     126                     c->cid, c->serno, c->data_seq_num, c->data_rec_seq_num,
     127                     c->pLr, c->tx_bytes, c->tx_pkts, c->rx_bytes, c->rx_pkts);
     128            c = c->next;
     129        }
     130        t = t->next;
     131    }
     132    log (LOG_WARN, "==========Config File===========\n");
     133    tlns = lnslist;
     134    while (tlns)
     135    {
     136        log (LOG_WARN, "LNS entry %s\n",
     137                 tlns->entname[0] ? tlns->entname : "(unnamed)");
     138        tlns = tlns->next;
     139    };
     140    tlac = laclist;
     141    while (tlac)
     142    {
     143        log (LOG_WARN, "LAC entry %s, LNS is/are:",
     144                 tlac->entname[0] ? tlac->entname : "(unnamed)");
     145        h = tlac->lns;
     146        if (h)
     147        {
     148            while (h)
     149            {
     150                log (LOG_WARN, " %s", h->hostname);
     151                h = h->next;
     152            }
     153        }
     154        else
     155            log (LOG_WARN, " [none]");
     156        log (LOG_WARN, "\n");
     157        tlac = tlac->next;
     158    };
     159    log (LOG_WARN, "================================\n");
     160}
     161
     162void null_handler(int sig)
     163{
     164       /* FIXME
     165        * A sighup is received when a call is terminated, unknown origine ..
     166        * I catch it and ll looks good, but ..
     167        */
     168}
     169
     170void status_handler (int sig)
     171{
     172    show_status ();
     173}
     174
     175void child_handler (int signal)
     176{
     177    /*
     178     * Oops, somebody we launched was killed.
     179     * It's time to reap them and close that call.
     180     * But first, we have to find out what PID died.
     181     * unfortunately, pppd will
     182     */
     183    struct tunnel *t;
     184    struct call *c;
     185    pid_t pid;
     186    int status;
     187    t = tunnels.head;
     188    /* Keep looping until all are cleared */
     189    for(;;)
     190    {
     191        pid = waitpid (-1, &status, WNOHANG);
     192        if (pid < 1)
     193        {
     194            /*
     195             * Oh well, nobody there.  Maybe we reaped it
     196             * somewhere else already
     197             */
     198            return;
     199        }
     200        while (t)
     201        {
     202            c = t->call_head;
     203            while (c)
     204            {
     205                if (c->pppd == pid)
     206                {
     207                    if ( WIFEXITED( status ) )
     208                    {
     209                        log (LOG_DEBUG, "%s : pppd exited for call %d with code %d\n", __FUNCTION__,
     210                         c->cid, WEXITSTATUS( status ) );
     211                    }
     212                    else if( WIFSIGNALED( status ) )
     213                    {
     214                        log (LOG_DEBUG, "%s : pppd terminated for call %d by signal %d\n", __FUNCTION__,
     215                         c->cid, WTERMSIG( status ) );
     216                    }
     217                    else
     218                    {
     219                        log (LOG_DEBUG, "%s : pppd exited for call %d for unknown reason\n", __FUNCTION__,
     220                         c->cid );
     221                    }
     222                    c->needclose = -1;
     223                    /*
     224                     * OK...pppd died, we can go ahead and close the pty for
     225                     * it
     226                     */
     227                    close (c->fd);
     228                    c->fd = -1;
     229                    return;
     230                }
     231                c = c->next;
     232            }
     233            t = t->next;
     234        }
     235    }
     236}
     237
     238void death_handler (int signal)
     239{
     240    /*
     241       * If we get here, somebody terminated us with a kill or a control-c.
     242       * we call call_close on each tunnel twice to get a StopCCN out
     243       * for each one (we can't pause to make sure it's received.
     244       * Then we close the connections
     245     */
     246    struct tunnel *st, *st2;
     247    int sec;
     248    log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
     249    st = tunnels.head;
     250    while (st)
     251    {
     252        st2 = st->next;
     253        strcpy (st->self->errormsg, "Server closing");
     254        sec = st->self->closing;
     255        if (st->lac)
     256            st->lac->redial = 0;
     257        call_close (st->self);
     258        if (!sec)
     259        {
     260            st->self->closing = -1;
     261            call_close (st->self);
     262        }
     263        st = st2;
     264    }
     265
     266    /* erase pid file */
     267        unlink (gconfig.pidfile);
     268
     269        /* erase control pipe */
     270        unlink(CONTROL_PIPE);
     271
     272    exit (1);
     273}
     274
     275int start_pppd (struct call *c, struct ppp_opts *opts)
     276{
     277    char a, b;
     278    char tty[80];
     279    char *stropt[80];
     280    struct ppp_opts *p;
     281#ifdef USE_KERNEL
     282    struct l2tp_call_opts co;
     283#endif
     284    int pos = 1;
     285    int fd2;
     286#ifdef DEBUG_PPPD
     287    int x;
     288#endif
     289    struct termios ptyconf;
     290    char *str;
     291    p = opts;
     292    stropt[0] = strdup (PPPD);
     293    while (p)
     294    {
     295        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
     296        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
     297        pos++;
     298        p = p->next;
     299    }
     300    stropt[pos] = NULL;
     301    if (c->pppd > 0)
     302    {
     303        log (LOG_WARN, "%s: PPP already started on call!\n", __FUNCTION__);
     304        return -EINVAL;
     305    }
     306    if (c->fd > -1)
     307    {
     308        log (LOG_WARN, "%s: file descriptor already assigned!\n",
     309             __FUNCTION__);
     310        return -EINVAL;
     311    }
     312#ifdef USE_KERNEL
     313    if (kernel_support)
     314    {
     315        co.ourtid = c->container->ourtid;
     316        co.ourcid = c->ourcid;
     317        ioctl (server_socket, L2TPIOCGETCALLOPTS, &co);
     318        stropt[pos++] = strdup ("channel");
     319        stropt[pos] = (char *) malloc (10);
     320        snprintf (stropt[pos], 10, "%d", co.id);
     321        pos++;
     322        stropt[pos] = NULL;
     323    }
     324    else
     325    {
     326#endif
     327        if ((c->fd = getPtyMaster (&a, &b)) < 0)
     328        {
     329            log (LOG_WARN, "%s: unable to allocate pty, abandoning!\n",
     330                 __FUNCTION__);
     331            return -EINVAL;
     332        }
     333
     334        /* set fd opened above to not echo so we don't see read our own packets
     335           back of the file descriptor that we just wrote them to */
     336        tcgetattr (c->fd, &ptyconf);
     337        *(c->oldptyconf) = ptyconf;
     338        ptyconf.c_cflag &= ~(ICANON | ECHO);
     339        tcsetattr (c->fd, TCSANOW, &ptyconf);
     340
     341        snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b);
     342        fd2 = open (tty, O_RDWR);
     343
     344#ifdef USE_KERNEL
     345    }
     346#endif
     347    str = stropt[0];
     348#ifdef DEBUG_PPPD
     349    log (LOG_DEBUG, "%s: I'm running:  ", __FUNCTION__);
     350    for (x = 0; stropt[x]; x++)
     351    {
     352        log (LOG_DEBUG, "\"%s\" ", stropt[x]);
     353    };
     354    log (LOG_DEBUG, "\n");
     355#endif
     356    c->pppd = fork ();
     357    if (c->pppd < 0)
     358    {
     359        log (LOG_WARN, "%s: unable to fork(), abandoning!\n", __FUNCTION__);
     360        return -EINVAL;
     361    }
     362    else if (!c->pppd)
     363    {
     364        struct call *sc;
     365        struct tunnel *st;
     366
     367        close (0);
     368        close (1);
     369        close (2);
     370#ifdef USE_KERNEL
     371        if (!kernel_support && (fd2 < 0))
     372#else
     373        if (fd2 < 0)
     374#endif
     375        {
     376            log (LOG_WARN, "%s: Unable to open %s to launch pppd!\n",
     377                 __FUNCTION__, tty);
     378            exit (1);
     379        }
     380        dup2 (fd2, 0);
     381        dup2 (fd2, 1);
     382
     383
     384        /* close all the calls pty fds */
     385        st = tunnels.head;
     386        while (st)
     387        {
     388            sc = st->call_head;
     389            while (sc)
     390            {
     391                close (sc->fd);
     392                sc = sc->next;
     393            }
     394            st = st->next;
     395        }
     396
     397        /* close the UDP socket fd */
     398        close (server_socket);
     399
     400        /* close the control pipe fd */
     401        close (control_fd);
     402
     403        if( c->dialing[0] )
     404        {
     405            setenv( "CALLER_ID", c->dialing, 1 );
     406        }
     407        execv (PPPD, stropt);
     408        log (LOG_WARN, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD);
     409        exit (1);
     410    };
     411    close (fd2);
     412    pos = 0;
     413    while (stropt[pos])
     414    {
     415        free (stropt[pos]);
     416        pos++;
     417    };
     418    return 0;
     419}
     420
     421void destroy_tunnel (struct tunnel *t)
     422{
     423    /*
     424     * Immediately destroy a tunnel (and all its calls)
     425     * and free its resources.  This may be called
     426     * by the tunnel itself,so it needs to be
     427     * "suicide safe"
     428     */
     429
     430    struct call *c, *me;
     431    struct tunnel *p;
     432    struct timeval tv;
     433    if (!t)
     434        return;
     435
     436    /*
     437     * Save ourselves until the very
     438     * end, since we might be calling this ourselves.
     439     * We must divorce ourself from the tunnel
     440     * structure, however, to avoid recursion
     441     * because of the logic of the destroy_call
     442     */
     443    me = t->self;
     444
     445    /*
     446     * Destroy all the member calls
     447     */
     448    c = t->call_head;
     449    while (c)
     450    {
     451        destroy_call (c);
     452        c = c->next;
     453    };
     454    /*
     455     * Remove ourselves from the list of tunnels
     456     */
     457
     458    if (tunnels.head == t)
     459    {
     460        tunnels.head = t->next;
     461        tunnels.count--;
     462    }
     463    else
     464    {
     465        p = tunnels.head;
     466        if (p)
     467        {
     468            while (p->next && (p->next != t))
     469                p = p->next;
     470            if (p->next)
     471            {
     472                p->next = t->next;
     473                tunnels.count--;
     474            }
     475            else
     476            {
     477                log (LOG_WARN,
     478                     "%s: unable to locate tunnel in tunnel list\n",
     479                     __FUNCTION__);
     480            }
     481        }
     482        else
     483        {
     484            log (LOG_WARN, "%s: tunnel list is empty!\n", __FUNCTION__);
     485        }
     486    }
     487    if (t->lac)
     488    {
     489        t->lac->t = NULL;
     490        if (t->lac->redial && (t->lac->rtimeout > 0) && !t->lac->rsched &&
     491            t->lac->active)
     492        {
     493            log (LOG_LOG, "%s: Will redial in %d seconds\n", __FUNCTION__,
     494                 t->lac->rtimeout);
     495            tv.tv_sec = t->lac->rtimeout;
     496            tv.tv_usec = 0;
     497            t->lac->rsched = schedule (tv, magic_lac_dial, t->lac);
     498        }
     499    }
     500    /* XXX L2TP/IPSec: remove relevant SAs here?  NTB 20011010
     501     * XXX But what if another tunnel is using same SA?
     502     */
     503    if (t->lns)
     504        t->lns->t = NULL;
     505    free (t);
     506    free (me);
     507}
     508
     509struct tunnel *l2tp_call (char *host, int port, struct lac *lac,
     510                          struct lns *lns)
     511{
     512    /*
     513     * Establish a tunnel from us to host
     514     * on port port
     515     */
     516    struct call *tmp = NULL;
     517    struct hostent *hp;
     518    unsigned int addr;
     519    port = htons (port);
     520    hp = gethostbyname (host);
     521    if (!hp)
     522    {
     523        log (LOG_WARN, "%s: gethostbyname() failed for %s.\n", __FUNCTION__,
     524             host);
     525        return NULL;
     526    }
     527    bcopy (hp->h_addr, &addr, hp->h_length);
     528    /* Force creation of a new tunnel
     529       and set it's tid to 0 to cause
     530       negotiation to occur */
     531    /* XXX L2TP/IPSec: Set up SA to addr:port here?  NTB 20011010
     532     */
     533    tmp = get_call (0, 0, addr, port);
     534    if (!tmp)
     535    {
     536        log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,
     537             host);
     538        return NULL;
     539    }
     540    tmp->container->tid = 0;
     541    tmp->container->lac = lac;
     542    tmp->container->lns = lns;
     543    tmp->lac = lac;
     544    tmp->lns = lns;
     545    if (lac)
     546        lac->t = tmp->container;
     547    if (lns)
     548        lns->t = tmp->container;
     549    /*
     550     * Since our state is 0, we will establish a tunnel now
     551     */
     552    log (LOG_LOG, "%s:Connecting to host %s, port %d\n", __FUNCTION__, host,
     553         ntohs (port));
     554    control_finish (tmp->container, tmp);
     555    return tmp->container;
     556}
     557
     558void magic_lac_tunnel (void *data)
     559{
     560    struct lac *lac;
     561    lac = (struct lac *) data;
     562    if (!lac)
     563    {
     564        log (LOG_WARN, "%s: magic_lac_tunnel: called on NULL lac!\n",
     565             __FUNCTION__);
     566        return;
     567    }
     568    if (lac->lns)
     569    {
     570        /* FIXME: I should try different LNS's if I get failures */
     571        l2tp_call (lac->lns->hostname, lac->lns->port, lac, NULL);
     572        return;
     573    }
     574    else if (deflac && deflac->lns)
     575    {
     576        l2tp_call (deflac->lns->hostname, deflac->lns->port, lac, NULL);
     577        return;
     578    }
     579    else
     580    {
     581        log (LOG_WARN, "%s: Unable to find hostname to dial for '%s'\n",
     582             __FUNCTION__, lac->entname);
     583        return;
     584    }
     585}
     586
     587struct call *lac_call (int tid, struct lac *lac, struct lns *lns)
     588{
     589    struct tunnel *t = tunnels.head;
     590    struct call *tmp;
     591    while (t)
     592    {
     593        if (t->ourtid == tid)
     594        {
     595            tmp = new_call (t);
     596            if (!tmp)
     597            {
     598                log (LOG_WARN, "%s: unable to create new call\n",
     599                     __FUNCTION__);
     600                return NULL;
     601            }
     602            tmp->next = t->call_head;
     603            t->call_head = tmp;
     604            t->count++;
     605            tmp->cid = 0;
     606            tmp->lac = lac;
     607            tmp->lns = lns;
     608            if (lac)
     609                lac->c = tmp;
     610            log (LOG_LOG, "%s: Calling on tunnel %d\n", __FUNCTION__, tid);
     611            strcpy (tmp->dial_no, dial_no_tmp); /*  jz: copy dialnumber to tmp->dial_no  */
     612            control_finish (t, tmp);
     613            return tmp;
     614        }
     615        t = t->next;
     616    };
     617    log (LOG_DEBUG, "%s: No such tunnel %d to generate call.\n", __FUNCTION__,
     618         tid);
     619    return NULL;
     620}
     621
     622void magic_lac_dial (void *data)
     623{
     624    struct lac *lac;
     625    lac = (struct lac *) data;
     626
     627    if (!lac)
     628    {
     629        log (LOG_WARN, "%s : called on NULL lac!\n", __FUNCTION__);
     630        return;
     631    }
     632        if (!lac->active)
     633    {
     634        log (LOG_DEBUG, "%s: LAC %s not active", __FUNCTION__, lac->entname);
     635        return;
     636    }
     637    lac->rsched = NULL;
     638    lac->rtries++;
     639    if (lac->rmax && (lac->rtries > lac->rmax))
     640    {
     641        log (LOG_LOG, "%s: maximum retries exceeded.\n", __FUNCTION__);
     642        return;
     643    }
     644    if (!lac->t)
     645    {
     646#ifdef DEGUG_MAGIC
     647        log (LOG_DEBUG, "%s : tunnel not up!  Connecting!\n", __FUNCTION__);
     648#endif
     649        magic_lac_tunnel (lac);
     650        return;
     651    }
     652    lac_call (lac->t->ourtid, lac, NULL);
     653}
     654
     655void lac_hangup (int cid)
     656{
     657    struct tunnel *t = tunnels.head;
     658    struct call *tmp;
     659    while (t)
     660    {
     661        tmp = t->call_head;
     662        while (tmp)
     663        {
     664            if (tmp->ourcid == cid)
     665            {
     666                log (LOG_LOG,
     667                     "%s :Hanging up call %d, Local: %d, Remote: %d\n",
     668                     __FUNCTION__, tmp->serno, tmp->ourcid, tmp->cid);
     669                strcpy (tmp->errormsg, "Goodbye!");
     670/*                              tmp->needclose = -1; */
     671                kill (tmp->pppd, SIGTERM);
     672                return;
     673            }
     674            tmp = tmp->next;
     675        }
     676        t = t->next;
     677    };
     678    log (LOG_DEBUG, "%s : No such call %d to hang up.\n", __FUNCTION__, cid);
     679    return;
     680}
     681
     682void lac_disconnect (int tid)
     683{
     684    struct tunnel *t = tunnels.head;
     685    while (t)
     686    {
     687        if (t->ourtid == tid)
     688        {
     689            log (LOG_LOG,
     690                 "%s: Disconnecting from %s, Local: %d, Remote: %d\n",
     691                 __FUNCTION__, IPADDY (t->peer.sin_addr), t->ourtid, t->tid);
     692            t->self->needclose = -1;
     693            strcpy (t->self->errormsg, "Goodbye!");
     694            call_close (t->self);
     695            return;
     696        }
     697        t = t->next;
     698    };
     699    log (LOG_DEBUG, "%s: No such tunnel %d to hang up.\n", __FUNCTION__, tid);
     700    return;
     701}
     702
     703struct tunnel *new_tunnel ()
     704{
     705    struct tunnel *tmp = malloc (sizeof (struct tunnel));
     706    char entropy_buf[2] = "\0";
     707    if (!tmp)
     708        return NULL;
     709    tmp->control_seq_num = 0;
     710    tmp->control_rec_seq_num = 0;
     711    tmp->cLr = 0;
     712    tmp->call_head = NULL;
     713    tmp->next = NULL;
     714    tmp->debug = -1;
     715    tmp->tid = -1;
     716    tmp->hello = NULL;
     717#ifndef TESTING
     718/*      while(get_call((tmp->ourtid = rand() & 0xFFFF),0,0,0)); */
     719#ifdef USE_KERNEL
     720    if (kernel_support)
     721        tmp->ourtid = ioctl (server_socket, L2TPIOCADDTUNNEL, 0);
     722    else
     723#endif
     724/*        tmp->ourtid = rand () & 0xFFFF; */
     725        /* get_entropy((char *)&tmp->ourtid, 2); */
     726        get_entropy(entropy_buf, 2);
     727        {
     728            int *temp;
     729            temp = (int *)entropy_buf;
     730            tmp->ourtid = *temp & 0xFFFF;
     731#ifdef DEBUG_ENTROPY
     732            log(LOG_DEBUG, "ourtid = %u, entropy_buf = %hx\n", tmp->ourtid, *temp);
     733#endif
     734        }
     735#else
     736    tmp->ourtid = 0x6227;
     737#endif
     738    tmp->nego = 0;
     739    tmp->count = 0;
     740    tmp->state = 0;             /* Nothing */
     741    tmp->peer.sin_family = AF_INET;
     742    tmp->peer.sin_port = 0;
     743    bzero (&(tmp->peer.sin_addr), sizeof (tmp->peer.sin_addr));
     744    tmp->sanity = -1;
     745    tmp->qtid = -1;
     746    tmp->ourfc = ASYNC_FRAMING | SYNC_FRAMING;
     747    tmp->ourbc = 0;
     748    tmp->ourtb = (((_u64) rand ()) << 32) | ((_u64) rand ());
     749    tmp->fc = -1;               /* These really need to be specified by the peer */
     750    tmp->bc = -1;               /* And we want to know if they forgot */
     751    tmp->hostname[0] = 0;
     752    tmp->vendor[0] = 0;
     753    tmp->secret[0] = 0;
     754    if (!(tmp->self = new_call (tmp)))
     755    {
     756        free (tmp);
     757        return NULL;
     758    };
     759    tmp->ourrws = DEFAULT_RWS_SIZE;
     760    tmp->self->ourfbit = FBIT;
     761    tmp->lac = NULL;
     762    tmp->lns = NULL;
     763    tmp->chal_us.state = 0;
     764    tmp->chal_us.secret[0] = 0;
     765    memset (tmp->chal_us.reply, 0, MD_SIG_SIZE);
     766    tmp->chal_them.state = 0;
     767    tmp->chal_them.secret[0] = 0;
     768    memset (tmp->chal_them.reply, 0, MD_SIG_SIZE);
     769    tmp->chal_them.vector = (unsigned char *) malloc (VECTOR_SIZE);
     770    tmp->chal_us.vector = NULL;
     771    tmp->hbit = 0;
     772    return tmp;
     773}
     774
     775void do_control ()
     776{
     777    char buf[1024];
     778    char *host, *tunstr, *callstr, *tmpstr;
     779    struct lac *lac;
     780    int call;
     781    int tunl;
     782    int cnt = -1;
     783    while (cnt)
     784    {
     785        cnt = read (control_fd, buf, sizeof (buf));
     786        if (cnt > 0)
     787        {
     788            if (buf[cnt - 1] == '\n')
     789                buf[--cnt] = 0;
     790#ifdef DEBUG_CONTROL
     791            log (LOG_DEBUG, "%s: Got message \"%s\" (%d bytes long)\n",
     792                 __FUNCTION__, buf, cnt);
     793#endif
     794            switch (buf[0])
     795            {
     796            case 't':
     797                host = strchr (buf, ' ');
     798                                if(!host)
     799                                        goto out;
     800                                host++;
     801#ifdef DEBUG_CONTROL
     802                log (LOG_DEBUG, "%s: Attempting to tunnel to %s\n",
     803                     __FUNCTION__, host);
     804#endif
     805                l2tp_call (host, UDP_LISTEN_PORT, NULL, NULL);
     806                break;
     807            case 'c':              /* option 'c' for incoming call */
     808            case 'o':          /* option 'o' for outgoing call */
     809                                tunstr = strchr (buf, ' ');
     810                                if(!tunstr)
     811                                        goto out;
     812                                tunstr++;
     813
     814                                if(buf[0] == 'c')
     815                        switch_io = 1;  /* Switch for Incoming Calls */
     816                                else {
     817                        switch_io = 0;  /* Switch for Outgoing Calls */
     818                                        tmpstr = strchr(tunstr, ' ');
     819                                        if(!tmpstr)
     820                                                goto out;
     821                                        strncpy(dial_no_tmp,tmpstr, sizeof(*dial_no_tmp));
     822                                }
     823               
     824                lac = laclist;
     825                while (lac)
     826                {
     827                    if (!strcasecmp (lac->entname, tunstr))
     828                    {
     829                        lac->active = -1;
     830                        lac->rtries = 0;
     831                        if (!lac->c)
     832                            magic_lac_dial (lac);
     833                        else
     834                            log (LOG_DEBUG,
     835                                 "%s: Session '%s' already active!\n",
     836                                 __FUNCTION__, lac->entname);
     837                        break;
     838                    }
     839                    lac = lac->next;
     840                }
     841                if (lac)
     842                    break;
     843                tunl = atoi (tunstr);
     844                if (!tunl)
     845                {
     846                    log (LOG_DEBUG, "%s: No such tunnel '%s'\n", __FUNCTION__,
     847                         tunstr);
     848                    break;
     849                }
     850#ifdef DEBUG_CONTROL
     851                log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n",
     852                     __FUNCTION__, tunl);
     853#endif
     854                lac_call (tunl, NULL, NULL);
     855                break;
     856            case 'h':
     857                callstr = strchr (buf, ' ');
     858                if(!callstr)
     859                                        goto out;
     860                                callstr++;
     861
     862                call = atoi (callstr);
     863#ifdef DEBUG_CONTROL
     864                log (LOG_DEBUG, "%s: Attempting to call %d\n", __FUNCTION__,
     865                     call);
     866#endif
     867                lac_hangup (call);
     868                break;
     869            case 'd':
     870                tunstr = strchr (buf, ' ');
     871                if(!tunstr)
     872                                        goto out;
     873                                tunstr++;
     874
     875                lac = laclist;
     876                while (lac)
     877                {
     878                    if (!strcasecmp (lac->entname, tunstr))
     879                    {
     880                        lac->active = 0;
     881                        lac->rtries = 0;
     882                        if (lac->t)
     883                            lac_disconnect (lac->t->ourtid);
     884                        else
     885                            log (LOG_DEBUG, "%s: Session '%s' not up\n",
     886                                 __FUNCTION__, lac->entname);
     887                        break;
     888                    }
     889                    lac = lac->next;
     890                }
     891                if (lac)
     892                    break;
     893                tunl = atoi (tunstr);
     894                if (!tunl)
     895                {
     896                    log (LOG_DEBUG, "%s: No such tunnel '%s'\n", __FUNCTION__,
     897                         tunstr);
     898                    break;
     899                }
     900#ifdef DEBUG_CONTROL
     901                log (LOG_DEBUG, "%s: Attempting to disconnect tunnel %d\n",
     902                     __FUNCTION__, tunl);
     903#endif
     904                lac_disconnect (tunl);
     905                break;
     906            case 's':
     907                show_status ();
     908                break;
     909            default:
     910                log (LOG_DEBUG, "%s: Unknown command %c\n", __FUNCTION__,
     911                     buf[0]);
     912            }
     913        }
     914    }
     915
     916out:
     917    /* Otherwise select goes nuts */
     918    close (control_fd);
     919    control_fd = open (CONTROL_PIPE, O_RDONLY | O_NONBLOCK, 0600);
     920}
     921
     922void usage(void) {
     923    printf("Usage: l2tpd -D -c [config file] -s [secret file] -p [pid file]\n");
     924    printf("\n");
     925    exit(1);
     926}
     927
     928void init_args(int argc, char *argv[]) {
     929    int i=0;
     930    gconfig.daemon=1;
     931    memset(gconfig.altauthfile,0,STRLEN);
     932    memset(gconfig.altconfigfile,0,STRLEN);
     933    memset(gconfig.authfile,0,STRLEN);
     934    memset(gconfig.configfile,0,STRLEN);
     935    memset(gconfig.pidfile,0,STRLEN);
     936    strncpy(gconfig.altauthfile,ALT_DEFAULT_AUTH_FILE,
     937            sizeof(gconfig.altauthfile) - 1);
     938    strncpy(gconfig.altconfigfile,ALT_DEFAULT_CONFIG_FILE,
     939            sizeof(gconfig.altconfigfile) - 1);
     940    strncpy(gconfig.authfile,DEFAULT_AUTH_FILE,
     941            sizeof(gconfig.authfile) - 1);
     942    strncpy(gconfig.configfile,DEFAULT_CONFIG_FILE,
     943            sizeof(gconfig.configfile) - 1);
     944    strncpy(gconfig.pidfile,DEFAULT_PID_FILE,
     945            sizeof(gconfig.pidfile) - 1);
     946    for (i = 1; i < argc; i++) {
     947        if(! strncmp(argv[i],"-c",2)) {
     948            if(++i == argc)
     949                usage();
     950            else
     951                strncpy(gconfig.configfile,argv[i],
     952                        sizeof(gconfig.configfile) - 1);
     953        }
     954        else if (! strncmp(argv[i],"-D",2)) {
     955            gconfig.daemon=0;
     956        }
     957        else if (! strncmp(argv[i],"-s",2)) {
     958            if(++i == argc)
     959                usage();
     960            else
     961                strncpy(gconfig.authfile,argv[i],
     962                        sizeof(gconfig.authfile) - 1);
     963        }
     964        else if (! strncmp(argv[i],"-p",2)) {
     965            if(++i == argc)
     966                usage();
     967            else
     968                strncpy(gconfig.pidfile,argv[i],
     969                        sizeof(gconfig.pidfile) - 1);
     970        }
     971        else {
     972            usage();
     973        }
     974    }
     975}
     976
     977
     978void daemonize() {
     979    int pid=0;
     980    int i,l;
     981    char buf[STRLEN];
     982
     983    if((pid = fork()) < 0) {
     984        log(LOG_LOG, "%s: Unable to fork ()\n",__FUNCTION__);
     985        close(server_socket);
     986        exit(1);
     987    }
     988    else if (pid)
     989        exit(0);
     990
     991
     992        close(0);
     993        close(1);
     994        close(2);
     995        dup2(open("/dev/null", O_RDONLY), 0);
     996        dup2(open("/dev/null", O_RDONLY), 1);
     997        dup2(open("/dev/null", O_RDONLY), 2);
     998
     999    /* Read previous pid file. */
     1000    if((i = open(gconfig.pidfile,O_RDONLY)) > 0) {
     1001                l=read(i,buf,sizeof(buf)-1);                                                             
     1002        if (l >= 0) {
     1003                buf[l] = '\0';                                                                       
     1004                pid = atoi(buf);                                                                     
     1005        }
     1006                close(i);
     1007
     1008                /* if pid is read and process exist exit */
     1009        if(pid && !kill(pid, 0)) {
     1010            log(LOG_LOG, "%s: There's already a l2tpd server running.\n",
     1011                    __FUNCTION__);
     1012            close(server_socket);
     1013            exit(1);
     1014        }
     1015
     1016                /* remove stalled pid file */
     1017                unlink(gconfig.pidfile);
     1018    }
     1019
     1020    pid = setsid();
     1021
     1022        /* create new pid file */
     1023        if ((i = open (gconfig.pidfile, O_WRONLY | O_CREAT, 0644)) >= 0) {
     1024                snprintf (buf, sizeof(buf), "%d", (int)getpid());
     1025                write (i, buf, strlen(buf));
     1026                close (i);
     1027        }
     1028        else {
     1029                log(LOG_LOG, "%s: could not write pid file %s error %d",
     1030                                __FUNCTION__, gconfig.pidfile, i);
     1031                close(server_socket);
     1032                exit(1);
     1033        }
     1034}
     1035
     1036
     1037void init (int argc,char *argv[])
     1038{
     1039    struct lac *lac;
     1040    struct in_addr listenaddr;
     1041
     1042    init_args (argc,argv);
     1043    srand( time(NULL) );
     1044    rand_source = 0;
     1045    init_addr ();
     1046    if (init_config ())
     1047    {
     1048        log (LOG_CRIT, "%s: Unable to load config file\n", __FUNCTION__);
     1049        exit (1);
     1050    }
     1051    if (uname (&uts))
     1052    {
     1053        log (LOG_CRIT, "%s : Unable to determine host system\n",
     1054             __FUNCTION__);
     1055        exit (1);
     1056    }
     1057    init_tunnel_list (&tunnels);
     1058    if (init_network ())
     1059        exit (1);
     1060    if (gconfig.daemon)
     1061        daemonize ();
     1062    signal (SIGTERM, &death_handler);
     1063    signal (SIGINT, &death_handler);
     1064    signal (SIGCHLD, &child_handler);
     1065    signal (SIGUSR1, &status_handler);
     1066    signal (SIGHUP, &null_handler);
     1067    init_scheduler ();
     1068    mkfifo (CONTROL_PIPE, 0600);
     1069    control_fd = open (CONTROL_PIPE, O_RDONLY | O_NONBLOCK, 0600);
     1070    if (control_fd < 0)
     1071    {
     1072        log (LOG_CRIT, "%s: Unable to open " CONTROL_PIPE " for reading.",
     1073             __FUNCTION__);
     1074        exit (1);
     1075    }
     1076    log (LOG_LOG, "l2tpd version " SERVER_VERSION " started on %s PID:%d\n",
     1077         hostname, getpid ());
     1078    listenaddr.s_addr = gconfig.listenaddr;
     1079    log (LOG_LOG, "%s version %s on a %s, listening on IP address %s, port %d\n", uts.sysname,
     1080       uts.release, uts.machine, inet_ntoa(listenaddr), gconfig.port);
     1081    lac = laclist;
     1082    while (lac)
     1083    {
     1084        if (lac->autodial)
     1085        {
     1086#ifdef DEBUG_MAGIC
     1087            log (LOG_DEBUG, "%s: Autodialing '%s'\n", __FUNCTION__,
     1088                 lac->entname[0] ? lac->entname : "(unnamed)");
     1089#endif
     1090            lac->active = -1;
     1091            switch_io = 1;      /* If we're a LAC, autodials will be ICRQ's */
     1092            magic_lac_dial (lac);
     1093        }
     1094        lac = lac->next;
     1095    }
     1096}
     1097
     1098int main (int argc, char *argv[])
     1099{
     1100    init(argc,argv);
     1101    dial_no_tmp = calloc (128, sizeof (char));
     1102    network_thread ();
     1103    return 0;
     1104}
Note: See TracBrowser for help on using the repository browser.