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

📄 pptp_ctrl.c

📁 pptp第二层隧道模块
💻 C
📖 第 1 页 / 共 3 页
字号:
                    reply.result_code = hton8(5);                    pptp_send_ctrl_packet(conn, &reply, sizeof(reply));                    pptp_reset_timer(); /* give sender a chance for a retry */                } else { /* same or greater version */                    if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {                        conn->conn_state = CONN_ESTABLISHED;                        log("server connection ESTABLISHED.");                        pptp_reset_timer();                    }                }            }            break;        }        case PPTP_START_CTRL_CONN_RPLY:        {            struct pptp_start_ctrl_conn *packet =                 (struct pptp_start_ctrl_conn *) buffer;            log("Received Start Control Connection Reply");            if (conn->conn_state == CONN_WAIT_CTL_REPLY) {                /* XXX handle collision XXX [see rfc] */                if (ntoh16(packet->version) != PPTP_VERSION) {                    if (conn->callback != NULL)                        conn->callback(conn, CONN_OPEN_FAIL);                    close_reason = PPTP_STOP_PROTOCOL;                    goto pptp_conn_close;                }                if (ntoh8(packet->result_code) != 1 &&                    /* J'ai change le if () afin que la connection ne se ferme                     * pas pour un "rien" :p adel@cybercable.fr -                     *                      * Don't close the connection if the result code is zero                     * (feature found in certain ADSL modems)                     */                        ntoh8(packet->result_code) != 0) {                     log("Negative reply received to our Start Control "                            "Connection Request");                    ctrlp_error(packet->result_code, packet->error_code,                            -1, pptp_start_ctrl_conn_rply,                            MAX_START_CTRL_CONN_REPLY);                    if (conn->callback != NULL)                        conn->callback(conn, CONN_OPEN_FAIL);                    close_reason = PPTP_STOP_PROTOCOL;                    goto pptp_conn_close;                }                conn->conn_state = CONN_ESTABLISHED;                /* log session properties */                conn->version      = ntoh16(packet->version);                conn->firmware_rev = ntoh16(packet->firmware_rev);                memcpy(conn->hostname, packet->hostname, sizeof(conn->hostname));                memcpy(conn->vendor, packet->vendor, sizeof(conn->vendor));                pptp_reset_timer(); /* 60 seconds until keep-alive */                log("Client connection established.");                if (conn->callback != NULL)                    conn->callback(conn, CONN_OPEN_DONE);            } /* else goto pptp_conn_close; */            break;        }            /* ----------- STANDARD Stop-Session MESSAGES ------------ */        case PPTP_STOP_CTRL_CONN_RQST:        {            /* conn_state should be CONN_ESTABLISHED, but it could be              * something else */            struct pptp_stop_ctrl_conn reply = {                PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RPLY),                 hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0            };            log("Received Stop Control Connection Request.");            if (conn->conn_state == CONN_IDLE) break;            if (pptp_send_ctrl_packet(conn, &reply, sizeof(reply))) {                if (conn->callback != NULL)                    conn->callback(conn, CONN_CLOSE_RQST);                conn->conn_state = CONN_IDLE;		return -1;            }            break;        }        case PPTP_STOP_CTRL_CONN_RPLY:        {            log("Received Stop Control Connection Reply.");            /* conn_state should be CONN_WAIT_STOP_REPLY, but it              * could be something else */            if (conn->conn_state == CONN_IDLE) break;            conn->conn_state = CONN_IDLE;	    return -1;        }            /* ----------- STANDARD Echo/Keepalive MESSAGES ------------ */        case PPTP_ECHO_RPLY:        {            struct pptp_echo_rply *packet =                 (struct pptp_echo_rply *) buffer;            logecho( PPTP_ECHO_RPLY);            if ((conn->ka_state == KA_OUTSTANDING) &&                     (ntoh32(packet->identifier) == conn->ka_id)) {                conn->ka_id++;                conn->ka_state = KA_NONE;                pptp_reset_timer();            }            break;        }        case PPTP_ECHO_RQST:        {            struct pptp_echo_rqst *packet =                 (struct pptp_echo_rqst *) buffer;            struct pptp_echo_rply reply = {                PPTP_HEADER_CTRL(PPTP_ECHO_RPLY),                 packet->identifier, /* skip hton32(ntoh32(id)) */                hton8(1), hton8(PPTP_GENERAL_ERROR_NONE), 0            };            logecho( PPTP_ECHO_RQST);            pptp_send_ctrl_packet(conn, &reply, sizeof(reply));            pptp_reset_timer();            break;        }            /* ----------- OUTGOING CALL MESSAGES ------------ */        case PPTP_OUT_CALL_RQST:        {            struct pptp_out_call_rqst *packet =                (struct pptp_out_call_rqst *)buffer;            struct pptp_out_call_rply reply = {                PPTP_HEADER_CTRL(PPTP_OUT_CALL_RPLY),                0 /* callid */, packet->call_id, 1, PPTP_GENERAL_ERROR_NONE, 0,                hton32(PPTP_CONNECT_SPEED),                 hton16(PPTP_WINDOW), hton16(PPTP_DELAY), 0             };            log("Received Outgoing Call Request.");            /* XXX PAC: eventually this should make an outgoing call. XXX */            reply.result_code = hton8(7); /* outgoing calls verboten */            pptp_send_ctrl_packet(conn, &reply, sizeof(reply));            break;        }        case PPTP_OUT_CALL_RPLY:        {            struct pptp_out_call_rply *packet =                (struct pptp_out_call_rply *)buffer;            PPTP_CALL * call;            u_int16_t callid = ntoh16(packet->call_id_peer);            log("Received Outgoing Call Reply.");            if (!vector_search(conn->call, (int) callid, &call)) {                log("PPTP_OUT_CALL_RPLY received for non-existant call: "                        "peer call ID (us)  %d call ID (them) %d.",                        callid, ntoh16(packet->call_id));                break;            }            if (call->call_type != PPTP_CALL_PNS) {                log("Ack!  How did this call_type get here?"); /* XXX? */                break;             }            if (call->state.pns != PNS_WAIT_REPLY) {                warn("Unexpected(?) Outgoing Call Reply will be ignored.");                break;            }            /* check for errors */            if (packet->result_code != 1) {                /* An error.  Log it verbosely. */                log("Our outgoing call request [callid %d] has not been "                        "accepted.", (int) callid);                ctrlp_error(packet->result_code, packet->error_code,                        packet->cause_code, pptp_out_call_reply_result,                        MAX_OUT_CALL_REPLY_RESULT);                call->state.pns = PNS_IDLE;                if (call->callback != NULL)                    call->callback(conn, call, CALL_OPEN_FAIL);                pptp_call_destroy(conn, call);            } else {                /* connection established */                call->state.pns = PNS_ESTABLISHED;                call->peer_call_id = ntoh16(packet->call_id);                call->speed        = ntoh32(packet->speed);                pptp_reset_timer();                /* call pptp_set_link. unless the user specified a quirk                   and this quirk has a set_link hook, this is a noop */                pptp_set_link(conn, call->peer_call_id);                if (call->callback != NULL)                    call->callback(conn, call, CALL_OPEN_DONE);                log("Outgoing call established (call ID %u, peer's "                        "call ID %u).\n", call->call_id, call->peer_call_id);            }            break;        }            /* ----------- INCOMING CALL MESSAGES ------------ */            /* XXX write me XXX */            /* ----------- CALL CONTROL MESSAGES ------------ */        case PPTP_CALL_CLEAR_RQST:        {            struct pptp_call_clear_rqst *packet =                (struct pptp_call_clear_rqst *)buffer;            struct pptp_call_clear_ntfy reply = {                PPTP_HEADER_CTRL(PPTP_CALL_CLEAR_NTFY), packet->call_id,                1, PPTP_GENERAL_ERROR_NONE, 0, 0, {0}            };            log("Received Call Clear Request.");            if (vector_contains(conn->call, ntoh16(packet->call_id))) {                PPTP_CALL * call;                vector_search(conn->call, ntoh16(packet->call_id), &call);                if (call->callback != NULL)                    call->callback(conn, call, CALL_CLOSE_RQST);                pptp_send_ctrl_packet(conn, &reply, sizeof(reply));                pptp_call_destroy(conn, call);                log("Call closed (RQST) (call id %d)", (int) call->call_id);            }            break;        }        case PPTP_CALL_CLEAR_NTFY:        {            struct pptp_call_clear_ntfy *packet =                (struct pptp_call_clear_ntfy *)buffer;            log("Call disconnect notification received (call id %d)",                    ntoh16(packet->call_id));            if (vector_contains(conn->call, ntoh16(packet->call_id))) {                PPTP_CALL * call;                ctrlp_error(packet->result_code, packet->error_code,                        packet->cause_code, pptp_call_disc_ntfy,                        MAX_CALL_DISC_NTFY);                vector_search(conn->call, ntoh16(packet->call_id), &call);                pptp_call_destroy(conn, call);            }            /* XXX we could log call stats here XXX */            /* XXX not all servers send this XXX */            break;        }        case PPTP_SET_LINK_INFO:        {            /* I HAVE NO CLUE WHAT TO DO IF send_accm IS NOT 0! */            /* this is really dealt with in the HDLC deencapsulation, anyway. */            struct pptp_set_link_info *packet =                (struct pptp_set_link_info *)buffer;            /* log it. */            log("PPTP_SET_LINK_INFO received from peer_callid %u",                    (unsigned int) ntoh16(packet->call_id_peer));            log("  send_accm is %08lX, recv_accm is %08lX",                    (unsigned long) ntoh32(packet->send_accm),                    (unsigned long) ntoh32(packet->recv_accm));            if (!(ntoh32(packet->send_accm) == 0 &&                    ntoh32(packet->recv_accm) == 0))                warn("Non-zero Async Control Character Maps are not supported!");            break;        }        default:            log("Unrecognized Packet %d received.",                     (int) ntoh16(((struct pptp_header *)buffer)->ctrl_type));            /* goto pptp_conn_close; */            break;    }    return 0;pptp_conn_close:    warn("pptp_conn_close(%d)", (int) close_reason);    pptp_conn_close(conn, close_reason);    return 0;}/*** pptp_set_link **************************************************************/void pptp_set_link(PPTP_CONN* conn, int peer_call_id){    int idx, rc;    /* if we need to send a set_link packet because of buggy       hardware or pptp server, do it now */    if ((idx = get_quirk_index()) != -1 && pptp_fixups[idx].set_link_hook) {        struct pptp_set_link_info packet;        if ((rc = pptp_fixups[idx].set_link_hook(&packet, peer_call_id)))            warn("calling the set_link hook failed (%d)", rc);        if (pptp_send_ctrl_packet(conn, &packet, sizeof(packet))) {            pptp_reset_timer();        }    }}/*** Get info from call structure *********************************************//* NOTE: The peer_call_id is undefined until we get a server response. */void pptp_call_get_ids(PPTP_CONN * conn, PPTP_CALL * call,		       u_int16_t * call_id, u_int16_t * peer_call_id){    assert(conn != NULL); assert(call != NULL);    *call_id = call->call_id;    *peer_call_id = call->peer_call_id;}/*** pptp_call_closure_put ****************************************************/void   pptp_call_closure_put(PPTP_CONN * conn, PPTP_CALL * call, void *cl){    assert(conn != NULL); assert(call != NULL);    call->closure = cl;}/*** pptp_call_closure_get ****************************************************/void * pptp_call_closure_get(PPTP_CONN * conn, PPTP_CALL * call){    assert(conn != NULL); assert(call != NULL);    return call->closure;}/*** pptp_conn_closure_put ****************************************************/void   pptp_conn_closure_put(PPTP_CONN * conn, void *cl){    assert(conn != NULL);    conn->closure = cl;}/*** pptp_conn_closure_get ****************************************************/void * pptp_conn_closure_get(PPTP_CONN * conn){    assert(conn != NULL);    return conn->closure;}/*** Reset keep-alive timer ***************************************************/static void pptp_reset_timer(void){    const struct itimerval tv = { {  0, 0 },   /* stop on time-out */        { idle_wait, 0 } };    if (idle_wait) setitimer(ITIMER_REAL, &tv, NULL);}/*** Handle keep-alive timer **************************************************/static void pptp_handle_timer(){    int i;    /* "Keep Alives and Timers, 1": check connection state */    if (global.conn->conn_state != CONN_ESTABLISHED) {        if (global.conn->conn_state == CONN_WAIT_STOP_REPLY)             /* hard close. */            pptp_conn_destroy(global.conn);        else /* soft close */            pptp_conn_close(global.conn, PPTP_STOP_NONE);    }    /* "Keep Alives and Timers, 2": check echo status */    if (global.conn->ka_state == KA_OUTSTANDING) {        /* no response to keep-alive */        log ("closing control connection due to missing echo reply");	pptp_conn_close(global.conn, PPTP_STOP_NONE);    } else { /* ka_state == NONE */ /* send keep-alive */        struct pptp_echo_rqst rqst = {            PPTP_HEADER_CTRL(PPTP_ECHO_RQST), hton32(global.conn->ka_id) };        pptp_send_ctrl_packet(global.conn, &rqst, sizeof(rqst));        global.conn->ka_state = KA_OUTSTANDING;    }    /* check incoming/outgoing call states for !IDLE && !ESTABLISHED */    for (i = 0; i < vector_size(global.conn->call); i++) {        PPTP_CALL * call = vector_get_Nth(global.conn->call, i);        if (call->call_type == PPTP_CALL_PNS) {            if (call->state.pns == PNS_WAIT_REPLY) {                /* send close request */                pptp_call_close(global.conn, call);                assert(call->state.pns == PNS_WAIT_DISCONNECT);            } else if (call->state.pns == PNS_WAIT_DISCONNECT) {                /* hard-close the call */                pptp_call_destroy(global.conn, call);            }        } else if (call->call_type == PPTP_CALL_PAC) {            if (call->state.pac == PAC_WAIT_REPLY) {                /* XXX FIXME -- drop the PAC connection XXX */            } else if (call->state.pac == PAC_WAIT_CS_ANS) {                /* XXX FIXME -- drop the PAC connection XXX */            }        }    }    pptp_reset_timer();}

⌨️ 快捷键说明

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