📄 pppipcp.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/ppp/pppipcp.c *//* Release: 2001.3 *//* Version: 2001.0 *//* Purpose: Negotiate IP parameters *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2001, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "pppp.h"#if MAX_PPP_INTF/***********************************************************************//* Configuration Values *//***********************************************************************/#define IPCP_REQ_LIMIT 10 /* max REQ sends */#define IPCP_NAK_LIMIT 5 /* max NAK sends */#define IPCP_TERM_LIMIT 3 /* max TERM REQ sends */#define IPCP_TIMEOUT 3 /* seconds to wait for response *//***********************************************************************//* Symbol Definitions *//***********************************************************************/#define IPCP_COMP_SLOT 1 /* may compress slot id *//***********************************************************************//* Function Prototypes *//***********************************************************************/static void ipcp_starting(FSM *fsm);static void ipcp_up(FSM *fsm);static void ipcp_down(FSM *fsm);static void ipcp_finished(FSM *fsm);static NetBuf *make_req(FSM *fsm);static int check_req(FSM *fsm, ConfigHdr *config);static int check_ack(FSM *fsm, ConfigHdr *config);static int nak_check(FSM *fsm, ConfigHdr *config);static int check_rej(FSM *fsm, ConfigHdr *config);/***********************************************************************//* Constant Data Definitions *//***********************************************************************/static const struct fsm_constants ipcp_constants ={ "IPCP", PPP_IPCP_PROTO, 0x00FE, /* codes 1-7 recognized */ kIPCP, IPCP_REQ_LIMIT, IPCP_NAK_LIMIT, IPCP_TERM_LIMIT, IPCP_TIMEOUT * TICKS_PER_SEC, ipcp_starting, ipcp_up, ipcp_down, ipcp_finished, make_req, check_req, check_ack, nak_check, check_rej,};/***********************************************************************//* Function Definitions *//***********************************************************************//***********************************************************************//* add_option: Write specified option to reply buffer *//* *//***********************************************************************/static void add_option(NetBuf *buf, IpcpOpts *opts, int otype){ int olen; ui8 *cp = buf->app_data + 2; /* point past type and length */ /*-------------------------------------------------------------------*/ /* Parse option type and write response to buffer. */ /*-------------------------------------------------------------------*/ switch (otype) { case IPCP_COMPRESS: cp = put16(cp, opts->comp_proto);#if PPP_TRACE pppLog(" making IP compression 0x%04X", opts->comp_proto);#endif if (opts->comp_proto == PPP_COMP_PROTO) { *cp++ = opts->slots - 1; *cp++ = opts->comp_slot;#if PPP_TRACE pppLog(" with IP compression slots %u, flag %X", opts->slots, opts->comp_slot);#endif } break; case IPCP_ADDRESS: cp = put32(cp, opts->address);#if PPP_TRACE pppLog(" making IP src address %s", pppIps(opts->address));#endif break; default:#if PPP_TRACE pppLog(" making unimplemented type %02X", otype);#endif break; } /*-------------------------------------------------------------------*/ /* Record option type and length. */ /*-------------------------------------------------------------------*/ olen = cp - buf->app_data; buf->app_data[0] = (ui8)otype; buf->app_data[1] = (ui8)olen; /*-------------------------------------------------------------------*/ /* Update buffer indices. */ /*-------------------------------------------------------------------*/ buf->app_data = cp; buf->length += olen;}/***********************************************************************//* make_opts: Build list of IPCP options. Used to build unsolicated *//* NAK list and our configuration requests *//* *//***********************************************************************/static void make_opts(NetBuf *buf, IpcpOpts *opts, uint negotiating){ int otype; /*-------------------------------------------------------------------*/ /* Add each option in turn. */ /*-------------------------------------------------------------------*/ for (otype = 1; otype <= IPCP_OPT_LIMIT; ++otype) { if (negotiating & (1 << otype)) add_option(buf, opts, otype); }}/***********************************************************************//* make_req: Build a request to send to peer *//* *//***********************************************************************/static NetBuf *make_req(FSM *fsm){ NetBuf *buf; IpcpCB *ipcp = &Ppp->ipcp; /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return NULL if unable. */ /*-------------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + PPP_MTU + CRC16_LEN); if (buf == NULL) return NULL; /*-------------------------------------------------------------------*/ /* Build packet with all options currently being negotiated. */ /*-------------------------------------------------------------------*/ make_opts(buf, &ipcp->local, ipcp->local.options); return buf;}/***********************************************************************//* check_req_opt: Check requested option, updating our remote value *//* *//* Inputs: remote = negotiation parameters for remote side *//* opt = pointer to received option header *//* *//* Returns: -1 if ran out of data, ACK/NAK/REJ as appropriate *//* *//***********************************************************************/static int check_req_opt(IpcpOpts *remote, OptHdr *opt){ int toss = opt->len - OPTION_HDR_LEN; int result = CONFIG_ACK; /* assume good values */ int test; /*-------------------------------------------------------------------*/ /* Parse option type. */ /*-------------------------------------------------------------------*/ switch (opt->type) { case IPCP_COMPRESS: /*---------------------------------------------------------------*/ /* Verify compression option length is correct. */ /*---------------------------------------------------------------*/ if (opt->len != 6) { opt->len = 6; result = CONFIG_NAK; if (toss < 0) toss = 0; break; } /*---------------------------------------------------------------*/ /* Read the peer's requested compression option. */ /*---------------------------------------------------------------*/ remote->comp_proto = pull16(pppRcvBuf); toss -= 2;#if PPP_TRACE pppLog(" checking IP comp_proto=0x%04X", remote->comp_proto);#endif /*---------------------------------------------------------------*/ /* Check if requested type is acceptable. */ /*---------------------------------------------------------------*/ switch (remote->comp_proto) { case PPP_COMP_PROTO: test = pullchar(pppRcvBuf); if (test == -1) return -1; remote->slots = test + 1; if (remote->slots < VJ_SLOT_LO) { remote->slots = VJ_SLOT_LO; result = CONFIG_NAK; } else if (remote->slots > VJ_SLOT_HI) { remote->slots = VJ_SLOT_HI; result = CONFIG_NAK; } test = pullchar(pppRcvBuf); if (test == -1) return -1; remote->comp_slot = test; if (remote->comp_slot > 1) { remote->comp_slot = 1; result = CONFIG_NAK; } toss -= 2;#if PPP_TRACE pppLog(" with IP compression slots=%u, flag=%X", remote->slots, remote->comp_slot);#endif break; default: remote->comp_proto = PPP_COMP_PROTO; remote->slots = VJ_SLOT_DEF; remote->comp_slot = IPCP_COMP_SLOT; result = CONFIG_NAK; break; } break; case IPCP_ADDRESS: /*---------------------------------------------------------------*/ /* Verify address option length is correct. */ /*---------------------------------------------------------------*/ if (opt->len != 6) { opt->len = 6; result = CONFIG_NAK; if (toss < 0) toss = 0; break; } /*---------------------------------------------------------------*/ /* Read the peer's requested address. */ /*---------------------------------------------------------------*/ remote->address = pull32(pppRcvBuf); toss -= 4;#if PPP_TRACE pppLog(" checking IP dst address %s", pppIps(remote->address));#endif /*---------------------------------------------------------------*/ /* If a remote address has been configured, must match it. */ /*---------------------------------------------------------------*/ if (Ppp->public.remote_addr) { if (remote->address != Ppp->public.remote_addr) { remote->address = Ppp->public.remote_addr; result = CONFIG_NAK; } } /*---------------------------------------------------------------*/ /* Else reject option if address not supplied by peer. */ /*---------------------------------------------------------------*/ else if (remote->address == 0) result = CONFIG_REJ; break; default: /*---------------------------------------------------------------*/ /* Reject option if we don't recognize it. */ /*---------------------------------------------------------------*/ result = CONFIG_REJ; break; } /*-------------------------------------------------------------------*/ /* Reject option if we are not set to accept it. */ /*-------------------------------------------------------------------*/ if ((Ppp->ipcp_accept_opts & (1 << opt->type)) == FALSE) result = CONFIG_REJ; /*-------------------------------------------------------------------*/ /* Return error if buffer ran out of data. */ /*-------------------------------------------------------------------*/ if (toss < 0) return -1; /*-------------------------------------------------------------------*/ /* Toss any remaining bytes in option. */ /*-------------------------------------------------------------------*/ while (toss-- > 0) { if (pullchar(pppRcvBuf) == -1) return -1; } return result;}/***********************************************************************//* check_req: Check peer's configuration request *//* *//* Returns: 0 if able to accept options, else TRUE *//* *//***********************************************************************/static int check_req(FSM *fsm, ConfigHdr *config){ int signed_length = config->len; IpcpCB *ipcp = &Ppp->ipcp; NetBuf *buf; /* reply packet */ int reply_result = CONFIG_ACK;/* reply to request */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -