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

📄 l2tpd.c

📁 第二层隧道模块l2tp源码,开发环境为linux
💻 C
📖 第 1 页 / 共 3 页
字号:
            sc = st->call_head;            while (sc)            {                close (sc->fd);                sc = sc->next;            }            st = st->next;        }        /* close the UDP socket fd */        close (server_socket);        /* close the control pipe fd */        close (control_fd);        execv (PPPD, stropt);        log (LOG_WARN, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD);        exit (1);    };    close (fd2);    pos = 0;    while (stropt[pos])    {        free (stropt[pos]);        pos++;    };    return 0;}void destroy_tunnel (struct tunnel *t){    /*     * Immediately destroy a tunnel (and all its calls)     * and free its resources.  This may be called     * by the tunnel itself,so it needs to be     * "suicide safe"     */    struct call *c, *me;    struct tunnel *p;    struct timeval tv;    if (!t)        return;    /*     * Save ourselves until the very     * end, since we might be calling this ourselves.     * We must divorce ourself from the tunnel     * structure, however, to avoid recursion     * because of the logic of the destroy_call     */    me = t->self;    /*     * Destroy all the member calls     */    c = t->call_head;    while (c)    {        destroy_call (c);        c = c->next;    };    /*     * Remove ourselves from the list of tunnels     */    if (tunnels.head == t)    {        tunnels.head = t->next;        tunnels.count--;    }    else    {        p = tunnels.head;        if (p)        {            while (p->next && (p->next != t))                p = p->next;            if (p->next)            {                p->next = t->next;                tunnels.count--;            }            else            {                log (LOG_WARN,                     "%s: unable to locate tunnel in tunnel list\n",                     __FUNCTION__);            }        }        else        {            log (LOG_WARN, "%s: tunnel list is empty!\n", __FUNCTION__);        }    }    if (t->lac)    {        t->lac->t = NULL;        if (t->lac->redial && (t->lac->rtimeout > 0) && !t->lac->rsched &&            t->lac->active)        {            log (LOG_LOG, "%s: Will redial in %d seconds\n", __FUNCTION__,                 t->lac->rtimeout);            tv.tv_sec = t->lac->rtimeout;            tv.tv_usec = 0;            t->lac->rsched = schedule (tv, magic_lac_dial, t->lac);        }    }    /* XXX L2TP/IPSec: remove relevant SAs here?  NTB 20011010     * XXX But what if another tunnel is using same SA?     */    if (t->lns)        t->lns->t = NULL;    free (t);    free (me);}struct tunnel *l2tp_call (char *host, int port, struct lac *lac,                          struct lns *lns){    /*     * Establish a tunnel from us to host     * on port port     */    struct call *tmp = NULL;    struct hostent *hp;    unsigned int addr;    port = htons (port);    hp = gethostbyname (host);    if (!hp)    {        log (LOG_WARN, "%s: gethostbyname() failed for %s.\n", __FUNCTION__,             host);        return NULL;    }    bcopy (hp->h_addr, &addr, hp->h_length);    /* Force creation of a new tunnel       and set it's tid to 0 to cause       negotiation to occur */    /* XXX L2TP/IPSec: Set up SA to addr:port here?  NTB 20011010     */    tmp = get_call (0, 0, addr, port);    if (!tmp)    {        log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__,             host);        return NULL;    }    tmp->container->tid = 0;    tmp->container->lac = lac;    tmp->container->lns = lns;    tmp->lac = lac;    tmp->lns = lns;    if (lac)        lac->t = tmp->container;    if (lns)        lns->t = tmp->container;    /*     * Since our state is 0, we will establish a tunnel now     */    log (LOG_LOG, "%s:Connecting to host %s, port %d\n", __FUNCTION__, host,         ntohs (port));    control_finish (tmp->container, tmp);    return tmp->container;}void magic_lac_tunnel (void *data){    struct lac *lac;    lac = (struct lac *) data;    if (!lac)    {        log (LOG_WARN, "%s: magic_lac_tunnel: called on NULL lac!\n",             __FUNCTION__);        return;    }    if (lac->lns)    {        /* FIXME: I should try different LNS's if I get failures */        l2tp_call (lac->lns->hostname, lac->lns->port, lac, NULL);        return;    }    else if (deflac && deflac->lns)    {        l2tp_call (deflac->lns->hostname, deflac->lns->port, lac, NULL);        return;    }    else    {        log (LOG_WARN, "%s: Unable to find hostname to dial for '%s'\n",             __FUNCTION__, lac->entname);        return;    }}struct call *lac_call (int tid, struct lac *lac, struct lns *lns){    struct tunnel *t = tunnels.head;    struct call *tmp;    while (t)    {        if (t->ourtid == tid)        {            tmp = new_call (t);            if (!tmp)            {                log (LOG_WARN, "%s: unable to create new call\n",                     __FUNCTION__);                return NULL;            }            tmp->next = t->call_head;            t->call_head = tmp;            t->count++;            tmp->cid = 0;            tmp->lac = lac;            tmp->lns = lns;            if (lac)                lac->c = tmp;            log (LOG_LOG, "%s: Calling on tunnel %d\n", __FUNCTION__, tid);            strcpy (tmp->dial_no, dial_no_tmp); /*  jz: copy dialnumber to tmp->dial_no  */            control_finish (t, tmp);            return tmp;        }        t = t->next;    };    log (LOG_DEBUG, "%s: No such tunnel %d to generate call.\n", __FUNCTION__,         tid);    return NULL;}void magic_lac_dial (void *data){    struct lac *lac;    lac = (struct lac *) data;    if (!lac->active)    {        log (LOG_DEBUG, "%s: LAC %s not active", __FUNCTION__, lac->entname);        return;    }    lac->rsched = NULL;    lac->rtries++;    if (lac->rmax && (lac->rtries > lac->rmax))    {        log (LOG_LOG, "%s: maximum retries exceeded.\n", __FUNCTION__);        return;    }    if (!lac)    {        log (LOG_WARN, "%s : called on NULL lac!\n", __FUNCTION__);        return;    }    if (!lac->t)    {#ifdef DEGUG_MAGIC        log (LOG_DEBUG, "%s : tunnel not up!  Connecting!\n", __FUNCTION__);#endif        magic_lac_tunnel (lac);        return;    }    lac_call (lac->t->ourtid, lac, NULL);}void lac_hangup (int cid){    struct tunnel *t = tunnels.head;    struct call *tmp;    while (t)    {        tmp = t->call_head;        while (tmp)        {            if (tmp->ourcid == cid)            {                log (LOG_LOG,                     "%s :Hanging up call %d, Local: %d, Remote: %d\n",                     __FUNCTION__, tmp->serno, tmp->ourcid, tmp->cid);                strcpy (tmp->errormsg, "Goodbye!");/*				tmp->needclose = -1; */                kill (tmp->pppd, SIGTERM);                return;            }            tmp = tmp->next;        }        t = t->next;    };    log (LOG_DEBUG, "%s : No such call %d to hang up.\n", __FUNCTION__, cid);    return;}void lac_disconnect (int tid){    struct tunnel *t = tunnels.head;    while (t)    {        if (t->ourtid == tid)        {            log (LOG_LOG,                 "%s: Disconnecting from %s, Local: %d, Remote: %d\n",                 __FUNCTION__, IPADDY (t->peer.sin_addr), t->ourtid, t->tid);            t->self->needclose = -1;            strcpy (t->self->errormsg, "Goodbye!");            call_close (t->self);            return;        }        t = t->next;    };    log (LOG_DEBUG, "%s: No such tunnel %d to hang up.\n", __FUNCTION__, tid);    return;}struct tunnel *new_tunnel (){    struct tunnel *tmp = malloc (sizeof (struct tunnel));    char entropy_buf[2] = "\0";    if (!tmp)        return NULL;    tmp->control_seq_num = 0;    tmp->control_rec_seq_num = 0;    tmp->cLr = 0;    tmp->call_head = NULL;    tmp->next = NULL;    tmp->debug = -1;    tmp->tid = -1;    tmp->hello = NULL;#ifndef TESTING/*	while(get_call((tmp->ourtid = rand() & 0xFFFF),0,0,0)); */#ifdef USE_KERNEL    if (kernel_support)        tmp->ourtid = ioctl (server_socket, L2TPIOCADDTUNNEL, 0);    else#endif/*        tmp->ourtid = rand () & 0xFFFF; */        /* get_entropy((char *)&tmp->ourtid, 2); */        get_entropy(entropy_buf, 2);        {            int *temp;            temp = (int *)entropy_buf;            tmp->ourtid = *temp & 0xFFFF;#ifdef DEBUG_ENTROPY            log(LOG_DEBUG, "ourtid = %u, entropy_buf = %hx\n", tmp->ourtid, *temp);#endif        }#else    tmp->ourtid = 0x6227;#endif    tmp->nego = 0;    tmp->count = 0;    tmp->state = 0;             /* Nothing */    tmp->peer.sin_family = AF_INET;    tmp->peer.sin_port = 0;    bzero (&(tmp->peer.sin_addr), sizeof (tmp->peer.sin_addr));    tmp->sanity = -1;    tmp->qtid = -1;    tmp->ourfc = ASYNC_FRAMING | SYNC_FRAMING;    tmp->ourbc = 0;    tmp->ourtb = (((_u64) rand ()) << 32) | ((_u64) rand ());    tmp->fc = -1;               /* These really need to be specified by the peer */    tmp->bc = -1;               /* And we want to know if they forgot */    tmp->hostname[0] = 0;    tmp->vendor[0] = 0;    tmp->secret[0] = 0;    if (!(tmp->self = new_call (tmp)))    {        free (tmp);        return NULL;    };    tmp->ourrws = DEFAULT_RWS_SIZE;    tmp->self->ourfbit = FBIT;    tmp->lac = NULL;    tmp->lns = NULL;    tmp->chal_us.state = 0;    tmp->chal_us.secret[0] = 0;

⌨️ 快捷键说明

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