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

📄 control.c

📁 第二层隧道模块l2tp源码,开发环境为linux
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif        strncpy (ip1, IPADDY (c->lns->localaddr), sizeof (ip1));        strncpy (ip2, IPADDY (c->addr), sizeof (ip2));        po = NULL;        po = add_opt (po, "passive");        po = add_opt (po, "-detach");        po = add_opt (po, "%s:%s", c->lns->localaddr ? ip1 : "", ip2);        if (c->lns->authself)        {            if (c->lns->pap_refuse)                po = add_opt (po, "refuse-pap");            if (c->lns->chap_refuse)                po = add_opt (po, "refuse-chap");        }        else        {            po = add_opt (po, "refuse-pap");            po = add_opt (po, "refuse-chap");        }        if (c->lns->authpeer)        {            po = add_opt (po, "auth");            if (c->lns->pap_require)                po = add_opt (po, "require-pap");            if (c->lns->chap_require)                po = add_opt (po, "require-chap");            if (c->lns->passwdauth)                po = add_opt (po, "login");        }        if (c->lns->authname[0])        {            po = add_opt (po, "name");            po = add_opt (po, c->lns->authname);        }        if (c->lns->debug)            po = add_opt (po, "debug");        if (c->lns->pppoptfile[0])        {            po = add_opt (po, "file");            po = add_opt (po, c->lns->pppoptfile);        }        start_pppd (c, po);        opt_destroy (po);        log (LOG_LOG,             "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n",             __FUNCTION__, IPADDY (t->peer.sin_addr), c->ourcid, c->cid,             c->serno);        break;    case OCRP:                 /* jz: nothing to do for OCRP, waiting for OCCN */        break;    case OCCN:                 /* jz: get OCCN, so the only thing we must do is to start the pppd */        po = NULL;        po = add_opt (po, "passive");        po = add_opt (po, "-detach");        po = add_opt (po, "file");        strcat (dummy_buf, c->dial_no); /* jz: use /etc/ppp/dialnumber.options for pppd - kick it if you dont like */        strcat (dummy_buf, ".options");        po = add_opt (po, dummy_buf);        if (c->lac)        {            if (c->lac->defaultroute)                po = add_opt (po, "defaultroute");            strncpy (ip1, IPADDY (c->lac->localaddr), sizeof (ip1));            strncpy (ip2, IPADDY (c->lac->remoteaddr), sizeof (ip2));            po = add_opt (po, "%s:%s", c->lac->localaddr ? ip1 : "",                          c->lac->remoteaddr ? ip2 : "");            if (c->lac->authself)            {                if (c->lac->pap_refuse)                    po = add_opt (po, "refuse-pap");                if (c->lac->chap_refuse)                    po = add_opt (po, "refuse-chap");            }            else            {                po = add_opt (po, "refuse-pap");                po = add_opt (po, "refuse-chap");            }            if (c->lac->authpeer)            {                po = add_opt (po, "auth");                if (c->lac->pap_require)                    po = add_opt (po, "require-pap");                if (c->lac->chap_require)                    po = add_opt (po, "require-chap");            }            if (c->lac->authname[0])            {                po = add_opt (po, "name");                po = add_opt (po, c->lac->authname);            }            if (c->lac->debug)                po = add_opt (po, "debug");            if (c->lac->pppoptfile[0])            {                po = add_opt (po, "file");                po = add_opt (po, c->lac->pppoptfile);            }        };        start_pppd (c, po);        log (LOG_LOG, "parameters: Local: %d , Remote: %d , Serial: %d , Pid: %d , Tunnelid: %d , Phoneid: %s\n", c->ourcid, c->cid, c->serno, c->pppd, t->ourtid, c->dial_no); /*  jz: just show some information */        opt_destroy (po);        if (c->lac)            c->lac->rtries = 0;        break;    case CDN:        if (c->qcid < 0)        {            if (DEBUG)                log (LOG_DEBUG,                     "%s: Peer tried to disconnect without specifying call ID\n",                     __FUNCTION__);            return -EINVAL;        }        if (c == t->self)        {            p = t->call_head;            while (p && (p->cid != c->qcid))                p = p->next;            if (!p)            {                if (DEBUG)                    log (LOG_DEBUG,                         "%s: Unable to determine call to be disconnected.\n",                         __FUNCTION__);                return -EINVAL;            }        }        else            p = c;        if ((c->qcid != p->cid) && p->cid > 0)        {            if (DEBUG)                log (LOG_DEBUG,                     "%s: Peer tried to disconnect with invalid CID (%d != %d)\n",                     __FUNCTION__, c->qcid, c->cid);            return -EINVAL;        }        c->qcid = -1;        if (c->result < 0)        {            if (DEBUG)                log (LOG_DEBUG,                     "%s: Peer tried to disconnect without specifying result code.\n",                     __FUNCTION__);            return -EINVAL;        }        log (LOG_LOG,             "%s: Connection closed to %s, serial %d (%s)\n", __FUNCTION__,             IPADDY (t->peer.sin_addr), c->serno, c->errormsg);        c->needclose = 0;        c->closing = -1;        break;    case Hello:        break;    case SLI:        break;    default:        log (LOG_DEBUG,             "%s: Don't know how to finish a message of type %d\n",             __FUNCTION__, c->msgtype);        set_error (c, VENDOR_ERROR, "Unimplemented message %d\n", c->msgtype);    }    return 0;}inline int check_control (const struct buffer *buf, struct tunnel *t,                          struct call *c){    /*     * Check if this is a valid control     * or not.  Returns 0 on success     */    struct control_hdr *h = (struct control_hdr *) (buf->start);    struct buffer *zlb;    if (buf->len < sizeof (struct control_hdr))    {        if (DEBUG)        {            log (LOG_DEBUG,                 "%s: Received too small of packet\n", __FUNCTION__);        }        return -EINVAL;    }#ifdef SANITY    if (buf->len != h->length)    {        if (DEBUG)        {            log (LOG_DEBUG,                 "%s: Reported and actual sizes differ (%d != %d)\n",                 __FUNCTION__, h->length, buf->len);        }        return -EINVAL;    }    /*     * FIXME: H-bit handling goes here     */#ifdef DEBUG_CONTROL    log (LOG_DEBUG, "%s: control, cid = %d, Ns = %d, Nr = %d\n", __FUNCTION__,         c->cid, h->Ns, h->Nr);#endif    if (h->Ns != t->control_rec_seq_num)    {        if (DEBUG)            log (LOG_DEBUG,                 "%s: Received out of order control packet on tunnel %d (%d != %d)\n",                 __FUNCTION__, t->tid, h->Ns, t->control_rec_seq_num);        if (((h->Ns < t->control_rec_seq_num) &&             ((t->control_rec_seq_num - h->Ns) < 32768)) ||            ((h->Ns > t->control_rec_seq_num) &&            ((t->control_rec_seq_num - h->Ns) > 32768)))        {            /*               * Woopsies, they sent us a message we should have already received               * so we should send them a ZLB so they know               * for sure that we already have it.             */#ifdef DEBUG_ZLB            if (DEBUG)                log (LOG_DEBUG, "%s: Sending an updated ZLB in reponse\n",                     __FUNCTION__);#endif            zlb = new_outgoing (t);            control_zlb (zlb, t, c);            udp_xmit (zlb);            toss (zlb);        }        else if (!t->control_rec_seq_num && (t->tid == -1))        {            /* We made this tunnel just for this message, so let's               destroy it.  */            c->needclose = 0;            c->closing = -1;        }        return -EINVAL;    }    else    {        t->control_rec_seq_num++;        c->cnu = -1;    }    /*     * So we know what the other end has received     * so far     */    t->cLr = h->Nr;    if (t->sanity)    {        if (!CTBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s: Control bit not set\n", __FUNCTION__);            }            return -EINVAL;        }        if (!CLBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s: Length bit not set\n", __FUNCTION__);            }            return -EINVAL;        }        if (!CFBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s: Flow bit not set\n", __FUNCTION__);            }            return -EINVAL;        }        if (CVER (h->ver) != VER_L2TP)        {            if (DEBUG)            {                if (CVER (h->ver) == VER_PPTP)                {                    log (LOG_DEBUG,                         "%s: PPTP packet received\n", __FUNCTION__);                }                else if (CVER (h->ver) < VER_L2TP)                {                    log (LOG_DEBUG,                         "%s: L2F packet received\n", __FUNCTION__);                }                else                {                    log (LOG_DEBUG,                         "%s: Unknown version received\n", __FUNCTION__);                }            }            return -EINVAL;        }    }#endif    return 0;}inline int check_payload (struct buffer *buf, struct tunnel *t,                          struct call *c){    /*     * Check if this is a valid payload     * or not.  Returns 0 on success.     */    int ehlen = MIN_PAYLOAD_HDR_LEN;    struct payload_hdr *h = (struct payload_hdr *) (buf->start);    if (!c)    {        if (DEBUG)        {            log (LOG_DEBUG, "%s: Aempted to send payload on tunnel\n",                 __FUNCTION__);        }        return -EINVAL;    }    if (buf->len < MIN_PAYLOAD_HDR_LEN)    {        /* has to be at least MIN_PAYLOAD_HDR_LEN            no matter what.  we'll look more later */        if (DEBUG)        {            log (LOG_DEBUG, "%s:Recieved to small of packet\n", __FUNCTION__);        }        return -EINVAL;    }#ifdef SANITY    if (t->sanity)    {        if (PTBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s Control bit set\n", __FUNCTION__);            }            return -EINVAL;        }        if (PLBIT (h->ver))            ehlen += 2;         /* Should have length information */        if (PFBIT (h->ver))        {/*			if (!c->fbit && !c->ourfbit) {				if (DEBUG)					log(LOG_DEBUG,"%s: flow bit set, but no RWS negotiated.\n",__FUNCTION__);				return -EINVAL;			} */            ehlen += 4;         /* Should have Ns and Nr too */        }/*		if (!PFBIT(h->ver)) {			if (c->fbit || c->ourfbit) {				if (DEBUG)					log(LOG_DEBUG, "%s: no flow bit, but RWS was negotiated.\n",__FUNCTION__);				return -EINVAL;;			}		} */        if (PSBIT (h->ver))            ehlen += 4;         /* Offset information */        if (PLBIT (h->ver))            ehlen += h->length; /* include length if available */        if (PVER (h->ver) != VER_L2TP)        {            if (DEBUG)            {                if (PVER (h->ver) == VER_PPTP)                {                    log (LOG_DEBUG, "%s: PPTP packet received\n",                         __FUNCTION__);                }                else if (CVER (h->ver) < VER_L2TP)                {                    log (LOG_DEBUG, "%s: L2F packet received\n",                         __FUNCTION__);                }                else                {                    log (LOG_DEBUG, "%s: Unknown version received\n",                         __FUNCTION__);                }            }            return -EINVAL;        }        if ((buf->len < ehlen) && !PLBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s payload too small (%d < %d)\n",                     __FUNCTION__, buf->len, ehlen);            }            return -EINVAL;        }        if ((buf->len != h->length) && PLBIT (h->ver))        {            if (DEBUG)            {                log (LOG_DEBUG, "%s: size mismatch (%d != %d)\n",                     __FUNCTION__, buf->len, h->length);            }            return -EINVAL;        }    }#endif    return 0;}inline int expand_payload (struct buffer *buf, struct tunnel *t,                           struct call *c){    /*     * Expands payload header.  Does not check for valid header,     * check_payload() should already be called as a prerequisite.     */    struct payload_hdr *h = (struct payload_hdr *) (buf->start);    _u16 *r = (_u16 *) h;       /* Nice to have raw word pointers */    struct payload_hdr *new_hdr;    int ehlen = 0;    /*     * We first calculate our offset     */    if (!PLBIT (h->ver))        ehlen += 2;             /* Should have length information */    if (!PFBIT (h->ver))        ehlen += 4;             /* Should have Ns and Nr too */    if (!PSBIT (h->ver))        ehlen += 4;             /* Offset information */    if (ehlen)    {        /*         * If this payload is missing any information, we'll         * fill it in         */        new_hdr = (struct payload_hdr *) (buf->start - ehlen);        if ((void *) new_hdr < (void *) buf->rstart)        {            log (LOG_WARN, "%s: not enough space to decompress frame\n",                 __FUNCTION__);            return -EINVAL;        };        new_hdr->ver = *r;        if (PLBIT (new_hdr->ver))        {            r++;            new_hdr->length = *r;        }        else        {

⌨️ 快捷键说明

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