⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l2tpd.c

📁 第二层隧道模块l2tp源码,开发环境为linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Layer Two Tunnelling Protocol Daemon * Copyright (C) 1998 Adtran, Inc. * Copyright (C) 2002 Jeff McAdams * * Mark Spencer * * This software is distributed under the terms * of the GPL, which you should have received * along with this source. * * Main Daemon source. * */#include <stdlib.h>#include <sys/utsname.h>#include <sys/stat.h>#include <sys/wait.h>#include <stdio.h>#include <errno.h>#include <unistd.h>#if (__GLIBC__ < 2)# if defined(FREEBSD)#  include <sys/signal.h># elif defined(LINUX)#  include <bsd/signal.h># elif defined(SOLARIS)#  include <signal.h># endif#else# include <signal.h>#endif#include <netdb.h>#include <string.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef USE_KERNEL#include <sys/ioctl.h>#endif#include "l2tp.h"struct tunnel_list tunnels;int max_tunnels = DEF_MAX_TUNNELS;struct utsname uts;int ppd = 1;                    /* Packet processing delay */int control_fd;                 /* descriptor of control area */char *args;char *dial_no_tmp;              /* jz: Dialnumber for Outgoing Call */int switch_io = 0;              /* jz: Switch for Incoming or Outgoing Call */void init_tunnel_list (struct tunnel_list *t){    t->head = NULL;    t->count = 0;    t->calls = 0;}void show_status (int fd){    struct schedule_entry *se;    struct tunnel *t;    struct call *c;    struct lns *tlns;    struct lac *tlac;    struct host *h;    int s = 0;    int fd2 = dup (fd);    FILE *f = fdopen (fd2, "a");    if (!f)    {        log (LOG_WARN, "show_status: fdopen() failed on fd %d\n", fd);        return;    }    fprintf (f, "====== l2tpd statistics ========\n");    fprintf (f, " Scheduler entries:\n");    se = events;    while (se)    {        s++;        t = (struct tunnel *) se->data;        tlac = (struct lac *) se->data;        c = (struct call *) se->data;        if (se->func == &hello)        {            fprintf (f, "%d: HELLO to %d\n", s, t->tid);        }        else if (se->func == &magic_lac_dial)        {            fprintf (f, "%d: Magic dial on %s\n", s, tlac->entname);        }        else if (se->func == &send_zlb)        {            fprintf (f, "%d: Send payload ZLB on call %d:%d\n", s,                     c->container->tid, c->cid);        }        else if (se->func == &dethrottle)        {            fprintf (f, "%d: Dethrottle call %d:%d\n", s, c->container->tid,                     c->cid);        }        else            fprintf (f, "%d: Unknown event\n", s);        se = se->next;    };    fprintf (f, "Total Events scheduled: %d\n", s);    fprintf (f, "Number of tunnels open: %d\n", tunnels.count);    fprintf (f, "Highest file descriptor: %d\n", fd2);    t = tunnels.head;    while (t)    {        fprintf (f, "Tunnel %s, ID = %d (local), %d (remote) to %s:%d\n"                 "   control_seq_num = %d, control_rec_seq_num = %d,\n"                 "   cLr = %d\n",                 (t->lac ? t->lac->entname : (t->lns ? t->lns->entname : "")),                 t->ourtid, t->tid, IPADDY (t->peer.sin_addr),                 ntohs (t->peer.sin_port), t->control_seq_num,                 t->control_rec_seq_num, t->cLr);        c = t->call_head;        while (c)        {            fprintf (f,                     "Call %s, ID = %d (local), %d (remote), serno = %u,\n"                     "      data_seq_num = %d, data_rec_seq_num = %d,\n"                     "      pLr = %d, tx = %u bytes (%u), rx= %u bytes (%u)\n",                     (c->lac ? c->lac->                      entname : (c->lns ? c->lns->entname : "")), c->ourcid,                     c->cid, c->serno, c->data_seq_num, c->data_rec_seq_num,                     c->pLr, c->tx_bytes, c->tx_pkts, c->rx_bytes, c->rx_pkts);            c = c->next;        }        t = t->next;    }    fprintf (f, "==========Config File===========\n");    tlns = lnslist;    while (tlns)    {        fprintf (f, "LNS entry %s\n",                 tlns->entname[0] ? tlns->entname : "(unnamed)");        tlns = tlns->next;    };    tlac = laclist;    while (tlac)    {        fprintf (f, "LAC entry %s, LNS is/are:",                 tlac->entname[0] ? tlac->entname : "(unnamed)");        h = tlac->lns;        if (h)        {            while (h)            {                fprintf (f, " %s", h->hostname);                h = h->next;            }        }        else            fprintf (f, " [none]");        fprintf (f, "\n");        tlac = tlac->next;    };    fprintf (f, "================================\n");    fclose (f);    close (fd2);}void null_handler(int sig){       /* FIXME         * A sighup is received when a call is terminated, unknown origine ..         * I catch it and ll looks good, but .. 	*/}void status_handler (int sig){    show_status (1);}void child_handler (int signal){    /*     * Oops, somebody we launched was killed.     * It's time to reap them and close that call.     * But first, we have to find out what PID died.     * unfortunately, pppd will      */    struct tunnel *t;    struct call *c;    pid_t pid;    int status;    t = tunnels.head;    pid = waitpid (-1, &status, WNOHANG);    if (pid < 1)    {        /*         * Oh well, nobody there.  Maybe we reaped it         * somewhere else already         */        return;    }    while (t)    {        c = t->call_head;        while (c)        {            if (c->pppd == pid)            {                log (LOG_DEBUG, "%s : pppd died for call %d\n", __FUNCTION__,                     c->cid);                c->needclose = -1;                /*                  * OK...pppd died, we can go ahead and close the pty for                 * it                 */                close (c->fd);                return;            }            c = c->next;        }        t = t->next;    }}void death_handler (int signal){    /*       * If we get here, somebody terminated us with a kill or a control-c.       * we call call_close on each tunnel twice to get a StopCCN out       * for each one (we can't pause to make sure it's received.       * Then we close the connections     */    struct tunnel *st, *st2;    int sec;    log (LOG_CRIT, "%s: Fatal signal %d received\n", __FUNCTION__, signal);    st = tunnels.head;    while (st)    {        st2 = st->next;        strcpy (st->self->errormsg, "Server closing");        sec = st->self->closing;        if (st->lac)            st->lac->redial = 0;        call_close (st->self);        if (!sec)        {            st->self->closing = -1;            call_close (st->self);        }        st = st2;    }    /* erase pid file */	unlink (gconfig.pidfile);    exit (1);}int start_pppd (struct call *c, struct ppp_opts *opts){    char a, b;    char tty[80];    char *stropt[80];    struct ppp_opts *p;#ifdef USE_KERNEL    struct l2tp_call_opts co;#endif    int pos = 1;    int fd2;#ifdef DEBUG_PPPD    int x;#endif    struct termios ptyconf;    char *str;    p = opts;    stropt[0] = strdup (PPPD);    while (p)    {        stropt[pos] = (char *) malloc (strlen (p->option) + 1);        strncpy (stropt[pos], p->option, strlen (p->option) + 1);        pos++;        p = p->next;    }    stropt[pos] = NULL;    if (c->pppd > 0)    {        log (LOG_WARN, "%s: PPP already started on call!\n", __FUNCTION__);        return -EINVAL;    }    if (c->fd > -1)    {        log (LOG_WARN, "%s: file descriptor already assigned!\n",             __FUNCTION__);        return -EINVAL;    }#ifdef USE_KERNEL    if (kernel_support)    {        co.ourtid = c->container->ourtid;        co.ourcid = c->ourcid;        ioctl (server_socket, L2TPIOCGETCALLOPTS, &co);        stropt[pos++] = strdup ("channel");        stropt[pos] = (char *) malloc (10);        snprintf (stropt[pos], 10, "%d", co.id);        pos++;        stropt[pos] = NULL;    }    else    {#endif        if ((c->fd = getPtyMaster (&a, &b)) < 0)        {            log (LOG_WARN, "%s: unable to allocate pty, abandoning!\n",                 __FUNCTION__);            return -EINVAL;        }        /* set fd opened above to not echo so we don't see read our own packets           back of the file descriptor that we just wrote them to */        tcgetattr (c->fd, &ptyconf);        *(c->oldptyconf) = ptyconf;        ptyconf.c_cflag &= ~(ICANON | ECHO);        tcsetattr (c->fd, TCSANOW, &ptyconf);        snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b);        fd2 = open (tty, O_RDWR);#ifdef USE_KERNEL    }#endif    str = stropt[0];#ifdef DEBUG_PPPD    log (LOG_DEBUG, "%s: I'm running:  ", __FUNCTION__);    for (x = 0; stropt[x]; x++)    {        log (LOG_DEBUG, "\"%s\" ", stropt[x]);    };    log (LOG_DEBUG, "\n");#endif    c->pppd = fork ();    if (c->pppd < 0)    {        log (LOG_WARN, "%s: unable to fork(), abandoning!\n", __FUNCTION__);        return -EINVAL;    }    else if (!c->pppd)    {        struct call *sc;        struct tunnel *st;        close (0);        close (1);        close (2);#ifdef USE_KERNEL        if (!kernel_support && (fd2 < 0))#else        if (fd2 < 0)#endif        {            log (LOG_WARN, "%s: Unable to open %s to launch pppd!\n",                 __FUNCTION__, tty);            exit (1);        }        dup2 (fd2, 0);        dup2 (fd2, 1);        /* close all the calls pty fds */        st = tunnels.head;        while (st)        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -